• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "chrome/common/json_schema_validator_unittest_base.h"
6 
7 #include <cfloat>
8 #include <cmath>
9 #include <limits>
10 
11 #include "base/file_util.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/path_service.h"
15 #include "base/stringprintf.h"
16 #include "base/values.h"
17 #include "chrome/common/chrome_paths.h"
18 #include "chrome/common/json_schema_validator.h"
19 #include "content/common/json_value_serializer.h"
20 
21 namespace {
22 
23 #define TEST_SOURCE base::StringPrintf("%s:%i", __FILE__, __LINE__)
24 
LoadValue(const std::string & filename)25 Value* LoadValue(const std::string& filename) {
26   FilePath path;
27   PathService::Get(chrome::DIR_TEST_DATA, &path);
28   path = path.AppendASCII("json_schema_validator").AppendASCII(filename);
29   EXPECT_TRUE(file_util::PathExists(path));
30 
31   std::string error_message;
32   JSONFileValueSerializer serializer(path);
33   Value* result = serializer.Deserialize(NULL, &error_message);
34   if (!result)
35     ADD_FAILURE() << "Could not parse JSON: " << error_message;
36   return result;
37 }
38 
LoadValue(const std::string & filename,Value::ValueType type)39 Value* LoadValue(const std::string& filename, Value::ValueType type) {
40   scoped_ptr<Value> result(LoadValue(filename));
41   if (!result.get())
42     return NULL;
43   if (!result->IsType(type)) {
44     ADD_FAILURE() << "Expected type " << type << ", got: " << result->GetType();
45     return NULL;
46   }
47   return result.release();
48 }
49 
LoadList(const std::string & filename)50 ListValue* LoadList(const std::string& filename) {
51   return static_cast<ListValue*>(
52       LoadValue(filename, Value::TYPE_LIST));
53 }
54 
LoadDictionary(const std::string & filename)55 DictionaryValue* LoadDictionary(const std::string& filename) {
56   return static_cast<DictionaryValue*>(
57       LoadValue(filename, Value::TYPE_DICTIONARY));
58 }
59 
60 }  // namespace
61 
62 
JSONSchemaValidatorTestBase(JSONSchemaValidatorTestBase::ValidatorType type)63 JSONSchemaValidatorTestBase::JSONSchemaValidatorTestBase(
64     JSONSchemaValidatorTestBase::ValidatorType type)
65     : type_(type) {
66 }
67 
RunTests()68 void JSONSchemaValidatorTestBase::RunTests() {
69   TestComplex();
70   TestStringPattern();
71   TestEnum();
72   TestChoices();
73   TestExtends();
74   TestObject();
75   TestTypeReference();
76   TestArrayTuple();
77   TestArrayNonTuple();
78   TestString();
79   TestNumber();
80   TestTypeClassifier();
81   TestTypes();
82 }
83 
TestComplex()84 void JSONSchemaValidatorTestBase::TestComplex() {
85   scoped_ptr<DictionaryValue> schema(LoadDictionary("complex_schema.json"));
86   scoped_ptr<ListValue> instance(LoadList("complex_instance.json"));
87 
88   ASSERT_TRUE(schema.get());
89   ASSERT_TRUE(instance.get());
90 
91   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
92   instance->Remove(instance->GetSize() - 1, NULL);
93   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
94   instance->Append(new DictionaryValue());
95   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
96                  JSONSchemaValidator::FormatErrorMessage(
97                      JSONSchemaValidator::kInvalidType, "number", "object"));
98   instance->Remove(instance->GetSize() - 1, NULL);
99 
100   DictionaryValue* item = NULL;
101   ASSERT_TRUE(instance->GetDictionary(0, &item));
102   item->SetString("url", "xxxxxxxxxxx");
103 
104   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
105                  "0.url",
106                  JSONSchemaValidator::FormatErrorMessage(
107                      JSONSchemaValidator::kStringMaxLength, "10"));
108 }
109 
TestStringPattern()110 void JSONSchemaValidatorTestBase::TestStringPattern() {
111   // Regex patterns not supported in CPP validator.
112   if (type_ == CPP)
113     return;
114 
115   scoped_ptr<DictionaryValue> schema(new DictionaryValue());
116   schema->SetString("type", "string");
117   schema->SetString("pattern", "foo+");
118 
119   ExpectValid(TEST_SOURCE,
120               scoped_ptr<Value>(Value::CreateStringValue("foo")).get(),
121               schema.get(), NULL);
122   ExpectValid(TEST_SOURCE,
123               scoped_ptr<Value>(Value::CreateStringValue("foooooo")).get(),
124               schema.get(), NULL);
125   ExpectNotValid(TEST_SOURCE,
126                  scoped_ptr<Value>(Value::CreateStringValue("bar")).get(),
127                  schema.get(), NULL, "",
128                  JSONSchemaValidator::FormatErrorMessage(
129                      JSONSchemaValidator::kStringPattern, "foo+"));
130 }
131 
TestEnum()132 void JSONSchemaValidatorTestBase::TestEnum() {
133   scoped_ptr<DictionaryValue> schema(LoadDictionary("enum_schema.json"));
134 
135   ExpectValid(TEST_SOURCE,
136               scoped_ptr<Value>(Value::CreateStringValue("foo")).get(),
137               schema.get(), NULL);
138   ExpectValid(TEST_SOURCE,
139               scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
140               schema.get(), NULL);
141   ExpectValid(TEST_SOURCE,
142               scoped_ptr<Value>(Value::CreateBooleanValue(false)).get(),
143               schema.get(), NULL);
144 
145   ExpectNotValid(TEST_SOURCE,
146                  scoped_ptr<Value>(Value::CreateStringValue("42")).get(),
147                  schema.get(), NULL, "", JSONSchemaValidator::kInvalidEnum);
148   ExpectNotValid(TEST_SOURCE,
149                  scoped_ptr<Value>(Value::CreateNullValue()).get(),
150                  schema.get(), NULL, "", JSONSchemaValidator::kInvalidEnum);
151 }
152 
TestChoices()153 void JSONSchemaValidatorTestBase::TestChoices() {
154   scoped_ptr<DictionaryValue> schema(LoadDictionary("choices_schema.json"));
155 
156   ExpectValid(TEST_SOURCE,
157               scoped_ptr<Value>(Value::CreateNullValue()).get(),
158               schema.get(), NULL);
159   ExpectValid(TEST_SOURCE,
160               scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
161               schema.get(), NULL);
162 
163   scoped_ptr<DictionaryValue> instance(new DictionaryValue());
164   instance->SetString("foo", "bar");
165   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
166 
167   ExpectNotValid(TEST_SOURCE,
168                  scoped_ptr<Value>(Value::CreateStringValue("foo")).get(),
169                  schema.get(), NULL, "", JSONSchemaValidator::kInvalidChoice);
170   ExpectNotValid(TEST_SOURCE,
171                  scoped_ptr<Value>(new ListValue()).get(),
172                  schema.get(), NULL, "", JSONSchemaValidator::kInvalidChoice);
173 
174   instance->SetInteger("foo", 42);
175   ExpectNotValid(TEST_SOURCE, instance.get(),
176                  schema.get(), NULL, "", JSONSchemaValidator::kInvalidChoice);
177 }
178 
TestExtends()179 void JSONSchemaValidatorTestBase::TestExtends() {
180   // TODO(aa): JS only
181 }
182 
TestObject()183 void JSONSchemaValidatorTestBase::TestObject() {
184   scoped_ptr<DictionaryValue> schema(new DictionaryValue());
185   schema->SetString("type", "object");
186   schema->SetString("properties.foo.type", "string");
187   schema->SetString("properties.bar.type", "integer");
188 
189   scoped_ptr<DictionaryValue> instance(new DictionaryValue());
190   instance->SetString("foo", "foo");
191   instance->SetInteger("bar", 42);
192 
193   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
194 
195   instance->SetBoolean("extra", true);
196   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
197                  "extra", JSONSchemaValidator::kUnexpectedProperty);
198 
199   instance->Remove("extra", NULL);
200   instance->Remove("bar", NULL);
201   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "bar",
202                  JSONSchemaValidator::kObjectPropertyIsRequired);
203 
204   instance->SetString("bar", "42");
205   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "bar",
206                  JSONSchemaValidator::FormatErrorMessage(
207                      JSONSchemaValidator::kInvalidType, "integer", "string"));
208 
209   DictionaryValue* additional_properties = new DictionaryValue();
210   additional_properties->SetString("type", "any");
211   schema->Set("additionalProperties", additional_properties);
212 
213   instance->SetInteger("bar", 42);
214   instance->SetBoolean("extra", true);
215   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
216 
217   instance->SetString("extra", "foo");
218   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
219 
220   additional_properties->SetString("type", "boolean");
221   instance->SetBoolean("extra", true);
222   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
223 
224   instance->SetString("extra", "foo");
225   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
226                  "extra", JSONSchemaValidator::FormatErrorMessage(
227                      JSONSchemaValidator::kInvalidType, "boolean", "string"));
228 
229   DictionaryValue* properties = NULL;
230   DictionaryValue* bar_property = NULL;
231   ASSERT_TRUE(schema->GetDictionary("properties", &properties));
232   ASSERT_TRUE(properties->GetDictionary("bar", &bar_property));
233 
234   bar_property->SetBoolean("optional", true);
235   instance->Remove("extra", NULL);
236   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
237   instance->Remove("bar", NULL);
238   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
239   instance->Set("bar", Value::CreateNullValue());
240   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
241                  "bar", JSONSchemaValidator::FormatErrorMessage(
242                      JSONSchemaValidator::kInvalidType, "integer", "null"));
243   instance->SetString("bar", "42");
244   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
245                  "bar", JSONSchemaValidator::FormatErrorMessage(
246                      JSONSchemaValidator::kInvalidType, "integer", "string"));
247 }
248 
TestTypeReference()249 void JSONSchemaValidatorTestBase::TestTypeReference() {
250   scoped_ptr<ListValue> types(LoadList("reference_types.json"));
251   ASSERT_TRUE(types.get());
252 
253   scoped_ptr<DictionaryValue> schema(new DictionaryValue());
254   schema->SetString("type", "object");
255   schema->SetString("properties.foo.type", "string");
256   schema->SetString("properties.bar.$ref", "Max10Int");
257   schema->SetString("properties.baz.$ref", "MinLengthString");
258 
259   scoped_ptr<DictionaryValue> schema_inline(new DictionaryValue());
260   schema_inline->SetString("type", "object");
261   schema_inline->SetString("properties.foo.type", "string");
262   schema_inline->SetString("properties.bar.id", "NegativeInt");
263   schema_inline->SetString("properties.bar.type", "integer");
264   schema_inline->SetInteger("properties.bar.maximum", 0);
265   schema_inline->SetString("properties.baz.$ref", "NegativeInt");
266 
267   scoped_ptr<DictionaryValue> instance(new DictionaryValue());
268   instance->SetString("foo", "foo");
269   instance->SetInteger("bar", 4);
270   instance->SetString("baz", "ab");
271 
272   scoped_ptr<DictionaryValue> instance_inline(new DictionaryValue());
273   instance_inline->SetString("foo", "foo");
274   instance_inline->SetInteger("bar", -4);
275   instance_inline->SetInteger("baz", -2);
276 
277   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), types.get());
278   ExpectValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL);
279 
280   // Validation failure, but successful schema reference.
281   instance->SetString("baz", "a");
282   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), types.get(),
283                  "baz", JSONSchemaValidator::FormatErrorMessage(
284                      JSONSchemaValidator::kStringMinLength, "2"));
285 
286   instance_inline->SetInteger("bar", 20);
287   ExpectNotValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL,
288                  "bar", JSONSchemaValidator::FormatErrorMessage(
289                      JSONSchemaValidator::kNumberMaximum, "0"));
290 
291   // Remove MinLengthString type.
292   types->Remove(types->GetSize() - 1, NULL);
293   instance->SetString("baz", "ab");
294   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), types.get(),
295                  "bar", JSONSchemaValidator::FormatErrorMessage(
296                      JSONSchemaValidator::kUnknownTypeReference,
297                      "Max10Int"));
298 
299   // Remove internal type "NegativeInt".
300   schema_inline->Remove("properties.bar", NULL);
301   instance_inline->Remove("bar", NULL);
302   ExpectNotValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL,
303                  "baz", JSONSchemaValidator::FormatErrorMessage(
304                      JSONSchemaValidator::kUnknownTypeReference,
305                      "NegativeInt"));
306 }
307 
TestArrayTuple()308 void JSONSchemaValidatorTestBase::TestArrayTuple() {
309   scoped_ptr<DictionaryValue> schema(LoadDictionary("array_tuple_schema.json"));
310   ASSERT_TRUE(schema.get());
311 
312   scoped_ptr<ListValue> instance(new ListValue());
313   instance->Append(Value::CreateStringValue("42"));
314   instance->Append(Value::CreateIntegerValue(42));
315 
316   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
317 
318   instance->Append(Value::CreateStringValue("anything"));
319   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "",
320                  JSONSchemaValidator::FormatErrorMessage(
321                      JSONSchemaValidator::kArrayMaxItems, "2"));
322 
323   instance->Remove(1, NULL);
324   instance->Remove(1, NULL);
325   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
326                  JSONSchemaValidator::kArrayItemRequired);
327 
328   instance->Set(0, Value::CreateIntegerValue(42));
329   instance->Append(Value::CreateIntegerValue(42));
330   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
331                  JSONSchemaValidator::FormatErrorMessage(
332                      JSONSchemaValidator::kInvalidType, "string", "integer"));
333 
334   DictionaryValue* additional_properties = new DictionaryValue();
335   additional_properties->SetString("type", "any");
336   schema->Set("additionalProperties", additional_properties);
337   instance->Set(0, Value::CreateStringValue("42"));
338   instance->Append(Value::CreateStringValue("anything"));
339   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
340   instance->Set(2, new ListValue());
341   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
342 
343   additional_properties->SetString("type", "boolean");
344   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "2",
345                  JSONSchemaValidator::FormatErrorMessage(
346                      JSONSchemaValidator::kInvalidType, "boolean", "array"));
347   instance->Set(2, Value::CreateBooleanValue(false));
348   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
349 
350   ListValue* items_schema = NULL;
351   DictionaryValue* item0_schema = NULL;
352   ASSERT_TRUE(schema->GetList("items", &items_schema));
353   ASSERT_TRUE(items_schema->GetDictionary(0, &item0_schema));
354   item0_schema->SetBoolean("optional", true);
355   instance->Remove(2, NULL);
356   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
357   // TODO(aa): I think this is inconsistent with the handling of NULL+optional
358   // for objects.
359   instance->Set(0, Value::CreateNullValue());
360   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
361   instance->Set(0, Value::CreateIntegerValue(42));
362   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
363                  JSONSchemaValidator::FormatErrorMessage(
364                      JSONSchemaValidator::kInvalidType, "string", "integer"));
365 }
366 
TestArrayNonTuple()367 void JSONSchemaValidatorTestBase::TestArrayNonTuple() {
368   scoped_ptr<DictionaryValue> schema(new DictionaryValue());
369   schema->SetString("type", "array");
370   schema->SetString("items.type", "string");
371   schema->SetInteger("minItems", 2);
372   schema->SetInteger("maxItems", 3);
373 
374   scoped_ptr<ListValue> instance(new ListValue());
375   instance->Append(Value::CreateStringValue("x"));
376   instance->Append(Value::CreateStringValue("x"));
377 
378   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
379   instance->Append(Value::CreateStringValue("x"));
380   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
381 
382   instance->Append(Value::CreateStringValue("x"));
383   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "",
384                  JSONSchemaValidator::FormatErrorMessage(
385                      JSONSchemaValidator::kArrayMaxItems, "3"));
386   instance->Remove(1, NULL);
387   instance->Remove(1, NULL);
388   instance->Remove(1, NULL);
389   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "",
390                  JSONSchemaValidator::FormatErrorMessage(
391                      JSONSchemaValidator::kArrayMinItems, "2"));
392 
393   instance->Remove(1, NULL);
394   instance->Append(Value::CreateIntegerValue(42));
395   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
396                  JSONSchemaValidator::FormatErrorMessage(
397                      JSONSchemaValidator::kInvalidType, "string", "integer"));
398 }
399 
TestString()400 void JSONSchemaValidatorTestBase::TestString() {
401   scoped_ptr<DictionaryValue> schema(new DictionaryValue());
402   schema->SetString("type", "string");
403   schema->SetInteger("minLength", 1);
404   schema->SetInteger("maxLength", 10);
405 
406   ExpectValid(TEST_SOURCE,
407               scoped_ptr<Value>(Value::CreateStringValue("x")).get(),
408               schema.get(), NULL);
409   ExpectValid(TEST_SOURCE,
410               scoped_ptr<Value>(Value::CreateStringValue("xxxxxxxxxx")).get(),
411               schema.get(), NULL);
412 
413   ExpectNotValid(TEST_SOURCE,
414                  scoped_ptr<Value>(Value::CreateStringValue("")).get(),
415                  schema.get(), NULL, "",
416                  JSONSchemaValidator::FormatErrorMessage(
417                      JSONSchemaValidator::kStringMinLength, "1"));
418   ExpectNotValid(
419       TEST_SOURCE,
420       scoped_ptr<Value>(Value::CreateStringValue("xxxxxxxxxxx")).get(),
421       schema.get(), NULL, "",
422       JSONSchemaValidator::FormatErrorMessage(
423           JSONSchemaValidator::kStringMaxLength, "10"));
424 
425 }
426 
TestNumber()427 void JSONSchemaValidatorTestBase::TestNumber() {
428   scoped_ptr<DictionaryValue> schema(new DictionaryValue());
429   schema->SetString("type", "number");
430   schema->SetInteger("minimum", 1);
431   schema->SetInteger("maximum", 100);
432   schema->SetInteger("maxDecimal", 2);
433 
434   ExpectValid(TEST_SOURCE,
435               scoped_ptr<Value>(Value::CreateIntegerValue(1)).get(),
436               schema.get(), NULL);
437   ExpectValid(TEST_SOURCE,
438               scoped_ptr<Value>(Value::CreateIntegerValue(50)).get(),
439               schema.get(), NULL);
440   ExpectValid(TEST_SOURCE,
441               scoped_ptr<Value>(Value::CreateIntegerValue(100)).get(),
442               schema.get(), NULL);
443   ExpectValid(TEST_SOURCE,
444               scoped_ptr<Value>(Value::CreateDoubleValue(88.88)).get(),
445               schema.get(), NULL);
446 
447   ExpectNotValid(
448       TEST_SOURCE,
449       scoped_ptr<Value>(Value::CreateDoubleValue(0.5)).get(),
450       schema.get(), NULL, "",
451       JSONSchemaValidator::FormatErrorMessage(
452           JSONSchemaValidator::kNumberMinimum, "1"));
453   ExpectNotValid(
454       TEST_SOURCE,
455       scoped_ptr<Value>(Value::CreateDoubleValue(100.1)).get(),
456       schema.get(), NULL, "",
457       JSONSchemaValidator::FormatErrorMessage(
458           JSONSchemaValidator::kNumberMaximum, "100"));
459 }
460 
TestTypeClassifier()461 void JSONSchemaValidatorTestBase::TestTypeClassifier() {
462   EXPECT_EQ("boolean", JSONSchemaValidator::GetJSONSchemaType(
463       scoped_ptr<Value>(Value::CreateBooleanValue(true)).get()));
464   EXPECT_EQ("boolean", JSONSchemaValidator::GetJSONSchemaType(
465       scoped_ptr<Value>(Value::CreateBooleanValue(false)).get()));
466 
467   // It doesn't matter whether the C++ type is 'integer' or 'real'. If the
468   // number is integral and within the representable range of integers in
469   // double, it's classified as 'integer'.
470   EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType(
471       scoped_ptr<Value>(Value::CreateIntegerValue(42)).get()));
472   EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType(
473       scoped_ptr<Value>(Value::CreateIntegerValue(0)).get()));
474   EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType(
475       scoped_ptr<Value>(Value::CreateDoubleValue(42)).get()));
476   EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType(
477       scoped_ptr<Value>(
478           Value::CreateDoubleValue(pow(2.0, DBL_MANT_DIG))).get()));
479   EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType(
480       scoped_ptr<Value>(
481           Value::CreateDoubleValue(pow(-2.0, DBL_MANT_DIG))).get()));
482 
483   // "number" is only used for non-integral numbers, or numbers beyond what
484   // double can accurately represent.
485   EXPECT_EQ("number", JSONSchemaValidator::GetJSONSchemaType(
486       scoped_ptr<Value>(Value::CreateDoubleValue(88.8)).get()));
487   EXPECT_EQ("number", JSONSchemaValidator::GetJSONSchemaType(
488       scoped_ptr<Value>(Value::CreateDoubleValue(
489           pow(2.0, DBL_MANT_DIG) * 2)).get()));
490   EXPECT_EQ("number", JSONSchemaValidator::GetJSONSchemaType(
491       scoped_ptr<Value>(Value::CreateDoubleValue(
492           pow(-2.0, DBL_MANT_DIG) * 2)).get()));
493 
494   EXPECT_EQ("string", JSONSchemaValidator::GetJSONSchemaType(
495       scoped_ptr<Value>(Value::CreateStringValue("foo")).get()));
496   EXPECT_EQ("array", JSONSchemaValidator::GetJSONSchemaType(
497       scoped_ptr<Value>(new ListValue()).get()));
498   EXPECT_EQ("object", JSONSchemaValidator::GetJSONSchemaType(
499       scoped_ptr<Value>(new DictionaryValue()).get()));
500   EXPECT_EQ("null", JSONSchemaValidator::GetJSONSchemaType(
501       scoped_ptr<Value>(Value::CreateNullValue()).get()));
502 }
503 
TestTypes()504 void JSONSchemaValidatorTestBase::TestTypes() {
505   scoped_ptr<DictionaryValue> schema(new DictionaryValue());
506 
507   // valid
508   schema->SetString("type", "object");
509   ExpectValid(TEST_SOURCE, scoped_ptr<Value>(new DictionaryValue()).get(),
510               schema.get(), NULL);
511 
512   schema->SetString("type", "array");
513   ExpectValid(TEST_SOURCE, scoped_ptr<Value>(new ListValue()).get(),
514               schema.get(), NULL);
515 
516   schema->SetString("type", "string");
517   ExpectValid(TEST_SOURCE,
518               scoped_ptr<Value>(Value::CreateStringValue("foobar")).get(),
519               schema.get(), NULL);
520 
521   schema->SetString("type", "number");
522   ExpectValid(TEST_SOURCE,
523               scoped_ptr<Value>(Value::CreateDoubleValue(88.8)).get(),
524               schema.get(), NULL);
525   ExpectValid(TEST_SOURCE,
526               scoped_ptr<Value>(Value::CreateDoubleValue(42)).get(),
527               schema.get(), NULL);
528   ExpectValid(TEST_SOURCE,
529               scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
530               schema.get(), NULL);
531   ExpectValid(TEST_SOURCE,
532               scoped_ptr<Value>(Value::CreateIntegerValue(0)).get(),
533               schema.get(), NULL);
534 
535   schema->SetString("type", "integer");
536   ExpectValid(TEST_SOURCE,
537               scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
538               schema.get(), NULL);
539   ExpectValid(TEST_SOURCE,
540               scoped_ptr<Value>(Value::CreateDoubleValue(42)).get(),
541               schema.get(), NULL);
542   ExpectValid(TEST_SOURCE,
543               scoped_ptr<Value>(Value::CreateIntegerValue(0)).get(),
544               schema.get(), NULL);
545   ExpectValid(TEST_SOURCE,
546               scoped_ptr<Value>(
547                   Value::CreateDoubleValue(pow(2.0, DBL_MANT_DIG))).get(),
548               schema.get(), NULL);
549   ExpectValid(TEST_SOURCE,
550               scoped_ptr<Value>(
551                   Value::CreateDoubleValue(pow(-2.0, DBL_MANT_DIG))).get(),
552               schema.get(), NULL);
553 
554   schema->SetString("type", "boolean");
555   ExpectValid(TEST_SOURCE,
556               scoped_ptr<Value>(Value::CreateBooleanValue(false)).get(),
557               schema.get(), NULL);
558   ExpectValid(TEST_SOURCE,
559               scoped_ptr<Value>(Value::CreateBooleanValue(true)).get(),
560               schema.get(), NULL);
561 
562   schema->SetString("type", "null");
563   ExpectValid(TEST_SOURCE,
564               scoped_ptr<Value>(Value::CreateNullValue()).get(),
565               schema.get(), NULL);
566 
567   // not valid
568   schema->SetString("type", "object");
569   ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(new ListValue()).get(),
570                  schema.get(), NULL, "",
571                  JSONSchemaValidator::FormatErrorMessage(
572                      JSONSchemaValidator::kInvalidType, "object", "array"));
573 
574   schema->SetString("type", "object");
575   ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateNullValue()).get(),
576                  schema.get(), NULL, "",
577                  JSONSchemaValidator::FormatErrorMessage(
578                      JSONSchemaValidator::kInvalidType, "object", "null"));
579 
580   schema->SetString("type", "array");
581   ExpectNotValid(TEST_SOURCE,
582                  scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
583                  schema.get(), NULL, "",
584                  JSONSchemaValidator::FormatErrorMessage(
585                      JSONSchemaValidator::kInvalidType, "array", "integer"));
586 
587   schema->SetString("type", "string");
588   ExpectNotValid(TEST_SOURCE,
589                  scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
590                  schema.get(), NULL, "",
591                  JSONSchemaValidator::FormatErrorMessage(
592                      JSONSchemaValidator::kInvalidType, "string", "integer"));
593 
594   schema->SetString("type", "number");
595   ExpectNotValid(TEST_SOURCE,
596                  scoped_ptr<Value>(Value::CreateStringValue("42")).get(),
597                  schema.get(), NULL, "",
598                  JSONSchemaValidator::FormatErrorMessage(
599                      JSONSchemaValidator::kInvalidType, "number", "string"));
600 
601   schema->SetString("type", "integer");
602   ExpectNotValid(TEST_SOURCE,
603                  scoped_ptr<Value>(Value::CreateDoubleValue(88.8)).get(),
604                  schema.get(), NULL, "",
605                  JSONSchemaValidator::FormatErrorMessage(
606                      JSONSchemaValidator::kInvalidType, "integer", "number"));
607 
608   schema->SetString("type", "integer");
609   ExpectNotValid(TEST_SOURCE,
610                  scoped_ptr<Value>(Value::CreateDoubleValue(88.8)).get(),
611                  schema.get(), NULL, "",
612                  JSONSchemaValidator::FormatErrorMessage(
613                      JSONSchemaValidator::kInvalidType, "integer", "number"));
614 
615   schema->SetString("type", "boolean");
616   ExpectNotValid(TEST_SOURCE,
617                  scoped_ptr<Value>(Value::CreateIntegerValue(1)).get(),
618                  schema.get(), NULL, "",
619                  JSONSchemaValidator::FormatErrorMessage(
620                      JSONSchemaValidator::kInvalidType, "boolean", "integer"));
621 
622   schema->SetString("type", "null");
623   ExpectNotValid(TEST_SOURCE,
624                  scoped_ptr<Value>(Value::CreateBooleanValue(false)).get(),
625                  schema.get(), NULL, "",
626                  JSONSchemaValidator::FormatErrorMessage(
627                      JSONSchemaValidator::kInvalidType, "null", "boolean"));
628 }
629