1 // Copyright (c) 2012 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 "tools/json_schema_compiler/test/choices.h"
6 
7 #include <stddef.h>
8 
9 #include <utility>
10 
11 #include "base/strings/string_piece.h"
12 #include "base/values.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "tools/json_schema_compiler/test/test_util.h"
15 
16 namespace {
17 
18 namespace choices = test::api::choices;
19 namespace TakesIntegers = choices::TakesIntegers;
20 using choices::NestedChoice;
21 using json_schema_compiler::test_util::Dictionary;
22 using json_schema_compiler::test_util::List;
23 using json_schema_compiler::test_util::ReadJson;
24 using json_schema_compiler::test_util::Vector;
25 
TEST(JsonSchemaCompilerChoicesTest,TakesIntegersParamsCreate)26 TEST(JsonSchemaCompilerChoicesTest, TakesIntegersParamsCreate) {
27   {
28     std::unique_ptr<TakesIntegers::Params> params(TakesIntegers::Params::Create(
29         *List(std::make_unique<base::Value>(true))));
30     EXPECT_FALSE(params);
31   }
32   {
33     std::unique_ptr<TakesIntegers::Params> params(
34         TakesIntegers::Params::Create(*List(std::make_unique<base::Value>(6))));
35     ASSERT_TRUE(params);
36     EXPECT_FALSE(params->nums.as_integers);
37     EXPECT_EQ(6, *params->nums.as_integer);
38   }
39   {
40     std::unique_ptr<TakesIntegers::Params> params(
41         TakesIntegers::Params::Create(*List(List(
42             std::make_unique<base::Value>(2), std::make_unique<base::Value>(6),
43             std::make_unique<base::Value>(8)))));
44     ASSERT_TRUE(params);
45     ASSERT_TRUE(params->nums.as_integers);
46     EXPECT_EQ(Vector(2, 6, 8), *params->nums.as_integers);
47   }
48 }
49 
TEST(JsonSchemaCompilerChoicesTest,ObjectWithChoicesParamsCreate)50 TEST(JsonSchemaCompilerChoicesTest, ObjectWithChoicesParamsCreate) {
51   {
52     std::unique_ptr<choices::ObjectWithChoices::Params> params(
53         choices::ObjectWithChoices::Params::Create(*List(
54             Dictionary("strings", std::make_unique<base::Value>("asdf")))));
55     ASSERT_TRUE(params);
56     EXPECT_FALSE(params->string_info.strings.as_strings);
57     EXPECT_EQ("asdf", *params->string_info.strings.as_string);
58     EXPECT_FALSE(params->string_info.integers);
59   }
60   {
61     std::unique_ptr<choices::ObjectWithChoices::Params> params(
62         choices::ObjectWithChoices::Params::Create(
63             *List(Dictionary("strings", std::make_unique<base::Value>("asdf"),
64                              "integers", std::make_unique<base::Value>(6)))));
65     ASSERT_TRUE(params);
66     EXPECT_FALSE(params->string_info.strings.as_strings);
67     EXPECT_EQ("asdf", *params->string_info.strings.as_string);
68     ASSERT_TRUE(params->string_info.integers);
69     EXPECT_FALSE(params->string_info.integers->as_integers);
70     EXPECT_EQ(6, *params->string_info.integers->as_integer);
71   }
72 }
73 
74 // TODO(kalman): Clean up the rest of these tests to use the
75 // Vector/List/Dictionary helpers.
76 
TEST(JsonSchemaCompilerChoicesTest,ObjectWithChoicesParamsCreateFail)77 TEST(JsonSchemaCompilerChoicesTest, ObjectWithChoicesParamsCreateFail) {
78   {
79     auto object_param = std::make_unique<base::DictionaryValue>();
80     object_param->SetKey("strings", base::Value(5));
81     std::unique_ptr<base::ListValue> params_value(new base::ListValue());
82     params_value->Append(std::move(object_param));
83     std::unique_ptr<choices::ObjectWithChoices::Params> params(
84         choices::ObjectWithChoices::Params::Create(*params_value));
85     EXPECT_FALSE(params.get());
86   }
87   {
88     auto object_param = std::make_unique<base::DictionaryValue>();
89     object_param->SetKey("strings", base::Value("asdf"));
90     object_param->SetKey("integers", base::Value("asdf"));
91     std::unique_ptr<base::ListValue> params_value(new base::ListValue());
92     params_value->Append(std::move(object_param));
93     std::unique_ptr<choices::ObjectWithChoices::Params> params(
94         choices::ObjectWithChoices::Params::Create(*params_value));
95     EXPECT_FALSE(params.get());
96   }
97   {
98     auto object_param = std::make_unique<base::DictionaryValue>();
99     object_param->SetKey("integers", base::Value(6));
100     std::unique_ptr<base::ListValue> params_value(new base::ListValue());
101     params_value->Append(std::move(object_param));
102     std::unique_ptr<choices::ObjectWithChoices::Params> params(
103         choices::ObjectWithChoices::Params::Create(*params_value));
104     EXPECT_FALSE(params.get());
105   }
106 }
107 
TEST(JsonSchemaCompilerChoicesTest,PopulateChoiceType)108 TEST(JsonSchemaCompilerChoicesTest, PopulateChoiceType) {
109   std::vector<std::string> strings = Vector(std::string("list"),
110                                             std::string("of"),
111                                             std::string("strings"));
112 
113   auto strings_value = std::make_unique<base::ListValue>();
114   for (size_t i = 0; i < strings.size(); ++i)
115     strings_value->AppendString(strings[i]);
116 
117   base::DictionaryValue value;
118   value.SetInteger("integers", 4);
119   value.Set("strings", std::move(strings_value));
120 
121   choices::ChoiceType out;
122   ASSERT_TRUE(choices::ChoiceType::Populate(value, &out));
123   ASSERT_TRUE(out.integers.as_integer.get());
124   EXPECT_FALSE(out.integers.as_integers.get());
125   EXPECT_EQ(4, *out.integers.as_integer);
126 
127   EXPECT_FALSE(out.strings->as_string.get());
128   ASSERT_TRUE(out.strings->as_strings.get());
129   EXPECT_EQ(strings, *out.strings->as_strings);
130 }
131 
TEST(JsonSchemaCompilerChoicesTest,ChoiceTypeToValue)132 TEST(JsonSchemaCompilerChoicesTest, ChoiceTypeToValue) {
133   auto strings_value = std::make_unique<base::ListValue>();
134   strings_value->AppendString("list");
135   strings_value->AppendString("of");
136   strings_value->AppendString("strings");
137 
138   base::DictionaryValue value;
139   value.SetInteger("integers", 5);
140   value.Set("strings", std::move(strings_value));
141 
142   choices::ChoiceType out;
143   ASSERT_TRUE(choices::ChoiceType::Populate(value, &out));
144 
145   EXPECT_TRUE(value.Equals(out.ToValue().get()));
146 }
147 
TEST(JsonSchemaCompilerChoicesTest,ReturnChoices)148 TEST(JsonSchemaCompilerChoicesTest, ReturnChoices) {
149   {
150     choices::ReturnChoices::Results::Result results;
151     results.as_integers = std::make_unique<std::vector<int>>(Vector(1, 2));
152 
153     std::unique_ptr<base::Value> results_value = results.ToValue();
154     ASSERT_TRUE(results_value);
155 
156     base::ListValue expected;
157     expected.AppendInteger(1);
158     expected.AppendInteger(2);
159 
160     EXPECT_TRUE(expected.Equals(results_value.get()));
161   }
162   {
163     choices::ReturnChoices::Results::Result results;
164     results.as_integer = std::make_unique<int>(5);
165 
166     std::unique_ptr<base::Value> results_value = results.ToValue();
167     ASSERT_TRUE(results_value);
168 
169     base::Value expected(5);
170 
171     EXPECT_TRUE(expected.Equals(results_value.get()));
172   }
173 }
174 
TEST(JsonSchemaCompilerChoicesTest,NestedChoices)175 TEST(JsonSchemaCompilerChoicesTest, NestedChoices) {
176   // These test both ToValue and FromValue for every legitimate configuration of
177   // NestedChoices.
178   {
179     // The plain integer choice.
180     base::Value value = ReadJson("42");
181     std::unique_ptr<NestedChoice> obj = NestedChoice::FromValue(value);
182 
183     ASSERT_TRUE(obj);
184     ASSERT_TRUE(obj->as_integer);
185     EXPECT_FALSE(obj->as_choice1);
186     EXPECT_FALSE(obj->as_choice2);
187     EXPECT_EQ(42, *obj->as_integer);
188 
189     EXPECT_EQ(value, *obj->ToValue());
190   }
191 
192   {
193     // The string choice within the first choice.
194     base::Value value = ReadJson("\"foo\"");
195     std::unique_ptr<NestedChoice> obj = NestedChoice::FromValue(value);
196 
197     ASSERT_TRUE(obj);
198     EXPECT_FALSE(obj->as_integer);
199     ASSERT_TRUE(obj->as_choice1);
200     EXPECT_FALSE(obj->as_choice2);
201     ASSERT_TRUE(obj->as_choice1->as_string);
202     EXPECT_FALSE(obj->as_choice1->as_boolean);
203     EXPECT_EQ("foo", *obj->as_choice1->as_string);
204 
205     EXPECT_EQ(value, *obj->ToValue());
206   }
207 
208   {
209     // The boolean choice within the first choice.
210     base::Value value = ReadJson("true");
211     std::unique_ptr<NestedChoice> obj = NestedChoice::FromValue(value);
212 
213     ASSERT_TRUE(obj);
214     EXPECT_FALSE(obj->as_integer);
215     ASSERT_TRUE(obj->as_choice1);
216     EXPECT_FALSE(obj->as_choice2);
217     EXPECT_FALSE(obj->as_choice1->as_string);
218     ASSERT_TRUE(obj->as_choice1->as_boolean);
219     EXPECT_TRUE(*obj->as_choice1->as_boolean);
220 
221     EXPECT_EQ(value, *obj->ToValue());
222   }
223 
224   {
225     // The double choice within the second choice.
226     base::Value value = ReadJson("42.0");
227     std::unique_ptr<NestedChoice> obj = NestedChoice::FromValue(value);
228 
229     ASSERT_TRUE(obj);
230     EXPECT_FALSE(obj->as_integer);
231     EXPECT_FALSE(obj->as_choice1);
232     ASSERT_TRUE(obj->as_choice2);
233     ASSERT_TRUE(obj->as_choice2->as_double);
234     EXPECT_FALSE(obj->as_choice2->as_choice_type);
235     EXPECT_FALSE(obj->as_choice2->as_choice_types);
236     EXPECT_EQ(42.0, *obj->as_choice2->as_double);
237 
238     EXPECT_EQ(value, *obj->ToValue());
239   }
240 
241   {
242     // The ChoiceType choice within the second choice.
243     base::Value value =
244         ReadJson("{\"integers\": [1, 2], \"strings\": \"foo\"}");
245     std::unique_ptr<NestedChoice> obj = NestedChoice::FromValue(value);
246 
247     ASSERT_TRUE(obj);
248     EXPECT_FALSE(obj->as_integer);
249     EXPECT_FALSE(obj->as_choice1);
250     ASSERT_TRUE(obj->as_choice2);
251     EXPECT_FALSE(obj->as_choice2->as_double);
252     ASSERT_TRUE(obj->as_choice2->as_choice_type);
253     EXPECT_FALSE(obj->as_choice2->as_choice_types);
254     {
255       choices::ChoiceType* choice_type = obj->as_choice2->as_choice_type.get();
256       ASSERT_TRUE(choice_type->integers.as_integers);
257       EXPECT_FALSE(choice_type->integers.as_integer);
258       EXPECT_EQ(Vector(1, 2), *choice_type->integers.as_integers);
259       ASSERT_TRUE(choice_type->strings);
260       EXPECT_FALSE(choice_type->strings->as_strings);
261       ASSERT_TRUE(choice_type->strings->as_string);
262       EXPECT_EQ("foo", *choice_type->strings->as_string);
263     }
264 
265     EXPECT_EQ(value, *obj->ToValue());
266   }
267 
268   {
269     // The array of ChoiceTypes within the second choice.
270     base::Value value = ReadJson(
271         "["
272         "  {\"integers\": [1, 2], \"strings\": \"foo\"},"
273         "  {\"integers\": 3, \"strings\": [\"bar\", \"baz\"]}"
274         "]");
275     std::unique_ptr<NestedChoice> obj = NestedChoice::FromValue(value);
276 
277     ASSERT_TRUE(obj);
278     EXPECT_FALSE(obj->as_integer);
279     EXPECT_FALSE(obj->as_choice1);
280     ASSERT_TRUE(obj->as_choice2);
281     EXPECT_FALSE(obj->as_choice2->as_double);
282     EXPECT_FALSE(obj->as_choice2->as_choice_type);
283     ASSERT_TRUE(obj->as_choice2->as_choice_types);
284     // Bleh too much effort to test everything.
285     ASSERT_EQ(2u, obj->as_choice2->as_choice_types->size());
286 
287     EXPECT_EQ(value, *obj->ToValue());
288   }
289 }
290 
291 }  // namespace
292