Instrumental test for BookmarksBridge. It currently tests these functionalities:...
[chromium-blink-merge.git] / tools / gn / header_checker_unittest.cc
blobdd1ce24351489f572d4feb5d41beaca153ce72d5
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
3 // found in the LICENSE file.
5 #include <vector>
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "tools/gn/config.h"
9 #include "tools/gn/header_checker.h"
10 #include "tools/gn/scheduler.h"
11 #include "tools/gn/target.h"
12 #include "tools/gn/test_with_scope.h"
14 namespace {
16 class HeaderCheckerTest : public testing::Test {
17 public:
18 HeaderCheckerTest()
19 : a_(setup_.settings(), Label(SourceDir("//a/"), "a")),
20 b_(setup_.settings(), Label(SourceDir("//b/"), "b")),
21 c_(setup_.settings(), Label(SourceDir("//c/"), "c")),
22 d_(setup_.settings(), Label(SourceDir("//d/"), "d")) {
23 a_.set_output_type(Target::SOURCE_SET);
24 b_.set_output_type(Target::SOURCE_SET);
25 c_.set_output_type(Target::SOURCE_SET);
26 d_.set_output_type(Target::SOURCE_SET);
28 Err err;
29 a_.SetToolchain(setup_.toolchain(), &err);
30 b_.SetToolchain(setup_.toolchain(), &err);
31 c_.SetToolchain(setup_.toolchain(), &err);
32 d_.SetToolchain(setup_.toolchain(), &err);
34 a_.public_deps().push_back(LabelTargetPair(&b_));
35 b_.public_deps().push_back(LabelTargetPair(&c_));
37 // Start with all public visibility.
38 a_.visibility().SetPublic();
39 b_.visibility().SetPublic();
40 c_.visibility().SetPublic();
41 d_.visibility().SetPublic();
43 d_.OnResolved(&err);
44 c_.OnResolved(&err);
45 b_.OnResolved(&err);
46 a_.OnResolved(&err);
48 targets_.push_back(&a_);
49 targets_.push_back(&b_);
50 targets_.push_back(&c_);
51 targets_.push_back(&d_);
54 protected:
55 Scheduler scheduler_;
57 TestWithScope setup_;
59 // Some headers that are automatically set up with a dependency chain.
60 // a -> b -> c
61 Target a_;
62 Target b_;
63 Target c_;
64 Target d_;
66 std::vector<const Target*> targets_;
69 } // namespace
71 TEST_F(HeaderCheckerTest, IsDependencyOf) {
72 scoped_refptr<HeaderChecker> checker(
73 new HeaderChecker(setup_.build_settings(), targets_));
75 // Add a target P ("private") that privately depends on C, and hook up the
76 // chain so that A -> P -> C. A will depend on C via two different paths.
77 Err err;
78 Target p(setup_.settings(), Label(SourceDir("//p/"), "p"));
79 p.set_output_type(Target::SOURCE_SET);
80 p.SetToolchain(setup_.toolchain(), &err);
81 EXPECT_FALSE(err.has_error());
82 p.private_deps().push_back(LabelTargetPair(&c_));
83 p.visibility().SetPublic();
84 p.OnResolved(&err);
86 a_.public_deps().push_back(LabelTargetPair(&p));
88 // A does not depend on itself.
89 bool is_public = false;
90 std::vector<const Target*> chain;
91 EXPECT_FALSE(checker->IsDependencyOf(&a_, &a_, &chain, &is_public));
93 // A depends on B.
94 chain.clear();
95 is_public = false;
96 EXPECT_TRUE(checker->IsDependencyOf(&b_, &a_, &chain, &is_public));
97 ASSERT_EQ(2u, chain.size());
98 EXPECT_EQ(&b_, chain[0]);
99 EXPECT_EQ(&a_, chain[1]);
100 EXPECT_TRUE(is_public);
102 // A indirectly depends on C. The "public" dependency path through B should
103 // be identified.
104 chain.clear();
105 is_public = false;
106 EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, &chain, &is_public));
107 ASSERT_EQ(3u, chain.size());
108 EXPECT_EQ(&c_, chain[0]);
109 EXPECT_EQ(&b_, chain[1]);
110 EXPECT_EQ(&a_, chain[2]);
111 EXPECT_TRUE(is_public);
113 // C does not depend on A.
114 chain.clear();
115 is_public = false;
116 EXPECT_FALSE(checker->IsDependencyOf(&a_, &c_, &chain, &is_public));
117 EXPECT_TRUE(chain.empty());
118 EXPECT_FALSE(is_public);
120 // Add a private A -> C dependency. This should not be detected since it's
121 // private, even though it's shorter than the A -> B -> C one.
122 chain.clear();
123 is_public = false;
124 a_.private_deps().push_back(LabelTargetPair(&c_));
125 EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, &chain, &is_public));
126 EXPECT_EQ(&c_, chain[0]);
127 EXPECT_EQ(&b_, chain[1]);
128 EXPECT_EQ(&a_, chain[2]);
129 EXPECT_TRUE(is_public);
131 // Remove the B -> C public dependency, leaving A's private dep on C the only
132 // path. This should now be found.
133 chain.clear();
134 EXPECT_EQ(&c_, b_.public_deps()[0].ptr); // Validate it's the right one.
135 b_.public_deps().erase(b_.public_deps().begin());
136 EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, &chain, &is_public));
137 EXPECT_EQ(&c_, chain[0]);
138 EXPECT_EQ(&a_, chain[1]);
139 EXPECT_FALSE(is_public);
142 TEST_F(HeaderCheckerTest, CheckInclude) {
143 InputFile input_file(SourceFile("//some_file.cc"));
144 input_file.SetContents(std::string());
145 LocationRange range; // Dummy value.
147 // Add a disconnected target d with a header to check that you have to have
148 // to depend on a target listing a header.
149 SourceFile d_header("//d_header.h");
150 d_.sources().push_back(SourceFile(d_header));
152 // Add a header on B and say everything in B is public.
153 SourceFile b_public("//b_public.h");
154 b_.sources().push_back(b_public);
155 c_.set_all_headers_public(true);
157 // Add a public and private header on C.
158 SourceFile c_public("//c_public.h");
159 SourceFile c_private("//c_private.h");
160 c_.sources().push_back(c_private);
161 c_.public_headers().push_back(c_public);
162 c_.set_all_headers_public(false);
164 targets_.push_back(&d_);
165 scoped_refptr<HeaderChecker> checker(
166 new HeaderChecker(setup_.build_settings(), targets_));
168 // A file in target A can't include a header from D because A has no
169 // dependency on D.
170 Err err;
171 EXPECT_FALSE(checker->CheckInclude(&a_, input_file, d_header, range, &err));
172 EXPECT_TRUE(err.has_error());
174 // A can include the public header in B.
175 err = Err();
176 EXPECT_TRUE(checker->CheckInclude(&a_, input_file, b_public, range, &err));
177 EXPECT_FALSE(err.has_error());
179 // Check A depending on the public and private headers in C.
180 err = Err();
181 EXPECT_TRUE(checker->CheckInclude(&a_, input_file, c_public, range, &err));
182 EXPECT_FALSE(err.has_error());
183 EXPECT_FALSE(checker->CheckInclude(&a_, input_file, c_private, range, &err));
184 EXPECT_TRUE(err.has_error());
186 // A can depend on a random file unknown to the build.
187 err = Err();
188 EXPECT_TRUE(checker->CheckInclude(&a_, input_file, SourceFile("//random.h"),
189 range, &err));
190 EXPECT_FALSE(err.has_error());
193 // Checks that the allow_circular_includes_from list works.
194 TEST_F(HeaderCheckerTest, CheckIncludeAllowCircular) {
195 InputFile input_file(SourceFile("//some_file.cc"));
196 input_file.SetContents(std::string());
197 LocationRange range; // Dummy value.
199 // Add an include file to A.
200 SourceFile a_public("//a_public.h");
201 a_.sources().push_back(a_public);
203 scoped_refptr<HeaderChecker> checker(
204 new HeaderChecker(setup_.build_settings(), targets_));
206 // A depends on B. So B normally can't include headers from A.
207 Err err;
208 EXPECT_FALSE(checker->CheckInclude(&b_, input_file, a_public, range, &err));
209 EXPECT_TRUE(err.has_error());
211 // Add an allow_circular_includes_from on A that lists B.
212 a_.allow_circular_includes_from().insert(b_.label());
214 // Now the include from B to A should be allowed.
215 err = Err();
216 EXPECT_TRUE(checker->CheckInclude(&b_, input_file, a_public, range, &err));
217 EXPECT_FALSE(err.has_error());