Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(784)

Side by Side Diff: tools/gn/header_checker_unittest.cc

Issue 424133002: GN: (HeaderChecker) Allow any chain to forward direct dependent configs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge with UniqueVector Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/gn/header_checker.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <vector> 5 #include <vector>
6 6
7 #include "testing/gtest/include/gtest/gtest.h" 7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "tools/gn/config.h"
8 #include "tools/gn/header_checker.h" 9 #include "tools/gn/header_checker.h"
9 #include "tools/gn/scheduler.h" 10 #include "tools/gn/scheduler.h"
10 #include "tools/gn/target.h" 11 #include "tools/gn/target.h"
11 #include "tools/gn/test_with_scope.h" 12 #include "tools/gn/test_with_scope.h"
12 13
13 namespace { 14 namespace {
14 15
15 class HeaderCheckerTest : public testing::Test { 16 class HeaderCheckerTest : public testing::Test {
16 public: 17 public:
17 HeaderCheckerTest() 18 HeaderCheckerTest()
18 : a_(setup_.settings(), Label(SourceDir("//a/"), "a")), 19 : a_(setup_.settings(), Label(SourceDir("//a/"), "a")),
19 b_(setup_.settings(), Label(SourceDir("//b/"), "a")), 20 b_(setup_.settings(), Label(SourceDir("//b/"), "a")),
20 c_(setup_.settings(), Label(SourceDir("//c/"), "c")) { 21 c_(setup_.settings(), Label(SourceDir("//c/"), "c")),
22 d_(setup_.settings(), Label(SourceDir("//d/"), "d")) {
21 a_.deps().push_back(LabelTargetPair(&b_)); 23 a_.deps().push_back(LabelTargetPair(&b_));
22 b_.deps().push_back(LabelTargetPair(&c_)); 24 b_.deps().push_back(LabelTargetPair(&c_));
23 25
24 // Start with all public visibility. 26 // Start with all public visibility.
25 a_.visibility().SetPublic(); 27 a_.visibility().SetPublic();
26 b_.visibility().SetPublic(); 28 b_.visibility().SetPublic();
27 c_.visibility().SetPublic(); 29 c_.visibility().SetPublic();
30 d_.visibility().SetPublic();
28 31
29 targets_.push_back(&a_); 32 targets_.push_back(&a_);
30 targets_.push_back(&b_); 33 targets_.push_back(&b_);
31 targets_.push_back(&c_); 34 targets_.push_back(&c_);
35 targets_.push_back(&d_);
32 } 36 }
33 37
34 protected: 38 protected:
35 Scheduler scheduler_; 39 Scheduler scheduler_;
36 40
37 TestWithScope setup_; 41 TestWithScope setup_;
38 42
39 // Some headers that are automatically set up with a dependency chain. 43 // Some headers that are automatically set up with a dependency chain.
40 // a -> b -> c 44 // a -> b -> c
41 Target a_; 45 Target a_;
42 Target b_; 46 Target b_;
43 Target c_; 47 Target c_;
48 Target d_;
44 49
45 std::vector<const Target*> targets_; 50 std::vector<const Target*> targets_;
46 }; 51 };
47 52
48 } // namespace 53 } // namespace
49 54
50 TEST_F(HeaderCheckerTest, IsDependencyOf) { 55 TEST_F(HeaderCheckerTest, IsDependencyOf) {
51 scoped_refptr<HeaderChecker> checker( 56 scoped_refptr<HeaderChecker> checker(
52 new HeaderChecker(setup_.build_settings(), targets_)); 57 new HeaderChecker(setup_.build_settings(), targets_));
53 58
54 std::vector<const Target*> chain; 59 std::vector<const Target*> chain;
55 EXPECT_FALSE(checker->IsDependencyOf(&a_, &a_, &chain)); 60 EXPECT_FALSE(checker->IsDependencyOf(&a_, &a_, false, &chain, NULL));
56 61
57 chain.clear(); 62 chain.clear();
58 EXPECT_TRUE(checker->IsDependencyOf(&b_, &a_, &chain)); 63 EXPECT_TRUE(checker->IsDependencyOf(&b_, &a_, false, &chain, NULL));
59 ASSERT_EQ(2u, chain.size()); 64 ASSERT_EQ(2u, chain.size());
60 EXPECT_EQ(&b_, chain[0]); 65 EXPECT_EQ(&b_, chain[0]);
61 EXPECT_EQ(&a_, chain[1]); 66 EXPECT_EQ(&a_, chain[1]);
62 67
63 chain.clear(); 68 chain.clear();
64 EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, &chain)); 69 EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, false, &chain, NULL));
65 ASSERT_EQ(3u, chain.size()); 70 ASSERT_EQ(3u, chain.size());
66 EXPECT_EQ(&c_, chain[0]); 71 EXPECT_EQ(&c_, chain[0]);
67 EXPECT_EQ(&b_, chain[1]); 72 EXPECT_EQ(&b_, chain[1]);
68 EXPECT_EQ(&a_, chain[2]); 73 EXPECT_EQ(&a_, chain[2]);
69 74
70 chain.clear(); 75 chain.clear();
71 EXPECT_FALSE(checker->IsDependencyOf(&a_, &c_, &chain)); 76 EXPECT_FALSE(checker->IsDependencyOf(&a_, &c_, false, &chain, NULL));
72 EXPECT_TRUE(chain.empty()); 77 EXPECT_TRUE(chain.empty());
78
79 // If an a -> c dependency exists, this should be chosen for the chain.
80 chain.clear();
81 a_.deps().push_back(LabelTargetPair(&c_));
82 EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, false, &chain, NULL));
83 EXPECT_EQ(&c_, chain[0]);
84 EXPECT_EQ(&a_, chain[1]);
85 }
86
87 TEST_F(HeaderCheckerTest, IsDependencyOf_ForwardsDirectDependentConfigs) {
88 scoped_refptr<HeaderChecker> checker(
89 new HeaderChecker(setup_.build_settings(), targets_));
90
91 // The a -> b -> c chain is found, since no chains that forward direct-
92 // dependent configs exist.
93 std::vector<const Target*> chain;
94 bool direct_dependent_configs_apply = false;
95 EXPECT_TRUE(checker->IsDependencyOf(
96 &c_, &a_, true, &chain, &direct_dependent_configs_apply));
97 EXPECT_FALSE(direct_dependent_configs_apply);
98 EXPECT_EQ(3u, chain.size());
99 EXPECT_EQ(&c_, chain[0]);
100 EXPECT_EQ(&b_, chain[1]);
101 EXPECT_EQ(&a_, chain[2]);
102
103 // Create a chain a -> d -> c where d forwards direct-dependent configs.
104 // This path should be preferred when dependency chains which forward
105 // direct-dependent configs are preferred.
106 chain.clear();
107 direct_dependent_configs_apply = false;
108 d_.deps().push_back(LabelTargetPair(&c_));
109 d_.forward_dependent_configs().push_back(LabelTargetPair(&c_));
110 a_.deps().push_back(LabelTargetPair(&d_));
111 EXPECT_TRUE(checker->IsDependencyOf(
112 &c_, &a_, true, &chain, &direct_dependent_configs_apply));
113 EXPECT_TRUE(direct_dependent_configs_apply);
114 EXPECT_EQ(3u, chain.size());
115 EXPECT_EQ(&c_, chain[0]);
116 EXPECT_EQ(&d_, chain[1]);
117 EXPECT_EQ(&a_, chain[2]);
118
119 // d also forwards direct-dependent configs if it is a group.
120 chain.clear();
121 direct_dependent_configs_apply = false;
122 d_.set_output_type(Target::GROUP);
123 d_.forward_dependent_configs().clear();
124 EXPECT_TRUE(checker->IsDependencyOf(
125 &c_, &a_, true, &chain, &direct_dependent_configs_apply));
126 EXPECT_TRUE(direct_dependent_configs_apply);
127 EXPECT_EQ(3u, chain.size());
128 EXPECT_EQ(&c_, chain[0]);
129 EXPECT_EQ(&d_, chain[1]);
130 EXPECT_EQ(&a_, chain[2]);
131
132 // A direct dependency a -> c carries direct-dependent configs.
133 chain.clear();
134 direct_dependent_configs_apply = false;
135 a_.deps().push_back(LabelTargetPair(&c_));
136 EXPECT_TRUE(checker->IsDependencyOf(
137 &c_, &a_, true, &chain, &direct_dependent_configs_apply));
138 EXPECT_TRUE(direct_dependent_configs_apply);
139 EXPECT_EQ(2u, chain.size());
140 EXPECT_EQ(&c_, chain[0]);
141 EXPECT_EQ(&a_, chain[1]);
73 } 142 }
74 143
75 TEST_F(HeaderCheckerTest, CheckInclude) { 144 TEST_F(HeaderCheckerTest, CheckInclude) {
76 InputFile input_file(SourceFile("//some_file.cc")); 145 InputFile input_file(SourceFile("//some_file.cc"));
77 input_file.SetContents(std::string()); 146 input_file.SetContents(std::string());
78 LocationRange range; // Dummy value. 147 LocationRange range; // Dummy value.
79 148
80 // Add a disconnected target d with a header to check that you have to have 149 // Add a disconnected target d with a header to check that you have to have
81 // to depend on a target listing a header. 150 // to depend on a target listing a header.
82 Target d(setup_.settings(), Label(SourceDir("//"), "d"));
83 SourceFile d_header("//d_header.h"); 151 SourceFile d_header("//d_header.h");
84 d.sources().push_back(SourceFile(d_header)); 152 d_.sources().push_back(SourceFile(d_header));
85 153
86 // Add a header on B and say everything in B is public. 154 // Add a header on B and say everything in B is public.
87 SourceFile b_public("//b_public.h"); 155 SourceFile b_public("//b_public.h");
88 b_.sources().push_back(b_public); 156 b_.sources().push_back(b_public);
89 c_.set_all_headers_public(true); 157 c_.set_all_headers_public(true);
90 158
91 // Add a public and private header on C. 159 // Add a public and private header on C.
92 SourceFile c_public("//c_public.h"); 160 SourceFile c_public("//c_public.h");
93 SourceFile c_private("//c_private.h"); 161 SourceFile c_private("//c_private.h");
94 c_.sources().push_back(c_private); 162 c_.sources().push_back(c_private);
95 c_.public_headers().push_back(c_public); 163 c_.public_headers().push_back(c_public);
96 c_.set_all_headers_public(false); 164 c_.set_all_headers_public(false);
97 165
98 targets_.push_back(&d); 166 targets_.push_back(&d_);
99 scoped_refptr<HeaderChecker> checker( 167 scoped_refptr<HeaderChecker> checker(
100 new HeaderChecker(setup_.build_settings(), targets_)); 168 new HeaderChecker(setup_.build_settings(), targets_));
101 169
102 // A file in target A can't include a header from D because A has no 170 // A file in target A can't include a header from D because A has no
103 // dependency on D. 171 // dependency on D.
104 Err err; 172 Err err;
105 EXPECT_FALSE(checker->CheckInclude(&a_, input_file, d_header, range, &err)); 173 EXPECT_FALSE(checker->CheckInclude(&a_, input_file, d_header, range, &err));
106 EXPECT_TRUE(err.has_error()); 174 EXPECT_TRUE(err.has_error());
107 175
108 // A can include the public header in B. 176 // A can include the public header in B.
(...skipping 13 matching lines...) Expand all
122 EXPECT_TRUE(checker->CheckInclude(&a_, input_file, SourceFile("//random.h"), 190 EXPECT_TRUE(checker->CheckInclude(&a_, input_file, SourceFile("//random.h"),
123 range, &err)); 191 range, &err));
124 EXPECT_FALSE(err.has_error()); 192 EXPECT_FALSE(err.has_error());
125 193
126 // If C is not visible from A, A can't include public headers even if there 194 // If C is not visible from A, A can't include public headers even if there
127 // is a dependency path. 195 // is a dependency path.
128 c_.visibility().SetPrivate(c_.label().dir()); 196 c_.visibility().SetPrivate(c_.label().dir());
129 err = Err(); 197 err = Err();
130 EXPECT_FALSE(checker->CheckInclude(&a_, input_file, c_public, range, &err)); 198 EXPECT_FALSE(checker->CheckInclude(&a_, input_file, c_public, range, &err));
131 EXPECT_TRUE(err.has_error()); 199 EXPECT_TRUE(err.has_error());
200 c_.visibility().SetPublic();
201
202 // If C has direct-dependent configs, then B must forward them to A.
203 // If B is a group, that suffices to forward direct-dependent configs.
204 {
205 Config direct(setup_.settings(), Label(SourceDir("//c/"), "config"));
206 direct.config_values().cflags().push_back("-DSOME_DEFINE");
207
208 c_.direct_dependent_configs().push_back(LabelConfigPair(&direct));
209 err = Err();
210 EXPECT_FALSE(checker->CheckInclude(&a_, input_file, c_public, range, &err));
211 EXPECT_TRUE(err.has_error());
212
213 b_.forward_dependent_configs().push_back(LabelTargetPair(&c_));
214 err = Err();
215 EXPECT_TRUE(checker->CheckInclude(&a_, input_file, c_public, range, &err));
216 EXPECT_FALSE(err.has_error());
217
218 b_.forward_dependent_configs().clear();
219 b_.set_output_type(Target::GROUP);
220 err = Err();
221 EXPECT_TRUE(checker->CheckInclude(&a_, input_file, c_public, range, &err));
222 EXPECT_FALSE(err.has_error());
223
224 b_.set_output_type(Target::UNKNOWN);
225 c_.direct_dependent_configs().clear();
226 }
132 } 227 }
133 228
134 TEST_F(HeaderCheckerTest, DoDirectDependentConfigsApply) { 229 TEST_F(HeaderCheckerTest, GetDependentConfigChainProblemIndex) {
135 // Assume we have a chain A -> B -> C -> D. 230 // Assume we have a chain A -> B -> C -> D.
136 Target target_a(setup_.settings(), Label(SourceDir("//a/"), "a")); 231 Target target_a(setup_.settings(), Label(SourceDir("//a/"), "a"));
137 Target target_b(setup_.settings(), Label(SourceDir("//b/"), "b")); 232 Target target_b(setup_.settings(), Label(SourceDir("//b/"), "b"));
138 Target target_c(setup_.settings(), Label(SourceDir("//c/"), "c")); 233 Target target_c(setup_.settings(), Label(SourceDir("//c/"), "c"));
139 Target target_d(setup_.settings(), Label(SourceDir("//d/"), "d")); 234 Target target_d(setup_.settings(), Label(SourceDir("//d/"), "d"));
140 235
141 // C is a group, and B forwards deps from C, so A should get configs from D. 236 // C is a group, and B forwards deps from C, so A should get configs from D.
142 target_a.set_output_type(Target::SOURCE_SET); 237 target_a.set_output_type(Target::SOURCE_SET);
143 target_b.set_output_type(Target::SOURCE_SET); 238 target_b.set_output_type(Target::SOURCE_SET);
144 target_c.set_output_type(Target::GROUP); 239 target_c.set_output_type(Target::GROUP);
145 target_d.set_output_type(Target::SOURCE_SET); 240 target_d.set_output_type(Target::SOURCE_SET);
146 target_b.forward_dependent_configs().push_back( 241 target_b.forward_dependent_configs().push_back(
147 LabelTargetPair(&target_c)); 242 LabelTargetPair(&target_c));
148 243
149 // Dependency chain goes from bottom to top. 244 // Dependency chain goes from bottom to top.
150 std::vector<const Target*> chain; 245 std::vector<const Target*> chain;
151 chain.push_back(&target_d); 246 chain.push_back(&target_d);
152 chain.push_back(&target_c); 247 chain.push_back(&target_c);
153 chain.push_back(&target_b); 248 chain.push_back(&target_b);
154 chain.push_back(&target_a); 249 chain.push_back(&target_a);
155 250
156 // This chain should be valid.
157 size_t badone = 0;
158 EXPECT_TRUE(HeaderChecker::DoDirectDependentConfigsApply(chain, &badone));
159
160 // If C is not a group, it shouldn't work anymore. 251 // If C is not a group, it shouldn't work anymore.
161 target_c.set_output_type(Target::SOURCE_SET); 252 target_c.set_output_type(Target::SOURCE_SET);
162 EXPECT_FALSE(HeaderChecker::DoDirectDependentConfigsApply(chain, &badone)); 253 EXPECT_EQ(1u, HeaderChecker::GetDependentConfigChainProblemIndex(chain));
163 EXPECT_EQ(1u, badone);
164 254
165 // Or if B stops forwarding from C, it shouldn't work anymore. 255 // Or if B stops forwarding from C, it shouldn't work anymore.
166 target_c.set_output_type(Target::GROUP); 256 target_c.set_output_type(Target::GROUP);
167 badone = 0;
168 target_b.forward_dependent_configs().clear(); 257 target_b.forward_dependent_configs().clear();
169 EXPECT_FALSE(HeaderChecker::DoDirectDependentConfigsApply(chain, &badone)); 258 EXPECT_EQ(2u, HeaderChecker::GetDependentConfigChainProblemIndex(chain));
170 EXPECT_EQ(2u, badone);
171 } 259 }
OLDNEW
« no previous file with comments | « tools/gn/header_checker.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698