blob: 13300993024de9e73ecc0409c54a160159ae38fd [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
Vitaly Buka32005de2015-05-01 12:33:31 -070022namespace buffet {
23
24using unittests::CreateValue;
25using unittests::CreateDictionaryValue;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070026
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -070027namespace {
28
Vitaly Buka32005de2015-05-01 12:33:31 -070029template <typename T>
30std::vector<T> GetArrayValues(const native_types::Array& arr) {
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -070031 std::vector<T> values;
Alex Vakulenko29e64442015-03-20 13:59:19 -070032 values.reserve(arr.size());
33 for (const auto& prop_value : arr) {
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -070034 values.push_back(prop_value->GetValueAsAny().Get<T>());
35 }
36 return values;
37}
38
Vitaly Buka32005de2015-05-01 12:33:31 -070039template <typename T>
40std::vector<T> GetOneOfValues(const PropType* prop_type) {
41 auto one_of = static_cast<const ConstraintOneOf*>(
42 prop_type->GetConstraint(ConstraintType::OneOf));
Alex Vakulenko29e64442015-03-20 13:59:19 -070043 if (!one_of)
44 return {};
45
46 return GetArrayValues<T>(one_of->set_.value);
47}
48
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -070049} // anonymous namespace
50
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070051TEST(CommandSchema, IntPropType_Empty) {
Vitaly Buka32005de2015-05-01 12:33:31 -070052 IntPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070053 EXPECT_TRUE(prop.GetConstraints().empty());
54 EXPECT_FALSE(prop.HasOverriddenAttributes());
55 EXPECT_FALSE(prop.IsBasedOnSchema());
Alex Vakulenko2a17a532015-02-24 14:51:13 -080056 EXPECT_EQ(nullptr, prop.GetDefaultValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070057}
58
59TEST(CommandSchema, IntPropType_Types) {
Vitaly Buka32005de2015-05-01 12:33:31 -070060 IntPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070061 EXPECT_EQ(nullptr, prop.GetBoolean());
62 EXPECT_EQ(&prop, prop.GetInt());
63 EXPECT_EQ(nullptr, prop.GetDouble());
64 EXPECT_EQ(nullptr, prop.GetString());
Alex Vakulenko66ec2922014-06-17 15:30:22 -070065 EXPECT_EQ(nullptr, prop.GetObject());
Alex Vakulenko29e64442015-03-20 13:59:19 -070066 EXPECT_EQ(nullptr, prop.GetArray());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070067}
68
69TEST(CommandSchema, IntPropType_ToJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -070070 IntPropType prop;
Vitaly Buka7c82d292015-05-03 18:08:12 -070071 EXPECT_JSON_EQ("'integer'", *prop.ToJson(false, nullptr));
72 EXPECT_JSON_EQ("{'type':'integer'}", *prop.ToJson(true, nullptr));
Vitaly Buka32005de2015-05-01 12:33:31 -070073 IntPropType param2;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070074 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -070075 EXPECT_JSON_EQ("{}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070076 param2.FromJson(CreateDictionaryValue("{'minimum':3}").get(),
77 &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -070078 EXPECT_JSON_EQ("{'minimum':3}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070079 param2.FromJson(CreateDictionaryValue("{'maximum':-7}").get(),
80 &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -070081 EXPECT_JSON_EQ("{'maximum':-7}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070082 param2.FromJson(CreateDictionaryValue("{'minimum':0,'maximum':5}").get(),
83 &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -070084 EXPECT_JSON_EQ("{'maximum':5,'minimum':0}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070085 param2.FromJson(CreateDictionaryValue("{'enum':[1,2,3]}").get(), &prop,
86 nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -070087 EXPECT_JSON_EQ("[1,2,3]", *param2.ToJson(false, nullptr));
Alex Vakulenko2a17a532015-02-24 14:51:13 -080088 param2.FromJson(CreateDictionaryValue("{'default':123}").get(),
89 &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -070090 EXPECT_JSON_EQ("{'default':123}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070091}
92
93TEST(CommandSchema, IntPropType_FromJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -070094 IntPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070095 prop.AddMinMaxConstraint(2, 8);
Vitaly Buka32005de2015-05-01 12:33:31 -070096 IntPropType param2;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070097 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
98 EXPECT_FALSE(param2.HasOverriddenAttributes());
99 EXPECT_TRUE(param2.IsBasedOnSchema());
100 EXPECT_EQ(2, prop.GetMinValue());
101 EXPECT_EQ(8, prop.GetMaxValue());
102 prop.AddMinMaxConstraint(-2, 30);
103 param2.FromJson(CreateDictionaryValue("{'minimum':7}").get(),
104 &prop, nullptr);
105 EXPECT_TRUE(param2.HasOverriddenAttributes());
106 EXPECT_TRUE(param2.IsBasedOnSchema());
107 EXPECT_EQ(7, param2.GetMinValue());
108 EXPECT_EQ(30, param2.GetMaxValue());
109 param2.FromJson(CreateDictionaryValue("{'maximum':17}").get(),
110 &prop, nullptr);
111 EXPECT_TRUE(param2.HasOverriddenAttributes());
112 EXPECT_TRUE(param2.IsBasedOnSchema());
113 EXPECT_EQ(-2, param2.GetMinValue());
114 EXPECT_EQ(17, param2.GetMaxValue());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800115
116 ASSERT_TRUE(param2.FromJson(CreateDictionaryValue("{'default':3}").get(),
117 &prop, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700118 EXPECT_TRUE(param2.HasOverriddenAttributes());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800119 ASSERT_NE(nullptr, param2.GetDefaultValue());
120 EXPECT_EQ(3, param2.GetDefaultValue()->GetInt()->GetValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700121}
122
123TEST(CommandSchema, IntPropType_Validate) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700124 IntPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700125 prop.AddMinMaxConstraint(2, 4);
Alex Vakulenko5f472062014-08-14 17:54:04 -0700126 chromeos::ErrorPtr error;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700127 EXPECT_FALSE(prop.ValidateValue(CreateValue("-1").get(), &error));
128 EXPECT_EQ("out_of_range", error->GetCode());
129 error.reset();
130 EXPECT_FALSE(prop.ValidateValue(CreateValue("0").get(), &error));
131 EXPECT_EQ("out_of_range", error->GetCode());
132 error.reset();
133 EXPECT_FALSE(prop.ValidateValue(CreateValue("1").get(), &error));
134 EXPECT_EQ("out_of_range", error->GetCode());
135 error.reset();
136 EXPECT_TRUE(prop.ValidateValue(CreateValue("2").get(), &error));
137 EXPECT_EQ(nullptr, error.get());
138 EXPECT_TRUE(prop.ValidateValue(CreateValue("3").get(), &error));
139 EXPECT_EQ(nullptr, error.get());
140 EXPECT_TRUE(prop.ValidateValue(CreateValue("4").get(), &error));
141 EXPECT_EQ(nullptr, error.get());
142 EXPECT_FALSE(prop.ValidateValue(CreateValue("5").get(), &error));
143 EXPECT_EQ("out_of_range", error->GetCode());
144 error.reset();
145 EXPECT_FALSE(prop.ValidateValue(CreateValue("true").get(), &error));
146 EXPECT_EQ("type_mismatch", error->GetCode());
147 error.reset();
148 EXPECT_FALSE(prop.ValidateValue(CreateValue("3.0").get(), &error));
149 EXPECT_EQ("type_mismatch", error->GetCode());
150 error.reset();
151 EXPECT_FALSE(prop.ValidateValue(CreateValue("'3'").get(), &error));
152 EXPECT_EQ("type_mismatch", error->GetCode());
153}
154
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700155TEST(CommandSchema, IntPropType_CreateValue) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700156 IntPropType prop;
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700157 chromeos::ErrorPtr error;
158 auto val = prop.CreateValue(2, &error);
159 ASSERT_NE(nullptr, val.get());
160 EXPECT_EQ(nullptr, error.get());
161 EXPECT_EQ(2, val->GetValueAsAny().Get<int>());
162
163 val = prop.CreateValue("blah", &error);
164 EXPECT_EQ(nullptr, val.get());
165 ASSERT_NE(nullptr, error.get());
Vitaly Buka32005de2015-05-01 12:33:31 -0700166 EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700167}
168
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700169///////////////////////////////////////////////////////////////////////////////
170
171TEST(CommandSchema, BoolPropType_Empty) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700172 BooleanPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700173 EXPECT_TRUE(prop.GetConstraints().empty());
174 EXPECT_FALSE(prop.HasOverriddenAttributes());
175 EXPECT_FALSE(prop.IsBasedOnSchema());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800176 EXPECT_EQ(nullptr, prop.GetDefaultValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700177}
178
179TEST(CommandSchema, BoolPropType_Types) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700180 BooleanPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700181 EXPECT_EQ(nullptr, prop.GetInt());
182 EXPECT_EQ(&prop, prop.GetBoolean());
183 EXPECT_EQ(nullptr, prop.GetDouble());
184 EXPECT_EQ(nullptr, prop.GetString());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700185 EXPECT_EQ(nullptr, prop.GetObject());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700186 EXPECT_EQ(nullptr, prop.GetArray());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700187}
188
189TEST(CommandSchema, BoolPropType_ToJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700190 BooleanPropType prop;
Vitaly Buka7c82d292015-05-03 18:08:12 -0700191 EXPECT_JSON_EQ("'boolean'", *prop.ToJson(false, nullptr));
192 EXPECT_JSON_EQ("{'type':'boolean'}", *prop.ToJson(true, nullptr));
Vitaly Buka32005de2015-05-01 12:33:31 -0700193 BooleanPropType param2;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700194 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700195 EXPECT_JSON_EQ("{}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700196 param2.FromJson(CreateDictionaryValue("{'enum':[true,false]}").get(), &prop,
197 nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700198 EXPECT_JSON_EQ("[true,false]", *param2.ToJson(false, nullptr));
199 EXPECT_JSON_EQ("{'enum':[true,false],'type':'boolean'}",
200 *param2.ToJson(true, nullptr));
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800201 param2.FromJson(CreateDictionaryValue("{'default':true}").get(),
202 &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700203 EXPECT_JSON_EQ("{'default':true}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700204}
205
206TEST(CommandSchema, BoolPropType_FromJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700207 BooleanPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700208 prop.FromJson(CreateDictionaryValue("{'enum':[true]}").get(), &prop,
209 nullptr);
Vitaly Buka32005de2015-05-01 12:33:31 -0700210 BooleanPropType param2;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700211 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
212 EXPECT_FALSE(param2.HasOverriddenAttributes());
213 EXPECT_TRUE(param2.IsBasedOnSchema());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -0700214 EXPECT_EQ(std::vector<bool>{true}, GetOneOfValues<bool>(&prop));
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800215
Vitaly Buka32005de2015-05-01 12:33:31 -0700216 BooleanPropType prop_base;
217 BooleanPropType param3;
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800218 ASSERT_TRUE(param3.FromJson(CreateDictionaryValue("{'default':false}").get(),
219 &prop_base, nullptr));
220 EXPECT_TRUE(param3.HasOverriddenAttributes());
221 ASSERT_NE(nullptr, param3.GetDefaultValue());
222 EXPECT_FALSE(param3.GetDefaultValue()->GetBoolean()->GetValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700223}
224
225TEST(CommandSchema, BoolPropType_Validate) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700226 BooleanPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700227 prop.FromJson(CreateDictionaryValue("{'enum':[true]}").get(), &prop,
228 nullptr);
Alex Vakulenko5f472062014-08-14 17:54:04 -0700229 chromeos::ErrorPtr error;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700230 EXPECT_FALSE(prop.ValidateValue(CreateValue("false").get(), &error));
231 EXPECT_EQ("out_of_range", error->GetCode());
232 error.reset();
233 EXPECT_TRUE(prop.ValidateValue(CreateValue("true").get(), &error));
234 error.reset();
235 EXPECT_FALSE(prop.ValidateValue(CreateValue("1").get(), &error));
236 EXPECT_EQ("type_mismatch", error->GetCode());
237 error.reset();
238 EXPECT_FALSE(prop.ValidateValue(CreateValue("3.0").get(), &error));
239 EXPECT_EQ("type_mismatch", error->GetCode());
240 error.reset();
241 EXPECT_FALSE(prop.ValidateValue(CreateValue("'3'").get(), &error));
242 EXPECT_EQ("type_mismatch", error->GetCode());
243}
244
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700245TEST(CommandSchema, BoolPropType_CreateValue) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700246 BooleanPropType prop;
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700247 chromeos::ErrorPtr error;
248 auto val = prop.CreateValue(true, &error);
249 ASSERT_NE(nullptr, val.get());
250 EXPECT_EQ(nullptr, error.get());
251 EXPECT_TRUE(val->GetValueAsAny().Get<bool>());
252
253 val = prop.CreateValue("blah", &error);
254 EXPECT_EQ(nullptr, val.get());
255 ASSERT_NE(nullptr, error.get());
Vitaly Buka32005de2015-05-01 12:33:31 -0700256 EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700257}
258
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700259///////////////////////////////////////////////////////////////////////////////
260
261TEST(CommandSchema, DoublePropType_Empty) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700262 DoublePropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700263 EXPECT_DOUBLE_EQ(std::numeric_limits<double>::lowest(), prop.GetMinValue());
264 EXPECT_DOUBLE_EQ((std::numeric_limits<double>::max)(), prop.GetMaxValue());
265 EXPECT_FALSE(prop.HasOverriddenAttributes());
266 EXPECT_FALSE(prop.IsBasedOnSchema());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800267 EXPECT_EQ(nullptr, prop.GetDefaultValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700268}
269
270TEST(CommandSchema, DoublePropType_Types) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700271 DoublePropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700272 EXPECT_EQ(nullptr, prop.GetInt());
273 EXPECT_EQ(nullptr, prop.GetBoolean());
274 EXPECT_EQ(&prop, prop.GetDouble());
275 EXPECT_EQ(nullptr, prop.GetString());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700276 EXPECT_EQ(nullptr, prop.GetObject());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700277 EXPECT_EQ(nullptr, prop.GetArray());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700278}
279
280TEST(CommandSchema, DoublePropType_ToJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700281 DoublePropType prop;
Vitaly Buka7c82d292015-05-03 18:08:12 -0700282 EXPECT_JSON_EQ("'number'", *prop.ToJson(false, nullptr));
283 EXPECT_JSON_EQ("{'type':'number'}", *prop.ToJson(true, nullptr));
Vitaly Buka32005de2015-05-01 12:33:31 -0700284 DoublePropType param2;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700285 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700286 EXPECT_JSON_EQ("{}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700287 param2.FromJson(CreateDictionaryValue("{'minimum':3}").get(), &prop,
288 nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700289 EXPECT_JSON_EQ("{'minimum':3.0}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700290 param2.FromJson(CreateDictionaryValue("{'maximum':-7}").get(), &prop,
291 nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700292 EXPECT_JSON_EQ("{'maximum':-7.0}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700293 param2.FromJson(CreateDictionaryValue("{'minimum':0,'maximum':5}").get(),
294 &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700295 EXPECT_JSON_EQ("{'maximum':5.0,'minimum':0.0}",
296 *param2.ToJson(false, nullptr));
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800297 param2.FromJson(CreateDictionaryValue("{'default':12.3}").get(),
298 &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700299 EXPECT_JSON_EQ("{'default':12.3}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700300}
301
302TEST(CommandSchema, DoublePropType_FromJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700303 DoublePropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700304 prop.AddMinMaxConstraint(2.5, 8.7);
Vitaly Buka32005de2015-05-01 12:33:31 -0700305 DoublePropType param2;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700306 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
307 EXPECT_FALSE(param2.HasOverriddenAttributes());
308 EXPECT_TRUE(param2.IsBasedOnSchema());
309 EXPECT_DOUBLE_EQ(2.5, prop.GetMinValue());
310 EXPECT_DOUBLE_EQ(8.7, prop.GetMaxValue());
311 prop.AddMinMaxConstraint(-2.2, 30.4);
312 param2.FromJson(CreateDictionaryValue("{'minimum':7}").get(), &prop,
313 nullptr);
314 EXPECT_TRUE(param2.HasOverriddenAttributes());
315 EXPECT_TRUE(param2.IsBasedOnSchema());
316 EXPECT_DOUBLE_EQ(7.0, param2.GetMinValue());
317 EXPECT_DOUBLE_EQ(30.4, param2.GetMaxValue());
318 param2.FromJson(CreateDictionaryValue("{'maximum':17.2}").get(), &prop,
319 nullptr);
320 EXPECT_TRUE(param2.HasOverriddenAttributes());
321 EXPECT_TRUE(param2.IsBasedOnSchema());
322 EXPECT_DOUBLE_EQ(-2.2, param2.GetMinValue());
323 EXPECT_DOUBLE_EQ(17.2, param2.GetMaxValue());
324 param2.FromJson(CreateDictionaryValue("{'minimum':0,'maximum':6.1}").get(),
325 &prop, nullptr);
326 EXPECT_TRUE(param2.HasOverriddenAttributes());
327 EXPECT_TRUE(param2.IsBasedOnSchema());
328 EXPECT_DOUBLE_EQ(0.0, param2.GetMinValue());
329 EXPECT_DOUBLE_EQ(6.1, param2.GetMaxValue());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800330
331 ASSERT_TRUE(param2.FromJson(CreateDictionaryValue("{'default':-1.234}").get(),
332 &prop, nullptr));
333 EXPECT_TRUE(param2.HasOverriddenAttributes());
334 ASSERT_NE(nullptr, param2.GetDefaultValue());
335 EXPECT_DOUBLE_EQ(-1.234, param2.GetDefaultValue()->GetDouble()->GetValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700336}
337
338TEST(CommandSchema, DoublePropType_Validate) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700339 DoublePropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700340 prop.AddMinMaxConstraint(-1.2, 1.3);
Alex Vakulenko5f472062014-08-14 17:54:04 -0700341 chromeos::ErrorPtr error;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700342 EXPECT_FALSE(prop.ValidateValue(CreateValue("-2").get(), &error));
343 EXPECT_EQ("out_of_range", error->GetCode());
344 error.reset();
345 EXPECT_FALSE(prop.ValidateValue(CreateValue("-1.3").get(), &error));
346 EXPECT_EQ("out_of_range", error->GetCode());
347 error.reset();
348 EXPECT_TRUE(prop.ValidateValue(CreateValue("-1.2").get(), &error));
349 EXPECT_EQ(nullptr, error.get());
350 EXPECT_TRUE(prop.ValidateValue(CreateValue("0.0").get(), &error));
351 EXPECT_EQ(nullptr, error.get());
352 EXPECT_TRUE(prop.ValidateValue(CreateValue("1.3").get(), &error));
353 EXPECT_EQ(nullptr, error.get());
354 EXPECT_FALSE(prop.ValidateValue(CreateValue("1.31").get(), &error));
355 EXPECT_EQ("out_of_range", error->GetCode());
356 error.reset();
357 EXPECT_FALSE(prop.ValidateValue(CreateValue("true").get(), &error));
358 EXPECT_EQ("type_mismatch", error->GetCode());
359 error.reset();
360 EXPECT_FALSE(prop.ValidateValue(CreateValue("'0.0'").get(), &error));
361 EXPECT_EQ("type_mismatch", error->GetCode());
362}
363
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700364TEST(CommandSchema, DoublePropType_CreateValue) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700365 DoublePropType prop;
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700366 chromeos::ErrorPtr error;
367 auto val = prop.CreateValue(2.0, &error);
368 ASSERT_NE(nullptr, val.get());
369 EXPECT_EQ(nullptr, error.get());
370 EXPECT_DOUBLE_EQ(2.0, val->GetValueAsAny().Get<double>());
371
372 val = prop.CreateValue("blah", &error);
373 EXPECT_EQ(nullptr, val.get());
374 ASSERT_NE(nullptr, error.get());
Vitaly Buka32005de2015-05-01 12:33:31 -0700375 EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700376}
377
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700378///////////////////////////////////////////////////////////////////////////////
379
380TEST(CommandSchema, StringPropType_Empty) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700381 StringPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700382 EXPECT_EQ(0, prop.GetMinLength());
383 EXPECT_EQ((std::numeric_limits<int>::max)(), prop.GetMaxLength());
384 EXPECT_FALSE(prop.HasOverriddenAttributes());
385 EXPECT_FALSE(prop.IsBasedOnSchema());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800386 EXPECT_EQ(nullptr, prop.GetDefaultValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700387}
388
389TEST(CommandSchema, StringPropType_Types) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700390 StringPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700391 EXPECT_EQ(nullptr, prop.GetInt());
392 EXPECT_EQ(nullptr, prop.GetBoolean());
393 EXPECT_EQ(nullptr, prop.GetDouble());
394 EXPECT_EQ(&prop, prop.GetString());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700395 EXPECT_EQ(nullptr, prop.GetObject());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700396 EXPECT_EQ(nullptr, prop.GetArray());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700397}
398
399TEST(CommandSchema, StringPropType_ToJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700400 StringPropType prop;
Vitaly Buka7c82d292015-05-03 18:08:12 -0700401 EXPECT_JSON_EQ("'string'", *prop.ToJson(false, nullptr));
402 EXPECT_JSON_EQ("{'type':'string'}", *prop.ToJson(true, nullptr));
Vitaly Buka32005de2015-05-01 12:33:31 -0700403 StringPropType param2;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700404 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700405 EXPECT_JSON_EQ("{}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700406 param2.FromJson(CreateDictionaryValue("{'minLength':3}").get(), &prop,
407 nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700408 EXPECT_JSON_EQ("{'minLength':3}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700409 param2.FromJson(CreateDictionaryValue("{'maxLength':7}").get(), &prop,
410 nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700411 EXPECT_JSON_EQ("{'maxLength':7}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700412 param2.FromJson(CreateDictionaryValue("{'minLength':0,'maxLength':5}").get(),
413 &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700414 EXPECT_JSON_EQ("{'maxLength':5,'minLength':0}",
415 *param2.ToJson(false, nullptr));
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800416 param2.FromJson(CreateDictionaryValue("{'default':'abcd'}").get(),
417 &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700418 EXPECT_JSON_EQ("{'default':'abcd'}", *param2.ToJson(false, nullptr));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700419}
420
421TEST(CommandSchema, StringPropType_FromJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700422 StringPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700423 prop.AddLengthConstraint(2, 8);
Vitaly Buka32005de2015-05-01 12:33:31 -0700424 StringPropType param2;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700425 param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
426 EXPECT_FALSE(param2.HasOverriddenAttributes());
427 EXPECT_TRUE(param2.IsBasedOnSchema());
428 EXPECT_EQ(2, prop.GetMinLength());
429 EXPECT_EQ(8, prop.GetMaxLength());
430 prop.AddLengthConstraint(3, 5);
431 param2.FromJson(CreateDictionaryValue("{'minLength':4}").get(), &prop,
432 nullptr);
433 EXPECT_TRUE(param2.HasOverriddenAttributes());
434 EXPECT_TRUE(param2.IsBasedOnSchema());
435 EXPECT_EQ(4, param2.GetMinLength());
436 EXPECT_EQ(5, param2.GetMaxLength());
437 param2.FromJson(CreateDictionaryValue("{'maxLength':8}").get(), &prop,
438 nullptr);
439 EXPECT_TRUE(param2.HasOverriddenAttributes());
440 EXPECT_TRUE(param2.IsBasedOnSchema());
441 EXPECT_EQ(3, param2.GetMinLength());
442 EXPECT_EQ(8, param2.GetMaxLength());
443 param2.FromJson(CreateDictionaryValue(
444 "{'minLength':1,'maxLength':7}").get(), &prop, nullptr);
445 EXPECT_TRUE(param2.HasOverriddenAttributes());
446 EXPECT_TRUE(param2.IsBasedOnSchema());
447 EXPECT_EQ(1, param2.GetMinLength());
448 EXPECT_EQ(7, param2.GetMaxLength());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800449
450 ASSERT_TRUE(param2.FromJson(CreateDictionaryValue("{'default':'foo'}").get(),
451 &prop, nullptr));
452 EXPECT_TRUE(param2.HasOverriddenAttributes());
453 ASSERT_NE(nullptr, param2.GetDefaultValue());
454 EXPECT_EQ("foo", param2.GetDefaultValue()->GetString()->GetValue());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700455}
456
457TEST(CommandSchema, StringPropType_Validate) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700458 StringPropType prop;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700459 prop.AddLengthConstraint(1, 3);
Alex Vakulenko5f472062014-08-14 17:54:04 -0700460 chromeos::ErrorPtr error;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700461 EXPECT_FALSE(prop.ValidateValue(CreateValue("''").get(), &error));
462 EXPECT_EQ("out_of_range", error->GetCode());
463 error.reset();
464 prop.AddLengthConstraint(2, 3);
465 EXPECT_FALSE(prop.ValidateValue(CreateValue("''").get(), &error));
466 EXPECT_EQ("out_of_range", error->GetCode());
467 error.reset();
468 EXPECT_FALSE(prop.ValidateValue(CreateValue("'a'").get(), &error));
469 EXPECT_EQ("out_of_range", error->GetCode());
470 error.reset();
471 EXPECT_TRUE(prop.ValidateValue(CreateValue("'ab'").get(), &error));
472 EXPECT_EQ(nullptr, error.get());
473 EXPECT_TRUE(prop.ValidateValue(CreateValue("'abc'").get(), &error));
474 EXPECT_EQ(nullptr, error.get());
475 EXPECT_FALSE(prop.ValidateValue(CreateValue("'abcd'").get(), &error));
476 EXPECT_EQ("out_of_range", error->GetCode());
477 error.reset();
478
479 prop.FromJson(CreateDictionaryValue("{'enum':['abc','def','xyz!!']}").get(),
480 nullptr, &error);
481 EXPECT_TRUE(prop.ValidateValue(CreateValue("'abc'").get(), &error));
482 EXPECT_TRUE(prop.ValidateValue(CreateValue("'def'").get(), &error));
483 EXPECT_TRUE(prop.ValidateValue(CreateValue("'xyz!!'").get(), &error));
484 EXPECT_FALSE(prop.ValidateValue(CreateValue("'xyz'").get(), &error));
485 EXPECT_EQ("out_of_range", error->GetCode());
486 error.reset();
487}
488
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700489TEST(CommandSchema, StringPropType_CreateValue) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700490 StringPropType prop;
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700491 chromeos::ErrorPtr error;
492 auto val = prop.CreateValue(std::string{"blah"}, &error);
493 ASSERT_NE(nullptr, val.get());
494 EXPECT_EQ(nullptr, error.get());
495 EXPECT_EQ("blah", val->GetValueAsAny().Get<std::string>());
496
497 val = prop.CreateValue(4, &error);
498 EXPECT_EQ(nullptr, val.get());
499 ASSERT_NE(nullptr, error.get());
Vitaly Buka32005de2015-05-01 12:33:31 -0700500 EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700501}
502
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700503///////////////////////////////////////////////////////////////////////////////
504
505TEST(CommandSchema, ObjectPropType_Empty) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700506 ObjectPropType prop;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700507 EXPECT_TRUE(prop.HasOverriddenAttributes());
508 EXPECT_FALSE(prop.IsBasedOnSchema());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800509 EXPECT_EQ(nullptr, prop.GetDefaultValue());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700510}
511
512TEST(CommandSchema, ObjectPropType_Types) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700513 ObjectPropType prop;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700514 EXPECT_EQ(nullptr, prop.GetInt());
515 EXPECT_EQ(nullptr, prop.GetBoolean());
516 EXPECT_EQ(nullptr, prop.GetDouble());
517 EXPECT_EQ(nullptr, prop.GetString());
518 EXPECT_EQ(&prop, prop.GetObject());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700519 EXPECT_EQ(nullptr, prop.GetArray());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700520}
521
522TEST(CommandSchema, ObjectPropType_ToJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700523 ObjectPropType prop;
Vitaly Buka7c82d292015-05-03 18:08:12 -0700524 EXPECT_JSON_EQ("{'additionalProperties':false,'properties':{}}",
525 *prop.ToJson(false, nullptr));
526 EXPECT_JSON_EQ(
527 "{'additionalProperties':false,'properties':{},'type':'object'}",
528 *prop.ToJson(true, nullptr));
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700529 EXPECT_FALSE(prop.IsBasedOnSchema());
Vitaly Buka32005de2015-05-01 12:33:31 -0700530 ObjectPropType prop2;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700531 prop2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700532 EXPECT_JSON_EQ("{}", *prop2.ToJson(false, nullptr));
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700533 EXPECT_TRUE(prop2.IsBasedOnSchema());
534
Vitaly Buka32005de2015-05-01 12:33:31 -0700535 auto schema = ObjectSchema::Create();
536 schema->AddProp("expires", PropType::Create(ValueType::Int));
537 auto pw = PropType::Create(ValueType::String);
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700538 pw->GetString()->AddLengthConstraint(6, 100);
539 schema->AddProp("password", std::move(pw));
540 prop2.SetObjectSchema(std::move(schema));
Vitaly Buka7c82d292015-05-03 18:08:12 -0700541 auto expected = R"({
542 'additionalProperties': false,
543 'properties': {
544 'expires': 'integer',
545 'password': {
546 'maxLength': 100,
547 'minLength': 6
548 }
549 }
550 })";
551 EXPECT_JSON_EQ(expected, *prop2.ToJson(false, nullptr));
552
553 expected = R"({
554 'additionalProperties': false,
555 'properties': {
556 'expires': {
557 'type': 'integer'
558 },
559 'password': {
560 'maxLength': 100,
561 'minLength': 6,
562 'type': 'string'
563 }
564 },
565 'type': 'object'
566 })";
567 EXPECT_JSON_EQ(expected, *prop2.ToJson(true, nullptr));
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800568
Vitaly Buka32005de2015-05-01 12:33:31 -0700569 ObjectPropType prop3;
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800570 ASSERT_TRUE(prop3.FromJson(CreateDictionaryValue(
571 "{'default':{'expires':3,'password':'abracadabra'}}").get(), &prop2,
572 nullptr));
Vitaly Buka7c82d292015-05-03 18:08:12 -0700573 expected = R"({
574 'default': {
575 'expires': 3,
576 'password': 'abracadabra'
577 }
578 })";
579 EXPECT_JSON_EQ(expected, *prop3.ToJson(false, nullptr));
580
581 expected = R"({
582 'additionalProperties': false,
583 'default': {
584 'expires': 3,
585 'password': 'abracadabra'
586 },
587 'properties': {
588 'expires': {
589 'type': 'integer'
590 },
591 'password': {
592 'maxLength': 100,
593 'minLength': 6,
594 'type': 'string'
595 }
596 },
597 'type': 'object'
598 })";
599 EXPECT_JSON_EQ(expected, *prop3.ToJson(true, nullptr));
Alex Vakulenko45d255b2015-03-31 10:44:49 -0700600
Vitaly Buka32005de2015-05-01 12:33:31 -0700601 ObjectPropType prop4;
Alex Vakulenko45d255b2015-03-31 10:44:49 -0700602 ASSERT_TRUE(prop4.FromJson(CreateDictionaryValue(
603 "{'additionalProperties':true,"
604 "'default':{'expires':3,'password':'abracadabra'}}").get(), &prop2,
605 nullptr));
Vitaly Buka7c82d292015-05-03 18:08:12 -0700606 expected = R"({
607 'additionalProperties': true,
608 'default': {
609 'expires': 3,
610 'password': 'abracadabra'
611 },
612 'properties': {
613 'expires': 'integer',
614 'password': {
615 'maxLength': 100,
616 'minLength': 6
617 }
618 }
619 })";
620 EXPECT_JSON_EQ(expected, *prop4.ToJson(false, nullptr));
621
622 expected = R"({
623 'additionalProperties': true,
624 'default': {
625 'expires': 3,
626 'password': 'abracadabra'
627 },
628 'properties': {
629 'expires': {
630 'type': 'integer'
631 },
632 'password': {
633 'maxLength': 100,
634 'minLength': 6,
635 'type': 'string'
636 }
637 },
638 'type': 'object'
639 })";
640 EXPECT_JSON_EQ(expected, *prop4.ToJson(true, nullptr));
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700641}
642
643TEST(CommandSchema, ObjectPropType_FromJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700644 ObjectPropType base_prop;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700645 EXPECT_TRUE(base_prop.FromJson(CreateDictionaryValue(
646 "{'properties':{'name':'string','age':'integer'}}").get(), nullptr,
647 nullptr));
Alex Vakulenkod94656e2015-03-18 09:54:37 -0700648 auto schema = base_prop.GetObject()->GetObjectSchemaPtr();
Vitaly Buka32005de2015-05-01 12:33:31 -0700649 const PropType* prop = schema->GetProp("name");
650 EXPECT_EQ(ValueType::String, prop->GetType());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700651 prop = schema->GetProp("age");
Vitaly Buka32005de2015-05-01 12:33:31 -0700652 EXPECT_EQ(ValueType::Int, prop->GetType());
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800653
Vitaly Buka32005de2015-05-01 12:33:31 -0700654 ObjectPropType prop2;
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800655 ASSERT_TRUE(prop2.FromJson(CreateDictionaryValue(
656 "{'properties':{'name':'string','age':'integer'},"
657 "'default':{'name':'Bob','age':33}}").get(), nullptr, nullptr));
658 ASSERT_NE(nullptr, prop2.GetDefaultValue());
Vitaly Buka32005de2015-05-01 12:33:31 -0700659 const ObjectValue* defval = prop2.GetDefaultValue()->GetObject();
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800660 ASSERT_NE(nullptr, defval);
Vitaly Buka32005de2015-05-01 12:33:31 -0700661 native_types::Object objval = defval->GetValue();
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800662 EXPECT_EQ("Bob", objval["name"]->GetString()->GetValue());
663 EXPECT_EQ(33, objval["age"]->GetInt()->GetValue());
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700664}
665
666TEST(CommandSchema, ObjectPropType_Validate) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700667 ObjectPropType prop;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700668 prop.FromJson(CreateDictionaryValue(
669 "{'properties':{'expires':'integer',"
670 "'password':{'maxLength':100,'minLength':6}}}").get(), nullptr,
671 nullptr);
Alex Vakulenko5f472062014-08-14 17:54:04 -0700672 chromeos::ErrorPtr error;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700673 EXPECT_TRUE(prop.ValidateValue(CreateValue(
674 "{'expires':10,'password':'abcdef'}").get(), &error));
675 error.reset();
676
677 EXPECT_FALSE(prop.ValidateValue(CreateValue(
678 "{'expires':10}").get(), &error));
679 EXPECT_EQ("parameter_missing", error->GetCode());
680 error.reset();
681
682 EXPECT_FALSE(prop.ValidateValue(CreateValue(
683 "{'password':'abcdef'}").get(), &error));
684 EXPECT_EQ("parameter_missing", error->GetCode());
685 error.reset();
686
687 EXPECT_FALSE(prop.ValidateValue(CreateValue(
688 "{'expires':10,'password':'abcde'}").get(), &error));
689 EXPECT_EQ("out_of_range", error->GetFirstError()->GetCode());
690 error.reset();
691
692 EXPECT_FALSE(prop.ValidateValue(CreateValue("2").get(), &error));
693 EXPECT_EQ("type_mismatch", error->GetCode());
694 error.reset();
695
696 EXPECT_FALSE(prop.ValidateValue(CreateValue(
697 "{'expires':10,'password':'abcdef','retry':true}").get(), &error));
698 EXPECT_EQ("unexpected_parameter", error->GetCode());
699 error.reset();
700}
701
702TEST(CommandSchema, ObjectPropType_Validate_Enum) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700703 ObjectPropType prop;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700704 EXPECT_TRUE(prop.FromJson(CreateDictionaryValue(
705 "{'properties':{'width':'integer','height':'integer'},"
706 "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}").get(),
707 nullptr, nullptr));
Alex Vakulenko5f472062014-08-14 17:54:04 -0700708 chromeos::ErrorPtr error;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700709 EXPECT_TRUE(prop.ValidateValue(CreateValue(
710 "{'height':20,'width':10}").get(), &error));
711 error.reset();
712
713 EXPECT_TRUE(prop.ValidateValue(CreateValue(
714 "{'height':200,'width':100}").get(), &error));
715 error.reset();
716
717 EXPECT_FALSE(prop.ValidateValue(CreateValue(
718 "{'height':12,'width':10}").get(), &error));
719 EXPECT_EQ("out_of_range", error->GetCode());
720 error.reset();
721}
722
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700723TEST(CommandSchema, ObjectPropType_CreateValue) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700724 ObjectPropType prop;
725 IntPropType int_type;
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700726 ASSERT_TRUE(prop.FromJson(CreateDictionaryValue(
727 "{'properties':{'width':'integer','height':'integer'},"
728 "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}").get(),
729 nullptr, nullptr));
Vitaly Buka32005de2015-05-01 12:33:31 -0700730 native_types::Object obj{
731 {"width", int_type.CreateValue(10, nullptr)},
732 {"height", int_type.CreateValue(20, nullptr)},
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700733 };
734
735 chromeos::ErrorPtr error;
736 auto val = prop.CreateValue(obj, &error);
737 ASSERT_NE(nullptr, val.get());
738 EXPECT_EQ(nullptr, error.get());
Vitaly Buka32005de2015-05-01 12:33:31 -0700739 EXPECT_EQ(obj, val->GetValueAsAny().Get<native_types::Object>());
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700740
741 val = prop.CreateValue("blah", &error);
742 EXPECT_EQ(nullptr, val.get());
743 ASSERT_NE(nullptr, error.get());
Vitaly Buka32005de2015-05-01 12:33:31 -0700744 EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
Alex Vakulenko157ccaa2014-09-19 14:59:34 -0700745}
746
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700747///////////////////////////////////////////////////////////////////////////////
748
Alex Vakulenko29e64442015-03-20 13:59:19 -0700749TEST(CommandSchema, ArrayPropType_Empty) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700750 ArrayPropType prop;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700751 EXPECT_FALSE(prop.HasOverriddenAttributes());
752 EXPECT_FALSE(prop.IsBasedOnSchema());
753 EXPECT_EQ(nullptr, prop.GetDefaultValue());
754 EXPECT_EQ(nullptr, prop.GetItemTypePtr());
Vitaly Buka32005de2015-05-01 12:33:31 -0700755 prop.SetItemType(PropType::Create(ValueType::Int));
Alex Vakulenko29e64442015-03-20 13:59:19 -0700756 EXPECT_TRUE(prop.HasOverriddenAttributes());
757 EXPECT_FALSE(prop.IsBasedOnSchema());
758 EXPECT_NE(nullptr, prop.GetItemTypePtr());
759}
760
761TEST(CommandSchema, ArrayPropType_Types) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700762 ArrayPropType prop;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700763 EXPECT_EQ(nullptr, prop.GetInt());
764 EXPECT_EQ(nullptr, prop.GetBoolean());
765 EXPECT_EQ(nullptr, prop.GetDouble());
766 EXPECT_EQ(nullptr, prop.GetString());
767 EXPECT_EQ(nullptr, prop.GetObject());
768 EXPECT_EQ(&prop, prop.GetArray());
769}
770
771TEST(CommandSchema, ArrayPropType_ToJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700772 ArrayPropType prop;
773 prop.SetItemType(PropType::Create(ValueType::Int));
Vitaly Buka7c82d292015-05-03 18:08:12 -0700774 EXPECT_JSON_EQ("{'items':'integer'}", *prop.ToJson(false, nullptr));
775 EXPECT_JSON_EQ("{'items':{'type':'integer'},'type':'array'}",
776 *prop.ToJson(true, nullptr));
Alex Vakulenko29e64442015-03-20 13:59:19 -0700777 EXPECT_FALSE(prop.IsBasedOnSchema());
Vitaly Buka32005de2015-05-01 12:33:31 -0700778 ArrayPropType prop2;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700779 prop2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700780 EXPECT_JSON_EQ("{}", *prop2.ToJson(false, nullptr));
Alex Vakulenko29e64442015-03-20 13:59:19 -0700781 EXPECT_TRUE(prop2.IsBasedOnSchema());
782 prop2.FromJson(CreateDictionaryValue("{'default':[1,2,3]}").get(),
783 &prop, nullptr);
Vitaly Buka7c82d292015-05-03 18:08:12 -0700784 EXPECT_JSON_EQ("{'default':[1,2,3]}", *prop2.ToJson(false, nullptr));
785 EXPECT_JSON_EQ(
786 "{'default':[1,2,3],'items':{'type':'integer'},'type':'array'}",
787 *prop2.ToJson(true, nullptr));
Alex Vakulenko29e64442015-03-20 13:59:19 -0700788}
789
790TEST(CommandSchema, ArrayPropType_FromJson) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700791 ArrayPropType prop;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700792 EXPECT_TRUE(prop.FromJson(
793 CreateDictionaryValue("{'items':'integer'}").get(), nullptr, nullptr));
Vitaly Buka32005de2015-05-01 12:33:31 -0700794 EXPECT_EQ(ValueType::Int, prop.GetItemTypePtr()->GetType());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700795
Vitaly Buka32005de2015-05-01 12:33:31 -0700796 ArrayPropType prop2;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700797 ASSERT_TRUE(prop2.FromJson(CreateDictionaryValue(
798 "{'items':'string','default':['foo', 'bar', 'baz']}").get(), nullptr,
799 nullptr));
800 ASSERT_NE(nullptr, prop2.GetDefaultValue());
Vitaly Buka32005de2015-05-01 12:33:31 -0700801 const ArrayValue* defval = prop2.GetDefaultValue()->GetArray();
Alex Vakulenko29e64442015-03-20 13:59:19 -0700802 ASSERT_NE(nullptr, defval);
803 EXPECT_EQ((std::vector<std::string>{"foo", "bar", "baz"}),
804 GetArrayValues<std::string>(defval->GetValue()));
805}
806
807TEST(CommandSchema, ArrayPropType_Validate) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700808 ArrayPropType prop;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700809 prop.FromJson(CreateDictionaryValue(
810 "{'items':{'minimum':2.3, 'maximum':10.5}}").get(), nullptr,
811 nullptr);
812
813 chromeos::ErrorPtr error;
814 EXPECT_TRUE(prop.ValidateValue(CreateValue("[3,4,10.5]").get(), &error));
815 error.reset();
816
817 EXPECT_FALSE(prop.ValidateValue(CreateValue("[2]").get(), &error));
818 EXPECT_EQ("out_of_range", error->GetCode());
819 EXPECT_EQ("Value 2 is out of range. It must not be less than 2.3",
820 error->GetMessage());
821 error.reset();
822
823 EXPECT_FALSE(prop.ValidateValue(CreateValue("[4, 5, 20]").get(), &error));
824 EXPECT_EQ("out_of_range", error->GetCode());
825 EXPECT_EQ("Value 20 is out of range. It must not be greater than 10.5",
826 error->GetMessage());
827 error.reset();
828}
829
830TEST(CommandSchema, ArrayPropType_Validate_Enum) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700831 ArrayPropType prop;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700832 prop.FromJson(CreateDictionaryValue(
833 "{'items':'integer', 'enum':[[1], [2,3], [4,5,6]]}").get(), nullptr,
834 nullptr);
835
836 chromeos::ErrorPtr error;
837 EXPECT_TRUE(prop.ValidateValue(CreateValue("[2,3]").get(), &error));
838 error.reset();
839
840 EXPECT_FALSE(prop.ValidateValue(CreateValue("[2]").get(), &error));
841 EXPECT_EQ("out_of_range", error->GetCode());
842 EXPECT_EQ("Value [2] is invalid. Expected one of [[1],[2,3],[4,5,6]]",
843 error->GetMessage());
844 error.reset();
845
846 EXPECT_FALSE(prop.ValidateValue(CreateValue("[2,3,4]").get(), &error));
847 EXPECT_EQ("out_of_range", error->GetCode());
848 error.reset();
849}
850
851TEST(CommandSchema, ArrayPropType_CreateValue) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700852 ArrayPropType prop;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700853 ASSERT_TRUE(prop.FromJson(CreateDictionaryValue(
854 "{'items':{'properties':{'width':'integer','height':'integer'}}}").get(),
855 nullptr, nullptr));
856
857 chromeos::ErrorPtr error;
Vitaly Buka32005de2015-05-01 12:33:31 -0700858 native_types::Array arr;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700859
860 auto val = prop.CreateValue(arr, &error);
861 ASSERT_NE(nullptr, val.get());
862 EXPECT_EQ(nullptr, error.get());
Vitaly Buka32005de2015-05-01 12:33:31 -0700863 EXPECT_EQ(arr, val->GetValueAsAny().Get<native_types::Array>());
Vitaly Buka7c82d292015-05-03 18:08:12 -0700864 EXPECT_JSON_EQ("[]", *val->ToJson(nullptr));
Alex Vakulenko29e64442015-03-20 13:59:19 -0700865
Vitaly Buka32005de2015-05-01 12:33:31 -0700866 IntPropType int_type;
867 ObjectPropType obj_type;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700868 ASSERT_TRUE(obj_type.FromJson(CreateDictionaryValue(
869 "{'properties':{'width':'integer','height':'integer'}}").get(),
870 nullptr, nullptr));
Vitaly Buka32005de2015-05-01 12:33:31 -0700871 arr.push_back(obj_type.CreateValue(
872 native_types::Object{
873 {"width", int_type.CreateValue(10, nullptr)},
874 {"height", int_type.CreateValue(20, nullptr)},
875 },
876 nullptr));
877 arr.push_back(obj_type.CreateValue(
878 native_types::Object{
879 {"width", int_type.CreateValue(17, nullptr)},
880 {"height", int_type.CreateValue(18, nullptr)},
881 },
882 nullptr));
Alex Vakulenko29e64442015-03-20 13:59:19 -0700883
884 val = prop.CreateValue(arr, &error);
885 ASSERT_NE(nullptr, val.get());
886 EXPECT_EQ(nullptr, error.get());
Vitaly Buka32005de2015-05-01 12:33:31 -0700887 EXPECT_EQ(arr, val->GetValueAsAny().Get<native_types::Array>());
Vitaly Buka7c82d292015-05-03 18:08:12 -0700888 EXPECT_JSON_EQ("[{'height':20,'width':10},{'height':18,'width':17}]",
889 *val->ToJson(nullptr));
Alex Vakulenko29e64442015-03-20 13:59:19 -0700890
891 val = prop.CreateValue("blah", &error);
892 EXPECT_EQ(nullptr, val.get());
893 ASSERT_NE(nullptr, error.get());
Vitaly Buka32005de2015-05-01 12:33:31 -0700894 EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700895}
896
897TEST(CommandSchema, ArrayPropType_NestedArrays_NotSupported) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700898 ArrayPropType prop;
Alex Vakulenko29e64442015-03-20 13:59:19 -0700899 chromeos::ErrorPtr error;
900 EXPECT_FALSE(prop.FromJson(CreateDictionaryValue(
901 "{'items':{'items':'integer'}}").get(), nullptr, &error));
Vitaly Buka32005de2015-05-01 12:33:31 -0700902 EXPECT_EQ(errors::commands::kInvalidObjectSchema, error->GetCode());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700903 error.reset();
904}
905
906///////////////////////////////////////////////////////////////////////////////
907
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700908TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeName) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700909 ObjectSchema schema;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700910 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800911 "'param1':'integer',"
912 "'param2':'number',"
913 "'param3':'string'"
914 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700915 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
916 nullptr));
Vitaly Buka32005de2015-05-01 12:33:31 -0700917 EXPECT_EQ(ValueType::Int, schema.GetProp("param1")->GetType());
918 EXPECT_EQ(ValueType::Double, schema.GetProp("param2")->GetType());
919 EXPECT_EQ(ValueType::String, schema.GetProp("param3")->GetType());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700920 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
921 EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
922 EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
923 EXPECT_EQ(nullptr, schema.GetProp("param4"));
924
925 int min_int = (std::numeric_limits<int>::min)();
926 int max_int = (std::numeric_limits<int>::max)();
927 double min_dbl = (std::numeric_limits<double>::lowest)();
928 double max_dbl = (std::numeric_limits<double>::max)();
929 EXPECT_EQ(min_int, schema.GetProp("param1")->GetInt()->GetMinValue());
930 EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
931 EXPECT_EQ(min_dbl, schema.GetProp("param2")->GetDouble()->GetMinValue());
932 EXPECT_EQ(max_dbl, schema.GetProp("param2")->GetDouble()->GetMaxValue());
933 EXPECT_EQ(0, schema.GetProp("param3")->GetString()->GetMinLength());
934 EXPECT_EQ(max_int, schema.GetProp("param3")->GetString()->GetMaxLength());
935}
936
937TEST(CommandSchema, ObjectSchema_FromJson_Full_TypeName) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700938 ObjectSchema schema;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700939 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800940 "'param1':{'type':'integer'},"
941 "'param2':{'type':'number'},"
Alex Vakulenko29e64442015-03-20 13:59:19 -0700942 "'param3':{'type':'string'},"
943 "'param4':{'type':'array', 'items':'integer'},"
944 "'param5':{'type':'object', 'properties':{'p1':'integer'}}"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800945 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700946 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
947 nullptr));
Vitaly Buka32005de2015-05-01 12:33:31 -0700948 EXPECT_EQ(ValueType::Int, schema.GetProp("param1")->GetType());
949 EXPECT_EQ(ValueType::Double, schema.GetProp("param2")->GetType());
950 EXPECT_EQ(ValueType::String, schema.GetProp("param3")->GetType());
951 EXPECT_EQ(ValueType::Array, schema.GetProp("param4")->GetType());
952 EXPECT_EQ(ValueType::Object, schema.GetProp("param5")->GetType());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700953 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
954 EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
955 EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
Alex Vakulenko29e64442015-03-20 13:59:19 -0700956 EXPECT_EQ("array", schema.GetProp("param4")->GetTypeAsString());
957 EXPECT_EQ("object", schema.GetProp("param5")->GetTypeAsString());
958 EXPECT_EQ(nullptr, schema.GetProp("param77"));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700959
960 int min_int = (std::numeric_limits<int>::min)();
961 int max_int = (std::numeric_limits<int>::max)();
962 double min_dbl = (std::numeric_limits<double>::lowest)();
963 double max_dbl = (std::numeric_limits<double>::max)();
964 EXPECT_EQ(min_int, schema.GetProp("param1")->GetInt()->GetMinValue());
965 EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
966 EXPECT_EQ(min_dbl, schema.GetProp("param2")->GetDouble()->GetMinValue());
967 EXPECT_EQ(max_dbl, schema.GetProp("param2")->GetDouble()->GetMaxValue());
968 EXPECT_EQ(0, schema.GetProp("param3")->GetString()->GetMinLength());
969 EXPECT_EQ(max_int, schema.GetProp("param3")->GetString()->GetMaxLength());
970}
971
972TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeDeduction_Scalar) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700973 ObjectSchema schema;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700974 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800975 "'param1' :{'minimum':2},"
976 "'param2' :{'maximum':10},"
977 "'param3' :{'maximum':8, 'minimum':2},"
978 "'param4' :{'minimum':2.1},"
979 "'param5' :{'maximum':10.1},"
980 "'param6' :{'maximum':8.1, 'minimum':3.1},"
981 "'param7' :{'maximum':8, 'minimum':3.1},"
982 "'param8' :{'maximum':8.1, 'minimum':3},"
983 "'param9' :{'minLength':2},"
984 "'param10':{'maxLength':10},"
985 "'param11':{'maxLength':8, 'minLength':3},"
986 "'param12':{'default':12},"
987 "'param13':{'default':13.5},"
988 "'param14':{'default':true},"
989 "'param15':{'default':false},"
Alex Vakulenko29e64442015-03-20 13:59:19 -0700990 "'param16':{'default':'foobar'},"
991 "'param17':{'default':[1,2,3]},"
992 "'param18':{'items':'number', 'default':[]}"
Alex Vakulenko2a17a532015-02-24 14:51:13 -0800993 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700994 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
995 nullptr));
996 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
997 EXPECT_EQ("integer", schema.GetProp("param2")->GetTypeAsString());
998 EXPECT_EQ("integer", schema.GetProp("param3")->GetTypeAsString());
999 EXPECT_EQ("number", schema.GetProp("param4")->GetTypeAsString());
1000 EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
1001 EXPECT_EQ("number", schema.GetProp("param6")->GetTypeAsString());
1002 EXPECT_EQ("number", schema.GetProp("param7")->GetTypeAsString());
1003 EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
1004 EXPECT_EQ("string", schema.GetProp("param9")->GetTypeAsString());
1005 EXPECT_EQ("string", schema.GetProp("param10")->GetTypeAsString());
1006 EXPECT_EQ("string", schema.GetProp("param11")->GetTypeAsString());
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001007 EXPECT_EQ("integer", schema.GetProp("param12")->GetTypeAsString());
1008 EXPECT_EQ("number", schema.GetProp("param13")->GetTypeAsString());
1009 EXPECT_EQ("boolean", schema.GetProp("param14")->GetTypeAsString());
1010 EXPECT_EQ("boolean", schema.GetProp("param15")->GetTypeAsString());
1011 EXPECT_EQ("string", schema.GetProp("param16")->GetTypeAsString());
Alex Vakulenko29e64442015-03-20 13:59:19 -07001012 EXPECT_EQ("array", schema.GetProp("param17")->GetTypeAsString());
1013 auto prop17 = schema.GetProp("param17");
1014 EXPECT_EQ("integer",
1015 prop17->GetArray()->GetItemTypePtr()->GetTypeAsString());
1016 EXPECT_EQ("array", schema.GetProp("param18")->GetTypeAsString());
1017 auto prop18 = schema.GetProp("param18");
1018 EXPECT_EQ("number",
1019 prop18->GetArray()->GetItemTypePtr()->GetTypeAsString());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001020
1021 int min_int = (std::numeric_limits<int>::min)();
1022 int max_int = (std::numeric_limits<int>::max)();
1023 double min_dbl = (std::numeric_limits<double>::lowest)();
1024 double max_dbl = (std::numeric_limits<double>::max)();
1025 EXPECT_EQ(2, schema.GetProp("param1")->GetInt()->GetMinValue());
1026 EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
1027 EXPECT_EQ(min_int, schema.GetProp("param2")->GetInt()->GetMinValue());
1028 EXPECT_EQ(10, schema.GetProp("param2")->GetInt()->GetMaxValue());
1029 EXPECT_EQ(2, schema.GetProp("param3")->GetInt()->GetMinValue());
1030 EXPECT_EQ(8, schema.GetProp("param3")->GetInt()->GetMaxValue());
1031 EXPECT_DOUBLE_EQ(2.1, schema.GetProp("param4")->GetDouble()->GetMinValue());
1032 EXPECT_DOUBLE_EQ(max_dbl,
1033 schema.GetProp("param4")->GetDouble()->GetMaxValue());
1034 EXPECT_DOUBLE_EQ(min_dbl,
1035 schema.GetProp("param5")->GetDouble()->GetMinValue());
1036 EXPECT_DOUBLE_EQ(10.1, schema.GetProp("param5")->GetDouble()->GetMaxValue());
1037 EXPECT_DOUBLE_EQ(3.1, schema.GetProp("param6")->GetDouble()->GetMinValue());
1038 EXPECT_DOUBLE_EQ(8.1, schema.GetProp("param6")->GetDouble()->GetMaxValue());
1039 EXPECT_DOUBLE_EQ(3.1, schema.GetProp("param7")->GetDouble()->GetMinValue());
1040 EXPECT_DOUBLE_EQ(8.0, schema.GetProp("param7")->GetDouble()->GetMaxValue());
1041 EXPECT_DOUBLE_EQ(3.0, schema.GetProp("param8")->GetDouble()->GetMinValue());
1042 EXPECT_DOUBLE_EQ(8.1, schema.GetProp("param8")->GetDouble()->GetMaxValue());
1043 EXPECT_EQ(2, schema.GetProp("param9")->GetString()->GetMinLength());
1044 EXPECT_EQ(max_int, schema.GetProp("param9")->GetString()->GetMaxLength());
1045 EXPECT_EQ(0, schema.GetProp("param10")->GetString()->GetMinLength());
1046 EXPECT_EQ(10, schema.GetProp("param10")->GetString()->GetMaxLength());
1047 EXPECT_EQ(3, schema.GetProp("param11")->GetString()->GetMinLength());
1048 EXPECT_EQ(8, schema.GetProp("param11")->GetString()->GetMaxLength());
Vitaly Buka32005de2015-05-01 12:33:31 -07001049 const PropValue* val = schema.GetProp("param12")->GetDefaultValue();
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001050 EXPECT_EQ(12, val->GetInt()->GetValue());
1051 val = schema.GetProp("param13")->GetDefaultValue();
1052 EXPECT_DOUBLE_EQ(13.5, val->GetDouble()->GetValue());
1053 val = schema.GetProp("param14")->GetDefaultValue();
1054 EXPECT_TRUE(val->GetBoolean()->GetValue());
1055 val = schema.GetProp("param15")->GetDefaultValue();
1056 EXPECT_FALSE(val->GetBoolean()->GetValue());
1057 val = schema.GetProp("param16")->GetDefaultValue();
1058 EXPECT_EQ("foobar", val->GetString()->GetValue());
Alex Vakulenko29e64442015-03-20 13:59:19 -07001059 val = schema.GetProp("param17")->GetDefaultValue();
1060 EXPECT_EQ((std::vector<int>{1, 2, 3}),
1061 GetArrayValues<int>(val->GetArray()->GetValue()));
1062 val = schema.GetProp("param18")->GetDefaultValue();
1063 EXPECT_TRUE(val->GetArray()->GetValue().empty());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001064}
1065
1066TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeDeduction_Array) {
Vitaly Buka32005de2015-05-01 12:33:31 -07001067 ObjectSchema schema;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001068 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001069 "'param1' :[0,1,2,3],"
1070 "'param2' :[0.0,1.1,2.2],"
1071 "'param3' :['id1', 'id2'],"
1072 "'param4' :{'enum':[1,2,3]},"
1073 "'param5' :{'enum':[-1.1,2.2,3]},"
1074 "'param6' :{'enum':['id0', 'id1']},"
1075 "'param7' :{'type':'integer', 'enum':[1,2,3]},"
1076 "'param8' :{'type':'number', 'enum':[1,2,3]},"
1077 "'param9' :{'type':'number', 'enum':[]},"
Alex Vakulenko29e64442015-03-20 13:59:19 -07001078 "'param10':{'type':'integer', 'enum':[]},"
1079 "'param11':[[0,1],[2,3]],"
1080 "'param12':[['foo','bar']],"
1081 "'param13':{'enum':[['id0', 'id1']]}"
1082 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001083 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1084 nullptr));
1085 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
1086 EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
1087 EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
1088 EXPECT_EQ("integer", schema.GetProp("param4")->GetTypeAsString());
1089 EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
1090 EXPECT_EQ("string", schema.GetProp("param6")->GetTypeAsString());
1091 EXPECT_EQ("integer", schema.GetProp("param7")->GetTypeAsString());
1092 EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
1093 EXPECT_EQ("number", schema.GetProp("param9")->GetTypeAsString());
1094 EXPECT_EQ("integer", schema.GetProp("param10")->GetTypeAsString());
1095
Alex Vakulenko29e64442015-03-20 13:59:19 -07001096 auto prop_type11 = schema.GetProp("param11");
1097 EXPECT_EQ("array", prop_type11->GetTypeAsString());
1098 EXPECT_EQ("integer",
1099 prop_type11->GetArray()->GetItemTypePtr()->GetTypeAsString());
1100
1101 auto prop_type12 = schema.GetProp("param12");
1102 EXPECT_EQ("array", prop_type12->GetTypeAsString());
1103 EXPECT_EQ("string",
1104 prop_type12->GetArray()->GetItemTypePtr()->GetTypeAsString());
1105
1106 auto prop_type13 = schema.GetProp("param13");
1107 EXPECT_EQ("array", prop_type12->GetTypeAsString());
1108 EXPECT_EQ("string",
1109 prop_type13->GetArray()->GetItemTypePtr()->GetTypeAsString());
1110
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001111 EXPECT_EQ((std::vector<int>{0, 1, 2, 3}),
1112 GetOneOfValues<int>(schema.GetProp("param1")));
1113 EXPECT_EQ((std::vector<double>{0.0, 1.1, 2.2}),
1114 GetOneOfValues<double>(schema.GetProp("param2")));
1115 EXPECT_EQ((std::vector<std::string>{"id1", "id2"}),
1116 GetOneOfValues<std::string>(schema.GetProp("param3")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001117
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001118 EXPECT_EQ((std::vector<int>{1, 2, 3}),
1119 GetOneOfValues<int>(schema.GetProp("param4")));
1120 EXPECT_EQ((std::vector<double>{-1.1, 2.2, 3.0}),
1121 GetOneOfValues<double>(schema.GetProp("param5")));
1122 EXPECT_EQ((std::vector<std::string>{"id0", "id1"}),
1123 GetOneOfValues<std::string>(schema.GetProp("param6")));
1124 EXPECT_EQ((std::vector<int>{1, 2, 3}),
1125 GetOneOfValues<int>(schema.GetProp("param7")));
1126 EXPECT_EQ((std::vector<double>{1.0, 2.0, 3.0}),
1127 GetOneOfValues<double>(schema.GetProp("param8")));
1128 EXPECT_TRUE(GetOneOfValues<double>(schema.GetProp("param9")).empty());
1129 EXPECT_TRUE(GetOneOfValues<int>(schema.GetProp("param10")).empty());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001130}
1131
1132TEST(CommandSchema, ObjectSchema_FromJson_Inheritance) {
1133 const char* base_schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001134 "'param0' :{'minimum':1, 'maximum':5},"
1135 "'param1' :{'minimum':1, 'maximum':5},"
1136 "'param2' :{'minimum':1, 'maximum':5},"
1137 "'param3' :{'minimum':1, 'maximum':5},"
1138 "'param4' :{'minimum':1, 'maximum':5},"
1139 "'param5' :{'minimum':1.1, 'maximum':5.5},"
1140 "'param6' :{'minimum':1.1, 'maximum':5.5},"
1141 "'param7' :{'minimum':1.1, 'maximum':5.5},"
1142 "'param8' :{'minimum':1.1, 'maximum':5.5},"
1143 "'param9' :{'minLength':1, 'maxLength':5},"
1144 "'param10':{'minLength':1, 'maxLength':5},"
1145 "'param11':{'minLength':1, 'maxLength':5},"
1146 "'param12':{'minLength':1, 'maxLength':5},"
1147 "'param13':[1,2,3],"
1148 "'param14':[1,2,3],"
1149 "'param15':[1.1,2.2,3.3],"
1150 "'param16':[1.1,2.2,3.3],"
1151 "'param17':['id1', 'id2'],"
1152 "'param18':['id1', 'id2'],"
1153 "'param19':{'minimum':1, 'maximum':5},"
1154 "'param20':{'default':49},"
1155 "'param21':{'default':49},"
1156 "'param22':'integer'"
1157 "}";
Vitaly Buka32005de2015-05-01 12:33:31 -07001158 ObjectSchema base_schema;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001159 EXPECT_TRUE(base_schema.FromJson(CreateDictionaryValue(base_schema_str).get(),
1160 nullptr, nullptr));
1161 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001162 "'param1' :{},"
1163 "'param2' :{'minimum':2},"
1164 "'param3' :{'maximum':9},"
1165 "'param4' :{'minimum':2, 'maximum':9},"
1166 "'param5' :{},"
1167 "'param6' :{'minimum':2.2},"
1168 "'param7' :{'maximum':9.9},"
1169 "'param8' :{'minimum':2.2, 'maximum':9.9},"
1170 "'param9' :{},"
1171 "'param10':{'minLength':3},"
1172 "'param11':{'maxLength':8},"
1173 "'param12':{'minLength':3, 'maxLength':8},"
1174 "'param13':{},"
1175 "'param14':[1,2,3,4],"
1176 "'param15':{},"
1177 "'param16':[1.1,2.2,3.3,4.4],"
1178 "'param17':{},"
1179 "'param18':['id1', 'id3'],"
1180 "'param19':{},"
1181 "'param20':{},"
1182 "'param21':{'default':8},"
1183 "'param22':{'default':123}"
1184 "}";
Vitaly Buka32005de2015-05-01 12:33:31 -07001185 ObjectSchema schema;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001186 EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(),
1187 &base_schema, nullptr));
1188 EXPECT_EQ(nullptr, schema.GetProp("param0"));
1189 EXPECT_NE(nullptr, schema.GetProp("param1"));
1190 EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
1191 EXPECT_EQ(1, schema.GetProp("param1")->GetInt()->GetMinValue());
1192 EXPECT_EQ(5, schema.GetProp("param1")->GetInt()->GetMaxValue());
1193 EXPECT_EQ("integer", schema.GetProp("param2")->GetTypeAsString());
1194 EXPECT_EQ(2, schema.GetProp("param2")->GetInt()->GetMinValue());
1195 EXPECT_EQ(5, schema.GetProp("param2")->GetInt()->GetMaxValue());
1196 EXPECT_EQ("integer", schema.GetProp("param3")->GetTypeAsString());
1197 EXPECT_EQ(1, schema.GetProp("param3")->GetInt()->GetMinValue());
1198 EXPECT_EQ(9, schema.GetProp("param3")->GetInt()->GetMaxValue());
1199 EXPECT_EQ("integer", schema.GetProp("param4")->GetTypeAsString());
1200 EXPECT_EQ(2, schema.GetProp("param4")->GetInt()->GetMinValue());
1201 EXPECT_EQ(9, schema.GetProp("param4")->GetInt()->GetMaxValue());
1202 EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
1203 EXPECT_EQ(1.1, schema.GetProp("param5")->GetDouble()->GetMinValue());
1204 EXPECT_EQ(5.5, schema.GetProp("param5")->GetDouble()->GetMaxValue());
1205 EXPECT_EQ("number", schema.GetProp("param6")->GetTypeAsString());
1206 EXPECT_EQ(2.2, schema.GetProp("param6")->GetDouble()->GetMinValue());
1207 EXPECT_EQ(5.5, schema.GetProp("param6")->GetDouble()->GetMaxValue());
1208 EXPECT_EQ("number", schema.GetProp("param7")->GetTypeAsString());
1209 EXPECT_EQ(1.1, schema.GetProp("param7")->GetDouble()->GetMinValue());
1210 EXPECT_EQ(9.9, schema.GetProp("param7")->GetDouble()->GetMaxValue());
1211 EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
1212 EXPECT_EQ(2.2, schema.GetProp("param8")->GetDouble()->GetMinValue());
1213 EXPECT_EQ(9.9, schema.GetProp("param8")->GetDouble()->GetMaxValue());
1214 EXPECT_EQ("string", schema.GetProp("param9")->GetTypeAsString());
1215 EXPECT_EQ(1, schema.GetProp("param9")->GetString()->GetMinLength());
1216 EXPECT_EQ(5, schema.GetProp("param9")->GetString()->GetMaxLength());
1217 EXPECT_EQ("string", schema.GetProp("param10")->GetTypeAsString());
1218 EXPECT_EQ(3, schema.GetProp("param10")->GetString()->GetMinLength());
1219 EXPECT_EQ(5, schema.GetProp("param10")->GetString()->GetMaxLength());
1220 EXPECT_EQ("string", schema.GetProp("param11")->GetTypeAsString());
1221 EXPECT_EQ(1, schema.GetProp("param11")->GetString()->GetMinLength());
1222 EXPECT_EQ(8, schema.GetProp("param11")->GetString()->GetMaxLength());
1223 EXPECT_EQ("string", schema.GetProp("param12")->GetTypeAsString());
1224 EXPECT_EQ(3, schema.GetProp("param12")->GetString()->GetMinLength());
1225 EXPECT_EQ(8, schema.GetProp("param12")->GetString()->GetMaxLength());
1226 EXPECT_EQ("integer", schema.GetProp("param13")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001227 EXPECT_EQ((std::vector<int>{1, 2, 3}),
1228 GetOneOfValues<int>(schema.GetProp("param13")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001229 EXPECT_EQ("integer", schema.GetProp("param14")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001230 EXPECT_EQ((std::vector<int>{1, 2, 3, 4}),
1231 GetOneOfValues<int>(schema.GetProp("param14")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001232 EXPECT_EQ("number", schema.GetProp("param15")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001233 EXPECT_EQ((std::vector<double>{1.1, 2.2, 3.3}),
1234 GetOneOfValues<double>(schema.GetProp("param15")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001235 EXPECT_EQ("number", schema.GetProp("param16")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001236 EXPECT_EQ((std::vector<double>{1.1, 2.2, 3.3, 4.4}),
1237 GetOneOfValues<double>(schema.GetProp("param16")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001238 EXPECT_EQ("string", schema.GetProp("param17")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001239 EXPECT_EQ((std::vector<std::string>{"id1", "id2"}),
1240 GetOneOfValues<std::string>(schema.GetProp("param17")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001241 EXPECT_EQ("string", schema.GetProp("param18")->GetTypeAsString());
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07001242 EXPECT_EQ((std::vector<std::string>{"id1", "id3"}),
1243 GetOneOfValues<std::string>(schema.GetProp("param18")));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001244 EXPECT_EQ("integer", schema.GetProp("param19")->GetTypeAsString());
1245 EXPECT_EQ(1, schema.GetProp("param19")->GetInt()->GetMinValue());
1246 EXPECT_EQ(5, schema.GetProp("param19")->GetInt()->GetMaxValue());
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001247 EXPECT_EQ(49,
1248 schema.GetProp("param20")->GetDefaultValue()->GetInt()->GetValue());
1249 EXPECT_EQ(8,
1250 schema.GetProp("param21")->GetDefaultValue()->GetInt()->GetValue());
1251 EXPECT_EQ(123,
1252 schema.GetProp("param22")->GetDefaultValue()->GetInt()->GetValue());
1253}
1254
1255TEST(CommandSchema, ObjectSchema_UseDefaults) {
Vitaly Buka32005de2015-05-01 12:33:31 -07001256 ObjectPropType prop;
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001257 const char* schema_str = "{'properties':{"
1258 "'param1':{'default':true},"
1259 "'param2':{'default':2},"
1260 "'param3':{'default':3.3},"
1261 "'param4':{'default':'four'},"
1262 "'param5':{'default':{'x':5,'y':6},"
Alex Vakulenko29e64442015-03-20 13:59:19 -07001263 "'properties':{'x':'integer','y':'integer'}},"
1264 "'param6':{'default':[1,2,3]}"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001265 "}}";
1266 ASSERT_TRUE(prop.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1267 nullptr));
1268
1269 // Omit all.
1270 auto value = prop.CreateValue();
1271 ASSERT_TRUE(value->FromJson(CreateDictionaryValue("{}").get(), nullptr));
Vitaly Buka32005de2015-05-01 12:33:31 -07001272 native_types::Object obj = value->GetObject()->GetValue();
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001273 EXPECT_TRUE(obj["param1"]->GetBoolean()->GetValue());
1274 EXPECT_EQ(2, obj["param2"]->GetInt()->GetValue());
1275 EXPECT_DOUBLE_EQ(3.3, obj["param3"]->GetDouble()->GetValue());
1276 EXPECT_EQ("four", obj["param4"]->GetString()->GetValue());
Vitaly Buka32005de2015-05-01 12:33:31 -07001277 native_types::Object param5 = obj["param5"]->GetObject()->GetValue();
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001278 EXPECT_EQ(5, param5["x"]->GetInt()->GetValue());
1279 EXPECT_EQ(6, param5["y"]->GetInt()->GetValue());
Vitaly Buka32005de2015-05-01 12:33:31 -07001280 native_types::Array param6 = obj["param6"]->GetArray()->GetValue();
Alex Vakulenko29e64442015-03-20 13:59:19 -07001281 EXPECT_EQ((std::vector<int>{1, 2, 3}), GetArrayValues<int>(param6));
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001282
1283 // Specify some.
1284 value = prop.CreateValue();
1285 const char* val_json = "{"
1286 "'param1':false,"
1287 "'param3':33.3,"
1288 "'param5':{'x':-5,'y':-6}"
1289 "}";
1290 ASSERT_TRUE(value->FromJson(CreateDictionaryValue(val_json).get(), nullptr));
1291 obj = value->GetObject()->GetValue();
1292 EXPECT_FALSE(obj["param1"]->GetBoolean()->GetValue());
1293 EXPECT_EQ(2, obj["param2"]->GetInt()->GetValue());
1294 EXPECT_DOUBLE_EQ(33.3, obj["param3"]->GetDouble()->GetValue());
1295 EXPECT_EQ("four", obj["param4"]->GetString()->GetValue());
1296 param5 = obj["param5"]->GetObject()->GetValue();
1297 EXPECT_EQ(-5, param5["x"]->GetInt()->GetValue());
1298 EXPECT_EQ(-6, param5["y"]->GetInt()->GetValue());
Alex Vakulenko29e64442015-03-20 13:59:19 -07001299 param6 = obj["param6"]->GetArray()->GetValue();
1300 EXPECT_EQ((std::vector<int>{1, 2, 3}), GetArrayValues<int>(param6));
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001301
1302 // Specify all.
1303 value = prop.CreateValue();
1304 val_json = "{"
1305 "'param1':false,"
1306 "'param2':22,"
1307 "'param3':333.3,"
1308 "'param4':'FOUR',"
Alex Vakulenko29e64442015-03-20 13:59:19 -07001309 "'param5':{'x':-55,'y':66},"
1310 "'param6':[-1, 0]"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001311 "}";
1312 ASSERT_TRUE(value->FromJson(CreateDictionaryValue(val_json).get(), nullptr));
1313 obj = value->GetObject()->GetValue();
1314 EXPECT_FALSE(obj["param1"]->GetBoolean()->GetValue());
1315 EXPECT_EQ(22, obj["param2"]->GetInt()->GetValue());
1316 EXPECT_DOUBLE_EQ(333.3, obj["param3"]->GetDouble()->GetValue());
1317 EXPECT_EQ("FOUR", obj["param4"]->GetString()->GetValue());
1318 param5 = obj["param5"]->GetObject()->GetValue();
1319 EXPECT_EQ(-55, param5["x"]->GetInt()->GetValue());
1320 EXPECT_EQ(66, param5["y"]->GetInt()->GetValue());
Alex Vakulenko29e64442015-03-20 13:59:19 -07001321 param6 = obj["param6"]->GetArray()->GetValue();
1322 EXPECT_EQ((std::vector<int>{-1, 0}), GetArrayValues<int>(param6));
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001323}
1324
1325TEST(CommandSchema, ObjectSchema_FromJson_BaseSchema_Failures) {
Vitaly Buka32005de2015-05-01 12:33:31 -07001326 ObjectSchema schema;
Alex Vakulenko5f472062014-08-14 17:54:04 -07001327 chromeos::ErrorPtr error;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001328 const char* schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001329 "'param1':{}"
1330 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001331 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1332 &error));
1333 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1334 error.reset();
1335
1336 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001337 "'param1':{'type':'foo'}"
1338 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001339 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1340 &error));
1341 EXPECT_EQ("unknown_type", error->GetFirstError()->GetCode());
1342 error.reset();
1343
1344 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001345 "'param1':[]"
1346 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001347 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1348 &error));
1349 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1350 error.reset();
1351
1352 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001353 "'param1':{'minimum':'foo'}"
1354 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001355 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1356 &error));
1357 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1358 error.reset();
1359
1360 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001361 "'param1':[1,2.2]"
1362 "}";
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001363 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1364 &error));
1365 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1366 error.reset();
Alex Vakulenko5109b202014-06-20 14:49:41 -07001367
1368 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001369 "'param1':{'minimum':1, 'enum':[1,2,3]}" // can't have min/max & enum.
1370 "}";
Alex Vakulenko5109b202014-06-20 14:49:41 -07001371 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1372 &error));
1373 EXPECT_EQ("unexpected_parameter", error->GetFirstError()->GetCode());
1374 error.reset();
1375
1376 schema_str = "{"
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001377 "'param1':{'maximum':1, 'blah':2}" // 'blah' is unexpected.
1378 "}";
Alex Vakulenko5109b202014-06-20 14:49:41 -07001379 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1380 &error));
1381 EXPECT_EQ("unexpected_parameter", error->GetFirstError()->GetCode());
1382 error.reset();
Alex Vakulenko2a17a532015-02-24 14:51:13 -08001383
1384 schema_str = "{"
1385 "'param1':{'enum':[1,2,3],'default':5}" // 'default' must be 1, 2, or 3.
1386 "}";
1387 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1388 &error));
1389 EXPECT_EQ("out_of_range", error->GetFirstError()->GetCode());
1390 error.reset();
Alex Vakulenko29e64442015-03-20 13:59:19 -07001391
1392 schema_str = "{"
1393 "'param1':[[1,2.3]]"
1394 "}";
1395 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1396 &error));
1397 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1398 error.reset();
1399
1400 schema_str = "{"
1401 "'param1':[[1,2],[3,4],['blah']]"
1402 "}";
1403 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1404 &error));
1405 EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
1406 error.reset();
1407
1408 schema_str = "{"
1409 "'param1':{'default':[]}"
1410 "}";
1411 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1412 &error));
1413 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1414 error.reset();
1415
1416 schema_str = "{"
1417 "'param1':[[[1]],[[2]]]"
1418 "}";
1419 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1420 &error));
1421 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1422 error.reset();
1423
1424 schema_str = "{"
1425 "'param1':{'enum':[[['foo']]]}"
1426 "}";
1427 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1428 &error));
1429 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1430 error.reset();
1431
1432 schema_str = "{"
1433 "'param1':{'default':[[1],[2]]}"
1434 "}";
1435 EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
1436 &error));
1437 EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
1438 error.reset();
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001439}
Vitaly Buka32005de2015-05-01 12:33:31 -07001440
1441} // namespace buffet