• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 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.
4 
5 #include "gn/config.h"
6 #include "gn/scheduler.h"
7 #include "gn/scope.h"
8 #include "gn/test_with_scheduler.h"
9 #include "gn/test_with_scope.h"
10 #include "util/test/test.h"
11 
12 using RustFunctionsTarget = TestWithScheduler;
13 
14 // Checks that the appropriate crate type is used.
TEST_F(RustFunctionsTarget,CrateName)15 TEST_F(RustFunctionsTarget, CrateName) {
16   TestWithScope setup;
17 
18   // The target generator needs a place to put the targets or it will fail.
19   Scope::ItemVector item_collector;
20   setup.scope()->set_item_collector(&item_collector);
21   setup.scope()->set_source_dir(SourceDir("/"));
22 
23   TestParseInput exe_input(
24       "executable(\"foo\") {\n"
25       "  crate_name = \"foo_crate\"\n"
26       "  sources = [ \"foo.rs\", \"lib.rs\", \"main.rs\" ]\n"
27       "}\n");
28   ASSERT_FALSE(exe_input.has_error());
29   Err err;
30   exe_input.parsed()->Execute(setup.scope(), &err);
31   ASSERT_FALSE(err.has_error()) << err.message();
32   ASSERT_EQ(item_collector.back()->AsTarget()->rust_values().crate_name(),
33             "foo_crate");
34 
35   TestParseInput lib_input(
36       "executable(\"foo\") {\n"
37       "  sources = [ \"lib.rs\" ]\n"
38       "}\n");
39   ASSERT_FALSE(lib_input.has_error());
40   err = Err();
41   lib_input.parsed()->Execute(setup.scope(), &err);
42   ASSERT_FALSE(err.has_error()) << err.message();
43   ASSERT_EQ(item_collector.back()->AsTarget()->rust_values().crate_name(),
44             "foo")
45       << item_collector.back()->AsTarget()->rust_values().crate_name();
46 }
47 
48 // Checks that the appropriate crate root is found.
TEST_F(RustFunctionsTarget,CrateRootFind)49 TEST_F(RustFunctionsTarget, CrateRootFind) {
50   TestWithScope setup;
51 
52   // The target generator needs a place to put the targets or it will fail.
53   Scope::ItemVector item_collector;
54   setup.scope()->set_item_collector(&item_collector);
55   setup.scope()->set_source_dir(SourceDir("/"));
56 
57   TestParseInput normal_input(
58       "executable(\"foo\") {\n"
59       "  crate_root = \"foo.rs\""
60       "  sources = [ \"main.rs\" ]\n"
61       "}\n");
62   ASSERT_FALSE(normal_input.has_error());
63   Err err;
64   normal_input.parsed()->Execute(setup.scope(), &err);
65   ASSERT_FALSE(err.has_error()) << err.message();
66   ASSERT_EQ(
67       item_collector.back()->AsTarget()->rust_values().crate_root().value(),
68       "/foo.rs");
69 
70   TestParseInput normal_shlib_input(
71       "shared_library(\"foo\") {\n"
72       "  crate_root = \"foo.rs\""
73       "  crate_type = \"dylib\"\n"
74       "  sources = [ \"main.rs\" ]\n"
75       "}\n");
76   ASSERT_FALSE(normal_shlib_input.has_error());
77   err = Err();
78   normal_shlib_input.parsed()->Execute(setup.scope(), &err);
79   ASSERT_FALSE(err.has_error()) << err.message();
80   ASSERT_EQ(
81       item_collector.back()->AsTarget()->rust_values().crate_root().value(),
82       "/foo.rs");
83 
84   TestParseInput exe_input(
85       "executable(\"foo\") {\n"
86       "  sources = [ \"foo.rs\", \"lib.rs\", \"main.rs\" ]\n"
87       "}\n");
88   ASSERT_FALSE(exe_input.has_error());
89   err = Err();
90   exe_input.parsed()->Execute(setup.scope(), &err);
91   ASSERT_FALSE(err.has_error()) << err.message();
92   ASSERT_EQ(
93       item_collector.back()->AsTarget()->rust_values().crate_root().value(),
94       "/main.rs");
95 
96   TestParseInput lib_input(
97       "rust_library(\"libfoo\") {\n"
98       "  sources = [ \"foo.rs\", \"lib.rs\", \"main.rs\" ]\n"
99       "}\n");
100   ASSERT_FALSE(lib_input.has_error());
101   err = Err();
102   lib_input.parsed()->Execute(setup.scope(), &err);
103   ASSERT_FALSE(err.has_error()) << err.message();
104   ASSERT_EQ(
105       item_collector.back()->AsTarget()->rust_values().crate_root().value(),
106       "/lib.rs");
107 
108   TestParseInput singlesource_input(
109       "executable(\"bar\") {\n"
110       "  sources = [ \"bar.rs\" ]\n"
111       "}\n");
112   ASSERT_FALSE(singlesource_input.has_error());
113   err = Err();
114   singlesource_input.parsed()->Execute(setup.scope(), &err);
115   ASSERT_FALSE(err.has_error()) << err.message();
116   ASSERT_EQ(
117       item_collector.back()->AsTarget()->rust_values().crate_root().value(),
118       "/bar.rs");
119 
120   TestParseInput error_input(
121       "rust_library(\"foo\") {\n"
122       "  sources = [ \"foo.rs\", \"main.rs\" ]\n"
123       "}\n");
124   ASSERT_FALSE(error_input.has_error());
125   err = Err();
126   error_input.parsed()->Execute(setup.scope(), &err);
127   ASSERT_TRUE(err.has_error());
128   EXPECT_EQ("Missing \"crate_root\" and missing \"lib.rs\" in sources.",
129             err.message());
130 
131   TestParseInput nosources_input(
132       "executable(\"bar\") {\n"
133       "  crate_root = \"bar.rs\"\n"
134       "}\n");
135   ASSERT_FALSE(nosources_input.has_error());
136   err = Err();
137   nosources_input.parsed()->Execute(setup.scope(), &err);
138   ASSERT_FALSE(err.has_error()) << err.message();
139   ASSERT_EQ(
140       item_collector.back()->AsTarget()->rust_values().crate_root().value(),
141       "/bar.rs");
142 }
143 
144 // Checks that the appropriate crate type is used.
TEST_F(RustFunctionsTarget,CrateTypeSelection)145 TEST_F(RustFunctionsTarget, CrateTypeSelection) {
146   TestWithScope setup;
147 
148   // The target generator needs a place to put the targets or it will fail.
149   Scope::ItemVector item_collector;
150   setup.scope()->set_item_collector(&item_collector);
151   setup.scope()->set_source_dir(SourceDir("/"));
152 
153   TestParseInput lib_input(
154       "shared_library(\"libfoo\") {\n"
155       "  crate_type = \"dylib\"\n"
156       "  sources = [ \"lib.rs\" ]\n"
157       "}\n");
158   ASSERT_FALSE(lib_input.has_error());
159   Err err;
160   lib_input.parsed()->Execute(setup.scope(), &err);
161   ASSERT_FALSE(err.has_error()) << err.message();
162   ASSERT_EQ(item_collector.back()->AsTarget()->rust_values().crate_type(),
163             RustValues::CRATE_DYLIB);
164 
165   TestParseInput exe_non_default_input(
166       "executable(\"foo\") {\n"
167       "  crate_type = \"rlib\"\n"
168       "  sources = [ \"main.rs\" ]\n"
169       "}\n");
170   ASSERT_FALSE(exe_non_default_input.has_error());
171   err = Err();
172   exe_non_default_input.parsed()->Execute(setup.scope(), &err);
173   ASSERT_FALSE(err.has_error()) << err.message();
174   ASSERT_EQ(item_collector.back()->AsTarget()->rust_values().crate_type(),
175             RustValues::CRATE_RLIB);
176 
177   TestParseInput lib_error_input(
178       "shared_library(\"foo\") {\n"
179       "  crate_type = \"bad\"\n"
180       "  sources = [ \"lib.rs\" ]\n"
181       "}\n");
182   ASSERT_FALSE(lib_error_input.has_error());
183   err = Err();
184   lib_error_input.parsed()->Execute(setup.scope(), &err);
185   ASSERT_TRUE(err.has_error());
186   EXPECT_EQ("Inadmissible crate type \"bad\".", err.message()) << err.message();
187 
188   TestParseInput lib_missing_error_input(
189       "shared_library(\"foo\") {\n"
190       "  sources = [ \"lib.rs\" ]\n"
191       "}\n");
192   ASSERT_FALSE(lib_missing_error_input.has_error());
193   err = Err();
194   lib_missing_error_input.parsed()->Execute(setup.scope(), &err);
195   ASSERT_TRUE(err.has_error());
196   EXPECT_EQ("Must set \"crate_type\" on a Rust \"shared_library\".",
197             err.message());
198 }
199 
200 // Checks that the appropriate config values are propagated.
TEST_F(RustFunctionsTarget,ConfigValues)201 TEST_F(RustFunctionsTarget, ConfigValues) {
202   TestWithScope setup;
203 
204   // The target generator needs a place to put the targets or it will fail.
205   Scope::ItemVector item_collector;
206   setup.scope()->set_item_collector(&item_collector);
207   setup.scope()->set_source_dir(SourceDir("/"));
208 
209   TestParseInput exe_input(
210       "config(\"foo\") {\n"
211       "  rustflags = [ \"-Cdebuginfo=2\" ]\n"
212       "  rustenv = [ \"RUST_BACKTRACE=1\" ]"
213       "}\n");
214   ASSERT_FALSE(exe_input.has_error());
215   Err err;
216   exe_input.parsed()->Execute(setup.scope(), &err);
217   ASSERT_FALSE(err.has_error()) << err.message();
218 
219   EXPECT_EQ(item_collector.back()->AsConfig()->own_values().rustflags().size(),
220             1U);
221   EXPECT_EQ(item_collector.back()->AsConfig()->own_values().rustflags()[0],
222             "-Cdebuginfo=2");
223   EXPECT_EQ(item_collector.back()->AsConfig()->own_values().rustenv().size(),
224             1U);
225   EXPECT_EQ(item_collector.back()->AsConfig()->own_values().rustenv()[0],
226             "RUST_BACKTRACE=1");
227 }
228 
229 // Checks that set_defaults works properly.
TEST_F(RustFunctionsTarget,SetDefaults)230 TEST_F(RustFunctionsTarget, SetDefaults) {
231   TestWithScope setup;
232 
233   // The target generator needs a place to put the targets or it will fail.
234   Scope::ItemVector item_collector;
235   setup.scope()->set_item_collector(&item_collector);
236   setup.scope()->set_source_dir(SourceDir("/"));
237 
238   TestParseInput exe_input(
239       "config(\"foo\") {\n"
240       "  rustflags = [ \"-Cdebuginfo=2\" ]\n"
241       "  rustenv = [ \"RUST_BACKTRACE=1\" ]"
242       "}\n"
243       "set_defaults(\"rust_library\") {\n"
244       "  configs = [ \":foo\" ]\n"
245       "}\n");
246   ASSERT_FALSE(exe_input.has_error());
247   Err err;
248   exe_input.parsed()->Execute(setup.scope(), &err);
249   ASSERT_FALSE(err.has_error()) << err.message() << err.message();
250 
251   EXPECT_EQ(setup.scope()
252                 ->GetTargetDefaults("rust_library")
253                 ->GetValue("configs")
254                 ->type(),
255             Value::LIST);
256   EXPECT_EQ(setup.scope()
257                 ->GetTargetDefaults("rust_library")
258                 ->GetValue("configs")
259                 ->list_value()
260                 .size(),
261             1U);
262   EXPECT_EQ(setup.scope()
263                 ->GetTargetDefaults("rust_library")
264                 ->GetValue("configs")
265                 ->list_value()[0]
266                 .type(),
267             Value::STRING);
268   EXPECT_EQ(setup.scope()
269                 ->GetTargetDefaults("rust_library")
270                 ->GetValue("configs")
271                 ->list_value()[0]
272                 .string_value(),
273             ":foo");
274 }
275 
276 // Checks aliased_deps parsing.
TEST_F(RustFunctionsTarget,AliasedDeps)277 TEST_F(RustFunctionsTarget, AliasedDeps) {
278   TestWithScope setup;
279 
280   // The target generator needs a place to put the targets or it will fail.
281   Scope::ItemVector item_collector;
282   setup.scope()->set_item_collector(&item_collector);
283   setup.scope()->set_source_dir(SourceDir("/"));
284 
285   TestParseInput exe_input(
286       "executable(\"foo\") {\n"
287       "  sources = [ \"main.rs\" ]\n"
288       "  deps = [ \"//bar\", \"//baz\" ]\n"
289       "  aliased_deps = {\n"
290       "    bar_renamed = \"//bar\"\n"
291       "    baz_renamed = \"//baz:baz\"\n"
292       "  }\n"
293       "}\n");
294   ASSERT_FALSE(exe_input.has_error());
295   Err err;
296   exe_input.parsed()->Execute(setup.scope(), &err);
297   ASSERT_FALSE(err.has_error()) << err.message();
298 
299   EXPECT_EQ(
300       item_collector.back()->AsTarget()->rust_values().aliased_deps().size(),
301       2U);
302 }
303 
TEST_F(RustFunctionsTarget,PublicConfigs)304 TEST_F(RustFunctionsTarget, PublicConfigs) {
305   TestWithScope setup;
306 
307   Scope::ItemVector item_collector;
308   setup.scope()->set_item_collector(&item_collector);
309   setup.scope()->set_source_dir(SourceDir("/"));
310 
311   TestParseInput exe_input(
312       "config(\"bar\") {\n"
313       "  defines = [ \"DOOM_MELON\" ]"
314       "}\n"
315       "executable(\"foo\") {\n"
316       "  crate_name = \"foo_crate\"\n"
317       "  sources = [ \"foo.rs\", \"lib.rs\", \"main.rs\" ]\n"
318       "  public_configs = [ \":bar\" ]"
319       "}\n");
320   ASSERT_FALSE(exe_input.has_error());
321   Err err;
322   exe_input.parsed()->Execute(setup.scope(), &err);
323   ASSERT_FALSE(err.has_error()) << err.message();
324 }
325