| Index: tools/gn/analyzer_unittest.cc
 | 
| diff --git a/tools/gn/analyzer_unittest.cc b/tools/gn/analyzer_unittest.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..6910a678483c2059d6a03c96b3e61e12d4609ef2
 | 
| --- /dev/null
 | 
| +++ b/tools/gn/analyzer_unittest.cc
 | 
| @@ -0,0 +1,173 @@
 | 
| +// Copyright 2016 The Chromium Authors. All rights reserved.
 | 
| +// Use of this source code is governed by a BSD-style license that can be
 | 
| +// found in the LICENSE file.
 | 
| +
 | 
| +#include "testing/gtest/include/gtest/gtest.h"
 | 
| +#include "tools/gn/analyzer.h"
 | 
| +#include "tools/gn/build_settings.h"
 | 
| +#include "tools/gn/builder.h"
 | 
| +#include "tools/gn/loader.h"
 | 
| +#include "tools/gn/settings.h"
 | 
| +#include "tools/gn/source_file.h"
 | 
| +
 | 
| +
 | 
| +namespace {
 | 
| +
 | 
| +class MockLoader : public Loader {
 | 
| + public:
 | 
| +  MockLoader() {}
 | 
| +
 | 
| +  void Load(const SourceFile& file,
 | 
| +            const LocationRange& origin,
 | 
| +            const Label& toolchain_name) override {}
 | 
| +  void ToolchainLoaded(const Toolchain* toolchain) override {}
 | 
| +  Label GetDefaultToolchain() const override {
 | 
| +    return Label(SourceDir("//tc/"), "default");
 | 
| +  }
 | 
| +  const Settings* GetToolchainSettings(const Label& label) const override {
 | 
| +    return nullptr;
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  ~MockLoader() override {}
 | 
| +};
 | 
| +
 | 
| +class AnalyzerTest : public testing::Test {
 | 
| + public:
 | 
| +  AnalyzerTest()
 | 
| +      : loader_(new MockLoader),
 | 
| +        builder_(loader_.get()),
 | 
| +        settings_(&build_settings_, std::string()) {
 | 
| +    build_settings_.SetBuildDir(SourceDir("//out/"));
 | 
| +    settings_.set_toolchain_label(Label(SourceDir("//tc/"), "default"));
 | 
| +    settings_.set_default_toolchain_label(settings_.toolchain_label());
 | 
| +    tc_dir_ = settings_.toolchain_label().dir();
 | 
| +    tc_name_ = settings_.toolchain_label().name();
 | 
| +  }
 | 
| +
 | 
| +  Target* MakeTarget(const std::string dir,
 | 
| +                     const std::string name,
 | 
| +                     Target::OutputType type,
 | 
| +                     const std::vector<std::string>& sources,
 | 
| +                     const std::vector<Target*>& deps) {
 | 
| +    Label lbl(SourceDir(dir), name, tc_dir_, tc_name_);
 | 
| +    Target* target = new Target(&settings_, lbl);
 | 
| +    target->set_output_type(type);
 | 
| +    for (const auto& s : sources)
 | 
| +      target->sources().push_back(SourceFile(s));
 | 
| +    for (const auto* d : deps)
 | 
| +      target->public_deps().push_back(LabelTargetPair(d));
 | 
| +    builder_.ItemDefined(std::unique_ptr<Item>(target));
 | 
| +    return target;
 | 
| +  }
 | 
| +
 | 
| +  void AddSource(Target* a, std::string path) {}
 | 
| +
 | 
| +  void AddDep(Target* a, Target* b) {}
 | 
| +
 | 
| +  void SetUpABasicBuildGraph() {
 | 
| +    std::vector<std::string> no_sources;
 | 
| +    std::vector<Target*> no_deps;
 | 
| +
 | 
| +    // All of the targets below are owned by the builder, so none of them
 | 
| +    // get leaked.
 | 
| +
 | 
| +    // Ignore the returned target since nothing depends on it.
 | 
| +    MakeTarget("//", "a", Target::EXECUTABLE, {"//a.cc"}, no_deps);
 | 
| +
 | 
| +    Target* b =
 | 
| +        MakeTarget("//d", "b", Target::SOURCE_SET, {"//d/b.cc"}, no_deps);
 | 
| +
 | 
| +    Target* b_unittests = MakeTarget("//d", "b_unittests", Target::EXECUTABLE,
 | 
| +                                     {"//d/b_unittest.cc"}, {b});
 | 
| +
 | 
| +    Target* c = MakeTarget("//d", "c", Target::EXECUTABLE, {"//d/c.cc"}, {b});
 | 
| +
 | 
| +    Target* b_unittests_and_c =
 | 
| +        MakeTarget("//d", "b_unittests_and_c", Target::GROUP, no_sources,
 | 
| +                   {b_unittests, c});
 | 
| +
 | 
| +    Target* e =
 | 
| +        MakeTarget("//d", "e", Target::EXECUTABLE, {"//d/e.cc"}, no_deps);
 | 
| +
 | 
| +    // Also ignore this returned target since nothing depends on it.
 | 
| +    MakeTarget("//d", "d", Target::GROUP, no_sources, {b_unittests_and_c, e});
 | 
| +  }
 | 
| +
 | 
| +  void RunBasicTest(const std::string& input,
 | 
| +                    const std::string& expected_output) {
 | 
| +    SetUpABasicBuildGraph();
 | 
| +    Err err;
 | 
| +    std::string actual_output = Analyzer(builder_).Analyze(input, &err);
 | 
| +    EXPECT_EQ(err.has_error(), false);
 | 
| +    EXPECT_EQ(expected_output, actual_output);
 | 
| +  }
 | 
| +
 | 
| + protected:
 | 
| +  scoped_refptr<MockLoader> loader_;
 | 
| +  Builder builder_;
 | 
| +  BuildSettings build_settings_;
 | 
| +  Settings settings_;
 | 
| +  SourceDir tc_dir_;
 | 
| +  std::string tc_name_;
 | 
| +};
 | 
| +
 | 
| +}  // namespace
 | 
| +
 | 
| +// TODO: clean this up when raw string literals are allowed.
 | 
| +
 | 
| +TEST_F(AnalyzerTest, AllWasPruned) {
 | 
| +  RunBasicTest(
 | 
| +      "{"
 | 
| +      "  \"files\": [ \"//d/b.cc\" ],"
 | 
| +      "  \"compile_targets\": [ \"all\" ],"
 | 
| +      "  \"test_targets\": [ ]"
 | 
| +      "}",
 | 
| +      "{"
 | 
| +      "\"compile_targets\":[\"//d:b_unittests\",\"//d:c\"],"
 | 
| +      "\"status\":\"Found dependency\","
 | 
| +      "\"test_targets\":[]"
 | 
| +      "}");
 | 
| +}
 | 
| +
 | 
| +TEST_F(AnalyzerTest, NoDependency) {
 | 
| +  RunBasicTest(
 | 
| +      "{"
 | 
| +      "  \"files\":[ \"//missing.cc\" ],"
 | 
| +      "  \"compile_targets\": [ \"all\" ],"
 | 
| +      "  \"test_targets\": [ \"//:a\" ]"
 | 
| +      "}",
 | 
| +      "{"
 | 
| +      "\"compile_targets\":[],"
 | 
| +      "\"status\":\"No dependency\","
 | 
| +      "\"test_targets\":[]"
 | 
| +      "}");
 | 
| +}
 | 
| +
 | 
| +TEST_F(AnalyzerTest, NoFilesNoTargets) {
 | 
| +  RunBasicTest(
 | 
| +      "{"
 | 
| +      "  \"files\": [],"
 | 
| +      "  \"compile_targets\": [],"
 | 
| +      "  \"test_targets\": []"
 | 
| +      "}",
 | 
| +      "{"
 | 
| +      "\"compile_targets\":[],"
 | 
| +      "\"status\":\"No dependency\","
 | 
| +      "\"test_targets\":[]"
 | 
| +      "}");
 | 
| +}
 | 
| +
 | 
| +TEST_F(AnalyzerTest, OneTestTargetModified) {
 | 
| +  RunBasicTest(
 | 
| +      "{"
 | 
| +      "  \"files\": [ \"//a.cc\" ],"
 | 
| +      "  \"compile_targets\": [],"
 | 
| +      "  \"test_targets\": [ \"//:a\" ]"
 | 
| +      "}",
 | 
| +      "{"
 | 
| +      "\"compile_targets\":[],"
 | 
| +      "\"status\":\"Found dependency\","
 | 
| +      "\"test_targets\":[\"//:a\"]"
 | 
| +      "}");
 | 
| +}
 | 
| 
 |