blob: ffa05a6a0d83f808f15102f01cf494e4a3985479 [file] [log] [blame]
Alex Vakulenko66ec2922014-06-17 15:30:22 -07001// Copyright 2014 The Chromium OS 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 <memory>
6#include <string>
7#include <vector>
8
Alex Vakulenko66ec2922014-06-17 15:30:22 -07009#include <base/values.h>
Alex Vakulenko576c9792014-09-22 16:49:45 -070010#include <chromeos/variant_dictionary.h>
Alex Vakulenko66ec2922014-06-17 15:30:22 -070011#include <gtest/gtest.h>
12
13#include "buffet/commands/object_schema.h"
14#include "buffet/commands/prop_types.h"
15#include "buffet/commands/prop_values.h"
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -070016#include "buffet/commands/schema_constants.h"
Alex Vakulenko66ec2922014-06-17 15:30:22 -070017#include "buffet/commands/schema_utils.h"
Alex Vakulenko6201d2d2014-07-16 14:46:48 -070018#include "buffet/commands/unittest_utils.h"
Alex Vakulenko66ec2922014-06-17 15:30:22 -070019
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -070020using buffet::unittests::CreateDictionaryValue;
Alex Vakulenko6201d2d2014-07-16 14:46:48 -070021using buffet::unittests::CreateValue;
22using buffet::unittests::ValueToString;
Alex Vakulenko576c9792014-09-22 16:49:45 -070023using chromeos::VariantDictionary;
Alex Vakulenko66ec2922014-06-17 15:30:22 -070024
25TEST(CommandSchemaUtils, TypedValueToJson_Scalar) {
26 EXPECT_EQ("true",
27 ValueToString(buffet::TypedValueToJson(true, nullptr).get()));
28 EXPECT_EQ("false",
29 ValueToString(buffet::TypedValueToJson(false, nullptr).get()));
30
31 EXPECT_EQ("0", ValueToString(buffet::TypedValueToJson(0, nullptr).get()));
32 EXPECT_EQ("-10", ValueToString(buffet::TypedValueToJson(-10, nullptr).get()));
33 EXPECT_EQ("20", ValueToString(buffet::TypedValueToJson(20, nullptr).get()));
34
35 EXPECT_EQ("0.0", ValueToString(buffet::TypedValueToJson(0.0, nullptr).get()));
36 EXPECT_EQ("1.2", ValueToString(buffet::TypedValueToJson(1.2, nullptr).get()));
37
38 EXPECT_EQ("'abc'",
39 ValueToString(buffet::TypedValueToJson(std::string("abc"),
40 nullptr).get()));
41
42 std::vector<bool> bool_array{true, false};
43 EXPECT_EQ("[true,false]",
44 ValueToString(buffet::TypedValueToJson(bool_array, nullptr).get()));
45
46 std::vector<int> int_array{1, 2, 5};
47 EXPECT_EQ("[1,2,5]",
48 ValueToString(buffet::TypedValueToJson(int_array, nullptr).get()));
49
50 std::vector<double> dbl_array{1.1, 2.2};
51 EXPECT_EQ("[1.1,2.2]",
52 ValueToString(buffet::TypedValueToJson(dbl_array, nullptr).get()));
53
54 std::vector<std::string> str_array{"a", "bc"};
55 EXPECT_EQ("['a','bc']",
56 ValueToString(buffet::TypedValueToJson(str_array, nullptr).get()));
57}
58
59TEST(CommandSchemaUtils, TypedValueToJson_Object) {
60 buffet::IntPropType int_type;
61 buffet::native_types::Object object;
62
Alex Vakulenko157ccaa2014-09-19 14:59:34 -070063 object.insert(std::make_pair("width", int_type.CreateValue(640, nullptr)));
64 object.insert(std::make_pair("height", int_type.CreateValue(480, nullptr)));
Alex Vakulenko66ec2922014-06-17 15:30:22 -070065 EXPECT_EQ("{'height':480,'width':640}",
66 ValueToString(buffet::TypedValueToJson(object, nullptr).get()));
67}
68
69TEST(CommandSchemaUtils, TypedValueFromJson_Bool) {
70 bool value;
71
72 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("true").get(), nullptr,
73 &value, nullptr));
74 EXPECT_TRUE(value);
75
76 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("false").get(), nullptr,
77 &value, nullptr));
78 EXPECT_FALSE(value);
79
Alex Vakulenko5f472062014-08-14 17:54:04 -070080 chromeos::ErrorPtr error;
Alex Vakulenko66ec2922014-06-17 15:30:22 -070081 EXPECT_FALSE(buffet::TypedValueFromJson(CreateValue("0").get(), nullptr,
82 &value, &error));
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -070083 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
Alex Vakulenko66ec2922014-06-17 15:30:22 -070084 error.reset();
85}
86
87TEST(CommandSchemaUtils, TypedValueFromJson_Int) {
88 int value;
89
90 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("0").get(), nullptr,
91 &value, nullptr));
92 EXPECT_EQ(0, value);
93
94 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("23").get(), nullptr,
95 &value, nullptr));
96 EXPECT_EQ(23, value);
97
98 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("-1234").get(), nullptr,
99 &value, nullptr));
100 EXPECT_EQ(-1234, value);
101
Alex Vakulenko5f472062014-08-14 17:54:04 -0700102 chromeos::ErrorPtr error;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700103 EXPECT_FALSE(buffet::TypedValueFromJson(CreateValue("'abc'").get(), nullptr,
104 &value, &error));
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700105 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700106 error.reset();
107}
108
109TEST(CommandSchemaUtils, TypedValueFromJson_Double) {
110 double value;
111
112 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("0").get(), nullptr,
113 &value, nullptr));
114 EXPECT_DOUBLE_EQ(0.0, value);
115 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("0.0").get(), nullptr,
116 &value, nullptr));
117 EXPECT_DOUBLE_EQ(0.0, value);
118
119 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("23").get(), nullptr,
120 &value, nullptr));
121 EXPECT_EQ(23.0, value);
122 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("23.1").get(), nullptr,
123 &value, nullptr));
124 EXPECT_EQ(23.1, value);
125
126 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("-1.23E+02").get(),
127 nullptr, &value, nullptr));
128 EXPECT_EQ(-123.0, value);
129
Alex Vakulenko5f472062014-08-14 17:54:04 -0700130 chromeos::ErrorPtr error;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700131 EXPECT_FALSE(buffet::TypedValueFromJson(CreateValue("'abc'").get(), nullptr,
132 &value, &error));
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700133 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700134 error.reset();
135}
136
137TEST(CommandSchemaUtils, TypedValueFromJson_String) {
138 std::string value;
139
140 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("''").get(), nullptr,
141 &value, nullptr));
142 EXPECT_EQ("", value);
143
144 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("'23'").get(), nullptr,
145 &value, nullptr));
146 EXPECT_EQ("23", value);
147
148 EXPECT_TRUE(buffet::TypedValueFromJson(CreateValue("'abc'").get(), nullptr,
149 &value, nullptr));
150 EXPECT_EQ("abc", value);
151
Alex Vakulenko5f472062014-08-14 17:54:04 -0700152 chromeos::ErrorPtr error;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700153 EXPECT_FALSE(buffet::TypedValueFromJson(CreateValue("12").get(), nullptr,
154 &value, &error));
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700155 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700156 error.reset();
157}
158
159TEST(CommandSchemaUtils, TypedValueFromJson_Object) {
160 buffet::native_types::Object value;
161 buffet::ObjectSchema schema;
162
163 auto age_prop = std::make_shared<buffet::IntPropType>();
164 age_prop->AddMinMaxConstraint(0, 150);
165 schema.AddProp("age", age_prop);
166
167 auto name_prop = std::make_shared<buffet::StringPropType>();
168 name_prop->AddLengthConstraint(1, 30);
169 schema.AddProp("name", name_prop);
170
171 EXPECT_TRUE(buffet::TypedValueFromJson(
172 CreateValue("{'age':20,'name':'Bob'}").get(), &schema, &value, nullptr));
173 buffet::native_types::Object value2;
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700174 value2.insert(std::make_pair("age", age_prop->CreateValue(20, nullptr)));
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700175 value2.insert(std::make_pair("name",
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700176 name_prop->CreateValue(std::string("Bob"),
177 nullptr)));
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700178 EXPECT_EQ(value2, value);
179
Alex Vakulenko5f472062014-08-14 17:54:04 -0700180 chromeos::ErrorPtr error;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700181 EXPECT_FALSE(buffet::TypedValueFromJson(CreateValue("'abc'").get(), nullptr,
182 &value, &error));
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700183 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700184 error.reset();
185}
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700186
187TEST(CommandSchemaUtils, PropValueToDBusVariant) {
188 buffet::IntPropType int_type;
189 auto prop_value = int_type.CreateValue(5, nullptr);
190 EXPECT_EQ(5, PropValueToDBusVariant(prop_value.get()).Get<int>());
191
192 buffet::BooleanPropType bool_type;
193 prop_value = bool_type.CreateValue(true, nullptr);
194 EXPECT_TRUE(PropValueToDBusVariant(prop_value.get()).Get<bool>());
195
196 buffet::DoublePropType dbl_type;
197 prop_value = dbl_type.CreateValue(5.5, nullptr);
198 EXPECT_DOUBLE_EQ(5.5, PropValueToDBusVariant(prop_value.get()).Get<double>());
199
200 buffet::StringPropType str_type;
201 prop_value = str_type.CreateValue(std::string{"foo"}, nullptr);
202 EXPECT_EQ("foo", PropValueToDBusVariant(prop_value.get()).Get<std::string>());
203
204 buffet::ObjectPropType obj_type;
205 ASSERT_TRUE(obj_type.FromJson(CreateDictionaryValue(
206 "{'properties':{'width':'integer','height':'integer'},"
207 "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}").get(),
208 nullptr, nullptr));
209 buffet::native_types::Object obj{
210 {"width", int_type.CreateValue(10, nullptr)},
211 {"height", int_type.CreateValue(20, nullptr)},
212 };
213 prop_value = obj_type.CreateValue(obj, nullptr);
Alex Vakulenko576c9792014-09-22 16:49:45 -0700214 VariantDictionary dict =
215 PropValueToDBusVariant(prop_value.get()).Get<VariantDictionary>();
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700216 EXPECT_EQ(20, dict["height"].Get<int>());
217 EXPECT_EQ(10, dict["width"].Get<int>());
218}
219
220TEST(CommandSchemaUtils, PropValueFromDBusVariant_Int) {
221 buffet::IntPropType int_type;
222 ASSERT_TRUE(int_type.FromJson(CreateDictionaryValue("{'enum':[1,2]}").get(),
223 nullptr, nullptr));
224
225 auto prop_value = PropValueFromDBusVariant(&int_type, 1, nullptr);
226 ASSERT_NE(nullptr, prop_value.get());
227 EXPECT_EQ(1, prop_value->GetValueAsAny().Get<int>());
228
229 chromeos::ErrorPtr error;
230 prop_value = PropValueFromDBusVariant(&int_type, 5, &error);
231 EXPECT_EQ(nullptr, prop_value.get());
232 ASSERT_NE(nullptr, error.get());
233 EXPECT_EQ(buffet::errors::commands::kOutOfRange, error->GetCode());
234}
235
236TEST(CommandSchemaUtils, PropValueFromDBusVariant_Bool) {
237 buffet::BooleanPropType bool_type;
238 ASSERT_TRUE(bool_type.FromJson(CreateDictionaryValue("{'enum':[true]}").get(),
239 nullptr, nullptr));
240
241 auto prop_value = PropValueFromDBusVariant(&bool_type, true, nullptr);
242 ASSERT_NE(nullptr, prop_value.get());
243 EXPECT_TRUE(prop_value->GetValueAsAny().Get<bool>());
244
245 chromeos::ErrorPtr error;
246 prop_value = PropValueFromDBusVariant(&bool_type, false, &error);
247 EXPECT_EQ(nullptr, prop_value.get());
248 ASSERT_NE(nullptr, error.get());
249 EXPECT_EQ(buffet::errors::commands::kOutOfRange, error->GetCode());
250}
251
252TEST(CommandSchemaUtils, PropValueFromDBusVariant_Double) {
253 buffet::DoublePropType dbl_type;
254 ASSERT_TRUE(dbl_type.FromJson(CreateDictionaryValue("{'maximum':2.0}").get(),
255 nullptr, nullptr));
256
257 auto prop_value = PropValueFromDBusVariant(&dbl_type, 1.0, nullptr);
258 ASSERT_NE(nullptr, prop_value.get());
259 EXPECT_DOUBLE_EQ(1.0, prop_value->GetValueAsAny().Get<double>());
260
261 chromeos::ErrorPtr error;
262 prop_value = PropValueFromDBusVariant(&dbl_type, 10.0, &error);
263 EXPECT_EQ(nullptr, prop_value.get());
264 ASSERT_NE(nullptr, error.get());
265 EXPECT_EQ(buffet::errors::commands::kOutOfRange, error->GetCode());
266}
267
268TEST(CommandSchemaUtils, PropValueFromDBusVariant_String) {
269 buffet::StringPropType str_type;
270 ASSERT_TRUE(str_type.FromJson(CreateDictionaryValue("{'minLength': 4}").get(),
271 nullptr, nullptr));
272
273 auto prop_value = PropValueFromDBusVariant(&str_type, std::string{"blah"},
274 nullptr);
275 ASSERT_NE(nullptr, prop_value.get());
276 EXPECT_EQ("blah", prop_value->GetValueAsAny().Get<std::string>());
277
278 chromeos::ErrorPtr error;
279 prop_value = PropValueFromDBusVariant(&str_type, std::string{"foo"}, &error);
280 EXPECT_EQ(nullptr, prop_value.get());
281 ASSERT_NE(nullptr, error.get());
282 EXPECT_EQ(buffet::errors::commands::kOutOfRange, error->GetCode());
283}
284
285TEST(CommandSchemaUtils, PropValueFromDBusVariant_Object) {
286 buffet::ObjectPropType obj_type;
287 ASSERT_TRUE(obj_type.FromJson(CreateDictionaryValue(
288 "{'properties':{'width':'integer','height':'integer'},"
289 "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}").get(),
290 nullptr, nullptr));
291
Alex Vakulenko576c9792014-09-22 16:49:45 -0700292 VariantDictionary obj{
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700293 {"width", 100},
294 {"height", 200},
295 };
296 auto prop_value = PropValueFromDBusVariant(&obj_type, obj, nullptr);
297 ASSERT_NE(nullptr, prop_value.get());
298 auto value = prop_value->GetValueAsAny().Get<buffet::native_types::Object>();
299 EXPECT_EQ(100, value["width"].get()->GetValueAsAny().Get<int>());
300 EXPECT_EQ(200, value["height"].get()->GetValueAsAny().Get<int>());
301
302 chromeos::ErrorPtr error;
303 obj["height"] = 20;
304 prop_value = PropValueFromDBusVariant(&obj_type, obj, &error);
305 EXPECT_EQ(nullptr, prop_value.get());
306 ASSERT_NE(nullptr, error.get());
307 EXPECT_EQ(buffet::errors::commands::kOutOfRange, error->GetCode());
308}