| Index: tools/gn/header_checker_unittest.cc
|
| diff --git a/tools/gn/header_checker_unittest.cc b/tools/gn/header_checker_unittest.cc
|
| index e916546a6ba66c14e3671dcb35bd58a32ef4ec18..331970426d1c2767b7e64c01e8286623a02c6ad8 100644
|
| --- a/tools/gn/header_checker_unittest.cc
|
| +++ b/tools/gn/header_checker_unittest.cc
|
| @@ -5,6 +5,7 @@
|
| #include <vector>
|
|
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| +#include "tools/gn/config.h"
|
| #include "tools/gn/header_checker.h"
|
| #include "tools/gn/scheduler.h"
|
| #include "tools/gn/target.h"
|
| @@ -17,7 +18,8 @@ class HeaderCheckerTest : public testing::Test {
|
| HeaderCheckerTest()
|
| : a_(setup_.settings(), Label(SourceDir("//a/"), "a")),
|
| b_(setup_.settings(), Label(SourceDir("//b/"), "a")),
|
| - c_(setup_.settings(), Label(SourceDir("//c/"), "c")) {
|
| + c_(setup_.settings(), Label(SourceDir("//c/"), "c")),
|
| + d_(setup_.settings(), Label(SourceDir("//d/"), "d")) {
|
| a_.deps().push_back(LabelTargetPair(&b_));
|
| b_.deps().push_back(LabelTargetPair(&c_));
|
|
|
| @@ -25,10 +27,12 @@ class HeaderCheckerTest : public testing::Test {
|
| a_.visibility().SetPublic();
|
| b_.visibility().SetPublic();
|
| c_.visibility().SetPublic();
|
| + d_.visibility().SetPublic();
|
|
|
| targets_.push_back(&a_);
|
| targets_.push_back(&b_);
|
| targets_.push_back(&c_);
|
| + targets_.push_back(&d_);
|
| }
|
|
|
| protected:
|
| @@ -41,6 +45,7 @@ class HeaderCheckerTest : public testing::Test {
|
| Target a_;
|
| Target b_;
|
| Target c_;
|
| + Target d_;
|
|
|
| std::vector<const Target*> targets_;
|
| };
|
| @@ -52,24 +57,88 @@ TEST_F(HeaderCheckerTest, IsDependencyOf) {
|
| new HeaderChecker(setup_.build_settings(), targets_));
|
|
|
| std::vector<const Target*> chain;
|
| - EXPECT_FALSE(checker->IsDependencyOf(&a_, &a_, &chain));
|
| + EXPECT_FALSE(checker->IsDependencyOf(&a_, &a_, false, &chain, NULL));
|
|
|
| chain.clear();
|
| - EXPECT_TRUE(checker->IsDependencyOf(&b_, &a_, &chain));
|
| + EXPECT_TRUE(checker->IsDependencyOf(&b_, &a_, false, &chain, NULL));
|
| ASSERT_EQ(2u, chain.size());
|
| EXPECT_EQ(&b_, chain[0]);
|
| EXPECT_EQ(&a_, chain[1]);
|
|
|
| chain.clear();
|
| - EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, &chain));
|
| + EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, false, &chain, NULL));
|
| ASSERT_EQ(3u, chain.size());
|
| EXPECT_EQ(&c_, chain[0]);
|
| EXPECT_EQ(&b_, chain[1]);
|
| EXPECT_EQ(&a_, chain[2]);
|
|
|
| chain.clear();
|
| - EXPECT_FALSE(checker->IsDependencyOf(&a_, &c_, &chain));
|
| + EXPECT_FALSE(checker->IsDependencyOf(&a_, &c_, false, &chain, NULL));
|
| EXPECT_TRUE(chain.empty());
|
| +
|
| + // If an a -> c dependency exists, this should be chosen for the chain.
|
| + chain.clear();
|
| + a_.deps().push_back(LabelTargetPair(&c_));
|
| + EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, false, &chain, NULL));
|
| + EXPECT_EQ(&c_, chain[0]);
|
| + EXPECT_EQ(&a_, chain[1]);
|
| +}
|
| +
|
| +TEST_F(HeaderCheckerTest, IsDependencyOf_ForwardsDirectDependentConfigs) {
|
| + scoped_refptr<HeaderChecker> checker(
|
| + new HeaderChecker(setup_.build_settings(), targets_));
|
| +
|
| + // The a -> b -> c chain is found, since no chains that forward direct-
|
| + // dependent configs exist.
|
| + std::vector<const Target*> chain;
|
| + bool direct_dependent_configs_apply = false;
|
| + EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, true, &chain,
|
| + &direct_dependent_configs_apply));
|
| + EXPECT_FALSE(direct_dependent_configs_apply);
|
| + EXPECT_EQ(3u, chain.size());
|
| + EXPECT_EQ(&c_, chain[0]);
|
| + EXPECT_EQ(&b_, chain[1]);
|
| + EXPECT_EQ(&a_, chain[2]);
|
| +
|
| + // Create a chain a -> d -> c where d forwards direct-dependent configs.
|
| + // This path should be preferred when dependency chains which forward
|
| + // direct-dependent configs are preferred.
|
| + chain.clear();
|
| + direct_dependent_configs_apply = false;
|
| + d_.deps().push_back(LabelTargetPair(&c_));
|
| + d_.forward_dependent_configs().push_back(LabelTargetPair(&c_));
|
| + a_.deps().push_back(LabelTargetPair(&d_));
|
| + EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, true, &chain,
|
| + &direct_dependent_configs_apply));
|
| + EXPECT_TRUE(direct_dependent_configs_apply);
|
| + EXPECT_EQ(3u, chain.size());
|
| + EXPECT_EQ(&c_, chain[0]);
|
| + EXPECT_EQ(&d_, chain[1]);
|
| + EXPECT_EQ(&a_, chain[2]);
|
| +
|
| + // d also forwards direct-dependent configs if it is a group.
|
| + chain.clear();
|
| + direct_dependent_configs_apply = false;
|
| + d_.set_output_type(Target::GROUP);
|
| + d_.forward_dependent_configs().clear();
|
| + EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, true, &chain,
|
| + &direct_dependent_configs_apply));
|
| + EXPECT_TRUE(direct_dependent_configs_apply);
|
| + EXPECT_EQ(3u, chain.size());
|
| + EXPECT_EQ(&c_, chain[0]);
|
| + EXPECT_EQ(&d_, chain[1]);
|
| + EXPECT_EQ(&a_, chain[2]);
|
| +
|
| + // A direct dependency a -> c carries direct-dependent configs.
|
| + chain.clear();
|
| + direct_dependent_configs_apply = false;
|
| + a_.deps().push_back(LabelTargetPair(&c_));
|
| + EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, true, &chain,
|
| + &direct_dependent_configs_apply));
|
| + EXPECT_TRUE(direct_dependent_configs_apply);
|
| + EXPECT_EQ(2u, chain.size());
|
| + EXPECT_EQ(&c_, chain[0]);
|
| + EXPECT_EQ(&a_, chain[1]);
|
| }
|
|
|
| TEST_F(HeaderCheckerTest, CheckInclude) {
|
| @@ -79,9 +148,8 @@ TEST_F(HeaderCheckerTest, CheckInclude) {
|
|
|
| // Add a disconnected target d with a header to check that you have to have
|
| // to depend on a target listing a header.
|
| - Target d(setup_.settings(), Label(SourceDir("//"), "d"));
|
| SourceFile d_header("//d_header.h");
|
| - d.sources().push_back(SourceFile(d_header));
|
| + d_.sources().push_back(SourceFile(d_header));
|
|
|
| // Add a header on B and say everything in B is public.
|
| SourceFile b_public("//b_public.h");
|
| @@ -95,7 +163,7 @@ TEST_F(HeaderCheckerTest, CheckInclude) {
|
| c_.public_headers().push_back(c_public);
|
| c_.set_all_headers_public(false);
|
|
|
| - targets_.push_back(&d);
|
| + targets_.push_back(&d_);
|
| scoped_refptr<HeaderChecker> checker(
|
| new HeaderChecker(setup_.build_settings(), targets_));
|
|
|
| @@ -129,9 +197,36 @@ TEST_F(HeaderCheckerTest, CheckInclude) {
|
| err = Err();
|
| EXPECT_FALSE(checker->CheckInclude(&a_, input_file, c_public, range, &err));
|
| EXPECT_TRUE(err.has_error());
|
| + c_.visibility().SetPublic();
|
| +
|
| + // If C has direct-dependent configs, then B must forward them to A.
|
| + // If B is a group, that suffices to forward direct-dependent configs.
|
| + {
|
| + Config direct(setup_.settings(), Label(SourceDir("//c/"), "config"));
|
| + direct.config_values().cflags().push_back("-DSOME_DEFINE");
|
| +
|
| + c_.direct_dependent_configs().push_back(LabelConfigPair(&direct));
|
| + err = Err();
|
| + EXPECT_FALSE(checker->CheckInclude(&a_, input_file, c_public, range, &err));
|
| + EXPECT_TRUE(err.has_error());
|
| +
|
| + b_.forward_dependent_configs().push_back(LabelTargetPair(&c_));
|
| + err = Err();
|
| + EXPECT_TRUE(checker->CheckInclude(&a_, input_file, c_public, range, &err));
|
| + EXPECT_FALSE(err.has_error());
|
| +
|
| + b_.forward_dependent_configs().clear();
|
| + b_.set_output_type(Target::GROUP);
|
| + err = Err();
|
| + EXPECT_TRUE(checker->CheckInclude(&a_, input_file, c_public, range, &err));
|
| + EXPECT_FALSE(err.has_error());
|
| +
|
| + b_.set_output_type(Target::UNKNOWN);
|
| + c_.direct_dependent_configs().clear();
|
| + }
|
| }
|
|
|
| -TEST_F(HeaderCheckerTest, DoDirectDependentConfigsApply) {
|
| +TEST_F(HeaderCheckerTest, GetDependentConfigChainProblemIndex) {
|
| // Assume we have a chain A -> B -> C -> D.
|
| Target target_a(setup_.settings(), Label(SourceDir("//a/"), "a"));
|
| Target target_b(setup_.settings(), Label(SourceDir("//b/"), "b"));
|
| @@ -153,19 +248,12 @@ TEST_F(HeaderCheckerTest, DoDirectDependentConfigsApply) {
|
| chain.push_back(&target_b);
|
| chain.push_back(&target_a);
|
|
|
| - // This chain should be valid.
|
| - size_t badone = 0;
|
| - EXPECT_TRUE(HeaderChecker::DoDirectDependentConfigsApply(chain, &badone));
|
| -
|
| // If C is not a group, it shouldn't work anymore.
|
| target_c.set_output_type(Target::SOURCE_SET);
|
| - EXPECT_FALSE(HeaderChecker::DoDirectDependentConfigsApply(chain, &badone));
|
| - EXPECT_EQ(1u, badone);
|
| + EXPECT_EQ(1u, HeaderChecker::GetDependentConfigChainProblemIndex(chain));
|
|
|
| // Or if B stops forwarding from C, it shouldn't work anymore.
|
| target_c.set_output_type(Target::GROUP);
|
| - badone = 0;
|
| target_b.forward_dependent_configs().clear();
|
| - EXPECT_FALSE(HeaderChecker::DoDirectDependentConfigsApply(chain, &badone));
|
| - EXPECT_EQ(2u, badone);
|
| + EXPECT_EQ(2u, HeaderChecker::GetDependentConfigChainProblemIndex(chain));
|
| }
|
|
|