Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / components / json_schema / json_schema_validator_unittest_base.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/json_schema/json_schema_validator_unittest_base.h"
6
7 #include <cfloat>
8 #include <cmath>
9 #include <limits>
10
11 #include "base/base_paths.h"
12 #include "base/files/file_util.h"
13 #include "base/json/json_file_value_serializer.h"
14 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/path_service.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/values.h"
19 #include "components/json_schema/json_schema_constants.h"
20 #include "components/json_schema/json_schema_validator.h"
21
22 namespace schema = json_schema_constants;
23
24 namespace {
25
26 #define TEST_SOURCE base::StringPrintf("%s:%i", __FILE__, __LINE__)
27
28 base::Value* LoadValue(const std::string& filename) {
29   base::FilePath path;
30   PathService::Get(base::DIR_SOURCE_ROOT, &path);
31   path = path.AppendASCII("components")
32              .AppendASCII("test")
33              .AppendASCII("data")
34              .AppendASCII("json_schema")
35              .AppendASCII(filename);
36   EXPECT_TRUE(base::PathExists(path));
37
38   std::string error_message;
39   JSONFileValueSerializer serializer(path);
40   base::Value* result = serializer.Deserialize(NULL, &error_message);
41   if (!result)
42     ADD_FAILURE() << "Could not parse JSON: " << error_message;
43   return result;
44 }
45
46 base::Value* LoadValue(const std::string& filename, base::Value::Type type) {
47   scoped_ptr<base::Value> result(LoadValue(filename));
48   if (!result.get())
49     return NULL;
50   if (!result->IsType(type)) {
51     ADD_FAILURE() << "Expected type " << type << ", got: " << result->GetType();
52     return NULL;
53   }
54   return result.release();
55 }
56
57 base::ListValue* LoadList(const std::string& filename) {
58   return static_cast<base::ListValue*>(
59       LoadValue(filename, base::Value::TYPE_LIST));
60 }
61
62 base::DictionaryValue* LoadDictionary(const std::string& filename) {
63   return static_cast<base::DictionaryValue*>(
64       LoadValue(filename, base::Value::TYPE_DICTIONARY));
65 }
66
67 }  // namespace
68
69
70 JSONSchemaValidatorTestBase::JSONSchemaValidatorTestBase() {
71 }
72
73 void JSONSchemaValidatorTestBase::RunTests() {
74   TestComplex();
75   TestStringPattern();
76   TestEnum();
77   TestChoices();
78   TestExtends();
79   TestObject();
80   TestTypeReference();
81   TestArrayTuple();
82   TestArrayNonTuple();
83   TestString();
84   TestNumber();
85   TestTypeClassifier();
86   TestTypes();
87 }
88
89 void JSONSchemaValidatorTestBase::TestComplex() {
90   scoped_ptr<base::DictionaryValue> schema(
91       LoadDictionary("complex_schema.json"));
92   scoped_ptr<base::ListValue> instance(LoadList("complex_instance.json"));
93
94   ASSERT_TRUE(schema.get());
95   ASSERT_TRUE(instance.get());
96
97   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
98   instance->Remove(instance->GetSize() - 1, NULL);
99   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
100   instance->Append(new base::DictionaryValue());
101   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
102                  JSONSchemaValidator::FormatErrorMessage(
103                      JSONSchemaValidator::kInvalidType,
104                      schema::kNumber,
105                      schema::kObject));
106   instance->Remove(instance->GetSize() - 1, NULL);
107
108   base::DictionaryValue* item = NULL;
109   ASSERT_TRUE(instance->GetDictionary(0, &item));
110   item->SetString("url", "xxxxxxxxxxx");
111
112   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
113                  "0.url",
114                  JSONSchemaValidator::FormatErrorMessage(
115                      JSONSchemaValidator::kStringMaxLength, "10"));
116 }
117
118 void JSONSchemaValidatorTestBase::TestStringPattern() {
119   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
120   schema->SetString(schema::kType, schema::kString);
121   schema->SetString(schema::kPattern, "foo+");
122
123   ExpectValid(TEST_SOURCE,
124               scoped_ptr<base::Value>(new base::StringValue("foo")).get(),
125               schema.get(), NULL);
126   ExpectValid(TEST_SOURCE,
127               scoped_ptr<base::Value>(new base::StringValue("foooooo")).get(),
128               schema.get(), NULL);
129   ExpectNotValid(TEST_SOURCE,
130                  scoped_ptr<base::Value>(new base::StringValue("bar")).get(),
131                  schema.get(),
132                  NULL,
133                  std::string(),
134                  JSONSchemaValidator::FormatErrorMessage(
135                      JSONSchemaValidator::kStringPattern, "foo+"));
136 }
137
138 void JSONSchemaValidatorTestBase::TestEnum() {
139   scoped_ptr<base::DictionaryValue> schema(LoadDictionary("enum_schema.json"));
140
141   ExpectValid(TEST_SOURCE,
142               scoped_ptr<base::Value>(new base::StringValue("foo")).get(),
143               schema.get(), NULL);
144   ExpectValid(TEST_SOURCE,
145               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
146               schema.get(), NULL);
147   ExpectValid(TEST_SOURCE,
148               scoped_ptr<base::Value>(new base::FundamentalValue(false)).get(),
149               schema.get(), NULL);
150
151   ExpectNotValid(TEST_SOURCE,
152                  scoped_ptr<base::Value>(new base::StringValue("42")).get(),
153                  schema.get(),
154                  NULL,
155                  std::string(),
156                  JSONSchemaValidator::kInvalidEnum);
157   ExpectNotValid(TEST_SOURCE,
158                  scoped_ptr<base::Value>(base::Value::CreateNullValue()).get(),
159                  schema.get(),
160                  NULL,
161                  std::string(),
162                  JSONSchemaValidator::kInvalidEnum);
163 }
164
165 void JSONSchemaValidatorTestBase::TestChoices() {
166   scoped_ptr<base::DictionaryValue> schema(
167       LoadDictionary("choices_schema.json"));
168
169   ExpectValid(TEST_SOURCE,
170               scoped_ptr<base::Value>(base::Value::CreateNullValue()).get(),
171               schema.get(), NULL);
172   ExpectValid(TEST_SOURCE,
173               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
174               schema.get(), NULL);
175
176   scoped_ptr<base::DictionaryValue> instance(new base::DictionaryValue());
177   instance->SetString("foo", "bar");
178   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
179
180   ExpectNotValid(TEST_SOURCE,
181                  scoped_ptr<base::Value>(new base::StringValue("foo")).get(),
182                  schema.get(),
183                  NULL,
184                  std::string(),
185                  JSONSchemaValidator::kInvalidChoice);
186   ExpectNotValid(TEST_SOURCE,
187                  scoped_ptr<base::Value>(new base::ListValue()).get(),
188                  schema.get(),
189                  NULL,
190                  std::string(),
191                  JSONSchemaValidator::kInvalidChoice);
192
193   instance->SetInteger("foo", 42);
194   ExpectNotValid(TEST_SOURCE,
195                  instance.get(),
196                  schema.get(),
197                  NULL,
198                  std::string(),
199                  JSONSchemaValidator::kInvalidChoice);
200 }
201
202 void JSONSchemaValidatorTestBase::TestExtends() {
203   // TODO(aa): JS only
204 }
205
206 void JSONSchemaValidatorTestBase::TestObject() {
207   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
208   schema->SetString(schema::kType, schema::kObject);
209   schema->SetString("properties.foo.type", schema::kString);
210   schema->SetString("properties.bar.type", schema::kInteger);
211
212   scoped_ptr<base::DictionaryValue> instance(new base::DictionaryValue());
213   instance->SetString("foo", "foo");
214   instance->SetInteger("bar", 42);
215
216   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
217
218   instance->SetBoolean("extra", true);
219   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
220                  "extra", JSONSchemaValidator::kUnexpectedProperty);
221   instance->Remove("extra", NULL);
222
223   instance->Remove("bar", NULL);
224   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "bar",
225                  JSONSchemaValidator::kObjectPropertyIsRequired);
226
227   instance->SetString("bar", "42");
228   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "bar",
229                  JSONSchemaValidator::FormatErrorMessage(
230                      JSONSchemaValidator::kInvalidType,
231                      schema::kInteger,
232                      schema::kString));
233   instance->SetInteger("bar", 42);
234
235   // Test "patternProperties".
236   instance->SetInteger("extra", 42);
237   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
238                  "extra", JSONSchemaValidator::kUnexpectedProperty);
239   schema->SetString("patternProperties.extra+.type",
240                     schema::kInteger);
241   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
242   instance->Remove("extra", NULL);
243   instance->SetInteger("extraaa", 42);
244   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
245   instance->Remove("extraaa", NULL);
246   instance->SetInteger("extr", 42);
247   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
248                  "extr", JSONSchemaValidator::kUnexpectedProperty);
249   instance->Remove("extr", NULL);
250   schema->Remove(schema::kPatternProperties, NULL);
251
252   // Test "patternProperties" and "properties" schemas are both checked if
253   // applicable.
254   schema->SetString("patternProperties.fo+.type", schema::kInteger);
255   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "foo",
256                  JSONSchemaValidator::FormatErrorMessage(
257                      JSONSchemaValidator::kInvalidType,
258                      schema::kInteger,
259                      schema::kString));
260   instance->SetInteger("foo", 123);
261   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "foo",
262                  JSONSchemaValidator::FormatErrorMessage(
263                      JSONSchemaValidator::kInvalidType,
264                      schema::kString,
265                      schema::kInteger));
266   instance->SetString("foo", "foo");
267   schema->Remove(schema::kPatternProperties, NULL);
268
269   // Test additional properties.
270   base::DictionaryValue* additional_properties = new base::DictionaryValue();
271   additional_properties->SetString(schema::kType, schema::kAny);
272   schema->Set(schema::kAdditionalProperties, additional_properties);
273
274   instance->SetBoolean("extra", true);
275   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
276
277   instance->SetString("extra", "foo");
278   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
279
280   additional_properties->SetString(schema::kType, schema::kBoolean);
281   instance->SetBoolean("extra", true);
282   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
283
284   instance->SetString("extra", "foo");
285   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
286                  "extra", JSONSchemaValidator::FormatErrorMessage(
287                      JSONSchemaValidator::kInvalidType,
288                      schema::kBoolean,
289                      schema::kString));
290   instance->Remove("extra", NULL);
291
292   base::DictionaryValue* properties = NULL;
293   base::DictionaryValue* bar_property = NULL;
294   ASSERT_TRUE(schema->GetDictionary(schema::kProperties, &properties));
295   ASSERT_TRUE(properties->GetDictionary("bar", &bar_property));
296
297   bar_property->SetBoolean(schema::kOptional, true);
298   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
299   instance->Remove("bar", NULL);
300   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
301   instance->Set("bar", base::Value::CreateNullValue());
302   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
303                  "bar", JSONSchemaValidator::FormatErrorMessage(
304                      JSONSchemaValidator::kInvalidType,
305                      schema::kInteger,
306                      schema::kNull));
307   instance->SetString("bar", "42");
308   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
309                  "bar", JSONSchemaValidator::FormatErrorMessage(
310                      JSONSchemaValidator::kInvalidType,
311                      schema::kInteger,
312                      schema::kString));
313
314   // Verify that JSON parser handles dot in "patternProperties" well.
315   schema.reset(LoadDictionary("pattern_properties_dot.json"));
316   ASSERT_TRUE(schema->GetDictionary(schema::kPatternProperties, &properties));
317   ASSERT_TRUE(properties->HasKey("^.$"));
318
319   instance.reset(new base::DictionaryValue());
320   instance->SetString("a", "whatever");
321   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
322   instance->SetString("foo", "bar");
323   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
324                  "foo", JSONSchemaValidator::kUnexpectedProperty);
325 }
326
327 void JSONSchemaValidatorTestBase::TestTypeReference() {
328   scoped_ptr<base::ListValue> types(LoadList("reference_types.json"));
329   ASSERT_TRUE(types.get());
330
331   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
332   schema->SetString(schema::kType, schema::kObject);
333   schema->SetString("properties.foo.type", schema::kString);
334   schema->SetString("properties.bar.$ref", "Max10Int");
335   schema->SetString("properties.baz.$ref", "MinLengthString");
336
337   scoped_ptr<base::DictionaryValue> schema_inline(new base::DictionaryValue());
338   schema_inline->SetString(schema::kType, schema::kObject);
339   schema_inline->SetString("properties.foo.type", schema::kString);
340   schema_inline->SetString("properties.bar.id", "NegativeInt");
341   schema_inline->SetString("properties.bar.type", schema::kInteger);
342   schema_inline->SetInteger("properties.bar.maximum", 0);
343   schema_inline->SetString("properties.baz.$ref", "NegativeInt");
344
345   scoped_ptr<base::DictionaryValue> instance(new base::DictionaryValue());
346   instance->SetString("foo", "foo");
347   instance->SetInteger("bar", 4);
348   instance->SetString("baz", "ab");
349
350   scoped_ptr<base::DictionaryValue> instance_inline(
351       new base::DictionaryValue());
352   instance_inline->SetString("foo", "foo");
353   instance_inline->SetInteger("bar", -4);
354   instance_inline->SetInteger("baz", -2);
355
356   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), types.get());
357   ExpectValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL);
358
359   // Validation failure, but successful schema reference.
360   instance->SetString("baz", "a");
361   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), types.get(),
362                  "baz", JSONSchemaValidator::FormatErrorMessage(
363                      JSONSchemaValidator::kStringMinLength, "2"));
364
365   instance_inline->SetInteger("bar", 20);
366   ExpectNotValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL,
367                  "bar", JSONSchemaValidator::FormatErrorMessage(
368                      JSONSchemaValidator::kNumberMaximum, "0"));
369
370   // Remove MinLengthString type.
371   types->Remove(types->GetSize() - 1, NULL);
372   instance->SetString("baz", "ab");
373   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), types.get(),
374                  "bar", JSONSchemaValidator::FormatErrorMessage(
375                      JSONSchemaValidator::kUnknownTypeReference,
376                      "Max10Int"));
377
378   // Remove internal type "NegativeInt".
379   schema_inline->Remove("properties.bar", NULL);
380   instance_inline->Remove("bar", NULL);
381   ExpectNotValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL,
382                  "baz", JSONSchemaValidator::FormatErrorMessage(
383                      JSONSchemaValidator::kUnknownTypeReference,
384                      "NegativeInt"));
385 }
386
387 void JSONSchemaValidatorTestBase::TestArrayTuple() {
388   scoped_ptr<base::DictionaryValue> schema(
389       LoadDictionary("array_tuple_schema.json"));
390   ASSERT_TRUE(schema.get());
391
392   scoped_ptr<base::ListValue> instance(new base::ListValue());
393   instance->Append(new base::StringValue("42"));
394   instance->Append(new base::FundamentalValue(42));
395
396   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
397
398   instance->Append(new base::StringValue("anything"));
399   ExpectNotValid(TEST_SOURCE,
400                  instance.get(),
401                  schema.get(),
402                  NULL,
403                  std::string(),
404                  JSONSchemaValidator::FormatErrorMessage(
405                      JSONSchemaValidator::kArrayMaxItems, "2"));
406
407   instance->Remove(1, NULL);
408   instance->Remove(1, NULL);
409   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
410                  JSONSchemaValidator::kArrayItemRequired);
411
412   instance->Set(0, new base::FundamentalValue(42));
413   instance->Append(new base::FundamentalValue(42));
414   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
415                  JSONSchemaValidator::FormatErrorMessage(
416                      JSONSchemaValidator::kInvalidType,
417                      schema::kString,
418                      schema::kInteger));
419
420   base::DictionaryValue* additional_properties = new base::DictionaryValue();
421   additional_properties->SetString(schema::kType, schema::kAny);
422   schema->Set(schema::kAdditionalProperties, additional_properties);
423   instance->Set(0, new base::StringValue("42"));
424   instance->Append(new base::StringValue("anything"));
425   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
426   instance->Set(2, new base::ListValue());
427   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
428
429   additional_properties->SetString(schema::kType, schema::kBoolean);
430   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "2",
431                  JSONSchemaValidator::FormatErrorMessage(
432                      JSONSchemaValidator::kInvalidType,
433                      schema::kBoolean,
434                      schema::kArray));
435   instance->Set(2, new base::FundamentalValue(false));
436   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
437
438   base::ListValue* items_schema = NULL;
439   base::DictionaryValue* item0_schema = NULL;
440   ASSERT_TRUE(schema->GetList(schema::kItems, &items_schema));
441   ASSERT_TRUE(items_schema->GetDictionary(0, &item0_schema));
442   item0_schema->SetBoolean(schema::kOptional, true);
443   instance->Remove(2, NULL);
444   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
445   // TODO(aa): I think this is inconsistent with the handling of NULL+optional
446   // for objects.
447   instance->Set(0, base::Value::CreateNullValue());
448   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
449   instance->Set(0, new base::FundamentalValue(42));
450   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
451                  JSONSchemaValidator::FormatErrorMessage(
452                      JSONSchemaValidator::kInvalidType,
453                      schema::kString,
454                      schema::kInteger));
455 }
456
457 void JSONSchemaValidatorTestBase::TestArrayNonTuple() {
458   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
459   schema->SetString(schema::kType, schema::kArray);
460   schema->SetString("items.type", schema::kString);
461   schema->SetInteger(schema::kMinItems, 2);
462   schema->SetInteger(schema::kMaxItems, 3);
463
464   scoped_ptr<base::ListValue> instance(new base::ListValue());
465   instance->Append(new base::StringValue("x"));
466   instance->Append(new base::StringValue("x"));
467
468   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
469   instance->Append(new base::StringValue("x"));
470   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
471
472   instance->Append(new base::StringValue("x"));
473   ExpectNotValid(TEST_SOURCE,
474                  instance.get(),
475                  schema.get(),
476                  NULL,
477                  std::string(),
478                  JSONSchemaValidator::FormatErrorMessage(
479                      JSONSchemaValidator::kArrayMaxItems, "3"));
480   instance->Remove(1, NULL);
481   instance->Remove(1, NULL);
482   instance->Remove(1, NULL);
483   ExpectNotValid(TEST_SOURCE,
484                  instance.get(),
485                  schema.get(),
486                  NULL,
487                  std::string(),
488                  JSONSchemaValidator::FormatErrorMessage(
489                      JSONSchemaValidator::kArrayMinItems, "2"));
490
491   instance->Remove(1, NULL);
492   instance->Append(new base::FundamentalValue(42));
493   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
494                  JSONSchemaValidator::FormatErrorMessage(
495                      JSONSchemaValidator::kInvalidType,
496                      schema::kString,
497                      schema::kInteger));
498 }
499
500 void JSONSchemaValidatorTestBase::TestString() {
501   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
502   schema->SetString(schema::kType, schema::kString);
503   schema->SetInteger(schema::kMinLength, 1);
504   schema->SetInteger(schema::kMaxLength, 10);
505
506   ExpectValid(TEST_SOURCE,
507               scoped_ptr<base::Value>(new base::StringValue("x")).get(),
508               schema.get(), NULL);
509   ExpectValid(TEST_SOURCE,
510               scoped_ptr<base::Value>(
511                   new base::StringValue("xxxxxxxxxx")).get(),
512               schema.get(), NULL);
513
514   ExpectNotValid(
515       TEST_SOURCE,
516       scoped_ptr<base::Value>(new base::StringValue(std::string())).get(),
517       schema.get(),
518       NULL,
519       std::string(),
520       JSONSchemaValidator::FormatErrorMessage(
521           JSONSchemaValidator::kStringMinLength, "1"));
522   ExpectNotValid(
523       TEST_SOURCE,
524       scoped_ptr<base::Value>(new base::StringValue("xxxxxxxxxxx")).get(),
525       schema.get(),
526       NULL,
527       std::string(),
528       JSONSchemaValidator::FormatErrorMessage(
529           JSONSchemaValidator::kStringMaxLength, "10"));
530 }
531
532 void JSONSchemaValidatorTestBase::TestNumber() {
533   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
534   schema->SetString(schema::kType, schema::kNumber);
535   schema->SetInteger(schema::kMinimum, 1);
536   schema->SetInteger(schema::kMaximum, 100);
537   schema->SetInteger("maxDecimal", 2);
538
539   ExpectValid(TEST_SOURCE,
540               scoped_ptr<base::Value>(new base::FundamentalValue(1)).get(),
541               schema.get(), NULL);
542   ExpectValid(TEST_SOURCE,
543               scoped_ptr<base::Value>(new base::FundamentalValue(50)).get(),
544               schema.get(), NULL);
545   ExpectValid(TEST_SOURCE,
546               scoped_ptr<base::Value>(new base::FundamentalValue(100)).get(),
547               schema.get(), NULL);
548   ExpectValid(TEST_SOURCE,
549               scoped_ptr<base::Value>(new base::FundamentalValue(88.88)).get(),
550               schema.get(), NULL);
551
552   ExpectNotValid(TEST_SOURCE,
553                  scoped_ptr<base::Value>(new base::FundamentalValue(0.5)).get(),
554                  schema.get(),
555                  NULL,
556                  std::string(),
557                  JSONSchemaValidator::FormatErrorMessage(
558                      JSONSchemaValidator::kNumberMinimum, "1"));
559   ExpectNotValid(
560       TEST_SOURCE,
561       scoped_ptr<base::Value>(new base::FundamentalValue(100.1)).get(),
562       schema.get(),
563       NULL,
564       std::string(),
565       JSONSchemaValidator::FormatErrorMessage(
566           JSONSchemaValidator::kNumberMaximum, "100"));
567 }
568
569 void JSONSchemaValidatorTestBase::TestTypeClassifier() {
570   EXPECT_EQ(std::string(schema::kBoolean),
571             JSONSchemaValidator::GetJSONSchemaType(
572                 scoped_ptr<base::Value>(
573                     new base::FundamentalValue(true)).get()));
574   EXPECT_EQ(std::string(schema::kBoolean),
575             JSONSchemaValidator::GetJSONSchemaType(
576                 scoped_ptr<base::Value>(
577                     new base::FundamentalValue(false)).get()));
578
579   // It doesn't matter whether the C++ type is 'integer' or 'real'. If the
580   // number is integral and within the representable range of integers in
581   // double, it's classified as 'integer'.
582   EXPECT_EQ(std::string(schema::kInteger),
583             JSONSchemaValidator::GetJSONSchemaType(
584                 scoped_ptr<base::Value>(new base::FundamentalValue(42)).get()));
585   EXPECT_EQ(std::string(schema::kInteger),
586             JSONSchemaValidator::GetJSONSchemaType(
587                 scoped_ptr<base::Value>(new base::FundamentalValue(0)).get()));
588   EXPECT_EQ(std::string(schema::kInteger),
589             JSONSchemaValidator::GetJSONSchemaType(
590                 scoped_ptr<base::Value>(new base::FundamentalValue(42)).get()));
591   EXPECT_EQ(std::string(schema::kInteger),
592             JSONSchemaValidator::GetJSONSchemaType(scoped_ptr<base::Value>(
593                 new base::FundamentalValue(pow(2.0, DBL_MANT_DIG))).get()));
594   EXPECT_EQ(std::string(schema::kInteger),
595             JSONSchemaValidator::GetJSONSchemaType(scoped_ptr<base::Value>(
596                 new base::FundamentalValue(pow(-2.0, DBL_MANT_DIG))).get()));
597
598   // "number" is only used for non-integral numbers, or numbers beyond what
599   // double can accurately represent.
600   EXPECT_EQ(std::string(schema::kNumber),
601             JSONSchemaValidator::GetJSONSchemaType(
602                 scoped_ptr<base::Value>(
603                     new base::FundamentalValue(88.8)).get()));
604   EXPECT_EQ(std::string(schema::kNumber),
605             JSONSchemaValidator::GetJSONSchemaType(scoped_ptr<base::Value>(
606                 new base::FundamentalValue(pow(2.0, DBL_MANT_DIG) * 2)).get()));
607   EXPECT_EQ(std::string(schema::kNumber),
608             JSONSchemaValidator::GetJSONSchemaType(scoped_ptr<base::Value>(
609                 new base::FundamentalValue(
610                     pow(-2.0, DBL_MANT_DIG) * 2)).get()));
611
612   EXPECT_EQ(std::string(schema::kString),
613             JSONSchemaValidator::GetJSONSchemaType(
614                 scoped_ptr<base::Value>(new base::StringValue("foo")).get()));
615   EXPECT_EQ(std::string(schema::kArray),
616             JSONSchemaValidator::GetJSONSchemaType(
617                 scoped_ptr<base::Value>(new base::ListValue()).get()));
618   EXPECT_EQ(std::string(schema::kObject),
619             JSONSchemaValidator::GetJSONSchemaType(
620                 scoped_ptr<base::Value>(new base::DictionaryValue()).get()));
621   EXPECT_EQ(std::string(schema::kNull),
622             JSONSchemaValidator::GetJSONSchemaType(
623                 scoped_ptr<base::Value>(base::Value::CreateNullValue()).get()));
624 }
625
626 void JSONSchemaValidatorTestBase::TestTypes() {
627   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
628
629   // valid
630   schema->SetString(schema::kType, schema::kObject);
631   ExpectValid(TEST_SOURCE,
632               scoped_ptr<base::Value>(new base::DictionaryValue()).get(),
633               schema.get(), NULL);
634
635   schema->SetString(schema::kType, schema::kArray);
636   ExpectValid(TEST_SOURCE, scoped_ptr<base::Value>(new base::ListValue()).get(),
637               schema.get(), NULL);
638
639   schema->SetString(schema::kType, schema::kString);
640   ExpectValid(TEST_SOURCE,
641               scoped_ptr<base::Value>(new base::StringValue("foobar")).get(),
642               schema.get(), NULL);
643
644   schema->SetString(schema::kType, schema::kNumber);
645   ExpectValid(TEST_SOURCE,
646               scoped_ptr<base::Value>(new base::FundamentalValue(88.8)).get(),
647               schema.get(), NULL);
648   ExpectValid(TEST_SOURCE,
649               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
650               schema.get(), NULL);
651   ExpectValid(TEST_SOURCE,
652               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
653               schema.get(), NULL);
654   ExpectValid(TEST_SOURCE,
655               scoped_ptr<base::Value>(new base::FundamentalValue(0)).get(),
656               schema.get(), NULL);
657
658   schema->SetString(schema::kType, schema::kInteger);
659   ExpectValid(TEST_SOURCE,
660               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
661               schema.get(), NULL);
662   ExpectValid(TEST_SOURCE,
663               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
664               schema.get(), NULL);
665   ExpectValid(TEST_SOURCE,
666               scoped_ptr<base::Value>(new base::FundamentalValue(0)).get(),
667               schema.get(), NULL);
668   ExpectValid(TEST_SOURCE,
669               scoped_ptr<base::Value>(
670                   new base::FundamentalValue(pow(2.0, DBL_MANT_DIG))).get(),
671               schema.get(), NULL);
672   ExpectValid(TEST_SOURCE,
673               scoped_ptr<base::Value>(
674                   new base::FundamentalValue(pow(-2.0, DBL_MANT_DIG))).get(),
675               schema.get(), NULL);
676
677   schema->SetString(schema::kType, schema::kBoolean);
678   ExpectValid(TEST_SOURCE,
679               scoped_ptr<base::Value>(new base::FundamentalValue(false)).get(),
680               schema.get(), NULL);
681   ExpectValid(TEST_SOURCE,
682               scoped_ptr<base::Value>(new base::FundamentalValue(true)).get(),
683               schema.get(), NULL);
684
685   schema->SetString(schema::kType, schema::kNull);
686   ExpectValid(TEST_SOURCE,
687               scoped_ptr<base::Value>(base::Value::CreateNullValue()).get(),
688               schema.get(), NULL);
689
690   // not valid
691   schema->SetString(schema::kType, schema::kObject);
692   ExpectNotValid(
693       TEST_SOURCE,
694       scoped_ptr<base::Value>(new base::ListValue()).get(),
695       schema.get(),
696       NULL,
697       std::string(),
698       JSONSchemaValidator::FormatErrorMessage(
699           JSONSchemaValidator::kInvalidType, schema::kObject, schema::kArray));
700
701   schema->SetString(schema::kType, schema::kObject);
702   ExpectNotValid(
703       TEST_SOURCE,
704       scoped_ptr<base::Value>(base::Value::CreateNullValue()).get(),
705       schema.get(),
706       NULL,
707       std::string(),
708       JSONSchemaValidator::FormatErrorMessage(
709           JSONSchemaValidator::kInvalidType, schema::kObject, schema::kNull));
710
711   schema->SetString(schema::kType, schema::kArray);
712   ExpectNotValid(
713       TEST_SOURCE,
714       scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
715       schema.get(),
716       NULL,
717       std::string(),
718       JSONSchemaValidator::FormatErrorMessage(
719           JSONSchemaValidator::kInvalidType, schema::kArray, schema::kInteger));
720
721   schema->SetString(schema::kType, schema::kString);
722   ExpectNotValid(
723       TEST_SOURCE,
724       scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
725       schema.get(),
726       NULL,
727       std::string(),
728       JSONSchemaValidator::FormatErrorMessage(JSONSchemaValidator::kInvalidType,
729                                               schema::kString,
730                                               schema::kInteger));
731
732   schema->SetString(schema::kType, schema::kNumber);
733   ExpectNotValid(
734       TEST_SOURCE,
735       scoped_ptr<base::Value>(new base::StringValue("42")).get(),
736       schema.get(),
737       NULL,
738       std::string(),
739       JSONSchemaValidator::FormatErrorMessage(
740           JSONSchemaValidator::kInvalidType, schema::kNumber, schema::kString));
741
742   schema->SetString(schema::kType, schema::kInteger);
743   ExpectNotValid(
744       TEST_SOURCE,
745       scoped_ptr<base::Value>(new base::FundamentalValue(88.8)).get(),
746       schema.get(),
747       NULL,
748       std::string(),
749       JSONSchemaValidator::kInvalidTypeIntegerNumber);
750
751   schema->SetString(schema::kType, schema::kBoolean);
752   ExpectNotValid(
753       TEST_SOURCE,
754       scoped_ptr<base::Value>(new base::FundamentalValue(1)).get(),
755       schema.get(),
756       NULL,
757       std::string(),
758       JSONSchemaValidator::FormatErrorMessage(JSONSchemaValidator::kInvalidType,
759                                               schema::kBoolean,
760                                               schema::kInteger));
761
762   schema->SetString(schema::kType, schema::kNull);
763   ExpectNotValid(
764       TEST_SOURCE,
765       scoped_ptr<base::Value>(new base::FundamentalValue(false)).get(),
766       schema.get(),
767       NULL,
768       std::string(),
769       JSONSchemaValidator::FormatErrorMessage(
770           JSONSchemaValidator::kInvalidType, schema::kNull, schema::kBoolean));
771 }