• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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/rust_project_writer_helpers.h"
6 
7 #include "base/strings/string_util.h"
8 #include "gn/filesystem_utils.h"
9 #include "gn/string_output_buffer.h"
10 #include "gn/test_with_scheduler.h"
11 #include "gn/test_with_scope.h"
12 #include "util/build_config.h"
13 #include "util/test/test.h"
14 
ExpectEqOrShowDiff(const char * expected,const std::string & actual)15 static void ExpectEqOrShowDiff(const char* expected,
16                                const std::string& actual) {
17   if (expected != actual) {
18     printf("\nExpected: >>>\n%s<<<\n", expected);
19     printf("  Actual: >>>\n%s<<<\n", actual.c_str());
20   }
21   EXPECT_EQ(expected, actual);
22 }
23 
24 using RustProjectWriterHelper = TestWithScheduler;
25 
TEST_F(RustProjectWriterHelper,WriteCrates)26 TEST_F(RustProjectWriterHelper, WriteCrates) {
27   TestWithScope setup;
28 
29   std::optional<std::string> sysroot;
30 
31   CrateList crates;
32   Crate dep = Crate(SourceFile("/root/tortoise/lib.rs"), std::nullopt, 0,
33                     "//tortoise:bar", "2015");
34   Crate target = Crate(SourceFile("/root/hare/lib.rs"),
35                        OutputFile("gendir/hare/"), 1, "//hare:bar", "2015");
36   target.AddDependency(0, "tortoise");
37   target.AddConfigItem("unix");
38   target.AddConfigItem("feature=\"test\"");
39 
40   crates.push_back(dep);
41   crates.push_back(target);
42 
43   std::ostringstream stream;
44   WriteCrates(setup.build_settings(), crates, sysroot, stream);
45   std::string out = stream.str();
46 #if defined(OS_WIN)
47   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
48 #endif
49   const char expected_json[] =
50       "{\n"
51       "  \"crates\": [\n"
52       "    {\n"
53       "      \"crate_id\": 0,\n"
54       "      \"root_module\": \"/root/tortoise/lib.rs\",\n"
55       "      \"label\": \"//tortoise:bar\",\n"
56       "      \"source\": {\n"
57       "          \"include_dirs\": [\n"
58       "               \"/root/tortoise/\"\n"
59       "          ],\n"
60       "          \"exclude_dirs\": []\n"
61       "      },\n"
62       "      \"deps\": [\n"
63       "      ],\n"
64       "      \"edition\": \"2015\",\n"
65       "      \"cfg\": [\n"
66       "      ]\n"
67       "    },\n"
68       "    {\n"
69       "      \"crate_id\": 1,\n"
70       "      \"root_module\": \"/root/hare/lib.rs\",\n"
71       "      \"label\": \"//hare:bar\",\n"
72       "      \"source\": {\n"
73       "          \"include_dirs\": [\n"
74       "               \"/root/hare/\",\n"
75       "               \"out/Debug/gendir/hare/\"\n"
76       "          ],\n"
77       "          \"exclude_dirs\": []\n"
78       "      },\n"
79       "      \"deps\": [\n"
80       "        {\n"
81       "          \"crate\": 0,\n"
82       "          \"name\": \"tortoise\"\n"
83       "        }\n"
84       "      ],\n"
85       "      \"edition\": \"2015\",\n"
86       "      \"cfg\": [\n"
87       "        \"unix\",\n"
88       "        \"feature=\\\"test\\\"\"\n"
89       "      ]\n"
90       "    }\n"
91       "  ]\n"
92       "}\n";
93 
94   ExpectEqOrShowDiff(expected_json, out);
95 }
96 
TEST_F(RustProjectWriterHelper,SysrootDepsAreCorrect)97 TEST_F(RustProjectWriterHelper, SysrootDepsAreCorrect) {
98   TestWithScope setup;
99   setup.build_settings()->SetRootPath(UTF8ToFilePath("/root"));
100 
101   std::optional<std::string> sysroot = "sysroot";
102   CrateList crates;
103 
104   std::ostringstream stream;
105   WriteCrates(setup.build_settings(), crates, sysroot, stream);
106   std::string out = stream.str();
107 #if defined(OS_WIN)
108   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
109 #endif
110 
111   const char expected_json[] =
112       "{\n"
113       "  \"sysroot\": \"/root/out/Debug/sysroot\",\n"
114       "  \"crates\": [\n"
115       "  ]\n"
116       "}\n";
117 
118   ExpectEqOrShowDiff(expected_json, out);
119 }
120 
TEST_F(RustProjectWriterHelper,ExtractCompilerTargetTupleSimple)121 TEST_F(RustProjectWriterHelper, ExtractCompilerTargetTupleSimple) {
122   TestWithScope setup;
123 
124   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
125   target.set_output_type(Target::RUST_LIBRARY);
126   target.visibility().SetPublic();
127   SourceFile lib("//foo/lib.rs");
128   target.sources().push_back(lib);
129   target.source_types_used().Set(SourceFile::SOURCE_RS);
130   target.rust_values().set_crate_root(lib);
131   target.rust_values().crate_name() = "foo";
132   target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
133   target.config_values().rustflags().push_back("--target");
134   target.config_values().rustflags().push_back("x86-someos");
135   target.config_values().rustflags().push_back("--edition=2018");
136 
137   auto args = ExtractCompilerArgs(&target);
138   std::optional<std::string> result = FindArgValue("--target", args);
139   auto expected = std::optional<std::string>{"x86-someos"};
140   EXPECT_EQ(expected, result);
141 }
142 
TEST_F(RustProjectWriterHelper,ExtractCompilerTargetTupleMissing)143 TEST_F(RustProjectWriterHelper, ExtractCompilerTargetTupleMissing) {
144   TestWithScope setup;
145 
146   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
147   target.set_output_type(Target::RUST_LIBRARY);
148   target.visibility().SetPublic();
149   SourceFile lib("//foo/lib.rs");
150   target.sources().push_back(lib);
151   target.source_types_used().Set(SourceFile::SOURCE_RS);
152   target.rust_values().set_crate_root(lib);
153   target.rust_values().crate_name() = "foo";
154   target.config_values().rustflags().push_back(
155       "--cfg=featur4e=\"foo_enabled\"");
156   target.config_values().rustflags().push_back("x86-someos");
157   target.config_values().rustflags().push_back("--edition=2018");
158 
159   auto args = ExtractCompilerArgs(&target);
160   std::optional<std::string> result = FindArgValue("--target", args);
161   auto expected = std::nullopt;
162   EXPECT_EQ(expected, result);
163 }
164 
TEST_F(RustProjectWriterHelper,ExtractCompilerTargetTupleDontFallOffEnd)165 TEST_F(RustProjectWriterHelper, ExtractCompilerTargetTupleDontFallOffEnd) {
166   TestWithScope setup;
167 
168   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
169   target.set_output_type(Target::RUST_LIBRARY);
170   target.visibility().SetPublic();
171   SourceFile lib("//foo/lib.rs");
172   target.sources().push_back(lib);
173   target.source_types_used().Set(SourceFile::SOURCE_RS);
174   target.rust_values().set_crate_root(lib);
175   target.rust_values().crate_name() = "foo";
176   target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
177   target.config_values().rustflags().push_back("--edition=2018");
178   target.config_values().rustflags().push_back("--target");
179 
180   auto args = ExtractCompilerArgs(&target);
181   std::optional<std::string> result = FindArgValue("--target", args);
182   auto expected = std::nullopt;
183   EXPECT_EQ(expected, result);
184 }
185 
TEST_F(RustProjectWriterHelper,ExtractFirstArgValueWithPrefixMissing)186 TEST_F(RustProjectWriterHelper, ExtractFirstArgValueWithPrefixMissing) {
187   TestWithScope setup;
188 
189   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
190   target.set_output_type(Target::RUST_LIBRARY);
191   target.visibility().SetPublic();
192   SourceFile lib("//foo/lib.rs");
193   target.sources().push_back(lib);
194   target.source_types_used().Set(SourceFile::SOURCE_RS);
195   target.rust_values().set_crate_root(lib);
196   target.rust_values().crate_name() = "foo";
197   target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
198   target.config_values().rustflags().push_back("--edition=2018");
199   target.config_values().rustflags().push_back("--target");
200 
201   auto args = ExtractCompilerArgs(&target);
202   std::optional<std::string> result =
203       FindArgValueAfterPrefix("--missing", args);
204   auto expected = std::nullopt;
205   EXPECT_EQ(expected, result);
206 }
207 
TEST_F(RustProjectWriterHelper,ExtractFirstArgValueWithPrefix)208 TEST_F(RustProjectWriterHelper, ExtractFirstArgValueWithPrefix) {
209   TestWithScope setup;
210 
211   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
212   target.set_output_type(Target::RUST_LIBRARY);
213   target.visibility().SetPublic();
214   SourceFile lib("//foo/lib.rs");
215   target.sources().push_back(lib);
216   target.source_types_used().Set(SourceFile::SOURCE_RS);
217   target.rust_values().set_crate_root(lib);
218   target.rust_values().crate_name() = "foo";
219   target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
220   target.config_values().rustflags().push_back("--edition=2018");
221   target.config_values().rustflags().push_back("--target");
222 
223   auto args = ExtractCompilerArgs(&target);
224   std::optional<std::string> result =
225       FindArgValueAfterPrefix("--edition=", args);
226   auto expected = std::optional<std::string>{"2018"};
227   EXPECT_EQ(expected, result);
228 }
229 
TEST_F(RustProjectWriterHelper,ExtractAllArgValueWithPrefix)230 TEST_F(RustProjectWriterHelper, ExtractAllArgValueWithPrefix) {
231   TestWithScope setup;
232 
233   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
234   target.set_output_type(Target::RUST_LIBRARY);
235   target.visibility().SetPublic();
236   SourceFile lib("//foo/lib.rs");
237   target.sources().push_back(lib);
238   target.source_types_used().Set(SourceFile::SOURCE_RS);
239   target.rust_values().set_crate_root(lib);
240   target.rust_values().crate_name() = "foo";
241   target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
242   target.config_values().rustflags().push_back("--edition=2018");
243   target.config_values().rustflags().push_back("--cfg=feature=\"bar_enabled\"");
244   target.config_values().rustflags().push_back("--target");
245 
246   auto args = ExtractCompilerArgs(&target);
247   std::vector<std::string> result = FindAllArgValuesAfterPrefix("--cfg=", args);
248   std::vector<std::string> expected = {"feature=\"foo_enabled\"",
249                                        "feature=\"bar_enabled\""};
250   EXPECT_EQ(expected, result);
251 }