blob: b0332d2127789af1851f1a84263eba106b28f63a [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;
539 EXPECT_EQ("{'properties':{}}",
540 ValueToString(prop.ToJson(false, nullptr).get()));
541 EXPECT_EQ("{'properties':{},'type':'object'}",
542 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 Vakulenko66ec2922014-06-17 15:30:22 -0700555 EXPECT_EQ("{'properties':{'expires':'integer',"
556 "'password':{'maxLength':100,'minLength':6}}}",
557 ValueToString(prop2.ToJson(false, nullptr).get()));
558 EXPECT_EQ("{'properties':{'expires':{'type':'integer'},"
559 "'password':{'maxLength':100,'minLength':6,'type':'string'}},"
560 "'type':'object'}",
561 ValueToString(prop2.ToJson(true, nullptr).get()));
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800562
563 buffet::ObjectPropType prop3;
564 ASSERT_TRUE(prop3.FromJson(CreateDictionaryValue(
565 "{'default':{'expires':3,'password':'abracadabra'}}").get(), &prop2,
566 nullptr));
567 EXPECT_EQ("{'default':{'expires':3,'password':'abracadabra'}}",
568 ValueToString(prop3.ToJson(false, nullptr).get()));
569 EXPECT_EQ("{'default':{'expires':3,'password':'abracadabra'},"
570 "'properties':{'expires':{'type':'integer'},"
571 "'password':{'maxLength':100,'minLength':6,'type':'string'}},"
572 "'type':'object'}",
573 ValueToString(prop3.ToJson(true, nullptr).get()));
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700574}
575
576TEST(CommandSchema, ObjectPropType_FromJson) {
577 buffet::ObjectPropType base_prop;
578 EXPECT_TRUE(base_prop.FromJson(CreateDictionaryValue(
579 "{'properties':{'name':'string','age':'integer'}}").get(), nullptr,
580 nullptr));
Alex Vakulenkod94656e2015-03-18 09:54:37 -0700581 auto schema = base_prop.GetObject()->GetObjectSchemaPtr();
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700582 const buffet::PropType* prop = schema->GetProp("name");
583 EXPECT_EQ(buffet::ValueType::String, prop->GetType());
584 prop = schema->GetProp("age");
585 EXPECT_EQ(buffet::ValueType::Int, prop->GetType());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800586
587 buffet::ObjectPropType prop2;
588 ASSERT_TRUE(prop2.FromJson(CreateDictionaryValue(
589 "{'properties':{'name':'string','age':'integer'},"
590 "'default':{'name':'Bob','age':33}}").get(), nullptr, nullptr));
591 ASSERT_NE(nullptr, prop2.GetDefaultValue());
592 const buffet::ObjectValue* defval = prop2.GetDefaultValue()->GetObject();
593 ASSERT_NE(nullptr, defval);
594 buffet::native_types::Object objval = defval->GetValue();
595 EXPECT_EQ("Bob", objval["name"]->GetString()->GetValue());
596 EXPECT_EQ(33, objval["age"]->GetInt()->GetValue());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700597}
598
599TEST(CommandSchema, ObjectPropType_Validate) {
600 buffet::ObjectPropType prop;
601 prop.FromJson(CreateDictionaryValue(
602 "{'properties':{'expires':'integer',"
603 "'password':{'maxLength':100,'minLength':6}}}").get(), nullptr,
604 nullptr);
Alex Vakulenko5f472062014-08-14 17:54:04 -0700605 chromeos::ErrorPtr error;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700606 EXPECT_TRUE(prop.ValidateValue(CreateValue(
607 "{'expires':10,'password':'abcdef'}").get(), &error));
608 error.reset();
609
610 EXPECT_FALSE(prop.ValidateValue(CreateValue(
611 "{'expires':10}").get(), &error));
612 EXPECT_EQ("parameter_missing", error->GetCode());
613 error.reset();
614
615 EXPECT_FALSE(prop.ValidateValue(CreateValue(
616 "{'password':'abcdef'}").get(), &error));
617 EXPECT_EQ("parameter_missing", error->GetCode());
618 error.reset();
619
620 EXPECT_FALSE(prop.ValidateValue(CreateValue(
621 "{'expires':10,'password':'abcde'}").get(), &error));
622 EXPECT_EQ("out_of_range", error->GetFirstError()->GetCode());
623 error.reset();
624
625 EXPECT_FALSE(prop.ValidateValue(CreateValue("2").get(), &error));
626 EXPECT_EQ("type_mismatch", error->GetCode());
627 error.reset();
628
629 EXPECT_FALSE(prop.ValidateValue(CreateValue(
630 "{'expires':10,'password':'abcdef','retry':true}").get(), &error));
631 EXPECT_EQ("unexpected_parameter", error->GetCode());
632 error.reset();
633}
634
635TEST(CommandSchema, ObjectPropType_Validate_Enum) {
636 buffet::ObjectPropType prop;
637 EXPECT_TRUE(prop.FromJson(CreateDictionaryValue(
638 "{'properties':{'width':'integer','height':'integer'},"
639 "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}").get(),
640 nullptr, nullptr));
Alex Vakulenko5f472062014-08-14 17:54:04 -0700641 chromeos::ErrorPtr error;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700642 EXPECT_TRUE(prop.ValidateValue(CreateValue(
643 "{'height':20,'width':10}").get(), &error));
644 error.reset();
645
646 EXPECT_TRUE(prop.ValidateValue(CreateValue(
647 "{'height':200,'width':100}").get(), &error));
648 error.reset();
649
650 EXPECT_FALSE(prop.ValidateValue(CreateValue(
651 "{'height':12,'width':10}").get(), &error));
652 EXPECT_EQ("out_of_range", error->GetCode());
653 error.reset();
654}
655
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700656TEST(CommandSchema, ObjectPropType_CreateValue) {
657 buffet::ObjectPropType prop;
658 buffet::IntPropType int_type;
659 ASSERT_TRUE(prop.FromJson(CreateDictionaryValue(
660 "{'properties':{'width':'integer','height':'integer'},"
661 "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}").get(),
662 nullptr, nullptr));
663 buffet::native_types::Object obj{
664 {"width", int_type.CreateValue(10, nullptr)},
665 {"height", int_type.CreateValue(20, nullptr)},
666 };
667
668 chromeos::ErrorPtr error;
669 auto val = prop.CreateValue(obj, &error);
670 ASSERT_NE(nullptr, val.get());
671 EXPECT_EQ(nullptr, error.get());
672 EXPECT_EQ(obj, val->GetValueAsAny().Get<buffet::native_types::Object>());
673
674 val = prop.CreateValue("blah", &error);
675 EXPECT_EQ(nullptr, val.get());
676 ASSERT_NE(nullptr, error.get());
677 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
678}
679
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700680///////////////////////////////////////////////////////////////////////////////
681
Alex Vakulenko29e64442015-03-20 13:59:19 -0700682TEST(CommandSchema, ArrayPropType_Empty) {
683 buffet::ArrayPropType prop;
684 EXPECT_FALSE(prop.HasOverriddenAttributes());
685 EXPECT_FALSE(prop.IsBasedOnSchema());
686 EXPECT_EQ(nullptr, prop.GetDefaultValue());
687 EXPECT_EQ(nullptr, prop.GetItemTypePtr());
688 prop.SetItemType(buffet::PropType::Create(buffet::ValueType::Int));
689 EXPECT_TRUE(prop.HasOverriddenAttributes());
690 EXPECT_FALSE(prop.IsBasedOnSchema());
691 EXPECT_NE(nullptr, prop.GetItemTypePtr());
692}
693
694TEST(CommandSchema, ArrayPropType_Types) {
695 buffet::ArrayPropType prop;
696 EXPECT_EQ(nullptr, prop.GetInt());
697 EXPECT_EQ(nullptr, prop.GetBoolean());
698 EXPECT_EQ(nullptr, prop.GetDouble());
699 EXPECT_EQ(nullptr, prop.GetString());
700 EXPECT_EQ(nullptr, prop.GetObject());
701 EXPECT_EQ(&prop, prop.GetArray());
702}
703
704TEST(CommandSchema, ArrayPropType_ToJson) {
705 buffet::ArrayPropType prop;
706 prop.SetItemType(buffet::PropType::Create(buffet::ValueType::Int));
707 EXPECT_EQ("{'items':'integer'}",
708 ValueToString(prop.ToJson(false, nullptr).get()));
709 EXPECT_EQ("{'items':{'type':'integer'},'type':'array'}",
710 ValueToString(prop.ToJson(true, nullptr).get()));
711 EXPECT_FALSE(prop.IsBasedOnSchema());
712 buffet::ArrayPropType prop2;
713 prop2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
714 EXPECT_EQ("{}", ValueToString(prop2.ToJson(false, nullptr).get()));
715 EXPECT_TRUE(prop2.IsBasedOnSchema());
716 prop2.FromJson(CreateDictionaryValue("{'default':[1,2,3]}").get(),
717 &prop, nullptr);
718 EXPECT_EQ("{'default':[1,2,3]}",
719 ValueToString(prop2.ToJson(false, nullptr).get()));
720 EXPECT_EQ("{'default':[1,2,3],'items':{'type':'integer'},'type':'array'}",
721 ValueToString(prop2.ToJson(true, nullptr).get()));
722}
723
724TEST(CommandSchema, ArrayPropType_FromJson) {
725 buffet::ArrayPropType prop;
726 EXPECT_TRUE(prop.FromJson(
727 CreateDictionaryValue("{'items':'integer'}").get(), nullptr, nullptr));
728 EXPECT_EQ(buffet::ValueType::Int, prop.GetItemTypePtr()->GetType());
729
730 buffet::ArrayPropType prop2;
731 ASSERT_TRUE(prop2.FromJson(CreateDictionaryValue(
732 "{'items':'string','default':['foo', 'bar', 'baz']}").get(), nullptr,
733 nullptr));
734 ASSERT_NE(nullptr, prop2.GetDefaultValue());
735 const buffet::ArrayValue* defval = prop2.GetDefaultValue()->GetArray();
736 ASSERT_NE(nullptr, defval);
737 EXPECT_EQ((std::vector<std::string>{"foo", "bar", "baz"}),
738 GetArrayValues<std::string>(defval->GetValue()));
739}
740
741TEST(CommandSchema, ArrayPropType_Validate) {
742 buffet::ArrayPropType prop;
743 prop.FromJson(CreateDictionaryValue(
744 "{'items':{'minimum':2.3, 'maximum':10.5}}").get(), nullptr,
745 nullptr);
746
747 chromeos::ErrorPtr error;
748 EXPECT_TRUE(prop.ValidateValue(CreateValue("[3,4,10.5]").get(), &error));
749 error.reset();
750
751 EXPECT_FALSE(prop.ValidateValue(CreateValue("[2]").get(), &error));
752 EXPECT_EQ("out_of_range", error->GetCode());
753 EXPECT_EQ("Value 2 is out of range. It must not be less than 2.3",
754 error->GetMessage());
755 error.reset();
756
757 EXPECT_FALSE(prop.ValidateValue(CreateValue("[4, 5, 20]").get(), &error));
758 EXPECT_EQ("out_of_range", error->GetCode());
759 EXPECT_EQ("Value 20 is out of range. It must not be greater than 10.5",
760 error->GetMessage());
761 error.reset();
762}
763
764TEST(CommandSchema, ArrayPropType_Validate_Enum) {
765 buffet::ArrayPropType prop;
766 prop.FromJson(CreateDictionaryValue(
767 "{'items':'integer', 'enum':[[1], [2,3], [4,5,6]]}").get(), nullptr,
768 nullptr);
769
770 chromeos::ErrorPtr error;
771 EXPECT_TRUE(prop.ValidateValue(CreateValue("[2,3]").get(), &error));
772 error.reset();
773
774 EXPECT_FALSE(prop.ValidateValue(CreateValue("[2]").get(), &error));
775 EXPECT_EQ("out_of_range", error->GetCode());
776 EXPECT_EQ("Value [2] is invalid. Expected one of [[1],[2,3],[4,5,6]]",
777 error->GetMessage());
778 error.reset();
779
780 EXPECT_FALSE(prop.ValidateValue(CreateValue("[2,3,4]").get(), &error));
781 EXPECT_EQ("out_of_range", error->GetCode());
782 error.reset();
783}
784
785TEST(CommandSchema, ArrayPropType_CreateValue) {
786 buffet::ArrayPropType prop;
787 ASSERT_TRUE(prop.FromJson(CreateDictionaryValue(
788 "{'items':{'properties':{'width':'integer','height':'integer'}}}").get(),
789 nullptr, nullptr));
790
791 chromeos::ErrorPtr error;
792 buffet::native_types::Array arr;
793
794 auto val = prop.CreateValue(arr, &error);
795 ASSERT_NE(nullptr, val.get());
796 EXPECT_EQ(nullptr, error.get());
797 EXPECT_EQ(arr, val->GetValueAsAny().Get<buffet::native_types::Array>());
798 EXPECT_EQ("[]", ValueToString(val->ToJson(nullptr).get()));
799
800 buffet::IntPropType int_type;
801 buffet::ObjectPropType obj_type;
802 ASSERT_TRUE(obj_type.FromJson(CreateDictionaryValue(
803 "{'properties':{'width':'integer','height':'integer'}}").get(),
804 nullptr, nullptr));
805 arr.push_back(obj_type.CreateValue(buffet::native_types::Object{
806 {"width", int_type.CreateValue(10, nullptr)},
807 {"height", int_type.CreateValue(20, nullptr)},
808 }, nullptr));
809 arr.push_back(obj_type.CreateValue(buffet::native_types::Object{
810 {"width", int_type.CreateValue(17, nullptr)},
811 {"height", int_type.CreateValue(18, nullptr)},
812 }, nullptr));
813
814 val = prop.CreateValue(arr, &error);
815 ASSERT_NE(nullptr, val.get());
816 EXPECT_EQ(nullptr, error.get());
817 EXPECT_EQ(arr, val->GetValueAsAny().Get<buffet::native_types::Array>());
818 EXPECT_EQ("[{'height':20,'width':10},{'height':18,'width':17}]",
819 ValueToString(val->ToJson(nullptr).get()));
820
821 val = prop.CreateValue("blah", &error);
822 EXPECT_EQ(nullptr, val.get());
823 ASSERT_NE(nullptr, error.get());
824 EXPECT_EQ(buffet::errors::commands::kTypeMismatch, error->GetCode());
825}
826
827TEST(CommandSchema, ArrayPropType_NestedArrays_NotSupported) {
828 buffet::ArrayPropType prop;
829 chromeos::ErrorPtr error;
830 EXPECT_FALSE(prop.FromJson(CreateDictionaryValue(
831 "{'items':{'items':'integer'}}").get(), nullptr, &error));
832 EXPECT_EQ(buffet::errors::commands::kInvalidObjectSchema, error->GetCode());
833 error.reset();
834}
835
836///////////////////////////////////////////////////////////////////////////////
837
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700838TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeName) {
839 buffet::ObjectSchema schema;
840 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800841 "'param1':'integer',"
842 "'param2':'number',"
843 "'param3':'string'"
844 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700845 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
846 nullptr));
847 EXPECT_EQ(buffet::ValueType::Int, schema.GetProp("param1")->GetType());
848 EXPECT_EQ(buffet::ValueType::Double, schema.GetProp("param2")->GetType());
849 EXPECT_EQ(buffet::ValueType::String, schema.GetProp("param3")->GetType());
850 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
851 EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
852 EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
853 EXPECT_EQ(nullptr, schema.GetProp("param4"));
854
855 int min_int = (std::numeric_limits<int>::min)();
856 int max_int = (std::numeric_limits<int>::max)();
857 double min_dbl = (std::numeric_limits<double>::lowest)();
858 double max_dbl = (std::numeric_limits<double>::max)();
859 EXPECT_EQ(min_int, schema.GetProp("param1")->GetInt()->GetMinValue());
860 EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
861 EXPECT_EQ(min_dbl, schema.GetProp("param2")->GetDouble()->GetMinValue());
862 EXPECT_EQ(max_dbl, schema.GetProp("param2")->GetDouble()->GetMaxValue());
863 EXPECT_EQ(0, schema.GetProp("param3")->GetString()->GetMinLength());
864 EXPECT_EQ(max_int, schema.GetProp("param3")->GetString()->GetMaxLength());
865}
866
867TEST(CommandSchema, ObjectSchema_FromJson_Full_TypeName) {
868 buffet::ObjectSchema schema;
869 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800870 "'param1':{'type':'integer'},"
871 "'param2':{'type':'number'},"
Alex Vakulenko29e64442015-03-20 13:59:19 -0700872 "'param3':{'type':'string'},"
873 "'param4':{'type':'array', 'items':'integer'},"
874 "'param5':{'type':'object', 'properties':{'p1':'integer'}}"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800875 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700876 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
877 nullptr));
878 EXPECT_EQ(buffet::ValueType::Int, schema.GetProp("param1")->GetType());
879 EXPECT_EQ(buffet::ValueType::Double, schema.GetProp("param2")->GetType());
880 EXPECT_EQ(buffet::ValueType::String, schema.GetProp("param3")->GetType());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700881 EXPECT_EQ(buffet::ValueType::Array, schema.GetProp("param4")->GetType());
882 EXPECT_EQ(buffet::ValueType::Object, schema.GetProp("param5")->GetType());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700883 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
884 EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
885 EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700886 EXPECT_EQ("array", schema.GetProp("param4")->GetTypeAsString());
887 EXPECT_EQ("object", schema.GetProp("param5")->GetTypeAsString());
888 EXPECT_EQ(nullptr, schema.GetProp("param77"));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700889
890 int min_int = (std::numeric_limits<int>::min)();
891 int max_int = (std::numeric_limits<int>::max)();
892 double min_dbl = (std::numeric_limits<double>::lowest)();
893 double max_dbl = (std::numeric_limits<double>::max)();
894 EXPECT_EQ(min_int, schema.GetProp("param1")->GetInt()->GetMinValue());
895 EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
896 EXPECT_EQ(min_dbl, schema.GetProp("param2")->GetDouble()->GetMinValue());
897 EXPECT_EQ(max_dbl, schema.GetProp("param2")->GetDouble()->GetMaxValue());
898 EXPECT_EQ(0, schema.GetProp("param3")->GetString()->GetMinLength());
899 EXPECT_EQ(max_int, schema.GetProp("param3")->GetString()->GetMaxLength());
900}
901
902TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeDeduction_Scalar) {
903 buffet::ObjectSchema schema;
904 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800905 "'param1' :{'minimum':2},"
906 "'param2' :{'maximum':10},"
907 "'param3' :{'maximum':8, 'minimum':2},"
908 "'param4' :{'minimum':2.1},"
909 "'param5' :{'maximum':10.1},"
910 "'param6' :{'maximum':8.1, 'minimum':3.1},"
911 "'param7' :{'maximum':8, 'minimum':3.1},"
912 "'param8' :{'maximum':8.1, 'minimum':3},"
913 "'param9' :{'minLength':2},"
914 "'param10':{'maxLength':10},"
915 "'param11':{'maxLength':8, 'minLength':3},"
916 "'param12':{'default':12},"
917 "'param13':{'default':13.5},"
918 "'param14':{'default':true},"
919 "'param15':{'default':false},"
Alex Vakulenko29e64442015-03-20 13:59:19 -0700920 "'param16':{'default':'foobar'},"
921 "'param17':{'default':[1,2,3]},"
922 "'param18':{'items':'number', 'default':[]}"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800923 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700924 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
925 nullptr));
926 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
927 EXPECT_EQ("integer", schema.GetProp("param2")->GetTypeAsString());
928 EXPECT_EQ("integer", schema.GetProp("param3")->GetTypeAsString());
929 EXPECT_EQ("number", schema.GetProp("param4")->GetTypeAsString());
930 EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
931 EXPECT_EQ("number", schema.GetProp("param6")->GetTypeAsString());
932 EXPECT_EQ("number", schema.GetProp("param7")->GetTypeAsString());
933 EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
934 EXPECT_EQ("string", schema.GetProp("param9")->GetTypeAsString());
935 EXPECT_EQ("string", schema.GetProp("param10")->GetTypeAsString());
936 EXPECT_EQ("string", schema.GetProp("param11")->GetTypeAsString());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800937 EXPECT_EQ("integer", schema.GetProp("param12")->GetTypeAsString());
938 EXPECT_EQ("number", schema.GetProp("param13")->GetTypeAsString());
939 EXPECT_EQ("boolean", schema.GetProp("param14")->GetTypeAsString());
940 EXPECT_EQ("boolean", schema.GetProp("param15")->GetTypeAsString());
941 EXPECT_EQ("string", schema.GetProp("param16")->GetTypeAsString());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700942 EXPECT_EQ("array", schema.GetProp("param17")->GetTypeAsString());
943 auto prop17 = schema.GetProp("param17");
944 EXPECT_EQ("integer",
945 prop17->GetArray()->GetItemTypePtr()->GetTypeAsString());
946 EXPECT_EQ("array", schema.GetProp("param18")->GetTypeAsString());
947 auto prop18 = schema.GetProp("param18");
948 EXPECT_EQ("number",
949 prop18->GetArray()->GetItemTypePtr()->GetTypeAsString());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700950
951 int min_int = (std::numeric_limits<int>::min)();
952 int max_int = (std::numeric_limits<int>::max)();
953 double min_dbl = (std::numeric_limits<double>::lowest)();
954 double max_dbl = (std::numeric_limits<double>::max)();
955 EXPECT_EQ(2, schema.GetProp("param1")->GetInt()->GetMinValue());
956 EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
957 EXPECT_EQ(min_int, schema.GetProp("param2")->GetInt()->GetMinValue());
958 EXPECT_EQ(10, schema.GetProp("param2")->GetInt()->GetMaxValue());
959 EXPECT_EQ(2, schema.GetProp("param3")->GetInt()->GetMinValue());
960 EXPECT_EQ(8, schema.GetProp("param3")->GetInt()->GetMaxValue());
961 EXPECT_DOUBLE_EQ(2.1, schema.GetProp("param4")->GetDouble()->GetMinValue());
962 EXPECT_DOUBLE_EQ(max_dbl,
963 schema.GetProp("param4")->GetDouble()->GetMaxValue());
964 EXPECT_DOUBLE_EQ(min_dbl,
965 schema.GetProp("param5")->GetDouble()->GetMinValue());
966 EXPECT_DOUBLE_EQ(10.1, schema.GetProp("param5")->GetDouble()->GetMaxValue());
967 EXPECT_DOUBLE_EQ(3.1, schema.GetProp("param6")->GetDouble()->GetMinValue());
968 EXPECT_DOUBLE_EQ(8.1, schema.GetProp("param6")->GetDouble()->GetMaxValue());
969 EXPECT_DOUBLE_EQ(3.1, schema.GetProp("param7")->GetDouble()->GetMinValue());
970 EXPECT_DOUBLE_EQ(8.0, schema.GetProp("param7")->GetDouble()->GetMaxValue());
971 EXPECT_DOUBLE_EQ(3.0, schema.GetProp("param8")->GetDouble()->GetMinValue());
972 EXPECT_DOUBLE_EQ(8.1, schema.GetProp("param8")->GetDouble()->GetMaxValue());
973 EXPECT_EQ(2, schema.GetProp("param9")->GetString()->GetMinLength());
974 EXPECT_EQ(max_int, schema.GetProp("param9")->GetString()->GetMaxLength());
975 EXPECT_EQ(0, schema.GetProp("param10")->GetString()->GetMinLength());
976 EXPECT_EQ(10, schema.GetProp("param10")->GetString()->GetMaxLength());
977 EXPECT_EQ(3, schema.GetProp("param11")->GetString()->GetMinLength());
978 EXPECT_EQ(8, schema.GetProp("param11")->GetString()->GetMaxLength());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800979 const buffet::PropValue* val = schema.GetProp("param12")->GetDefaultValue();
980 EXPECT_EQ(12, val->GetInt()->GetValue());
981 val = schema.GetProp("param13")->GetDefaultValue();
982 EXPECT_DOUBLE_EQ(13.5, val->GetDouble()->GetValue());
983 val = schema.GetProp("param14")->GetDefaultValue();
984 EXPECT_TRUE(val->GetBoolean()->GetValue());
985 val = schema.GetProp("param15")->GetDefaultValue();
986 EXPECT_FALSE(val->GetBoolean()->GetValue());
987 val = schema.GetProp("param16")->GetDefaultValue();
988 EXPECT_EQ("foobar", val->GetString()->GetValue());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700989 val = schema.GetProp("param17")->GetDefaultValue();
990 EXPECT_EQ((std::vector<int>{1, 2, 3}),
991 GetArrayValues<int>(val->GetArray()->GetValue()));
992 val = schema.GetProp("param18")->GetDefaultValue();
993 EXPECT_TRUE(val->GetArray()->GetValue().empty());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700994}
995
996TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeDeduction_Array) {
997 buffet::ObjectSchema schema;
998 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800999 "'param1' :[0,1,2,3],"
1000 "'param2' :[0.0,1.1,2.2],"
1001 "'param3' :['id1', 'id2'],"
1002 "'param4' :{'enum':[1,2,3]},"
1003 "'param5' :{'enum':[-1.1,2.2,3]},"
1004 "'param6' :{'enum':['id0', 'id1']},"
1005 "'param7' :{'type':'integer', 'enum':[1,2,3]},"
1006 "'param8' :{'type':'number', 'enum':[1,2,3]},"
1007 "'param9' :{'type':'number', 'enum':[]},"
Alex Vakulenko29e64442015-03-20 13:59:19 -07001008 "'param10':{'type':'integer', 'enum':[]},"
1009 "'param11':[[0,1],[2,3]],"
1010 "'param12':[['foo','bar']],"
1011 "'param13':{'enum':[['id0', 'id1']]}"
1012 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001013 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1014 nullptr));
1015 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
1016 EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
1017 EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
1018 EXPECT_EQ("integer", schema.GetProp("param4")->GetTypeAsString());
1019 EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
1020 EXPECT_EQ("string", schema.GetProp("param6")->GetTypeAsString());
1021 EXPECT_EQ("integer", schema.GetProp("param7")->GetTypeAsString());
1022 EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
1023 EXPECT_EQ("number", schema.GetProp("param9")->GetTypeAsString());
1024 EXPECT_EQ("integer", schema.GetProp("param10")->GetTypeAsString());
1025
Alex Vakulenko29e64442015-03-20 13:59:19 -07001026 auto prop_type11 = schema.GetProp("param11");
1027 EXPECT_EQ("array", prop_type11->GetTypeAsString());
1028 EXPECT_EQ("integer",
1029 prop_type11->GetArray()->GetItemTypePtr()->GetTypeAsString());
1030
1031 auto prop_type12 = schema.GetProp("param12");
1032 EXPECT_EQ("array", prop_type12->GetTypeAsString());
1033 EXPECT_EQ("string",
1034 prop_type12->GetArray()->GetItemTypePtr()->GetTypeAsString());
1035
1036 auto prop_type13 = schema.GetProp("param13");
1037 EXPECT_EQ("array", prop_type12->GetTypeAsString());
1038 EXPECT_EQ("string",
1039 prop_type13->GetArray()->GetItemTypePtr()->GetTypeAsString());
1040
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001041 EXPECT_EQ((std::vector<int>{0, 1, 2, 3}),
1042 GetOneOfValues<int>(schema.GetProp("param1")));
1043 EXPECT_EQ((std::vector<double>{0.0, 1.1, 2.2}),
1044 GetOneOfValues<double>(schema.GetProp("param2")));
1045 EXPECT_EQ((std::vector<std::string>{"id1", "id2"}),
1046 GetOneOfValues<std::string>(schema.GetProp("param3")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001047
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001048 EXPECT_EQ((std::vector<int>{1, 2, 3}),
1049 GetOneOfValues<int>(schema.GetProp("param4")));
1050 EXPECT_EQ((std::vector<double>{-1.1, 2.2, 3.0}),
1051 GetOneOfValues<double>(schema.GetProp("param5")));
1052 EXPECT_EQ((std::vector<std::string>{"id0", "id1"}),
1053 GetOneOfValues<std::string>(schema.GetProp("param6")));
1054 EXPECT_EQ((std::vector<int>{1, 2, 3}),
1055 GetOneOfValues<int>(schema.GetProp("param7")));
1056 EXPECT_EQ((std::vector<double>{1.0, 2.0, 3.0}),
1057 GetOneOfValues<double>(schema.GetProp("param8")));
1058 EXPECT_TRUE(GetOneOfValues<double>(schema.GetProp("param9")).empty());
1059 EXPECT_TRUE(GetOneOfValues<int>(schema.GetProp("param10")).empty());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001060}
1061
1062TEST(CommandSchema, ObjectSchema_FromJson_Inheritance) {
1063 const char* base_schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001064 "'param0' :{'minimum':1, 'maximum':5},"
1065 "'param1' :{'minimum':1, 'maximum':5},"
1066 "'param2' :{'minimum':1, 'maximum':5},"
1067 "'param3' :{'minimum':1, 'maximum':5},"
1068 "'param4' :{'minimum':1, 'maximum':5},"
1069 "'param5' :{'minimum':1.1, 'maximum':5.5},"
1070 "'param6' :{'minimum':1.1, 'maximum':5.5},"
1071 "'param7' :{'minimum':1.1, 'maximum':5.5},"
1072 "'param8' :{'minimum':1.1, 'maximum':5.5},"
1073 "'param9' :{'minLength':1, 'maxLength':5},"
1074 "'param10':{'minLength':1, 'maxLength':5},"
1075 "'param11':{'minLength':1, 'maxLength':5},"
1076 "'param12':{'minLength':1, 'maxLength':5},"
1077 "'param13':[1,2,3],"
1078 "'param14':[1,2,3],"
1079 "'param15':[1.1,2.2,3.3],"
1080 "'param16':[1.1,2.2,3.3],"
1081 "'param17':['id1', 'id2'],"
1082 "'param18':['id1', 'id2'],"
1083 "'param19':{'minimum':1, 'maximum':5},"
1084 "'param20':{'default':49},"
1085 "'param21':{'default':49},"
1086 "'param22':'integer'"
1087 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001088 buffet::ObjectSchema base_schema;
1089 EXPECT_TRUE(base_schema.FromJson(CreateDictionaryValue(base_schema_str).get(),
1090 nullptr, nullptr));
1091 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001092 "'param1' :{},"
1093 "'param2' :{'minimum':2},"
1094 "'param3' :{'maximum':9},"
1095 "'param4' :{'minimum':2, 'maximum':9},"
1096 "'param5' :{},"
1097 "'param6' :{'minimum':2.2},"
1098 "'param7' :{'maximum':9.9},"
1099 "'param8' :{'minimum':2.2, 'maximum':9.9},"
1100 "'param9' :{},"
1101 "'param10':{'minLength':3},"
1102 "'param11':{'maxLength':8},"
1103 "'param12':{'minLength':3, 'maxLength':8},"
1104 "'param13':{},"
1105 "'param14':[1,2,3,4],"
1106 "'param15':{},"
1107 "'param16':[1.1,2.2,3.3,4.4],"
1108 "'param17':{},"
1109 "'param18':['id1', 'id3'],"
1110 "'param19':{},"
1111 "'param20':{},"
1112 "'param21':{'default':8},"
1113 "'param22':{'default':123}"
1114 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001115 buffet::ObjectSchema schema;
1116 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(),
1117 &base_schema, nullptr));
1118 EXPECT_EQ(nullptr, schema.GetProp("param0"));
1119 EXPECT_NE(nullptr, schema.GetProp("param1"));
1120 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
1121 EXPECT_EQ(1, schema.GetProp("param1")->GetInt()->GetMinValue());
1122 EXPECT_EQ(5, schema.GetProp("param1")->GetInt()->GetMaxValue());
1123 EXPECT_EQ("integer", schema.GetProp("param2")->GetTypeAsString());
1124 EXPECT_EQ(2, schema.GetProp("param2")->GetInt()->GetMinValue());
1125 EXPECT_EQ(5, schema.GetProp("param2")->GetInt()->GetMaxValue());
1126 EXPECT_EQ("integer", schema.GetProp("param3")->GetTypeAsString());
1127 EXPECT_EQ(1, schema.GetProp("param3")->GetInt()->GetMinValue());
1128 EXPECT_EQ(9, schema.GetProp("param3")->GetInt()->GetMaxValue());
1129 EXPECT_EQ("integer", schema.GetProp("param4")->GetTypeAsString());
1130 EXPECT_EQ(2, schema.GetProp("param4")->GetInt()->GetMinValue());
1131 EXPECT_EQ(9, schema.GetProp("param4")->GetInt()->GetMaxValue());
1132 EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
1133 EXPECT_EQ(1.1, schema.GetProp("param5")->GetDouble()->GetMinValue());
1134 EXPECT_EQ(5.5, schema.GetProp("param5")->GetDouble()->GetMaxValue());
1135 EXPECT_EQ("number", schema.GetProp("param6")->GetTypeAsString());
1136 EXPECT_EQ(2.2, schema.GetProp("param6")->GetDouble()->GetMinValue());
1137 EXPECT_EQ(5.5, schema.GetProp("param6")->GetDouble()->GetMaxValue());
1138 EXPECT_EQ("number", schema.GetProp("param7")->GetTypeAsString());
1139 EXPECT_EQ(1.1, schema.GetProp("param7")->GetDouble()->GetMinValue());
1140 EXPECT_EQ(9.9, schema.GetProp("param7")->GetDouble()->GetMaxValue());
1141 EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
1142 EXPECT_EQ(2.2, schema.GetProp("param8")->GetDouble()->GetMinValue());
1143 EXPECT_EQ(9.9, schema.GetProp("param8")->GetDouble()->GetMaxValue());
1144 EXPECT_EQ("string", schema.GetProp("param9")->GetTypeAsString());
1145 EXPECT_EQ(1, schema.GetProp("param9")->GetString()->GetMinLength());
1146 EXPECT_EQ(5, schema.GetProp("param9")->GetString()->GetMaxLength());
1147 EXPECT_EQ("string", schema.GetProp("param10")->GetTypeAsString());
1148 EXPECT_EQ(3, schema.GetProp("param10")->GetString()->GetMinLength());
1149 EXPECT_EQ(5, schema.GetProp("param10")->GetString()->GetMaxLength());
1150 EXPECT_EQ("string", schema.GetProp("param11")->GetTypeAsString());
1151 EXPECT_EQ(1, schema.GetProp("param11")->GetString()->GetMinLength());
1152 EXPECT_EQ(8, schema.GetProp("param11")->GetString()->GetMaxLength());
1153 EXPECT_EQ("string", schema.GetProp("param12")->GetTypeAsString());
1154 EXPECT_EQ(3, schema.GetProp("param12")->GetString()->GetMinLength());
1155 EXPECT_EQ(8, schema.GetProp("param12")->GetString()->GetMaxLength());
1156 EXPECT_EQ("integer", schema.GetProp("param13")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001157 EXPECT_EQ((std::vector<int>{1, 2, 3}),
1158 GetOneOfValues<int>(schema.GetProp("param13")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001159 EXPECT_EQ("integer", schema.GetProp("param14")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001160 EXPECT_EQ((std::vector<int>{1, 2, 3, 4}),
1161 GetOneOfValues<int>(schema.GetProp("param14")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001162 EXPECT_EQ("number", schema.GetProp("param15")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001163 EXPECT_EQ((std::vector<double>{1.1, 2.2, 3.3}),
1164 GetOneOfValues<double>(schema.GetProp("param15")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001165 EXPECT_EQ("number", schema.GetProp("param16")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001166 EXPECT_EQ((std::vector<double>{1.1, 2.2, 3.3, 4.4}),
1167 GetOneOfValues<double>(schema.GetProp("param16")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001168 EXPECT_EQ("string", schema.GetProp("param17")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001169 EXPECT_EQ((std::vector<std::string>{"id1", "id2"}),
1170 GetOneOfValues<std::string>(schema.GetProp("param17")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001171 EXPECT_EQ("string", schema.GetProp("param18")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001172 EXPECT_EQ((std::vector<std::string>{"id1", "id3"}),
1173 GetOneOfValues<std::string>(schema.GetProp("param18")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001174 EXPECT_EQ("integer", schema.GetProp("param19")->GetTypeAsString());
1175 EXPECT_EQ(1, schema.GetProp("param19")->GetInt()->GetMinValue());
1176 EXPECT_EQ(5, schema.GetProp("param19")->GetInt()->GetMaxValue());
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001177 EXPECT_EQ(49,
1178 schema.GetProp("param20")->GetDefaultValue()->GetInt()->GetValue());
1179 EXPECT_EQ(8,
1180 schema.GetProp("param21")->GetDefaultValue()->GetInt()->GetValue());
1181 EXPECT_EQ(123,
1182 schema.GetProp("param22")->GetDefaultValue()->GetInt()->GetValue());
1183}
1184
1185TEST(CommandSchema, ObjectSchema_UseDefaults) {
1186 buffet::ObjectPropType prop;
1187 const char* schema_str = "{'properties':{"
1188 "'param1':{'default':true},"
1189 "'param2':{'default':2},"
1190 "'param3':{'default':3.3},"
1191 "'param4':{'default':'four'},"
1192 "'param5':{'default':{'x':5,'y':6},"
Alex Vakulenko29e64442015-03-20 13:59:19 -07001193 "'properties':{'x':'integer','y':'integer'}},"
1194 "'param6':{'default':[1,2,3]}"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001195 "}}";
1196 ASSERT_TRUE(prop.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1197 nullptr));
1198
1199 // Omit all.
1200 auto value = prop.CreateValue();
1201 ASSERT_TRUE(value->FromJson(CreateDictionaryValue("{}").get(), nullptr));
1202 buffet::native_types::Object obj = value->GetObject()->GetValue();
1203 EXPECT_TRUE(obj["param1"]->GetBoolean()->GetValue());
1204 EXPECT_EQ(2, obj["param2"]->GetInt()->GetValue());
1205 EXPECT_DOUBLE_EQ(3.3, obj["param3"]->GetDouble()->GetValue());
1206 EXPECT_EQ("four", obj["param4"]->GetString()->GetValue());
1207 buffet::native_types::Object param5 = obj["param5"]->GetObject()->GetValue();
1208 EXPECT_EQ(5, param5["x"]->GetInt()->GetValue());
1209 EXPECT_EQ(6, param5["y"]->GetInt()->GetValue());
Alex Vakulenko29e64442015-03-20 13:59:19 -07001210 buffet::native_types::Array param6 = obj["param6"]->GetArray()->GetValue();
1211 EXPECT_EQ((std::vector<int>{1, 2, 3}), GetArrayValues<int>(param6));
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001212
1213 // Specify some.
1214 value = prop.CreateValue();
1215 const char* val_json = "{"
1216 "'param1':false,"
1217 "'param3':33.3,"
1218 "'param5':{'x':-5,'y':-6}"
1219 "}";
1220 ASSERT_TRUE(value->FromJson(CreateDictionaryValue(val_json).get(), nullptr));
1221 obj = value->GetObject()->GetValue();
1222 EXPECT_FALSE(obj["param1"]->GetBoolean()->GetValue());
1223 EXPECT_EQ(2, obj["param2"]->GetInt()->GetValue());
1224 EXPECT_DOUBLE_EQ(33.3, obj["param3"]->GetDouble()->GetValue());
1225 EXPECT_EQ("four", obj["param4"]->GetString()->GetValue());
1226 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 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 all.
1233 value = prop.CreateValue();
1234 val_json = "{"
1235 "'param1':false,"
1236 "'param2':22,"
1237 "'param3':333.3,"
1238 "'param4':'FOUR',"
Alex Vakulenko29e64442015-03-20 13:59:19 -07001239 "'param5':{'x':-55,'y':66},"
1240 "'param6':[-1, 0]"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001241 "}";
1242 ASSERT_TRUE(value->FromJson(CreateDictionaryValue(val_json).get(), nullptr));
1243 obj = value->GetObject()->GetValue();
1244 EXPECT_FALSE(obj["param1"]->GetBoolean()->GetValue());
1245 EXPECT_EQ(22, obj["param2"]->GetInt()->GetValue());
1246 EXPECT_DOUBLE_EQ(333.3, obj["param3"]->GetDouble()->GetValue());
1247 EXPECT_EQ("FOUR", obj["param4"]->GetString()->GetValue());
1248 param5 = obj["param5"]->GetObject()->GetValue();
1249 EXPECT_EQ(-55, param5["x"]->GetInt()->GetValue());
1250 EXPECT_EQ(66, param5["y"]->GetInt()->GetValue());
Alex Vakulenko29e64442015-03-20 13:59:19 -07001251 param6 = obj["param6"]->GetArray()->GetValue();
1252 EXPECT_EQ((std::vector<int>{-1, 0}), GetArrayValues<int>(param6));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001253}
1254
1255TEST(CommandSchema, ObjectSchema_FromJson_BaseSchema_Failures) {
1256 buffet::ObjectSchema schema;
Alex Vakulenko5f472062014-08-14 17:54:04 -07001257 chromeos::ErrorPtr error;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001258 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001259 "'param1':{}"
1260 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001261 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1262 &error));
1263 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1264 error.reset();
1265
1266 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001267 "'param1':{'type':'foo'}"
1268 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001269 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1270 &error));
1271 EXPECT_EQ("unknown_type", error->GetFirstError()->GetCode());
1272 error.reset();
1273
1274 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001275 "'param1':[]"
1276 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001277 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1278 &error));
1279 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1280 error.reset();
1281
1282 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001283 "'param1':{'minimum':'foo'}"
1284 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001285 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1286 &error));
1287 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1288 error.reset();
1289
1290 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001291 "'param1':[1,2.2]"
1292 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001293 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1294 &error));
1295 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1296 error.reset();
Alex Vakulenko5109b202014-06-20 14:49:41 -07001297
1298 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001299 "'param1':{'minimum':1, 'enum':[1,2,3]}" // can't have min/max & enum.
1300 "}";
Alex Vakulenko5109b202014-06-20 14:49:41 -07001301 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1302 &error));
1303 EXPECT_EQ("unexpected_parameter", error->GetFirstError()->GetCode());
1304 error.reset();
1305
1306 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001307 "'param1':{'maximum':1, 'blah':2}" // 'blah' is unexpected.
1308 "}";
Alex Vakulenko5109b202014-06-20 14:49:41 -07001309 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1310 &error));
1311 EXPECT_EQ("unexpected_parameter", error->GetFirstError()->GetCode());
1312 error.reset();
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001313
1314 schema_str = "{"
1315 "'param1':{'enum':[1,2,3],'default':5}" // 'default' must be 1, 2, or 3.
1316 "}";
1317 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1318 &error));
1319 EXPECT_EQ("out_of_range", error->GetFirstError()->GetCode());
1320 error.reset();
Alex Vakulenko29e64442015-03-20 13:59:19 -07001321
1322 schema_str = "{"
1323 "'param1':[[1,2.3]]"
1324 "}";
1325 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1326 &error));
1327 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1328 error.reset();
1329
1330 schema_str = "{"
1331 "'param1':[[1,2],[3,4],['blah']]"
1332 "}";
1333 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1334 &error));
1335 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1336 error.reset();
1337
1338 schema_str = "{"
1339 "'param1':{'default':[]}"
1340 "}";
1341 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1342 &error));
1343 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1344 error.reset();
1345
1346 schema_str = "{"
1347 "'param1':[[[1]],[[2]]]"
1348 "}";
1349 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1350 &error));
1351 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1352 error.reset();
1353
1354 schema_str = "{"
1355 "'param1':{'enum':[[['foo']]]}"
1356 "}";
1357 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1358 &error));
1359 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1360 error.reset();
1361
1362 schema_str = "{"
1363 "'param1':{'default':[[1],[2]]}"
1364 "}";
1365 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1366 &error));
1367 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1368 error.reset();
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001369}