• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 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 "base/strings/string_util.h"
6 #include "gn/json_project_writer.h"
7 #include "gn/substitution_list.h"
8 #include "gn/target.h"
9 #include "gn/test_with_scope.h"
10 #include "gn/test_with_scheduler.h"
11 #include "util/build_config.h"
12 #include "util/test/test.h"
13 
14 using JSONWriter = TestWithScheduler;
15 
TEST_F(JSONWriter,ActionWithResponseFile)16 TEST_F(JSONWriter, ActionWithResponseFile) {
17   Err err;
18   TestWithScope setup;
19 
20   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
21   target.set_output_type(Target::ACTION);
22 
23   target.sources().push_back(SourceFile("//foo/source1.txt"));
24   target.config_values().inputs().push_back(SourceFile("//foo/input1.txt"));
25   target.action_values().set_script(SourceFile("//foo/script.py"));
26 
27   target.SetToolchain(setup.toolchain());
28   ASSERT_TRUE(target.OnResolved(&err));
29 
30   // Make sure we get interesting substitutions for both the args and the
31   // response file contents.
32   target.action_values().args() =
33       SubstitutionList::MakeForTest("{{response_file_name}}");
34   target.action_values().rsp_file_contents() =
35       SubstitutionList::MakeForTest("-j", "3");
36   target.action_values().outputs() =
37       SubstitutionList::MakeForTest("//out/Debug/output1.out");
38 
39   setup.build_settings()->set_python_path(
40       base::FilePath(FILE_PATH_LITERAL("/usr/bin/python")));
41   std::vector<const Target*> targets;
42   targets.push_back(&target);
43 #if defined(OS_WIN)
44   base::FilePath root_path = base::FilePath(FILE_PATH_LITERAL("c:/path/to/src"));
45 #else
46   base::FilePath root_path = base::FilePath(FILE_PATH_LITERAL("/path/to/src"));
47 #endif
48   setup.build_settings()->SetRootPath(root_path);
49   g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL(".gn")));
50   g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL("BUILD.gn")));
51   g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL("build/BUILD.gn")));
52   std::string out =
53       JSONProjectWriter::RenderJSON(setup.build_settings(), targets);
54 #if defined(OS_WIN)
55   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
56 #endif
57   const char expected_json[] =
58       "{\n"
59       "   \"build_settings\": {\n"
60       "      \"build_dir\": \"//out/Debug/\",\n"
61       "      \"default_toolchain\": \"//toolchain:default\",\n"
62       "      \"gen_input_files\": [ \"//.gn\", \"//BUILD.gn\", \"//build/BUILD.gn\" ],\n"
63 #if defined(OS_WIN)
64       "      \"root_path\": \"c:/path/to/src\"\n"
65 #else
66       "      \"root_path\": \"/path/to/src\"\n"
67 #endif
68       "   },\n"
69       "   \"targets\": {\n"
70       "      \"//foo:bar()\": {\n"
71       "         \"args\": [ \"{{response_file_name}}\" ],\n"
72       "         \"deps\": [  ],\n"
73       "         \"inputs\": [ \"//foo/input1.txt\" ],\n"
74       "         \"metadata\": {\n"
75       "\n"
76       "         },\n"
77       "         \"outputs\": [ \"//out/Debug/output1.out\" ],\n"
78       "         \"public\": \"*\",\n"
79       "         \"response_file_contents\": [ \"-j\", \"3\" ],\n"
80       "         \"script\": \"//foo/script.py\",\n"
81       "         \"sources\": [ \"//foo/source1.txt\" ],\n"
82       "         \"testonly\": false,\n"
83       "         \"toolchain\": \"\",\n"
84       "         \"type\": \"action\",\n"
85       "         \"visibility\": [  ]\n"
86       "      }\n"
87       "   }\n"
88       "}\n";
89   EXPECT_EQ(expected_json, out);
90 }
91 
TEST_F(JSONWriter,RustTarget)92 TEST_F(JSONWriter, RustTarget) {
93   Err err;
94   TestWithScope setup;
95 
96   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
97   target.set_output_type(Target::RUST_LIBRARY);
98   target.visibility().SetPublic();
99   SourceFile lib("//foo/lib.rs");
100   target.sources().push_back(lib);
101   target.source_types_used().Set(SourceFile::SOURCE_RS);
102   target.rust_values().set_crate_root(lib);
103   target.rust_values().crate_name() = "foo";
104   target.SetToolchain(setup.toolchain());
105   ASSERT_TRUE(target.OnResolved(&err));
106 
107   std::vector<const Target*> targets;
108   targets.push_back(&target);
109   std::string out =
110       JSONProjectWriter::RenderJSON(setup.build_settings(), targets);
111 #if defined(OS_WIN)
112   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
113 #endif
114   const char expected_json[] =
115       "{\n"
116       "   \"build_settings\": {\n"
117       "      \"build_dir\": \"//out/Debug/\",\n"
118       "      \"default_toolchain\": \"//toolchain:default\",\n"
119       "      \"gen_input_files\": [  ],\n"
120       "      \"root_path\": \"\"\n"
121       "   },\n"
122       "   \"targets\": {\n"
123       "      \"//foo:bar()\": {\n"
124       "         \"allow_circular_includes_from\": [  ],\n"
125       "         \"check_includes\": true,\n"
126       "         \"crate_name\": \"foo\",\n"
127       "         \"crate_root\": \"//foo/lib.rs\",\n"
128       "         \"deps\": [  ],\n"
129       "         \"externs\": {\n"
130       "\n"
131       "         },\n"
132       "         \"metadata\": {\n"
133       "\n"
134       "         },\n"
135       "         \"outputs\": [ \"//out/Debug/obj/foo/libbar.rlib\" ],\n"
136       "         \"public\": \"*\",\n"
137       "         \"sources\": [ \"//foo/lib.rs\" ],\n"
138       "         \"testonly\": false,\n"
139       "         \"toolchain\": \"\",\n"
140       "         \"type\": \"rust_library\",\n"
141       "         \"visibility\": [ \"*\" ]\n"
142       "      }\n"
143       "   }\n"
144       "}\n";
145   EXPECT_EQ(expected_json, out);
146 }
147 
TEST_F(JSONWriter,ForEachWithResponseFile)148 TEST_F(JSONWriter, ForEachWithResponseFile) {
149   Err err;
150   TestWithScope setup;
151 
152   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
153   target.set_output_type(Target::ACTION_FOREACH);
154 
155   target.sources().push_back(SourceFile("//foo/input1.txt"));
156   target.action_values().set_script(SourceFile("//foo/script.py"));
157 
158   target.SetToolchain(setup.toolchain());
159   ASSERT_TRUE(target.OnResolved(&err));
160 
161   // Make sure we get interesting substitutions for both the args and the
162   // response file contents.
163   target.action_values().args() = SubstitutionList::MakeForTest(
164       "{{source}}", "{{source_file_part}}", "{{response_file_name}}");
165   target.action_values().rsp_file_contents() =
166       SubstitutionList::MakeForTest("-j", "{{source_name_part}}");
167   target.action_values().outputs() =
168       SubstitutionList::MakeForTest("//out/Debug/{{source_name_part}}.out");
169 
170   setup.build_settings()->set_python_path(
171       base::FilePath(FILE_PATH_LITERAL("/usr/bin/python")));
172   std::vector<const Target*> targets;
173   targets.push_back(&target);
174 #if defined(OS_WIN)
175   base::FilePath root_path = base::FilePath(FILE_PATH_LITERAL("c:/path/to/src"));
176 #else
177   base::FilePath root_path = base::FilePath(FILE_PATH_LITERAL("/path/to/src"));
178 #endif
179   setup.build_settings()->SetRootPath(root_path);
180   g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL(".gn")));
181   g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL("BUILD.gn")));
182   std::string out =
183       JSONProjectWriter::RenderJSON(setup.build_settings(), targets);
184 #if defined(OS_WIN)
185   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
186 #endif
187   const char expected_json[] =
188       "{\n"
189       "   \"build_settings\": {\n"
190       "      \"build_dir\": \"//out/Debug/\",\n"
191       "      \"default_toolchain\": \"//toolchain:default\",\n"
192       "      \"gen_input_files\": [ \"//.gn\", \"//BUILD.gn\" ],\n"
193 #if defined(OS_WIN)
194       "      \"root_path\": \"c:/path/to/src\"\n"
195 #else
196       "      \"root_path\": \"/path/to/src\"\n"
197 #endif
198       "   },\n"
199       "   \"targets\": {\n"
200       "      \"//foo:bar()\": {\n"
201       "         \"args\": [ \"{{source}}\", \"{{source_file_part}}\", "
202       "\"{{response_file_name}}\" ],\n"
203       "         \"deps\": [  ],\n"
204       "         \"metadata\": {\n"
205       "\n"
206       "         },\n"
207       "         \"output_patterns\": [ "
208       "\"//out/Debug/{{source_name_part}}.out\" ],\n"
209       "         \"outputs\": [ \"//out/Debug/input1.out\" ],\n"
210       "         \"public\": \"*\",\n"
211       "         \"response_file_contents\": [ \"-j\", \"{{source_name_part}}\" "
212       "],\n"
213       "         \"script\": \"//foo/script.py\",\n"
214       "         \"sources\": [ \"//foo/input1.txt\" ],\n"
215       "         \"testonly\": false,\n"
216       "         \"toolchain\": \"\",\n"
217       "         \"type\": \"action_foreach\",\n"
218       "         \"visibility\": [  ]\n"
219       "      }\n"
220       "   }\n"
221       "}\n";
222   EXPECT_EQ(expected_json, out);
223 }
224