1 // Copyright 2018 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/output_conversion.h"
6
7 #include <sstream>
8
9 #include "gn/err.h"
10 #include "gn/input_conversion.h"
11 #include "gn/scope.h"
12 #include "gn/template.h"
13 #include "gn/test_with_scheduler.h"
14 #include "gn/test_with_scope.h"
15 #include "gn/value.h"
16 #include "util/test/test.h"
17
18 namespace {
19
20 // InputConversion needs a global scheduler object.
21 class OutputConversionTest : public TestWithScheduler {
22 public:
23 OutputConversionTest() = default;
24
settings()25 const Settings* settings() { return setup_.settings(); }
scope()26 Scope* scope() { return setup_.scope(); }
27
28 private:
29 TestWithScope setup_;
30 };
31
32 } // namespace
33
TEST_F(OutputConversionTest,ListLines)34 TEST_F(OutputConversionTest, ListLines) {
35 Err err;
36 Value output(nullptr, Value::LIST);
37 output.list_value().push_back(Value(nullptr, ""));
38 output.list_value().push_back(Value(nullptr, "foo"));
39 output.list_value().push_back(Value(nullptr, ""));
40 output.list_value().push_back(Value(nullptr, "bar"));
41 std::ostringstream result;
42 ConvertValueToOutput(settings(), output, Value(nullptr, "list lines"), result,
43 &err);
44
45 EXPECT_FALSE(err.has_error());
46 EXPECT_EQ("\nfoo\n\nbar\n", result.str());
47 }
48
TEST_F(OutputConversionTest,String)49 TEST_F(OutputConversionTest, String) {
50 Err err;
51 Value output(nullptr, "foo bar");
52 std::ostringstream result;
53 ConvertValueToOutput(settings(), output, Value(nullptr, "string"), result,
54 &err);
55
56 EXPECT_FALSE(err.has_error());
57 EXPECT_EQ(result.str(), "foo bar");
58 }
59
TEST_F(OutputConversionTest,StringInt)60 TEST_F(OutputConversionTest, StringInt) {
61 Err err;
62 Value output(nullptr, int64_t(6));
63 std::ostringstream result;
64 ConvertValueToOutput(settings(), output, Value(nullptr, "string"), result,
65 &err);
66
67 EXPECT_FALSE(err.has_error());
68 EXPECT_EQ(result.str(), "\"6\"");
69 }
70
TEST_F(OutputConversionTest,StringBool)71 TEST_F(OutputConversionTest, StringBool) {
72 Err err;
73 Value output(nullptr, true);
74 std::ostringstream result;
75 ConvertValueToOutput(settings(), output, Value(nullptr, "string"), result,
76 &err);
77
78 EXPECT_FALSE(err.has_error());
79 EXPECT_EQ(result.str(), "\"true\"");
80 }
81
TEST_F(OutputConversionTest,StringList)82 TEST_F(OutputConversionTest, StringList) {
83 Err err;
84 Value output(nullptr, Value::LIST);
85 output.list_value().push_back(Value(nullptr, "foo"));
86 output.list_value().push_back(Value(nullptr, "bar"));
87 output.list_value().push_back(Value(nullptr, int64_t(6)));
88 std::ostringstream result;
89 ConvertValueToOutput(settings(), output, Value(nullptr, "string"), result,
90 &err);
91
92 EXPECT_FALSE(err.has_error());
93 EXPECT_EQ(result.str(), "\"[\"foo\", \"bar\", 6]\"");
94 }
95
TEST_F(OutputConversionTest,StringScope)96 TEST_F(OutputConversionTest, StringScope) {
97 Err err;
98
99 auto new_scope = std::make_unique<Scope>(settings());
100 // Add some values to the scope.
101 Value value(nullptr, "hello");
102 new_scope->SetValue("v", value, nullptr);
103 std::string_view private_var_name("_private");
104 new_scope->SetValue(private_var_name, value, nullptr);
105
106 std::ostringstream result;
107 ConvertValueToOutput(settings(), Value(nullptr, std::move(new_scope)),
108 Value(nullptr, "string"), result, &err);
109 EXPECT_FALSE(err.has_error());
110 EXPECT_EQ(result.str(), "\"{\n _private = \"hello\"\n v = \"hello\"\n}\"");
111 }
112
TEST_F(OutputConversionTest,ValueString)113 TEST_F(OutputConversionTest, ValueString) {
114 Err err;
115 Value output(nullptr, "foo bar");
116 std::ostringstream result;
117 ConvertValueToOutput(settings(), output, Value(nullptr, "value"), result,
118 &err);
119
120 EXPECT_FALSE(err.has_error());
121 EXPECT_EQ(result.str(), "\"foo bar\"");
122 }
123
TEST_F(OutputConversionTest,ValueInt)124 TEST_F(OutputConversionTest, ValueInt) {
125 Err err;
126 Value output(nullptr, int64_t(6));
127 std::ostringstream result;
128 ConvertValueToOutput(settings(), output, Value(nullptr, "value"), result,
129 &err);
130
131 EXPECT_FALSE(err.has_error());
132 EXPECT_EQ(result.str(), "6");
133 }
134
TEST_F(OutputConversionTest,ValueBool)135 TEST_F(OutputConversionTest, ValueBool) {
136 Err err;
137 Value output(nullptr, true);
138 std::ostringstream result;
139 ConvertValueToOutput(settings(), output, Value(nullptr, "value"), result,
140 &err);
141
142 EXPECT_FALSE(err.has_error());
143 EXPECT_EQ(result.str(), "true");
144 }
145
TEST_F(OutputConversionTest,ValueList)146 TEST_F(OutputConversionTest, ValueList) {
147 Err err;
148 Value output(nullptr, Value::LIST);
149 output.list_value().push_back(Value(nullptr, "foo"));
150 output.list_value().push_back(Value(nullptr, "bar"));
151 output.list_value().push_back(Value(nullptr, int64_t(6)));
152 std::ostringstream result;
153 ConvertValueToOutput(settings(), output, Value(nullptr, "value"), result,
154 &err);
155
156 EXPECT_FALSE(err.has_error());
157 EXPECT_EQ(result.str(), "[\"foo\", \"bar\", 6]");
158 }
159
TEST_F(OutputConversionTest,ValueScope)160 TEST_F(OutputConversionTest, ValueScope) {
161 Err err;
162
163 auto new_scope = std::make_unique<Scope>(settings());
164 // Add some values to the scope.
165 Value value(nullptr, "hello");
166 new_scope->SetValue("v", value, nullptr);
167 std::string_view private_var_name("_private");
168 new_scope->SetValue(private_var_name, value, nullptr);
169
170 std::ostringstream result;
171 ConvertValueToOutput(settings(), Value(nullptr, std::move(new_scope)),
172 Value(nullptr, "value"), result, &err);
173 EXPECT_FALSE(err.has_error());
174 EXPECT_EQ(result.str(), "{\n _private = \"hello\"\n v = \"hello\"\n}");
175 }
176
TEST_F(OutputConversionTest,JSON)177 TEST_F(OutputConversionTest, JSON) {
178 Err err;
179 auto new_scope = std::make_unique<Scope>(settings());
180 // Add some values to the scope.
181 Value a_value(nullptr, "foo");
182 new_scope->SetValue("a", a_value, nullptr);
183 Value b_value(nullptr, int64_t(6));
184 new_scope->SetValue("b", b_value, nullptr);
185
186 auto c_scope = std::make_unique<Scope>(settings());
187 Value e_value(nullptr, Value::LIST);
188 e_value.list_value().push_back(Value(nullptr, "bar"));
189
190 auto e_value_scope = std::make_unique<Scope>(settings());
191 Value f_value(nullptr, "baz");
192 e_value_scope->SetValue("f", f_value, nullptr);
193 e_value.list_value().push_back(Value(nullptr, std::move(e_value_scope)));
194
195 c_scope->SetValue("e", e_value, nullptr);
196
197 new_scope->SetValue("c", Value(nullptr, std::move(c_scope)), nullptr);
198
199 std::string expected(R"*({
200 "a": "foo",
201 "b": 6,
202 "c": {
203 "e": [
204 "bar",
205 {
206 "f": "baz"
207 }
208 ]
209 }
210 })*");
211 std::ostringstream result;
212 ConvertValueToOutput(settings(), Value(nullptr, std::move(new_scope)),
213 Value(nullptr, "json"), result, &err);
214 EXPECT_FALSE(err.has_error());
215 EXPECT_EQ(result.str(), expected);
216 }
217
TEST_F(OutputConversionTest,ValueEmpty)218 TEST_F(OutputConversionTest, ValueEmpty) {
219 Err err;
220 std::ostringstream result;
221 ConvertValueToOutput(settings(), Value(), Value(nullptr, ""), result, &err);
222 EXPECT_FALSE(err.has_error());
223 EXPECT_EQ(result.str(), "<void>");
224 }
225
TEST_F(OutputConversionTest,DefaultValue)226 TEST_F(OutputConversionTest, DefaultValue) {
227 Err err;
228 Value output(nullptr, "foo bar");
229 std::ostringstream result;
230 ConvertValueToOutput(settings(), output, Value(nullptr, ""), result, &err);
231
232 EXPECT_FALSE(err.has_error());
233 EXPECT_EQ(result.str(), "foo bar");
234 }
235
TEST_F(OutputConversionTest,DefaultListLines)236 TEST_F(OutputConversionTest, DefaultListLines) {
237 Err err;
238 Value output(nullptr, Value::LIST);
239 output.list_value().push_back(Value(nullptr, ""));
240 output.list_value().push_back(Value(nullptr, "foo"));
241 output.list_value().push_back(Value(nullptr, ""));
242 output.list_value().push_back(Value(nullptr, "bar"));
243 std::ostringstream result;
244 ConvertValueToOutput(settings(), output, Value(nullptr, ""), result, &err);
245
246 EXPECT_FALSE(err.has_error());
247 EXPECT_EQ("\nfoo\n\nbar\n", result.str());
248 }
249
TEST_F(OutputConversionTest,ReverseString)250 TEST_F(OutputConversionTest, ReverseString) {
251 Err err;
252 std::string input("foo bar");
253 Value result = ConvertInputToValue(settings(), input, nullptr,
254 Value(nullptr, "string"), &err);
255 EXPECT_FALSE(err.has_error());
256
257 std::ostringstream reverse;
258 ConvertValueToOutput(settings(), result, Value(nullptr, "string"), reverse,
259 &err);
260 EXPECT_FALSE(err.has_error());
261 EXPECT_EQ(reverse.str(), input)
262 << "actual: " << reverse.str() << "expected:" << input;
263 }
264
TEST_F(OutputConversionTest,ReverseListLines)265 TEST_F(OutputConversionTest, ReverseListLines) {
266 Err err;
267 std::string input("\nfoo\nbar\n\n");
268 Value result = ConvertInputToValue(settings(), input, nullptr,
269 Value(nullptr, "list lines"), &err);
270 EXPECT_FALSE(err.has_error());
271
272 std::ostringstream reverse;
273 ConvertValueToOutput(settings(), result, Value(nullptr, "list lines"),
274 reverse, &err);
275 EXPECT_FALSE(err.has_error());
276 EXPECT_EQ(reverse.str(), input)
277 << "actual: " << reverse.str() << "expected:" << input;
278 }
279
TEST_F(OutputConversionTest,ReverseValueString)280 TEST_F(OutputConversionTest, ReverseValueString) {
281 Err err;
282 std::string input("\"str\"");
283 Value result = ConvertInputToValue(settings(), input, nullptr,
284 Value(nullptr, "value"), &err);
285 EXPECT_FALSE(err.has_error());
286
287 std::ostringstream reverse;
288 ConvertValueToOutput(settings(), result, Value(nullptr, "value"), reverse,
289 &err);
290 EXPECT_FALSE(err.has_error());
291 EXPECT_EQ(reverse.str(), input)
292 << "actual: " << reverse.str() << "expected:" << input;
293 }
294
TEST_F(OutputConversionTest,ReverseValueInt)295 TEST_F(OutputConversionTest, ReverseValueInt) {
296 Err err;
297 std::string input("6");
298 Value result = ConvertInputToValue(settings(), input, nullptr,
299 Value(nullptr, "value"), &err);
300 EXPECT_FALSE(err.has_error());
301
302 std::ostringstream reverse;
303 ConvertValueToOutput(settings(), result, Value(nullptr, "value"), reverse,
304 &err);
305 EXPECT_FALSE(err.has_error());
306 EXPECT_EQ(reverse.str(), input)
307 << "actual: " << reverse.str() << "expected:" << input;
308 }
309
TEST_F(OutputConversionTest,ReverseValueList)310 TEST_F(OutputConversionTest, ReverseValueList) {
311 Err err;
312 std::string input("[\"a\", 5]");
313 Value result = ConvertInputToValue(settings(), input, nullptr,
314 Value(nullptr, "value"), &err);
315 EXPECT_FALSE(err.has_error());
316
317 std::ostringstream reverse;
318 ConvertValueToOutput(settings(), result, Value(nullptr, "value"), reverse,
319 &err);
320 EXPECT_FALSE(err.has_error());
321 EXPECT_EQ(reverse.str(), input)
322 << "actual: " << reverse.str() << "expected:" << input;
323 }
324
TEST_F(OutputConversionTest,ReverseValueDict)325 TEST_F(OutputConversionTest, ReverseValueDict) {
326 Err err;
327 std::string input(" a = 5\n b = \"foo\"\n c = 7\n");
328 Value result = ConvertInputToValue(settings(), input, nullptr,
329 Value(nullptr, "scope"), &err);
330 EXPECT_FALSE(err.has_error());
331
332 std::ostringstream reverse;
333 ConvertValueToOutput(settings(), result, Value(nullptr, "scope"), reverse,
334 &err);
335 EXPECT_FALSE(err.has_error());
336 EXPECT_EQ(reverse.str(), input)
337 << "actual: " << reverse.str() << "expected:" << input;
338 }
339
TEST_F(OutputConversionTest,ReverseValueEmpty)340 TEST_F(OutputConversionTest, ReverseValueEmpty) {
341 Err err;
342 Value result = ConvertInputToValue(settings(), "", nullptr,
343 Value(nullptr, "value"), &err);
344 EXPECT_FALSE(err.has_error());
345
346 std::ostringstream reverse;
347 ConvertValueToOutput(settings(), result, Value(nullptr, "value"), reverse,
348 &err);
349 EXPECT_FALSE(err.has_error());
350 EXPECT_EQ(reverse.str(), "");
351 }
352