blob: 850f64e840f4ecf014a435d9acd16f4e934a6ed7 [file] [log] [blame]
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -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
Alex Deymof6cbe322014-11-10 19:55:35 -08005#include "buffet/commands/object_schema.h"
6
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07007#include <algorithm>
8#include <limits>
9#include <memory>
10#include <vector>
11
12#include <base/json/json_reader.h>
13#include <base/json/json_writer.h>
14#include <base/values.h>
15#include <gtest/gtest.h>
16
Alex Vakulenko5ef75792015-03-19 15:50:44 -070017#include "buffet/commands/prop_constraints.h"
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070018#include "buffet/commands/prop_types.h"
Alex Vakulenko157ccaa2014-09-19 14:59:34 -070019#include "buffet/commands/schema_constants.h"
Alex Vakulenko6201d2d2014-07-16 14:46:48 -070020#include "buffet/commands/unittest_utils.h"
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070021
Alex Vakulenko6201d2d2014-07-16 14:46:48 -070022using buffet::unittests::CreateValue;
23using buffet::unittests::CreateDictionaryValue;
24using buffet::unittests::ValueToString;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070025
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -070026namespace {
27
28template<typename T>
Alex Vakulenko29e64442015-03-20 13:59:19 -070029std::vector<T> GetArrayValues(const buffet::native_types::Array& arr) {
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -070030 std::vector<T> values;
Alex Vakulenko29e64442015-03-20 13:59:19 -070031 values.reserve(arr.size());
32 for (const auto& prop_value : arr) {
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -070033 values.push_back(prop_value->GetValueAsAny().Get<T>());
34 }
35 return values;
36}
37
Alex Vakulenko29e64442015-03-20 13:59:19 -070038template<typename T>
39std::vector<T> GetOneOfValues(const buffet::PropType* prop_type) {
40 auto one_of = static_cast<const buffet::ConstraintOneOf*>(
41 prop_type->GetConstraint(buffet::ConstraintType::OneOf));
42 if (!one_of)
43 return {};
44
45 return GetArrayValues<T>(one_of->set_.value);
46}
47
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -070048} // anonymous namespace
49
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070050TEST(CommandSchema, IntPropType_Empty) {
51 buffet::IntPropType prop;
52 EXPECT_TRUE(prop.GetConstraints().empty());
53 EXPECT_FALSE(prop.HasOverriddenAttributes());
54 EXPECT_FALSE(prop.IsBasedOnSchema());
Alex Vakulenko2a17a532015-02-24 14:51:13 -080055 EXPECT_EQ(nullptr, prop.GetDefaultValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070056}
57
58TEST(CommandSchema, IntPropType_Types) {
59 buffet::IntPropType prop;
60 EXPECT_EQ(nullptr, prop.GetBoolean());
61 EXPECT_EQ(&prop, prop.GetInt());
62 EXPECT_EQ(nullptr, prop.GetDouble());
63 EXPECT_EQ(nullptr, prop.GetString());
Alex Vakulenko66ec2922014-06-17 15:30:22 -070064 EXPECT_EQ(nullptr, prop.GetObject());
Alex Vakulenko29e64442015-03-20 13:59:19 -070065 EXPECT_EQ(nullptr, prop.GetArray());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070066}
67
68TEST(CommandSchema, IntPropType_ToJson) {
69 buffet::IntPropType prop;
70 EXPECT_EQ("'integer'", ValueToString(prop.ToJson(false, nullptr).get()));
71 EXPECT_EQ("{'type':'integer'}",
72 ValueToString(prop.ToJson(true, nullptr).get()));
73 buffet::IntPropType param2;
74 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
75 EXPECT_EQ("{}", ValueToString(param2.ToJson(false, nullptr).get()));
76 param2.FromJson(CreateDictionaryValue("{'minimum':3}").get(),
77 &prop, nullptr);
78 EXPECT_EQ("{'minimum':3}",
79 ValueToString(param2.ToJson(false, nullptr).get()));
80 param2.FromJson(CreateDictionaryValue("{'maximum':-7}").get(),
81 &prop, nullptr);
82 EXPECT_EQ("{'maximum':-7}",
83 ValueToString(param2.ToJson(false, nullptr).get()));
84 param2.FromJson(CreateDictionaryValue("{'minimum':0,'maximum':5}").get(),
85 &prop, nullptr);
86 EXPECT_EQ("{'maximum':5,'minimum':0}",
87 ValueToString(param2.ToJson(false, nullptr).get()));
88 param2.FromJson(CreateDictionaryValue("{'enum':[1,2,3]}").get(), &prop,
89 nullptr);
90 EXPECT_EQ("[1,2,3]",
91 ValueToString(param2.ToJson(false, nullptr).get()));
Alex Vakulenko2a17a532015-02-24 14:51:13 -080092 param2.FromJson(CreateDictionaryValue("{'default':123}").get(),
93 &prop, nullptr);
94 EXPECT_EQ("{'default':123}",
95 ValueToString(param2.ToJson(false, nullptr).get()));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070096}
97
98TEST(CommandSchema, IntPropType_FromJson) {
99 buffet::IntPropType prop;
100 prop.AddMinMaxConstraint(2, 8);
101 buffet::IntPropType param2;
102 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
103 EXPECT_FALSE(param2.HasOverriddenAttributes());
104 EXPECT_TRUE(param2.IsBasedOnSchema());
105 EXPECT_EQ(2, prop.GetMinValue());
106 EXPECT_EQ(8, prop.GetMaxValue());
107 prop.AddMinMaxConstraint(-2, 30);
108 param2.FromJson(CreateDictionaryValue("{'minimum':7}").get(),
109 &prop, nullptr);
110 EXPECT_TRUE(param2.HasOverriddenAttributes());
111 EXPECT_TRUE(param2.IsBasedOnSchema());
112 EXPECT_EQ(7, param2.GetMinValue());
113 EXPECT_EQ(30, param2.GetMaxValue());
114 param2.FromJson(CreateDictionaryValue("{'maximum':17}").get(),
115 &prop, nullptr);
116 EXPECT_TRUE(param2.HasOverriddenAttributes());
117 EXPECT_TRUE(param2.IsBasedOnSchema());
118 EXPECT_EQ(-2, param2.GetMinValue());
119 EXPECT_EQ(17, param2.GetMaxValue());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800120
121 ASSERT_TRUE(param2.FromJson(CreateDictionaryValue("{'default':3}").get(),
122 &prop, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700123 EXPECT_TRUE(param2.HasOverriddenAttributes());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800124 ASSERT_NE(nullptr, param2.GetDefaultValue());
125 EXPECT_EQ(3, param2.GetDefaultValue()->GetInt()->GetValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700126}
127
128TEST(CommandSchema, IntPropType_Validate) {
129 buffet::IntPropType prop;
130 prop.AddMinMaxConstraint(2, 4);
Alex Vakulenko5f472062014-08-14 17:54:04 -0700131 chromeos::ErrorPtr error;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700132 EXPECT_FALSE(prop.ValidateValue(CreateValue("-1").get(), &error));
133 EXPECT_EQ("out_of_range", error->GetCode());
134 error.reset();
135 EXPECT_FALSE(prop.ValidateValue(CreateValue("0").get(), &error));
136 EXPECT_EQ("out_of_range", error->GetCode());
137 error.reset();
138 EXPECT_FALSE(prop.ValidateValue(CreateValue("1").get(), &error));
139 EXPECT_EQ("out_of_range", error->GetCode());
140 error.reset();
141 EXPECT_TRUE(prop.ValidateValue(CreateValue("2").get(), &error));
142 EXPECT_EQ(nullptr, error.get());
143 EXPECT_TRUE(prop.ValidateValue(CreateValue("3").get(), &error));
144 EXPECT_EQ(nullptr, error.get());
145 EXPECT_TRUE(prop.ValidateValue(CreateValue("4").get(), &error));
146 EXPECT_EQ(nullptr, error.get());
147 EXPECT_FALSE(prop.ValidateValue(CreateValue("5").get(), &error));
148 EXPECT_EQ("out_of_range", error->GetCode());
149 error.reset();
150 EXPECT_FALSE(prop.ValidateValue(CreateValue("true").get(), &error));
151 EXPECT_EQ("type_mismatch", error->GetCode());
152 error.reset();
153 EXPECT_FALSE(prop.ValidateValue(CreateValue("3.0").get(), &error));
154 EXPECT_EQ("type_mismatch", error->GetCode());
155 error.reset();
156 EXPECT_FALSE(prop.ValidateValue(CreateValue("'3'").get(), &error));
157 EXPECT_EQ("type_mismatch", error->GetCode());
158}
159
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700160TEST(CommandSchema, IntPropType_CreateValue) {
161 buffet::IntPropType prop;
162 chromeos::ErrorPtr error;
163 auto val = prop.CreateValue(2, &error);
164 ASSERT_NE(nullptr, val.get());
165 EXPECT_EQ(nullptr, error.get());
166 EXPECT_EQ(2, val->GetValueAsAny().Get<int>());
167
168 val = prop.CreateValue("blah", &error);
169 EXPECT_EQ(nullptr, val.get());
170 ASSERT_NE(nullptr, error.get());
171 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
172}
173
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700174///////////////////////////////////////////////////////////////////////////////
175
176TEST(CommandSchema, BoolPropType_Empty) {
177 buffet::BooleanPropType prop;
178 EXPECT_TRUE(prop.GetConstraints().empty());
179 EXPECT_FALSE(prop.HasOverriddenAttributes());
180 EXPECT_FALSE(prop.IsBasedOnSchema());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800181 EXPECT_EQ(nullptr, prop.GetDefaultValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700182}
183
184TEST(CommandSchema, BoolPropType_Types) {
185 buffet::BooleanPropType prop;
186 EXPECT_EQ(nullptr, prop.GetInt());
187 EXPECT_EQ(&prop, prop.GetBoolean());
188 EXPECT_EQ(nullptr, prop.GetDouble());
189 EXPECT_EQ(nullptr, prop.GetString());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700190 EXPECT_EQ(nullptr, prop.GetObject());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700191 EXPECT_EQ(nullptr, prop.GetArray());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700192}
193
194TEST(CommandSchema, BoolPropType_ToJson) {
195 buffet::BooleanPropType prop;
196 EXPECT_EQ("'boolean'", ValueToString(prop.ToJson(false, nullptr).get()));
197 EXPECT_EQ("{'type':'boolean'}",
198 ValueToString(prop.ToJson(true, nullptr).get()));
199 buffet::BooleanPropType param2;
200 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
201 EXPECT_EQ("{}", ValueToString(param2.ToJson(false, nullptr).get()));
202 param2.FromJson(CreateDictionaryValue("{'enum':[true,false]}").get(), &prop,
203 nullptr);
204 EXPECT_EQ("[true,false]", ValueToString(param2.ToJson(false, nullptr).get()));
205 EXPECT_EQ("{'enum':[true,false],'type':'boolean'}",
206 ValueToString(param2.ToJson(true, nullptr).get()));
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800207 param2.FromJson(CreateDictionaryValue("{'default':true}").get(),
208 &prop, nullptr);
209 EXPECT_EQ("{'default':true}",
210 ValueToString(param2.ToJson(false, nullptr).get()));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700211}
212
213TEST(CommandSchema, BoolPropType_FromJson) {
214 buffet::BooleanPropType prop;
215 prop.FromJson(CreateDictionaryValue("{'enum':[true]}").get(), &prop,
216 nullptr);
217 buffet::BooleanPropType param2;
218 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
219 EXPECT_FALSE(param2.HasOverriddenAttributes());
220 EXPECT_TRUE(param2.IsBasedOnSchema());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -0700221 EXPECT_EQ(std::vector<bool>{true}, GetOneOfValues<bool>(&prop));
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800222
223 buffet::BooleanPropType prop_base;
224 buffet::BooleanPropType param3;
225 ASSERT_TRUE(param3.FromJson(CreateDictionaryValue("{'default':false}").get(),
226 &prop_base, nullptr));
227 EXPECT_TRUE(param3.HasOverriddenAttributes());
228 ASSERT_NE(nullptr, param3.GetDefaultValue());
229 EXPECT_FALSE(param3.GetDefaultValue()->GetBoolean()->GetValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700230}
231
232TEST(CommandSchema, BoolPropType_Validate) {
233 buffet::BooleanPropType prop;
234 prop.FromJson(CreateDictionaryValue("{'enum':[true]}").get(), &prop,
235 nullptr);
Alex Vakulenko5f472062014-08-14 17:54:04 -0700236 chromeos::ErrorPtr error;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700237 EXPECT_FALSE(prop.ValidateValue(CreateValue("false").get(), &error));
238 EXPECT_EQ("out_of_range", error->GetCode());
239 error.reset();
240 EXPECT_TRUE(prop.ValidateValue(CreateValue("true").get(), &error));
241 error.reset();
242 EXPECT_FALSE(prop.ValidateValue(CreateValue("1").get(), &error));
243 EXPECT_EQ("type_mismatch", error->GetCode());
244 error.reset();
245 EXPECT_FALSE(prop.ValidateValue(CreateValue("3.0").get(), &error));
246 EXPECT_EQ("type_mismatch", error->GetCode());
247 error.reset();
248 EXPECT_FALSE(prop.ValidateValue(CreateValue("'3'").get(), &error));
249 EXPECT_EQ("type_mismatch", error->GetCode());
250}
251
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700252TEST(CommandSchema, BoolPropType_CreateValue) {
253 buffet::BooleanPropType prop;
254 chromeos::ErrorPtr error;
255 auto val = prop.CreateValue(true, &error);
256 ASSERT_NE(nullptr, val.get());
257 EXPECT_EQ(nullptr, error.get());
258 EXPECT_TRUE(val->GetValueAsAny().Get<bool>());
259
260 val = prop.CreateValue("blah", &error);
261 EXPECT_EQ(nullptr, val.get());
262 ASSERT_NE(nullptr, error.get());
263 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
264}
265
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700266///////////////////////////////////////////////////////////////////////////////
267
268TEST(CommandSchema, DoublePropType_Empty) {
269 buffet::DoublePropType prop;
270 EXPECT_DOUBLE_EQ(std::numeric_limits<double>::lowest(), prop.GetMinValue());
271 EXPECT_DOUBLE_EQ((std::numeric_limits<double>::max)(), prop.GetMaxValue());
272 EXPECT_FALSE(prop.HasOverriddenAttributes());
273 EXPECT_FALSE(prop.IsBasedOnSchema());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800274 EXPECT_EQ(nullptr, prop.GetDefaultValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700275}
276
277TEST(CommandSchema, DoublePropType_Types) {
278 buffet::DoublePropType prop;
279 EXPECT_EQ(nullptr, prop.GetInt());
280 EXPECT_EQ(nullptr, prop.GetBoolean());
281 EXPECT_EQ(&prop, prop.GetDouble());
282 EXPECT_EQ(nullptr, prop.GetString());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700283 EXPECT_EQ(nullptr, prop.GetObject());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700284 EXPECT_EQ(nullptr, prop.GetArray());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700285}
286
287TEST(CommandSchema, DoublePropType_ToJson) {
288 buffet::DoublePropType prop;
289 EXPECT_EQ("'number'", ValueToString(prop.ToJson(false, nullptr).get()));
290 EXPECT_EQ("{'type':'number'}",
291 ValueToString(prop.ToJson(true, nullptr).get()));
292 buffet::DoublePropType param2;
293 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
294 EXPECT_EQ("{}", ValueToString(param2.ToJson(false, nullptr).get()));
295 param2.FromJson(CreateDictionaryValue("{'minimum':3}").get(), &prop,
296 nullptr);
297 EXPECT_EQ("{'minimum':3.0}",
298 ValueToString(param2.ToJson(false, nullptr).get()));
299 param2.FromJson(CreateDictionaryValue("{'maximum':-7}").get(), &prop,
300 nullptr);
301 EXPECT_EQ("{'maximum':-7.0}",
302 ValueToString(param2.ToJson(false, nullptr).get()));
303 param2.FromJson(CreateDictionaryValue("{'minimum':0,'maximum':5}").get(),
304 &prop, nullptr);
305 EXPECT_EQ("{'maximum':5.0,'minimum':0.0}",
306 ValueToString(param2.ToJson(false, nullptr).get()));
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800307 param2.FromJson(CreateDictionaryValue("{'default':12.3}").get(),
308 &prop, nullptr);
309 EXPECT_EQ("{'default':12.3}",
310 ValueToString(param2.ToJson(false, nullptr).get()));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700311}
312
313TEST(CommandSchema, DoublePropType_FromJson) {
314 buffet::DoublePropType prop;
315 prop.AddMinMaxConstraint(2.5, 8.7);
316 buffet::DoublePropType param2;
317 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
318 EXPECT_FALSE(param2.HasOverriddenAttributes());
319 EXPECT_TRUE(param2.IsBasedOnSchema());
320 EXPECT_DOUBLE_EQ(2.5, prop.GetMinValue());
321 EXPECT_DOUBLE_EQ(8.7, prop.GetMaxValue());
322 prop.AddMinMaxConstraint(-2.2, 30.4);
323 param2.FromJson(CreateDictionaryValue("{'minimum':7}").get(), &prop,
324 nullptr);
325 EXPECT_TRUE(param2.HasOverriddenAttributes());
326 EXPECT_TRUE(param2.IsBasedOnSchema());
327 EXPECT_DOUBLE_EQ(7.0, param2.GetMinValue());
328 EXPECT_DOUBLE_EQ(30.4, param2.GetMaxValue());
329 param2.FromJson(CreateDictionaryValue("{'maximum':17.2}").get(), &prop,
330 nullptr);
331 EXPECT_TRUE(param2.HasOverriddenAttributes());
332 EXPECT_TRUE(param2.IsBasedOnSchema());
333 EXPECT_DOUBLE_EQ(-2.2, param2.GetMinValue());
334 EXPECT_DOUBLE_EQ(17.2, param2.GetMaxValue());
335 param2.FromJson(CreateDictionaryValue("{'minimum':0,'maximum':6.1}").get(),
336 &prop, nullptr);
337 EXPECT_TRUE(param2.HasOverriddenAttributes());
338 EXPECT_TRUE(param2.IsBasedOnSchema());
339 EXPECT_DOUBLE_EQ(0.0, param2.GetMinValue());
340 EXPECT_DOUBLE_EQ(6.1, param2.GetMaxValue());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800341
342 ASSERT_TRUE(param2.FromJson(CreateDictionaryValue("{'default':-1.234}").get(),
343 &prop, nullptr));
344 EXPECT_TRUE(param2.HasOverriddenAttributes());
345 ASSERT_NE(nullptr, param2.GetDefaultValue());
346 EXPECT_DOUBLE_EQ(-1.234, param2.GetDefaultValue()->GetDouble()->GetValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700347}
348
349TEST(CommandSchema, DoublePropType_Validate) {
350 buffet::DoublePropType prop;
351 prop.AddMinMaxConstraint(-1.2, 1.3);
Alex Vakulenko5f472062014-08-14 17:54:04 -0700352 chromeos::ErrorPtr error;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700353 EXPECT_FALSE(prop.ValidateValue(CreateValue("-2").get(), &error));
354 EXPECT_EQ("out_of_range", error->GetCode());
355 error.reset();
356 EXPECT_FALSE(prop.ValidateValue(CreateValue("-1.3").get(), &error));
357 EXPECT_EQ("out_of_range", error->GetCode());
358 error.reset();
359 EXPECT_TRUE(prop.ValidateValue(CreateValue("-1.2").get(), &error));
360 EXPECT_EQ(nullptr, error.get());
361 EXPECT_TRUE(prop.ValidateValue(CreateValue("0.0").get(), &error));
362 EXPECT_EQ(nullptr, error.get());
363 EXPECT_TRUE(prop.ValidateValue(CreateValue("1.3").get(), &error));
364 EXPECT_EQ(nullptr, error.get());
365 EXPECT_FALSE(prop.ValidateValue(CreateValue("1.31").get(), &error));
366 EXPECT_EQ("out_of_range", error->GetCode());
367 error.reset();
368 EXPECT_FALSE(prop.ValidateValue(CreateValue("true").get(), &error));
369 EXPECT_EQ("type_mismatch", error->GetCode());
370 error.reset();
371 EXPECT_FALSE(prop.ValidateValue(CreateValue("'0.0'").get(), &error));
372 EXPECT_EQ("type_mismatch", error->GetCode());
373}
374
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700375TEST(CommandSchema, DoublePropType_CreateValue) {
376 buffet::DoublePropType prop;
377 chromeos::ErrorPtr error;
378 auto val = prop.CreateValue(2.0, &error);
379 ASSERT_NE(nullptr, val.get());
380 EXPECT_EQ(nullptr, error.get());
381 EXPECT_DOUBLE_EQ(2.0, val->GetValueAsAny().Get<double>());
382
383 val = prop.CreateValue("blah", &error);
384 EXPECT_EQ(nullptr, val.get());
385 ASSERT_NE(nullptr, error.get());
386 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
387}
388
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700389///////////////////////////////////////////////////////////////////////////////
390
391TEST(CommandSchema, StringPropType_Empty) {
392 buffet::StringPropType prop;
393 EXPECT_EQ(0, prop.GetMinLength());
394 EXPECT_EQ((std::numeric_limits<int>::max)(), prop.GetMaxLength());
395 EXPECT_FALSE(prop.HasOverriddenAttributes());
396 EXPECT_FALSE(prop.IsBasedOnSchema());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800397 EXPECT_EQ(nullptr, prop.GetDefaultValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700398}
399
400TEST(CommandSchema, StringPropType_Types) {
401 buffet::StringPropType prop;
402 EXPECT_EQ(nullptr, prop.GetInt());
403 EXPECT_EQ(nullptr, prop.GetBoolean());
404 EXPECT_EQ(nullptr, prop.GetDouble());
405 EXPECT_EQ(&prop, prop.GetString());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700406 EXPECT_EQ(nullptr, prop.GetObject());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700407 EXPECT_EQ(nullptr, prop.GetArray());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700408}
409
410TEST(CommandSchema, StringPropType_ToJson) {
411 buffet::StringPropType prop;
412 EXPECT_EQ("'string'", ValueToString(prop.ToJson(false, nullptr).get()));
413 EXPECT_EQ("{'type':'string'}",
414 ValueToString(prop.ToJson(true, nullptr).get()));
415 buffet::StringPropType param2;
416 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
417 EXPECT_EQ("{}", ValueToString(param2.ToJson(false, nullptr).get()));
418 param2.FromJson(CreateDictionaryValue("{'minLength':3}").get(), &prop,
419 nullptr);
420 EXPECT_EQ("{'minLength':3}",
421 ValueToString(param2.ToJson(false, nullptr).get()));
422 param2.FromJson(CreateDictionaryValue("{'maxLength':7}").get(), &prop,
423 nullptr);
424 EXPECT_EQ("{'maxLength':7}",
425 ValueToString(param2.ToJson(false, nullptr).get()));
426 param2.FromJson(CreateDictionaryValue("{'minLength':0,'maxLength':5}").get(),
427 &prop, nullptr);
428 EXPECT_EQ("{'maxLength':5,'minLength':0}",
429 ValueToString(param2.ToJson(false, nullptr).get()));
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800430 param2.FromJson(CreateDictionaryValue("{'default':'abcd'}").get(),
431 &prop, nullptr);
432 EXPECT_EQ("{'default':'abcd'}",
433 ValueToString(param2.ToJson(false, nullptr).get()));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700434}
435
436TEST(CommandSchema, StringPropType_FromJson) {
437 buffet::StringPropType prop;
438 prop.AddLengthConstraint(2, 8);
439 buffet::StringPropType param2;
440 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
441 EXPECT_FALSE(param2.HasOverriddenAttributes());
442 EXPECT_TRUE(param2.IsBasedOnSchema());
443 EXPECT_EQ(2, prop.GetMinLength());
444 EXPECT_EQ(8, prop.GetMaxLength());
445 prop.AddLengthConstraint(3, 5);
446 param2.FromJson(CreateDictionaryValue("{'minLength':4}").get(), &prop,
447 nullptr);
448 EXPECT_TRUE(param2.HasOverriddenAttributes());
449 EXPECT_TRUE(param2.IsBasedOnSchema());
450 EXPECT_EQ(4, param2.GetMinLength());
451 EXPECT_EQ(5, param2.GetMaxLength());
452 param2.FromJson(CreateDictionaryValue("{'maxLength':8}").get(), &prop,
453 nullptr);
454 EXPECT_TRUE(param2.HasOverriddenAttributes());
455 EXPECT_TRUE(param2.IsBasedOnSchema());
456 EXPECT_EQ(3, param2.GetMinLength());
457 EXPECT_EQ(8, param2.GetMaxLength());
458 param2.FromJson(CreateDictionaryValue(
459 "{'minLength':1,'maxLength':7}").get(), &prop, nullptr);
460 EXPECT_TRUE(param2.HasOverriddenAttributes());
461 EXPECT_TRUE(param2.IsBasedOnSchema());
462 EXPECT_EQ(1, param2.GetMinLength());
463 EXPECT_EQ(7, param2.GetMaxLength());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800464
465 ASSERT_TRUE(param2.FromJson(CreateDictionaryValue("{'default':'foo'}").get(),
466 &prop, nullptr));
467 EXPECT_TRUE(param2.HasOverriddenAttributes());
468 ASSERT_NE(nullptr, param2.GetDefaultValue());
469 EXPECT_EQ("foo", param2.GetDefaultValue()->GetString()->GetValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700470}
471
472TEST(CommandSchema, StringPropType_Validate) {
473 buffet::StringPropType prop;
474 prop.AddLengthConstraint(1, 3);
Alex Vakulenko5f472062014-08-14 17:54:04 -0700475 chromeos::ErrorPtr error;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700476 EXPECT_FALSE(prop.ValidateValue(CreateValue("''").get(), &error));
477 EXPECT_EQ("out_of_range", error->GetCode());
478 error.reset();
479 prop.AddLengthConstraint(2, 3);
480 EXPECT_FALSE(prop.ValidateValue(CreateValue("''").get(), &error));
481 EXPECT_EQ("out_of_range", error->GetCode());
482 error.reset();
483 EXPECT_FALSE(prop.ValidateValue(CreateValue("'a'").get(), &error));
484 EXPECT_EQ("out_of_range", error->GetCode());
485 error.reset();
486 EXPECT_TRUE(prop.ValidateValue(CreateValue("'ab'").get(), &error));
487 EXPECT_EQ(nullptr, error.get());
488 EXPECT_TRUE(prop.ValidateValue(CreateValue("'abc'").get(), &error));
489 EXPECT_EQ(nullptr, error.get());
490 EXPECT_FALSE(prop.ValidateValue(CreateValue("'abcd'").get(), &error));
491 EXPECT_EQ("out_of_range", error->GetCode());
492 error.reset();
493
494 prop.FromJson(CreateDictionaryValue("{'enum':['abc','def','xyz!!']}").get(),
495 nullptr, &error);
496 EXPECT_TRUE(prop.ValidateValue(CreateValue("'abc'").get(), &error));
497 EXPECT_TRUE(prop.ValidateValue(CreateValue("'def'").get(), &error));
498 EXPECT_TRUE(prop.ValidateValue(CreateValue("'xyz!!'").get(), &error));
499 EXPECT_FALSE(prop.ValidateValue(CreateValue("'xyz'").get(), &error));
500 EXPECT_EQ("out_of_range", error->GetCode());
501 error.reset();
502}
503
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700504TEST(CommandSchema, StringPropType_CreateValue) {
505 buffet::StringPropType prop;
506 chromeos::ErrorPtr error;
507 auto val = prop.CreateValue(std::string{"blah"}, &error);
508 ASSERT_NE(nullptr, val.get());
509 EXPECT_EQ(nullptr, error.get());
510 EXPECT_EQ("blah", val->GetValueAsAny().Get<std::string>());
511
512 val = prop.CreateValue(4, &error);
513 EXPECT_EQ(nullptr, val.get());
514 ASSERT_NE(nullptr, error.get());
515 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
516}
517
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700518///////////////////////////////////////////////////////////////////////////////
519
520TEST(CommandSchema, ObjectPropType_Empty) {
521 buffet::ObjectPropType prop;
522 EXPECT_TRUE(prop.HasOverriddenAttributes());
523 EXPECT_FALSE(prop.IsBasedOnSchema());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800524 EXPECT_EQ(nullptr, prop.GetDefaultValue());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700525}
526
527TEST(CommandSchema, ObjectPropType_Types) {
528 buffet::ObjectPropType prop;
529 EXPECT_EQ(nullptr, prop.GetInt());
530 EXPECT_EQ(nullptr, prop.GetBoolean());
531 EXPECT_EQ(nullptr, prop.GetDouble());
532 EXPECT_EQ(nullptr, prop.GetString());
533 EXPECT_EQ(&prop, prop.GetObject());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700534 EXPECT_EQ(nullptr, prop.GetArray());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700535}
536
537TEST(CommandSchema, ObjectPropType_ToJson) {
538 buffet::ObjectPropType prop;
Alex Vakulenko45d255b2015-03-31 10:44:49 -0700539 EXPECT_EQ("{'additionalProperties':false,'properties':{}}",
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700540 ValueToString(prop.ToJson(false, nullptr).get()));
Alex Vakulenko45d255b2015-03-31 10:44:49 -0700541 EXPECT_EQ("{'additionalProperties':false,'properties':{},'type':'object'}",
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700542 ValueToString(prop.ToJson(true, nullptr).get()));
543 EXPECT_FALSE(prop.IsBasedOnSchema());
544 buffet::ObjectPropType prop2;
545 prop2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
546 EXPECT_EQ("{}", ValueToString(prop2.ToJson(false, nullptr).get()));
547 EXPECT_TRUE(prop2.IsBasedOnSchema());
548
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700549 auto schema = buffet::ObjectSchema::Create();
550 schema->AddProp("expires", buffet::PropType::Create(buffet::ValueType::Int));
551 auto pw = buffet::PropType::Create(buffet::ValueType::String);
552 pw->GetString()->AddLengthConstraint(6, 100);
553 schema->AddProp("password", std::move(pw));
554 prop2.SetObjectSchema(std::move(schema));
Alex Vakulenko45d255b2015-03-31 10:44:49 -0700555 EXPECT_EQ("{'additionalProperties':false,'properties':{'expires':'integer',"
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700556 "'password':{'maxLength':100,'minLength':6}}}",
557 ValueToString(prop2.ToJson(false, nullptr).get()));
Alex Vakulenko45d255b2015-03-31 10:44:49 -0700558 EXPECT_EQ("{'additionalProperties':false,'properties':{"
559 "'expires':{'type':'integer'},"
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700560 "'password':{'maxLength':100,'minLength':6,'type':'string'}},"
561 "'type':'object'}",
562 ValueToString(prop2.ToJson(true, nullptr).get()));
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800563
564 buffet::ObjectPropType prop3;
565 ASSERT_TRUE(prop3.FromJson(CreateDictionaryValue(
566 "{'default':{'expires':3,'password':'abracadabra'}}").get(), &prop2,
567 nullptr));
568 EXPECT_EQ("{'default':{'expires':3,'password':'abracadabra'}}",
569 ValueToString(prop3.ToJson(false, nullptr).get()));
Alex Vakulenko45d255b2015-03-31 10:44:49 -0700570 EXPECT_EQ("{'additionalProperties':false,"
571 "'default':{'expires':3,'password':'abracadabra'},"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800572 "'properties':{'expires':{'type':'integer'},"
573 "'password':{'maxLength':100,'minLength':6,'type':'string'}},"
574 "'type':'object'}",
575 ValueToString(prop3.ToJson(true, nullptr).get()));
Alex Vakulenko45d255b2015-03-31 10:44:49 -0700576
577 buffet::ObjectPropType prop4;
578 ASSERT_TRUE(prop4.FromJson(CreateDictionaryValue(
579 "{'additionalProperties':true,"
580 "'default':{'expires':3,'password':'abracadabra'}}").get(), &prop2,
581 nullptr));
582 EXPECT_EQ("{'additionalProperties':true,"
583 "'default':{'expires':3,'password':'abracadabra'},"
584 "'properties':{'expires':'integer',"
585 "'password':{'maxLength':100,'minLength':6}}}",
586 ValueToString(prop4.ToJson(false, nullptr).get()));
587 EXPECT_EQ("{'additionalProperties':true,"
588 "'default':{'expires':3,'password':'abracadabra'},"
589 "'properties':{'expires':{'type':'integer'},"
590 "'password':{'maxLength':100,'minLength':6,'type':'string'}},"
591 "'type':'object'}",
592 ValueToString(prop4.ToJson(true, nullptr).get()));
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700593}
594
595TEST(CommandSchema, ObjectPropType_FromJson) {
596 buffet::ObjectPropType base_prop;
597 EXPECT_TRUE(base_prop.FromJson(CreateDictionaryValue(
598 "{'properties':{'name':'string','age':'integer'}}").get(), nullptr,
599 nullptr));
Alex Vakulenkod94656e2015-03-18 09:54:37 -0700600 auto schema = base_prop.GetObject()->GetObjectSchemaPtr();
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700601 const buffet::PropType* prop = schema->GetProp("name");
602 EXPECT_EQ(buffet::ValueType::String, prop->GetType());
603 prop = schema->GetProp("age");
604 EXPECT_EQ(buffet::ValueType::Int, prop->GetType());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800605
606 buffet::ObjectPropType prop2;
607 ASSERT_TRUE(prop2.FromJson(CreateDictionaryValue(
608 "{'properties':{'name':'string','age':'integer'},"
609 "'default':{'name':'Bob','age':33}}").get(), nullptr, nullptr));
610 ASSERT_NE(nullptr, prop2.GetDefaultValue());
611 const buffet::ObjectValue* defval = prop2.GetDefaultValue()->GetObject();
612 ASSERT_NE(nullptr, defval);
613 buffet::native_types::Object objval = defval->GetValue();
614 EXPECT_EQ("Bob", objval["name"]->GetString()->GetValue());
615 EXPECT_EQ(33, objval["age"]->GetInt()->GetValue());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700616}
617
618TEST(CommandSchema, ObjectPropType_Validate) {
619 buffet::ObjectPropType prop;
620 prop.FromJson(CreateDictionaryValue(
621 "{'properties':{'expires':'integer',"
622 "'password':{'maxLength':100,'minLength':6}}}").get(), nullptr,
623 nullptr);
Alex Vakulenko5f472062014-08-14 17:54:04 -0700624 chromeos::ErrorPtr error;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700625 EXPECT_TRUE(prop.ValidateValue(CreateValue(
626 "{'expires':10,'password':'abcdef'}").get(), &error));
627 error.reset();
628
629 EXPECT_FALSE(prop.ValidateValue(CreateValue(
630 "{'expires':10}").get(), &error));
631 EXPECT_EQ("parameter_missing", error->GetCode());
632 error.reset();
633
634 EXPECT_FALSE(prop.ValidateValue(CreateValue(
635 "{'password':'abcdef'}").get(), &error));
636 EXPECT_EQ("parameter_missing", error->GetCode());
637 error.reset();
638
639 EXPECT_FALSE(prop.ValidateValue(CreateValue(
640 "{'expires':10,'password':'abcde'}").get(), &error));
641 EXPECT_EQ("out_of_range", error->GetFirstError()->GetCode());
642 error.reset();
643
644 EXPECT_FALSE(prop.ValidateValue(CreateValue("2").get(), &error));
645 EXPECT_EQ("type_mismatch", error->GetCode());
646 error.reset();
647
648 EXPECT_FALSE(prop.ValidateValue(CreateValue(
649 "{'expires':10,'password':'abcdef','retry':true}").get(), &error));
650 EXPECT_EQ("unexpected_parameter", error->GetCode());
651 error.reset();
652}
653
654TEST(CommandSchema, ObjectPropType_Validate_Enum) {
655 buffet::ObjectPropType prop;
656 EXPECT_TRUE(prop.FromJson(CreateDictionaryValue(
657 "{'properties':{'width':'integer','height':'integer'},"
658 "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}").get(),
659 nullptr, nullptr));
Alex Vakulenko5f472062014-08-14 17:54:04 -0700660 chromeos::ErrorPtr error;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700661 EXPECT_TRUE(prop.ValidateValue(CreateValue(
662 "{'height':20,'width':10}").get(), &error));
663 error.reset();
664
665 EXPECT_TRUE(prop.ValidateValue(CreateValue(
666 "{'height':200,'width':100}").get(), &error));
667 error.reset();
668
669 EXPECT_FALSE(prop.ValidateValue(CreateValue(
670 "{'height':12,'width':10}").get(), &error));
671 EXPECT_EQ("out_of_range", error->GetCode());
672 error.reset();
673}
674
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700675TEST(CommandSchema, ObjectPropType_CreateValue) {
676 buffet::ObjectPropType prop;
677 buffet::IntPropType int_type;
678 ASSERT_TRUE(prop.FromJson(CreateDictionaryValue(
679 "{'properties':{'width':'integer','height':'integer'},"
680 "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}").get(),
681 nullptr, nullptr));
682 buffet::native_types::Object obj{
683 {"width", int_type.CreateValue(10, nullptr)},
684 {"height", int_type.CreateValue(20, nullptr)},
685 };
686
687 chromeos::ErrorPtr error;
688 auto val = prop.CreateValue(obj, &error);
689 ASSERT_NE(nullptr, val.get());
690 EXPECT_EQ(nullptr, error.get());
691 EXPECT_EQ(obj, val->GetValueAsAny().Get<buffet::native_types::Object>());
692
693 val = prop.CreateValue("blah", &error);
694 EXPECT_EQ(nullptr, val.get());
695 ASSERT_NE(nullptr, error.get());
696 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
697}
698
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700699///////////////////////////////////////////////////////////////////////////////
700
Alex Vakulenko29e64442015-03-20 13:59:19 -0700701TEST(CommandSchema, ArrayPropType_Empty) {
702 buffet::ArrayPropType prop;
703 EXPECT_FALSE(prop.HasOverriddenAttributes());
704 EXPECT_FALSE(prop.IsBasedOnSchema());
705 EXPECT_EQ(nullptr, prop.GetDefaultValue());
706 EXPECT_EQ(nullptr, prop.GetItemTypePtr());
707 prop.SetItemType(buffet::PropType::Create(buffet::ValueType::Int));
708 EXPECT_TRUE(prop.HasOverriddenAttributes());
709 EXPECT_FALSE(prop.IsBasedOnSchema());
710 EXPECT_NE(nullptr, prop.GetItemTypePtr());
711}
712
713TEST(CommandSchema, ArrayPropType_Types) {
714 buffet::ArrayPropType prop;
715 EXPECT_EQ(nullptr, prop.GetInt());
716 EXPECT_EQ(nullptr, prop.GetBoolean());
717 EXPECT_EQ(nullptr, prop.GetDouble());
718 EXPECT_EQ(nullptr, prop.GetString());
719 EXPECT_EQ(nullptr, prop.GetObject());
720 EXPECT_EQ(&prop, prop.GetArray());
721}
722
723TEST(CommandSchema, ArrayPropType_ToJson) {
724 buffet::ArrayPropType prop;
725 prop.SetItemType(buffet::PropType::Create(buffet::ValueType::Int));
726 EXPECT_EQ("{'items':'integer'}",
727 ValueToString(prop.ToJson(false, nullptr).get()));
728 EXPECT_EQ("{'items':{'type':'integer'},'type':'array'}",
729 ValueToString(prop.ToJson(true, nullptr).get()));
730 EXPECT_FALSE(prop.IsBasedOnSchema());
731 buffet::ArrayPropType prop2;
732 prop2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
733 EXPECT_EQ("{}", ValueToString(prop2.ToJson(false, nullptr).get()));
734 EXPECT_TRUE(prop2.IsBasedOnSchema());
735 prop2.FromJson(CreateDictionaryValue("{'default':[1,2,3]}").get(),
736 &prop, nullptr);
737 EXPECT_EQ("{'default':[1,2,3]}",
738 ValueToString(prop2.ToJson(false, nullptr).get()));
739 EXPECT_EQ("{'default':[1,2,3],'items':{'type':'integer'},'type':'array'}",
740 ValueToString(prop2.ToJson(true, nullptr).get()));
741}
742
743TEST(CommandSchema, ArrayPropType_FromJson) {
744 buffet::ArrayPropType prop;
745 EXPECT_TRUE(prop.FromJson(
746 CreateDictionaryValue("{'items':'integer'}").get(), nullptr, nullptr));
747 EXPECT_EQ(buffet::ValueType::Int, prop.GetItemTypePtr()->GetType());
748
749 buffet::ArrayPropType prop2;
750 ASSERT_TRUE(prop2.FromJson(CreateDictionaryValue(
751 "{'items':'string','default':['foo', 'bar', 'baz']}").get(), nullptr,
752 nullptr));
753 ASSERT_NE(nullptr, prop2.GetDefaultValue());
754 const buffet::ArrayValue* defval = prop2.GetDefaultValue()->GetArray();
755 ASSERT_NE(nullptr, defval);
756 EXPECT_EQ((std::vector<std::string>{"foo", "bar", "baz"}),
757 GetArrayValues<std::string>(defval->GetValue()));
758}
759
760TEST(CommandSchema, ArrayPropType_Validate) {
761 buffet::ArrayPropType prop;
762 prop.FromJson(CreateDictionaryValue(
763 "{'items':{'minimum':2.3, 'maximum':10.5}}").get(), nullptr,
764 nullptr);
765
766 chromeos::ErrorPtr error;
767 EXPECT_TRUE(prop.ValidateValue(CreateValue("[3,4,10.5]").get(), &error));
768 error.reset();
769
770 EXPECT_FALSE(prop.ValidateValue(CreateValue("[2]").get(), &error));
771 EXPECT_EQ("out_of_range", error->GetCode());
772 EXPECT_EQ("Value 2 is out of range. It must not be less than 2.3",
773 error->GetMessage());
774 error.reset();
775
776 EXPECT_FALSE(prop.ValidateValue(CreateValue("[4, 5, 20]").get(), &error));
777 EXPECT_EQ("out_of_range", error->GetCode());
778 EXPECT_EQ("Value 20 is out of range. It must not be greater than 10.5",
779 error->GetMessage());
780 error.reset();
781}
782
783TEST(CommandSchema, ArrayPropType_Validate_Enum) {
784 buffet::ArrayPropType prop;
785 prop.FromJson(CreateDictionaryValue(
786 "{'items':'integer', 'enum':[[1], [2,3], [4,5,6]]}").get(), nullptr,
787 nullptr);
788
789 chromeos::ErrorPtr error;
790 EXPECT_TRUE(prop.ValidateValue(CreateValue("[2,3]").get(), &error));
791 error.reset();
792
793 EXPECT_FALSE(prop.ValidateValue(CreateValue("[2]").get(), &error));
794 EXPECT_EQ("out_of_range", error->GetCode());
795 EXPECT_EQ("Value [2] is invalid. Expected one of [[1],[2,3],[4,5,6]]",
796 error->GetMessage());
797 error.reset();
798
799 EXPECT_FALSE(prop.ValidateValue(CreateValue("[2,3,4]").get(), &error));
800 EXPECT_EQ("out_of_range", error->GetCode());
801 error.reset();
802}
803
804TEST(CommandSchema, ArrayPropType_CreateValue) {
805 buffet::ArrayPropType prop;
806 ASSERT_TRUE(prop.FromJson(CreateDictionaryValue(
807 "{'items':{'properties':{'width':'integer','height':'integer'}}}").get(),
808 nullptr, nullptr));
809
810 chromeos::ErrorPtr error;
811 buffet::native_types::Array arr;
812
813 auto val = prop.CreateValue(arr, &error);
814 ASSERT_NE(nullptr, val.get());
815 EXPECT_EQ(nullptr, error.get());
816 EXPECT_EQ(arr, val->GetValueAsAny().Get<buffet::native_types::Array>());
817 EXPECT_EQ("[]", ValueToString(val->ToJson(nullptr).get()));
818
819 buffet::IntPropType int_type;
820 buffet::ObjectPropType obj_type;
821 ASSERT_TRUE(obj_type.FromJson(CreateDictionaryValue(
822 "{'properties':{'width':'integer','height':'integer'}}").get(),
823 nullptr, nullptr));
824 arr.push_back(obj_type.CreateValue(buffet::native_types::Object{
825 {"width", int_type.CreateValue(10, nullptr)},
826 {"height", int_type.CreateValue(20, nullptr)},
827 }, nullptr));
828 arr.push_back(obj_type.CreateValue(buffet::native_types::Object{
829 {"width", int_type.CreateValue(17, nullptr)},
830 {"height", int_type.CreateValue(18, nullptr)},
831 }, nullptr));
832
833 val = prop.CreateValue(arr, &error);
834 ASSERT_NE(nullptr, val.get());
835 EXPECT_EQ(nullptr, error.get());
836 EXPECT_EQ(arr, val->GetValueAsAny().Get<buffet::native_types::Array>());
837 EXPECT_EQ("[{'height':20,'width':10},{'height':18,'width':17}]",
838 ValueToString(val->ToJson(nullptr).get()));
839
840 val = prop.CreateValue("blah", &error);
841 EXPECT_EQ(nullptr, val.get());
842 ASSERT_NE(nullptr, error.get());
843 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
844}
845
846TEST(CommandSchema, ArrayPropType_NestedArrays_NotSupported) {
847 buffet::ArrayPropType prop;
848 chromeos::ErrorPtr error;
849 EXPECT_FALSE(prop.FromJson(CreateDictionaryValue(
850 "{'items':{'items':'integer'}}").get(), nullptr, &error));
851 EXPECT_EQ(buffet::errors::commands::kInvalidObjectSchema, error->GetCode());
852 error.reset();
853}
854
855///////////////////////////////////////////////////////////////////////////////
856
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700857TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeName) {
858 buffet::ObjectSchema schema;
859 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800860 "'param1':'integer',"
861 "'param2':'number',"
862 "'param3':'string'"
863 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700864 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
865 nullptr));
866 EXPECT_EQ(buffet::ValueType::Int, schema.GetProp("param1")->GetType());
867 EXPECT_EQ(buffet::ValueType::Double, schema.GetProp("param2")->GetType());
868 EXPECT_EQ(buffet::ValueType::String, schema.GetProp("param3")->GetType());
869 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
870 EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
871 EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
872 EXPECT_EQ(nullptr, schema.GetProp("param4"));
873
874 int min_int = (std::numeric_limits<int>::min)();
875 int max_int = (std::numeric_limits<int>::max)();
876 double min_dbl = (std::numeric_limits<double>::lowest)();
877 double max_dbl = (std::numeric_limits<double>::max)();
878 EXPECT_EQ(min_int, schema.GetProp("param1")->GetInt()->GetMinValue());
879 EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
880 EXPECT_EQ(min_dbl, schema.GetProp("param2")->GetDouble()->GetMinValue());
881 EXPECT_EQ(max_dbl, schema.GetProp("param2")->GetDouble()->GetMaxValue());
882 EXPECT_EQ(0, schema.GetProp("param3")->GetString()->GetMinLength());
883 EXPECT_EQ(max_int, schema.GetProp("param3")->GetString()->GetMaxLength());
884}
885
886TEST(CommandSchema, ObjectSchema_FromJson_Full_TypeName) {
887 buffet::ObjectSchema schema;
888 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800889 "'param1':{'type':'integer'},"
890 "'param2':{'type':'number'},"
Alex Vakulenko29e64442015-03-20 13:59:19 -0700891 "'param3':{'type':'string'},"
892 "'param4':{'type':'array', 'items':'integer'},"
893 "'param5':{'type':'object', 'properties':{'p1':'integer'}}"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800894 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700895 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
896 nullptr));
897 EXPECT_EQ(buffet::ValueType::Int, schema.GetProp("param1")->GetType());
898 EXPECT_EQ(buffet::ValueType::Double, schema.GetProp("param2")->GetType());
899 EXPECT_EQ(buffet::ValueType::String, schema.GetProp("param3")->GetType());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700900 EXPECT_EQ(buffet::ValueType::Array, schema.GetProp("param4")->GetType());
901 EXPECT_EQ(buffet::ValueType::Object, schema.GetProp("param5")->GetType());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700902 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
903 EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
904 EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700905 EXPECT_EQ("array", schema.GetProp("param4")->GetTypeAsString());
906 EXPECT_EQ("object", schema.GetProp("param5")->GetTypeAsString());
907 EXPECT_EQ(nullptr, schema.GetProp("param77"));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700908
909 int min_int = (std::numeric_limits<int>::min)();
910 int max_int = (std::numeric_limits<int>::max)();
911 double min_dbl = (std::numeric_limits<double>::lowest)();
912 double max_dbl = (std::numeric_limits<double>::max)();
913 EXPECT_EQ(min_int, schema.GetProp("param1")->GetInt()->GetMinValue());
914 EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
915 EXPECT_EQ(min_dbl, schema.GetProp("param2")->GetDouble()->GetMinValue());
916 EXPECT_EQ(max_dbl, schema.GetProp("param2")->GetDouble()->GetMaxValue());
917 EXPECT_EQ(0, schema.GetProp("param3")->GetString()->GetMinLength());
918 EXPECT_EQ(max_int, schema.GetProp("param3")->GetString()->GetMaxLength());
919}
920
921TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeDeduction_Scalar) {
922 buffet::ObjectSchema schema;
923 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800924 "'param1' :{'minimum':2},"
925 "'param2' :{'maximum':10},"
926 "'param3' :{'maximum':8, 'minimum':2},"
927 "'param4' :{'minimum':2.1},"
928 "'param5' :{'maximum':10.1},"
929 "'param6' :{'maximum':8.1, 'minimum':3.1},"
930 "'param7' :{'maximum':8, 'minimum':3.1},"
931 "'param8' :{'maximum':8.1, 'minimum':3},"
932 "'param9' :{'minLength':2},"
933 "'param10':{'maxLength':10},"
934 "'param11':{'maxLength':8, 'minLength':3},"
935 "'param12':{'default':12},"
936 "'param13':{'default':13.5},"
937 "'param14':{'default':true},"
938 "'param15':{'default':false},"
Alex Vakulenko29e64442015-03-20 13:59:19 -0700939 "'param16':{'default':'foobar'},"
940 "'param17':{'default':[1,2,3]},"
941 "'param18':{'items':'number', 'default':[]}"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800942 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700943 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
944 nullptr));
945 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
946 EXPECT_EQ("integer", schema.GetProp("param2")->GetTypeAsString());
947 EXPECT_EQ("integer", schema.GetProp("param3")->GetTypeAsString());
948 EXPECT_EQ("number", schema.GetProp("param4")->GetTypeAsString());
949 EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
950 EXPECT_EQ("number", schema.GetProp("param6")->GetTypeAsString());
951 EXPECT_EQ("number", schema.GetProp("param7")->GetTypeAsString());
952 EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
953 EXPECT_EQ("string", schema.GetProp("param9")->GetTypeAsString());
954 EXPECT_EQ("string", schema.GetProp("param10")->GetTypeAsString());
955 EXPECT_EQ("string", schema.GetProp("param11")->GetTypeAsString());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800956 EXPECT_EQ("integer", schema.GetProp("param12")->GetTypeAsString());
957 EXPECT_EQ("number", schema.GetProp("param13")->GetTypeAsString());
958 EXPECT_EQ("boolean", schema.GetProp("param14")->GetTypeAsString());
959 EXPECT_EQ("boolean", schema.GetProp("param15")->GetTypeAsString());
960 EXPECT_EQ("string", schema.GetProp("param16")->GetTypeAsString());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700961 EXPECT_EQ("array", schema.GetProp("param17")->GetTypeAsString());
962 auto prop17 = schema.GetProp("param17");
963 EXPECT_EQ("integer",
964 prop17->GetArray()->GetItemTypePtr()->GetTypeAsString());
965 EXPECT_EQ("array", schema.GetProp("param18")->GetTypeAsString());
966 auto prop18 = schema.GetProp("param18");
967 EXPECT_EQ("number",
968 prop18->GetArray()->GetItemTypePtr()->GetTypeAsString());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700969
970 int min_int = (std::numeric_limits<int>::min)();
971 int max_int = (std::numeric_limits<int>::max)();
972 double min_dbl = (std::numeric_limits<double>::lowest)();
973 double max_dbl = (std::numeric_limits<double>::max)();
974 EXPECT_EQ(2, schema.GetProp("param1")->GetInt()->GetMinValue());
975 EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
976 EXPECT_EQ(min_int, schema.GetProp("param2")->GetInt()->GetMinValue());
977 EXPECT_EQ(10, schema.GetProp("param2")->GetInt()->GetMaxValue());
978 EXPECT_EQ(2, schema.GetProp("param3")->GetInt()->GetMinValue());
979 EXPECT_EQ(8, schema.GetProp("param3")->GetInt()->GetMaxValue());
980 EXPECT_DOUBLE_EQ(2.1, schema.GetProp("param4")->GetDouble()->GetMinValue());
981 EXPECT_DOUBLE_EQ(max_dbl,
982 schema.GetProp("param4")->GetDouble()->GetMaxValue());
983 EXPECT_DOUBLE_EQ(min_dbl,
984 schema.GetProp("param5")->GetDouble()->GetMinValue());
985 EXPECT_DOUBLE_EQ(10.1, schema.GetProp("param5")->GetDouble()->GetMaxValue());
986 EXPECT_DOUBLE_EQ(3.1, schema.GetProp("param6")->GetDouble()->GetMinValue());
987 EXPECT_DOUBLE_EQ(8.1, schema.GetProp("param6")->GetDouble()->GetMaxValue());
988 EXPECT_DOUBLE_EQ(3.1, schema.GetProp("param7")->GetDouble()->GetMinValue());
989 EXPECT_DOUBLE_EQ(8.0, schema.GetProp("param7")->GetDouble()->GetMaxValue());
990 EXPECT_DOUBLE_EQ(3.0, schema.GetProp("param8")->GetDouble()->GetMinValue());
991 EXPECT_DOUBLE_EQ(8.1, schema.GetProp("param8")->GetDouble()->GetMaxValue());
992 EXPECT_EQ(2, schema.GetProp("param9")->GetString()->GetMinLength());
993 EXPECT_EQ(max_int, schema.GetProp("param9")->GetString()->GetMaxLength());
994 EXPECT_EQ(0, schema.GetProp("param10")->GetString()->GetMinLength());
995 EXPECT_EQ(10, schema.GetProp("param10")->GetString()->GetMaxLength());
996 EXPECT_EQ(3, schema.GetProp("param11")->GetString()->GetMinLength());
997 EXPECT_EQ(8, schema.GetProp("param11")->GetString()->GetMaxLength());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800998 const buffet::PropValue* val = schema.GetProp("param12")->GetDefaultValue();
999 EXPECT_EQ(12, val->GetInt()->GetValue());
1000 val = schema.GetProp("param13")->GetDefaultValue();
1001 EXPECT_DOUBLE_EQ(13.5, val->GetDouble()->GetValue());
1002 val = schema.GetProp("param14")->GetDefaultValue();
1003 EXPECT_TRUE(val->GetBoolean()->GetValue());
1004 val = schema.GetProp("param15")->GetDefaultValue();
1005 EXPECT_FALSE(val->GetBoolean()->GetValue());
1006 val = schema.GetProp("param16")->GetDefaultValue();
1007 EXPECT_EQ("foobar", val->GetString()->GetValue());
Alex Vakulenko29e64442015-03-20 13:59:19 -07001008 val = schema.GetProp("param17")->GetDefaultValue();
1009 EXPECT_EQ((std::vector<int>{1, 2, 3}),
1010 GetArrayValues<int>(val->GetArray()->GetValue()));
1011 val = schema.GetProp("param18")->GetDefaultValue();
1012 EXPECT_TRUE(val->GetArray()->GetValue().empty());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001013}
1014
1015TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeDeduction_Array) {
1016 buffet::ObjectSchema schema;
1017 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001018 "'param1' :[0,1,2,3],"
1019 "'param2' :[0.0,1.1,2.2],"
1020 "'param3' :['id1', 'id2'],"
1021 "'param4' :{'enum':[1,2,3]},"
1022 "'param5' :{'enum':[-1.1,2.2,3]},"
1023 "'param6' :{'enum':['id0', 'id1']},"
1024 "'param7' :{'type':'integer', 'enum':[1,2,3]},"
1025 "'param8' :{'type':'number', 'enum':[1,2,3]},"
1026 "'param9' :{'type':'number', 'enum':[]},"
Alex Vakulenko29e64442015-03-20 13:59:19 -07001027 "'param10':{'type':'integer', 'enum':[]},"
1028 "'param11':[[0,1],[2,3]],"
1029 "'param12':[['foo','bar']],"
1030 "'param13':{'enum':[['id0', 'id1']]}"
1031 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001032 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1033 nullptr));
1034 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
1035 EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
1036 EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
1037 EXPECT_EQ("integer", schema.GetProp("param4")->GetTypeAsString());
1038 EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
1039 EXPECT_EQ("string", schema.GetProp("param6")->GetTypeAsString());
1040 EXPECT_EQ("integer", schema.GetProp("param7")->GetTypeAsString());
1041 EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
1042 EXPECT_EQ("number", schema.GetProp("param9")->GetTypeAsString());
1043 EXPECT_EQ("integer", schema.GetProp("param10")->GetTypeAsString());
1044
Alex Vakulenko29e64442015-03-20 13:59:19 -07001045 auto prop_type11 = schema.GetProp("param11");
1046 EXPECT_EQ("array", prop_type11->GetTypeAsString());
1047 EXPECT_EQ("integer",
1048 prop_type11->GetArray()->GetItemTypePtr()->GetTypeAsString());
1049
1050 auto prop_type12 = schema.GetProp("param12");
1051 EXPECT_EQ("array", prop_type12->GetTypeAsString());
1052 EXPECT_EQ("string",
1053 prop_type12->GetArray()->GetItemTypePtr()->GetTypeAsString());
1054
1055 auto prop_type13 = schema.GetProp("param13");
1056 EXPECT_EQ("array", prop_type12->GetTypeAsString());
1057 EXPECT_EQ("string",
1058 prop_type13->GetArray()->GetItemTypePtr()->GetTypeAsString());
1059
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001060 EXPECT_EQ((std::vector<int>{0, 1, 2, 3}),
1061 GetOneOfValues<int>(schema.GetProp("param1")));
1062 EXPECT_EQ((std::vector<double>{0.0, 1.1, 2.2}),
1063 GetOneOfValues<double>(schema.GetProp("param2")));
1064 EXPECT_EQ((std::vector<std::string>{"id1", "id2"}),
1065 GetOneOfValues<std::string>(schema.GetProp("param3")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001066
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001067 EXPECT_EQ((std::vector<int>{1, 2, 3}),
1068 GetOneOfValues<int>(schema.GetProp("param4")));
1069 EXPECT_EQ((std::vector<double>{-1.1, 2.2, 3.0}),
1070 GetOneOfValues<double>(schema.GetProp("param5")));
1071 EXPECT_EQ((std::vector<std::string>{"id0", "id1"}),
1072 GetOneOfValues<std::string>(schema.GetProp("param6")));
1073 EXPECT_EQ((std::vector<int>{1, 2, 3}),
1074 GetOneOfValues<int>(schema.GetProp("param7")));
1075 EXPECT_EQ((std::vector<double>{1.0, 2.0, 3.0}),
1076 GetOneOfValues<double>(schema.GetProp("param8")));
1077 EXPECT_TRUE(GetOneOfValues<double>(schema.GetProp("param9")).empty());
1078 EXPECT_TRUE(GetOneOfValues<int>(schema.GetProp("param10")).empty());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001079}
1080
1081TEST(CommandSchema, ObjectSchema_FromJson_Inheritance) {
1082 const char* base_schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001083 "'param0' :{'minimum':1, 'maximum':5},"
1084 "'param1' :{'minimum':1, 'maximum':5},"
1085 "'param2' :{'minimum':1, 'maximum':5},"
1086 "'param3' :{'minimum':1, 'maximum':5},"
1087 "'param4' :{'minimum':1, 'maximum':5},"
1088 "'param5' :{'minimum':1.1, 'maximum':5.5},"
1089 "'param6' :{'minimum':1.1, 'maximum':5.5},"
1090 "'param7' :{'minimum':1.1, 'maximum':5.5},"
1091 "'param8' :{'minimum':1.1, 'maximum':5.5},"
1092 "'param9' :{'minLength':1, 'maxLength':5},"
1093 "'param10':{'minLength':1, 'maxLength':5},"
1094 "'param11':{'minLength':1, 'maxLength':5},"
1095 "'param12':{'minLength':1, 'maxLength':5},"
1096 "'param13':[1,2,3],"
1097 "'param14':[1,2,3],"
1098 "'param15':[1.1,2.2,3.3],"
1099 "'param16':[1.1,2.2,3.3],"
1100 "'param17':['id1', 'id2'],"
1101 "'param18':['id1', 'id2'],"
1102 "'param19':{'minimum':1, 'maximum':5},"
1103 "'param20':{'default':49},"
1104 "'param21':{'default':49},"
1105 "'param22':'integer'"
1106 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001107 buffet::ObjectSchema base_schema;
1108 EXPECT_TRUE(base_schema.FromJson(CreateDictionaryValue(base_schema_str).get(),
1109 nullptr, nullptr));
1110 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001111 "'param1' :{},"
1112 "'param2' :{'minimum':2},"
1113 "'param3' :{'maximum':9},"
1114 "'param4' :{'minimum':2, 'maximum':9},"
1115 "'param5' :{},"
1116 "'param6' :{'minimum':2.2},"
1117 "'param7' :{'maximum':9.9},"
1118 "'param8' :{'minimum':2.2, 'maximum':9.9},"
1119 "'param9' :{},"
1120 "'param10':{'minLength':3},"
1121 "'param11':{'maxLength':8},"
1122 "'param12':{'minLength':3, 'maxLength':8},"
1123 "'param13':{},"
1124 "'param14':[1,2,3,4],"
1125 "'param15':{},"
1126 "'param16':[1.1,2.2,3.3,4.4],"
1127 "'param17':{},"
1128 "'param18':['id1', 'id3'],"
1129 "'param19':{},"
1130 "'param20':{},"
1131 "'param21':{'default':8},"
1132 "'param22':{'default':123}"
1133 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001134 buffet::ObjectSchema schema;
1135 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(),
1136 &base_schema, nullptr));
1137 EXPECT_EQ(nullptr, schema.GetProp("param0"));
1138 EXPECT_NE(nullptr, schema.GetProp("param1"));
1139 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
1140 EXPECT_EQ(1, schema.GetProp("param1")->GetInt()->GetMinValue());
1141 EXPECT_EQ(5, schema.GetProp("param1")->GetInt()->GetMaxValue());
1142 EXPECT_EQ("integer", schema.GetProp("param2")->GetTypeAsString());
1143 EXPECT_EQ(2, schema.GetProp("param2")->GetInt()->GetMinValue());
1144 EXPECT_EQ(5, schema.GetProp("param2")->GetInt()->GetMaxValue());
1145 EXPECT_EQ("integer", schema.GetProp("param3")->GetTypeAsString());
1146 EXPECT_EQ(1, schema.GetProp("param3")->GetInt()->GetMinValue());
1147 EXPECT_EQ(9, schema.GetProp("param3")->GetInt()->GetMaxValue());
1148 EXPECT_EQ("integer", schema.GetProp("param4")->GetTypeAsString());
1149 EXPECT_EQ(2, schema.GetProp("param4")->GetInt()->GetMinValue());
1150 EXPECT_EQ(9, schema.GetProp("param4")->GetInt()->GetMaxValue());
1151 EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
1152 EXPECT_EQ(1.1, schema.GetProp("param5")->GetDouble()->GetMinValue());
1153 EXPECT_EQ(5.5, schema.GetProp("param5")->GetDouble()->GetMaxValue());
1154 EXPECT_EQ("number", schema.GetProp("param6")->GetTypeAsString());
1155 EXPECT_EQ(2.2, schema.GetProp("param6")->GetDouble()->GetMinValue());
1156 EXPECT_EQ(5.5, schema.GetProp("param6")->GetDouble()->GetMaxValue());
1157 EXPECT_EQ("number", schema.GetProp("param7")->GetTypeAsString());
1158 EXPECT_EQ(1.1, schema.GetProp("param7")->GetDouble()->GetMinValue());
1159 EXPECT_EQ(9.9, schema.GetProp("param7")->GetDouble()->GetMaxValue());
1160 EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
1161 EXPECT_EQ(2.2, schema.GetProp("param8")->GetDouble()->GetMinValue());
1162 EXPECT_EQ(9.9, schema.GetProp("param8")->GetDouble()->GetMaxValue());
1163 EXPECT_EQ("string", schema.GetProp("param9")->GetTypeAsString());
1164 EXPECT_EQ(1, schema.GetProp("param9")->GetString()->GetMinLength());
1165 EXPECT_EQ(5, schema.GetProp("param9")->GetString()->GetMaxLength());
1166 EXPECT_EQ("string", schema.GetProp("param10")->GetTypeAsString());
1167 EXPECT_EQ(3, schema.GetProp("param10")->GetString()->GetMinLength());
1168 EXPECT_EQ(5, schema.GetProp("param10")->GetString()->GetMaxLength());
1169 EXPECT_EQ("string", schema.GetProp("param11")->GetTypeAsString());
1170 EXPECT_EQ(1, schema.GetProp("param11")->GetString()->GetMinLength());
1171 EXPECT_EQ(8, schema.GetProp("param11")->GetString()->GetMaxLength());
1172 EXPECT_EQ("string", schema.GetProp("param12")->GetTypeAsString());
1173 EXPECT_EQ(3, schema.GetProp("param12")->GetString()->GetMinLength());
1174 EXPECT_EQ(8, schema.GetProp("param12")->GetString()->GetMaxLength());
1175 EXPECT_EQ("integer", schema.GetProp("param13")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001176 EXPECT_EQ((std::vector<int>{1, 2, 3}),
1177 GetOneOfValues<int>(schema.GetProp("param13")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001178 EXPECT_EQ("integer", schema.GetProp("param14")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001179 EXPECT_EQ((std::vector<int>{1, 2, 3, 4}),
1180 GetOneOfValues<int>(schema.GetProp("param14")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001181 EXPECT_EQ("number", schema.GetProp("param15")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001182 EXPECT_EQ((std::vector<double>{1.1, 2.2, 3.3}),
1183 GetOneOfValues<double>(schema.GetProp("param15")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001184 EXPECT_EQ("number", schema.GetProp("param16")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001185 EXPECT_EQ((std::vector<double>{1.1, 2.2, 3.3, 4.4}),
1186 GetOneOfValues<double>(schema.GetProp("param16")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001187 EXPECT_EQ("string", schema.GetProp("param17")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001188 EXPECT_EQ((std::vector<std::string>{"id1", "id2"}),
1189 GetOneOfValues<std::string>(schema.GetProp("param17")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001190 EXPECT_EQ("string", schema.GetProp("param18")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001191 EXPECT_EQ((std::vector<std::string>{"id1", "id3"}),
1192 GetOneOfValues<std::string>(schema.GetProp("param18")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001193 EXPECT_EQ("integer", schema.GetProp("param19")->GetTypeAsString());
1194 EXPECT_EQ(1, schema.GetProp("param19")->GetInt()->GetMinValue());
1195 EXPECT_EQ(5, schema.GetProp("param19")->GetInt()->GetMaxValue());
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001196 EXPECT_EQ(49,
1197 schema.GetProp("param20")->GetDefaultValue()->GetInt()->GetValue());
1198 EXPECT_EQ(8,
1199 schema.GetProp("param21")->GetDefaultValue()->GetInt()->GetValue());
1200 EXPECT_EQ(123,
1201 schema.GetProp("param22")->GetDefaultValue()->GetInt()->GetValue());
1202}
1203
1204TEST(CommandSchema, ObjectSchema_UseDefaults) {
1205 buffet::ObjectPropType prop;
1206 const char* schema_str = "{'properties':{"
1207 "'param1':{'default':true},"
1208 "'param2':{'default':2},"
1209 "'param3':{'default':3.3},"
1210 "'param4':{'default':'four'},"
1211 "'param5':{'default':{'x':5,'y':6},"
Alex Vakulenko29e64442015-03-20 13:59:19 -07001212 "'properties':{'x':'integer','y':'integer'}},"
1213 "'param6':{'default':[1,2,3]}"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001214 "}}";
1215 ASSERT_TRUE(prop.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1216 nullptr));
1217
1218 // Omit all.
1219 auto value = prop.CreateValue();
1220 ASSERT_TRUE(value->FromJson(CreateDictionaryValue("{}").get(), nullptr));
1221 buffet::native_types::Object obj = value->GetObject()->GetValue();
1222 EXPECT_TRUE(obj["param1"]->GetBoolean()->GetValue());
1223 EXPECT_EQ(2, obj["param2"]->GetInt()->GetValue());
1224 EXPECT_DOUBLE_EQ(3.3, obj["param3"]->GetDouble()->GetValue());
1225 EXPECT_EQ("four", obj["param4"]->GetString()->GetValue());
1226 buffet::native_types::Object param5 = obj["param5"]->GetObject()->GetValue();
1227 EXPECT_EQ(5, param5["x"]->GetInt()->GetValue());
1228 EXPECT_EQ(6, param5["y"]->GetInt()->GetValue());
Alex Vakulenko29e64442015-03-20 13:59:19 -07001229 buffet::native_types::Array param6 = obj["param6"]->GetArray()->GetValue();
1230 EXPECT_EQ((std::vector<int>{1, 2, 3}), GetArrayValues<int>(param6));
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001231
1232 // Specify some.
1233 value = prop.CreateValue();
1234 const char* val_json = "{"
1235 "'param1':false,"
1236 "'param3':33.3,"
1237 "'param5':{'x':-5,'y':-6}"
1238 "}";
1239 ASSERT_TRUE(value->FromJson(CreateDictionaryValue(val_json).get(), nullptr));
1240 obj = value->GetObject()->GetValue();
1241 EXPECT_FALSE(obj["param1"]->GetBoolean()->GetValue());
1242 EXPECT_EQ(2, obj["param2"]->GetInt()->GetValue());
1243 EXPECT_DOUBLE_EQ(33.3, obj["param3"]->GetDouble()->GetValue());
1244 EXPECT_EQ("four", obj["param4"]->GetString()->GetValue());
1245 param5 = obj["param5"]->GetObject()->GetValue();
1246 EXPECT_EQ(-5, param5["x"]->GetInt()->GetValue());
1247 EXPECT_EQ(-6, param5["y"]->GetInt()->GetValue());
Alex Vakulenko29e64442015-03-20 13:59:19 -07001248 param6 = obj["param6"]->GetArray()->GetValue();
1249 EXPECT_EQ((std::vector<int>{1, 2, 3}), GetArrayValues<int>(param6));
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001250
1251 // Specify all.
1252 value = prop.CreateValue();
1253 val_json = "{"
1254 "'param1':false,"
1255 "'param2':22,"
1256 "'param3':333.3,"
1257 "'param4':'FOUR',"
Alex Vakulenko29e64442015-03-20 13:59:19 -07001258 "'param5':{'x':-55,'y':66},"
1259 "'param6':[-1, 0]"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001260 "}";
1261 ASSERT_TRUE(value->FromJson(CreateDictionaryValue(val_json).get(), nullptr));
1262 obj = value->GetObject()->GetValue();
1263 EXPECT_FALSE(obj["param1"]->GetBoolean()->GetValue());
1264 EXPECT_EQ(22, obj["param2"]->GetInt()->GetValue());
1265 EXPECT_DOUBLE_EQ(333.3, obj["param3"]->GetDouble()->GetValue());
1266 EXPECT_EQ("FOUR", obj["param4"]->GetString()->GetValue());
1267 param5 = obj["param5"]->GetObject()->GetValue();
1268 EXPECT_EQ(-55, param5["x"]->GetInt()->GetValue());
1269 EXPECT_EQ(66, param5["y"]->GetInt()->GetValue());
Alex Vakulenko29e64442015-03-20 13:59:19 -07001270 param6 = obj["param6"]->GetArray()->GetValue();
1271 EXPECT_EQ((std::vector<int>{-1, 0}), GetArrayValues<int>(param6));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001272}
1273
1274TEST(CommandSchema, ObjectSchema_FromJson_BaseSchema_Failures) {
1275 buffet::ObjectSchema schema;
Alex Vakulenko5f472062014-08-14 17:54:04 -07001276 chromeos::ErrorPtr error;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001277 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001278 "'param1':{}"
1279 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001280 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1281 &error));
1282 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1283 error.reset();
1284
1285 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001286 "'param1':{'type':'foo'}"
1287 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001288 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1289 &error));
1290 EXPECT_EQ("unknown_type", error->GetFirstError()->GetCode());
1291 error.reset();
1292
1293 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001294 "'param1':[]"
1295 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001296 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1297 &error));
1298 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1299 error.reset();
1300
1301 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001302 "'param1':{'minimum':'foo'}"
1303 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001304 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1305 &error));
1306 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1307 error.reset();
1308
1309 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001310 "'param1':[1,2.2]"
1311 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001312 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1313 &error));
1314 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1315 error.reset();
Alex Vakulenko5109b202014-06-20 14:49:41 -07001316
1317 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001318 "'param1':{'minimum':1, 'enum':[1,2,3]}" // can't have min/max & enum.
1319 "}";
Alex Vakulenko5109b202014-06-20 14:49:41 -07001320 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1321 &error));
1322 EXPECT_EQ("unexpected_parameter", error->GetFirstError()->GetCode());
1323 error.reset();
1324
1325 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001326 "'param1':{'maximum':1, 'blah':2}" // 'blah' is unexpected.
1327 "}";
Alex Vakulenko5109b202014-06-20 14:49:41 -07001328 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1329 &error));
1330 EXPECT_EQ("unexpected_parameter", error->GetFirstError()->GetCode());
1331 error.reset();
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001332
1333 schema_str = "{"
1334 "'param1':{'enum':[1,2,3],'default':5}" // 'default' must be 1, 2, or 3.
1335 "}";
1336 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1337 &error));
1338 EXPECT_EQ("out_of_range", error->GetFirstError()->GetCode());
1339 error.reset();
Alex Vakulenko29e64442015-03-20 13:59:19 -07001340
1341 schema_str = "{"
1342 "'param1':[[1,2.3]]"
1343 "}";
1344 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1345 &error));
1346 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1347 error.reset();
1348
1349 schema_str = "{"
1350 "'param1':[[1,2],[3,4],['blah']]"
1351 "}";
1352 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1353 &error));
1354 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1355 error.reset();
1356
1357 schema_str = "{"
1358 "'param1':{'default':[]}"
1359 "}";
1360 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1361 &error));
1362 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1363 error.reset();
1364
1365 schema_str = "{"
1366 "'param1':[[[1]],[[2]]]"
1367 "}";
1368 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1369 &error));
1370 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1371 error.reset();
1372
1373 schema_str = "{"
1374 "'param1':{'enum':[[['foo']]]}"
1375 "}";
1376 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1377 &error));
1378 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1379 error.reset();
1380
1381 schema_str = "{"
1382 "'param1':{'default':[[1],[2]]}"
1383 "}";
1384 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1385 &error));
1386 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1387 error.reset();
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001388}