- add sources.
[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/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     JSONSchemaValidatorTestBase::ValidatorType type)
72     : type_(type) {
73 }
74
75 void JSONSchemaValidatorTestBase::RunTests() {
76   TestComplex();
77   TestStringPattern();
78   TestEnum();
79   TestChoices();
80   TestExtends();
81   TestObject();
82   TestTypeReference();
83   TestArrayTuple();
84   TestArrayNonTuple();
85   TestString();
86   TestNumber();
87   TestTypeClassifier();
88   TestTypes();
89 }
90
91 void JSONSchemaValidatorTestBase::TestComplex() {
92   scoped_ptr<base::DictionaryValue> schema(
93       LoadDictionary("complex_schema.json"));
94   scoped_ptr<base::ListValue> instance(LoadList("complex_instance.json"));
95
96   ASSERT_TRUE(schema.get());
97   ASSERT_TRUE(instance.get());
98
99   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
100   instance->Remove(instance->GetSize() - 1, NULL);
101   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
102   instance->Append(new base::DictionaryValue());
103   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
104                  JSONSchemaValidator::FormatErrorMessage(
105                      JSONSchemaValidator::kInvalidType,
106                      schema::kNumber,
107                      schema::kObject));
108   instance->Remove(instance->GetSize() - 1, NULL);
109
110   base::DictionaryValue* item = NULL;
111   ASSERT_TRUE(instance->GetDictionary(0, &item));
112   item->SetString("url", "xxxxxxxxxxx");
113
114   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
115                  "0.url",
116                  JSONSchemaValidator::FormatErrorMessage(
117                      JSONSchemaValidator::kStringMaxLength, "10"));
118 }
119
120 void JSONSchemaValidatorTestBase::TestStringPattern() {
121   // Regex patterns not supported in CPP validator.
122   if (type_ == CPP)
123     return;
124
125   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
126   schema->SetString(schema::kType, schema::kString);
127   schema->SetString(schema::kPattern, "foo+");
128
129   ExpectValid(TEST_SOURCE,
130               scoped_ptr<base::Value>(new base::StringValue("foo")).get(),
131               schema.get(), NULL);
132   ExpectValid(TEST_SOURCE,
133               scoped_ptr<base::Value>(new base::StringValue("foooooo")).get(),
134               schema.get(), NULL);
135   ExpectNotValid(TEST_SOURCE,
136                  scoped_ptr<base::Value>(new base::StringValue("bar")).get(),
137                  schema.get(),
138                  NULL,
139                  std::string(),
140                  JSONSchemaValidator::FormatErrorMessage(
141                      JSONSchemaValidator::kStringPattern, "foo+"));
142 }
143
144 void JSONSchemaValidatorTestBase::TestEnum() {
145   scoped_ptr<base::DictionaryValue> schema(LoadDictionary("enum_schema.json"));
146
147   ExpectValid(TEST_SOURCE,
148               scoped_ptr<base::Value>(new base::StringValue("foo")).get(),
149               schema.get(), NULL);
150   ExpectValid(TEST_SOURCE,
151               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
152               schema.get(), NULL);
153   ExpectValid(TEST_SOURCE,
154               scoped_ptr<base::Value>(new base::FundamentalValue(false)).get(),
155               schema.get(), NULL);
156
157   ExpectNotValid(TEST_SOURCE,
158                  scoped_ptr<base::Value>(new base::StringValue("42")).get(),
159                  schema.get(),
160                  NULL,
161                  std::string(),
162                  JSONSchemaValidator::kInvalidEnum);
163   ExpectNotValid(TEST_SOURCE,
164                  scoped_ptr<base::Value>(base::Value::CreateNullValue()).get(),
165                  schema.get(),
166                  NULL,
167                  std::string(),
168                  JSONSchemaValidator::kInvalidEnum);
169 }
170
171 void JSONSchemaValidatorTestBase::TestChoices() {
172   scoped_ptr<base::DictionaryValue> schema(
173       LoadDictionary("choices_schema.json"));
174
175   ExpectValid(TEST_SOURCE,
176               scoped_ptr<base::Value>(base::Value::CreateNullValue()).get(),
177               schema.get(), NULL);
178   ExpectValid(TEST_SOURCE,
179               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
180               schema.get(), NULL);
181
182   scoped_ptr<base::DictionaryValue> instance(new base::DictionaryValue());
183   instance->SetString("foo", "bar");
184   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
185
186   ExpectNotValid(TEST_SOURCE,
187                  scoped_ptr<base::Value>(new base::StringValue("foo")).get(),
188                  schema.get(),
189                  NULL,
190                  std::string(),
191                  JSONSchemaValidator::kInvalidChoice);
192   ExpectNotValid(TEST_SOURCE,
193                  scoped_ptr<base::Value>(new base::ListValue()).get(),
194                  schema.get(),
195                  NULL,
196                  std::string(),
197                  JSONSchemaValidator::kInvalidChoice);
198
199   instance->SetInteger("foo", 42);
200   ExpectNotValid(TEST_SOURCE,
201                  instance.get(),
202                  schema.get(),
203                  NULL,
204                  std::string(),
205                  JSONSchemaValidator::kInvalidChoice);
206 }
207
208 void JSONSchemaValidatorTestBase::TestExtends() {
209   // TODO(aa): JS only
210 }
211
212 void JSONSchemaValidatorTestBase::TestObject() {
213   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
214   schema->SetString(schema::kType, schema::kObject);
215   schema->SetString("properties.foo.type", schema::kString);
216   schema->SetString("properties.bar.type", schema::kInteger);
217
218   scoped_ptr<base::DictionaryValue> instance(new base::DictionaryValue());
219   instance->SetString("foo", "foo");
220   instance->SetInteger("bar", 42);
221
222   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
223
224   instance->SetBoolean("extra", true);
225   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
226                  "extra", JSONSchemaValidator::kUnexpectedProperty);
227
228   instance->Remove("extra", NULL);
229   instance->Remove("bar", NULL);
230   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "bar",
231                  JSONSchemaValidator::kObjectPropertyIsRequired);
232
233   instance->SetString("bar", "42");
234   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "bar",
235                  JSONSchemaValidator::FormatErrorMessage(
236                      JSONSchemaValidator::kInvalidType,
237                      schema::kInteger,
238                      schema::kString));
239
240   base::DictionaryValue* additional_properties = new base::DictionaryValue();
241   additional_properties->SetString(schema::kType, schema::kAny);
242   schema->Set(schema::kAdditionalProperties, additional_properties);
243
244   instance->SetInteger("bar", 42);
245   instance->SetBoolean("extra", true);
246   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
247
248   instance->SetString("extra", "foo");
249   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
250
251   additional_properties->SetString(schema::kType, schema::kBoolean);
252   instance->SetBoolean("extra", true);
253   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
254
255   instance->SetString("extra", "foo");
256   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
257                  "extra", JSONSchemaValidator::FormatErrorMessage(
258                      JSONSchemaValidator::kInvalidType,
259                      schema::kBoolean,
260                      schema::kString));
261
262   base::DictionaryValue* properties = NULL;
263   base::DictionaryValue* bar_property = NULL;
264   ASSERT_TRUE(schema->GetDictionary(schema::kProperties, &properties));
265   ASSERT_TRUE(properties->GetDictionary("bar", &bar_property));
266
267   bar_property->SetBoolean(schema::kOptional, true);
268   instance->Remove("extra", NULL);
269   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
270   instance->Remove("bar", NULL);
271   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
272   instance->Set("bar", base::Value::CreateNullValue());
273   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
274                  "bar", JSONSchemaValidator::FormatErrorMessage(
275                      JSONSchemaValidator::kInvalidType,
276                      schema::kInteger,
277                      schema::kNull));
278   instance->SetString("bar", "42");
279   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
280                  "bar", JSONSchemaValidator::FormatErrorMessage(
281                      JSONSchemaValidator::kInvalidType,
282                      schema::kInteger,
283                      schema::kString));
284 }
285
286 void JSONSchemaValidatorTestBase::TestTypeReference() {
287   scoped_ptr<base::ListValue> types(LoadList("reference_types.json"));
288   ASSERT_TRUE(types.get());
289
290   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
291   schema->SetString(schema::kType, schema::kObject);
292   schema->SetString("properties.foo.type", schema::kString);
293   schema->SetString("properties.bar.$ref", "Max10Int");
294   schema->SetString("properties.baz.$ref", "MinLengthString");
295
296   scoped_ptr<base::DictionaryValue> schema_inline(new base::DictionaryValue());
297   schema_inline->SetString(schema::kType, schema::kObject);
298   schema_inline->SetString("properties.foo.type", schema::kString);
299   schema_inline->SetString("properties.bar.id", "NegativeInt");
300   schema_inline->SetString("properties.bar.type", schema::kInteger);
301   schema_inline->SetInteger("properties.bar.maximum", 0);
302   schema_inline->SetString("properties.baz.$ref", "NegativeInt");
303
304   scoped_ptr<base::DictionaryValue> instance(new base::DictionaryValue());
305   instance->SetString("foo", "foo");
306   instance->SetInteger("bar", 4);
307   instance->SetString("baz", "ab");
308
309   scoped_ptr<base::DictionaryValue> instance_inline(
310       new base::DictionaryValue());
311   instance_inline->SetString("foo", "foo");
312   instance_inline->SetInteger("bar", -4);
313   instance_inline->SetInteger("baz", -2);
314
315   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), types.get());
316   ExpectValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL);
317
318   // Validation failure, but successful schema reference.
319   instance->SetString("baz", "a");
320   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), types.get(),
321                  "baz", JSONSchemaValidator::FormatErrorMessage(
322                      JSONSchemaValidator::kStringMinLength, "2"));
323
324   instance_inline->SetInteger("bar", 20);
325   ExpectNotValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL,
326                  "bar", JSONSchemaValidator::FormatErrorMessage(
327                      JSONSchemaValidator::kNumberMaximum, "0"));
328
329   // Remove MinLengthString type.
330   types->Remove(types->GetSize() - 1, NULL);
331   instance->SetString("baz", "ab");
332   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), types.get(),
333                  "bar", JSONSchemaValidator::FormatErrorMessage(
334                      JSONSchemaValidator::kUnknownTypeReference,
335                      "Max10Int"));
336
337   // Remove internal type "NegativeInt".
338   schema_inline->Remove("properties.bar", NULL);
339   instance_inline->Remove("bar", NULL);
340   ExpectNotValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL,
341                  "baz", JSONSchemaValidator::FormatErrorMessage(
342                      JSONSchemaValidator::kUnknownTypeReference,
343                      "NegativeInt"));
344 }
345
346 void JSONSchemaValidatorTestBase::TestArrayTuple() {
347   scoped_ptr<base::DictionaryValue> schema(
348       LoadDictionary("array_tuple_schema.json"));
349   ASSERT_TRUE(schema.get());
350
351   scoped_ptr<base::ListValue> instance(new base::ListValue());
352   instance->Append(new base::StringValue("42"));
353   instance->Append(new base::FundamentalValue(42));
354
355   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
356
357   instance->Append(new base::StringValue("anything"));
358   ExpectNotValid(TEST_SOURCE,
359                  instance.get(),
360                  schema.get(),
361                  NULL,
362                  std::string(),
363                  JSONSchemaValidator::FormatErrorMessage(
364                      JSONSchemaValidator::kArrayMaxItems, "2"));
365
366   instance->Remove(1, NULL);
367   instance->Remove(1, NULL);
368   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
369                  JSONSchemaValidator::kArrayItemRequired);
370
371   instance->Set(0, new base::FundamentalValue(42));
372   instance->Append(new base::FundamentalValue(42));
373   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
374                  JSONSchemaValidator::FormatErrorMessage(
375                      JSONSchemaValidator::kInvalidType,
376                      schema::kString,
377                      schema::kInteger));
378
379   base::DictionaryValue* additional_properties = new base::DictionaryValue();
380   additional_properties->SetString(schema::kType, schema::kAny);
381   schema->Set(schema::kAdditionalProperties, additional_properties);
382   instance->Set(0, new base::StringValue("42"));
383   instance->Append(new base::StringValue("anything"));
384   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
385   instance->Set(2, new base::ListValue());
386   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
387
388   additional_properties->SetString(schema::kType, schema::kBoolean);
389   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "2",
390                  JSONSchemaValidator::FormatErrorMessage(
391                      JSONSchemaValidator::kInvalidType,
392                      schema::kBoolean,
393                      schema::kArray));
394   instance->Set(2, new base::FundamentalValue(false));
395   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
396
397   base::ListValue* items_schema = NULL;
398   base::DictionaryValue* item0_schema = NULL;
399   ASSERT_TRUE(schema->GetList(schema::kItems, &items_schema));
400   ASSERT_TRUE(items_schema->GetDictionary(0, &item0_schema));
401   item0_schema->SetBoolean(schema::kOptional, true);
402   instance->Remove(2, NULL);
403   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
404   // TODO(aa): I think this is inconsistent with the handling of NULL+optional
405   // for objects.
406   instance->Set(0, base::Value::CreateNullValue());
407   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
408   instance->Set(0, new base::FundamentalValue(42));
409   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
410                  JSONSchemaValidator::FormatErrorMessage(
411                      JSONSchemaValidator::kInvalidType,
412                      schema::kString,
413                      schema::kInteger));
414 }
415
416 void JSONSchemaValidatorTestBase::TestArrayNonTuple() {
417   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
418   schema->SetString(schema::kType, schema::kArray);
419   schema->SetString("items.type", schema::kString);
420   schema->SetInteger(schema::kMinItems, 2);
421   schema->SetInteger(schema::kMaxItems, 3);
422
423   scoped_ptr<base::ListValue> instance(new base::ListValue());
424   instance->Append(new base::StringValue("x"));
425   instance->Append(new base::StringValue("x"));
426
427   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
428   instance->Append(new base::StringValue("x"));
429   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
430
431   instance->Append(new base::StringValue("x"));
432   ExpectNotValid(TEST_SOURCE,
433                  instance.get(),
434                  schema.get(),
435                  NULL,
436                  std::string(),
437                  JSONSchemaValidator::FormatErrorMessage(
438                      JSONSchemaValidator::kArrayMaxItems, "3"));
439   instance->Remove(1, NULL);
440   instance->Remove(1, NULL);
441   instance->Remove(1, NULL);
442   ExpectNotValid(TEST_SOURCE,
443                  instance.get(),
444                  schema.get(),
445                  NULL,
446                  std::string(),
447                  JSONSchemaValidator::FormatErrorMessage(
448                      JSONSchemaValidator::kArrayMinItems, "2"));
449
450   instance->Remove(1, NULL);
451   instance->Append(new base::FundamentalValue(42));
452   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
453                  JSONSchemaValidator::FormatErrorMessage(
454                      JSONSchemaValidator::kInvalidType,
455                      schema::kString,
456                      schema::kInteger));
457 }
458
459 void JSONSchemaValidatorTestBase::TestString() {
460   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
461   schema->SetString(schema::kType, schema::kString);
462   schema->SetInteger(schema::kMinLength, 1);
463   schema->SetInteger(schema::kMaxLength, 10);
464
465   ExpectValid(TEST_SOURCE,
466               scoped_ptr<base::Value>(new base::StringValue("x")).get(),
467               schema.get(), NULL);
468   ExpectValid(TEST_SOURCE,
469               scoped_ptr<base::Value>(
470                   new base::StringValue("xxxxxxxxxx")).get(),
471               schema.get(), NULL);
472
473   ExpectNotValid(
474       TEST_SOURCE,
475       scoped_ptr<base::Value>(new base::StringValue(std::string())).get(),
476       schema.get(),
477       NULL,
478       std::string(),
479       JSONSchemaValidator::FormatErrorMessage(
480           JSONSchemaValidator::kStringMinLength, "1"));
481   ExpectNotValid(
482       TEST_SOURCE,
483       scoped_ptr<base::Value>(new base::StringValue("xxxxxxxxxxx")).get(),
484       schema.get(),
485       NULL,
486       std::string(),
487       JSONSchemaValidator::FormatErrorMessage(
488           JSONSchemaValidator::kStringMaxLength, "10"));
489 }
490
491 void JSONSchemaValidatorTestBase::TestNumber() {
492   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
493   schema->SetString(schema::kType, schema::kNumber);
494   schema->SetInteger(schema::kMinimum, 1);
495   schema->SetInteger(schema::kMaximum, 100);
496   schema->SetInteger("maxDecimal", 2);
497
498   ExpectValid(TEST_SOURCE,
499               scoped_ptr<base::Value>(new base::FundamentalValue(1)).get(),
500               schema.get(), NULL);
501   ExpectValid(TEST_SOURCE,
502               scoped_ptr<base::Value>(new base::FundamentalValue(50)).get(),
503               schema.get(), NULL);
504   ExpectValid(TEST_SOURCE,
505               scoped_ptr<base::Value>(new base::FundamentalValue(100)).get(),
506               schema.get(), NULL);
507   ExpectValid(TEST_SOURCE,
508               scoped_ptr<base::Value>(new base::FundamentalValue(88.88)).get(),
509               schema.get(), NULL);
510
511   ExpectNotValid(TEST_SOURCE,
512                  scoped_ptr<base::Value>(new base::FundamentalValue(0.5)).get(),
513                  schema.get(),
514                  NULL,
515                  std::string(),
516                  JSONSchemaValidator::FormatErrorMessage(
517                      JSONSchemaValidator::kNumberMinimum, "1"));
518   ExpectNotValid(
519       TEST_SOURCE,
520       scoped_ptr<base::Value>(new base::FundamentalValue(100.1)).get(),
521       schema.get(),
522       NULL,
523       std::string(),
524       JSONSchemaValidator::FormatErrorMessage(
525           JSONSchemaValidator::kNumberMaximum, "100"));
526 }
527
528 void JSONSchemaValidatorTestBase::TestTypeClassifier() {
529   EXPECT_EQ(std::string(schema::kBoolean),
530             JSONSchemaValidator::GetJSONSchemaType(
531                 scoped_ptr<base::Value>(
532                     new base::FundamentalValue(true)).get()));
533   EXPECT_EQ(std::string(schema::kBoolean),
534             JSONSchemaValidator::GetJSONSchemaType(
535                 scoped_ptr<base::Value>(
536                     new base::FundamentalValue(false)).get()));
537
538   // It doesn't matter whether the C++ type is 'integer' or 'real'. If the
539   // number is integral and within the representable range of integers in
540   // double, it's classified as 'integer'.
541   EXPECT_EQ(std::string(schema::kInteger),
542             JSONSchemaValidator::GetJSONSchemaType(
543                 scoped_ptr<base::Value>(new base::FundamentalValue(42)).get()));
544   EXPECT_EQ(std::string(schema::kInteger),
545             JSONSchemaValidator::GetJSONSchemaType(
546                 scoped_ptr<base::Value>(new base::FundamentalValue(0)).get()));
547   EXPECT_EQ(std::string(schema::kInteger),
548             JSONSchemaValidator::GetJSONSchemaType(
549                 scoped_ptr<base::Value>(new base::FundamentalValue(42)).get()));
550   EXPECT_EQ(std::string(schema::kInteger),
551             JSONSchemaValidator::GetJSONSchemaType(scoped_ptr<base::Value>(
552                 new base::FundamentalValue(pow(2.0, DBL_MANT_DIG))).get()));
553   EXPECT_EQ(std::string(schema::kInteger),
554             JSONSchemaValidator::GetJSONSchemaType(scoped_ptr<base::Value>(
555                 new base::FundamentalValue(pow(-2.0, DBL_MANT_DIG))).get()));
556
557   // "number" is only used for non-integral numbers, or numbers beyond what
558   // double can accurately represent.
559   EXPECT_EQ(std::string(schema::kNumber),
560             JSONSchemaValidator::GetJSONSchemaType(
561                 scoped_ptr<base::Value>(
562                     new base::FundamentalValue(88.8)).get()));
563   EXPECT_EQ(std::string(schema::kNumber),
564             JSONSchemaValidator::GetJSONSchemaType(scoped_ptr<base::Value>(
565                 new base::FundamentalValue(pow(2.0, DBL_MANT_DIG) * 2)).get()));
566   EXPECT_EQ(std::string(schema::kNumber),
567             JSONSchemaValidator::GetJSONSchemaType(scoped_ptr<base::Value>(
568                 new base::FundamentalValue(
569                     pow(-2.0, DBL_MANT_DIG) * 2)).get()));
570
571   EXPECT_EQ(std::string(schema::kString),
572             JSONSchemaValidator::GetJSONSchemaType(
573                 scoped_ptr<base::Value>(new base::StringValue("foo")).get()));
574   EXPECT_EQ(std::string(schema::kArray),
575             JSONSchemaValidator::GetJSONSchemaType(
576                 scoped_ptr<base::Value>(new base::ListValue()).get()));
577   EXPECT_EQ(std::string(schema::kObject),
578             JSONSchemaValidator::GetJSONSchemaType(
579                 scoped_ptr<base::Value>(new base::DictionaryValue()).get()));
580   EXPECT_EQ(std::string(schema::kNull),
581             JSONSchemaValidator::GetJSONSchemaType(
582                 scoped_ptr<base::Value>(base::Value::CreateNullValue()).get()));
583 }
584
585 void JSONSchemaValidatorTestBase::TestTypes() {
586   scoped_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
587
588   // valid
589   schema->SetString(schema::kType, schema::kObject);
590   ExpectValid(TEST_SOURCE,
591               scoped_ptr<base::Value>(new base::DictionaryValue()).get(),
592               schema.get(), NULL);
593
594   schema->SetString(schema::kType, schema::kArray);
595   ExpectValid(TEST_SOURCE, scoped_ptr<base::Value>(new base::ListValue()).get(),
596               schema.get(), NULL);
597
598   schema->SetString(schema::kType, schema::kString);
599   ExpectValid(TEST_SOURCE,
600               scoped_ptr<base::Value>(new base::StringValue("foobar")).get(),
601               schema.get(), NULL);
602
603   schema->SetString(schema::kType, schema::kNumber);
604   ExpectValid(TEST_SOURCE,
605               scoped_ptr<base::Value>(new base::FundamentalValue(88.8)).get(),
606               schema.get(), NULL);
607   ExpectValid(TEST_SOURCE,
608               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
609               schema.get(), NULL);
610   ExpectValid(TEST_SOURCE,
611               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
612               schema.get(), NULL);
613   ExpectValid(TEST_SOURCE,
614               scoped_ptr<base::Value>(new base::FundamentalValue(0)).get(),
615               schema.get(), NULL);
616
617   schema->SetString(schema::kType, schema::kInteger);
618   ExpectValid(TEST_SOURCE,
619               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
620               schema.get(), NULL);
621   ExpectValid(TEST_SOURCE,
622               scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
623               schema.get(), NULL);
624   ExpectValid(TEST_SOURCE,
625               scoped_ptr<base::Value>(new base::FundamentalValue(0)).get(),
626               schema.get(), NULL);
627   ExpectValid(TEST_SOURCE,
628               scoped_ptr<base::Value>(
629                   new base::FundamentalValue(pow(2.0, DBL_MANT_DIG))).get(),
630               schema.get(), NULL);
631   ExpectValid(TEST_SOURCE,
632               scoped_ptr<base::Value>(
633                   new base::FundamentalValue(pow(-2.0, DBL_MANT_DIG))).get(),
634               schema.get(), NULL);
635
636   schema->SetString(schema::kType, schema::kBoolean);
637   ExpectValid(TEST_SOURCE,
638               scoped_ptr<base::Value>(new base::FundamentalValue(false)).get(),
639               schema.get(), NULL);
640   ExpectValid(TEST_SOURCE,
641               scoped_ptr<base::Value>(new base::FundamentalValue(true)).get(),
642               schema.get(), NULL);
643
644   schema->SetString(schema::kType, schema::kNull);
645   ExpectValid(TEST_SOURCE,
646               scoped_ptr<base::Value>(base::Value::CreateNullValue()).get(),
647               schema.get(), NULL);
648
649   // not valid
650   schema->SetString(schema::kType, schema::kObject);
651   ExpectNotValid(
652       TEST_SOURCE,
653       scoped_ptr<base::Value>(new base::ListValue()).get(),
654       schema.get(),
655       NULL,
656       std::string(),
657       JSONSchemaValidator::FormatErrorMessage(
658           JSONSchemaValidator::kInvalidType, schema::kObject, schema::kArray));
659
660   schema->SetString(schema::kType, schema::kObject);
661   ExpectNotValid(
662       TEST_SOURCE,
663       scoped_ptr<base::Value>(base::Value::CreateNullValue()).get(),
664       schema.get(),
665       NULL,
666       std::string(),
667       JSONSchemaValidator::FormatErrorMessage(
668           JSONSchemaValidator::kInvalidType, schema::kObject, schema::kNull));
669
670   schema->SetString(schema::kType, schema::kArray);
671   ExpectNotValid(
672       TEST_SOURCE,
673       scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
674       schema.get(),
675       NULL,
676       std::string(),
677       JSONSchemaValidator::FormatErrorMessage(
678           JSONSchemaValidator::kInvalidType, schema::kArray, schema::kInteger));
679
680   schema->SetString(schema::kType, schema::kString);
681   ExpectNotValid(
682       TEST_SOURCE,
683       scoped_ptr<base::Value>(new base::FundamentalValue(42)).get(),
684       schema.get(),
685       NULL,
686       std::string(),
687       JSONSchemaValidator::FormatErrorMessage(JSONSchemaValidator::kInvalidType,
688                                               schema::kString,
689                                               schema::kInteger));
690
691   schema->SetString(schema::kType, schema::kNumber);
692   ExpectNotValid(
693       TEST_SOURCE,
694       scoped_ptr<base::Value>(new base::StringValue("42")).get(),
695       schema.get(),
696       NULL,
697       std::string(),
698       JSONSchemaValidator::FormatErrorMessage(
699           JSONSchemaValidator::kInvalidType, schema::kNumber, schema::kString));
700
701   schema->SetString(schema::kType, schema::kInteger);
702   ExpectNotValid(
703       TEST_SOURCE,
704       scoped_ptr<base::Value>(new base::FundamentalValue(88.8)).get(),
705       schema.get(),
706       NULL,
707       std::string(),
708       JSONSchemaValidator::kInvalidTypeIntegerNumber);
709
710   schema->SetString(schema::kType, schema::kBoolean);
711   ExpectNotValid(
712       TEST_SOURCE,
713       scoped_ptr<base::Value>(new base::FundamentalValue(1)).get(),
714       schema.get(),
715       NULL,
716       std::string(),
717       JSONSchemaValidator::FormatErrorMessage(JSONSchemaValidator::kInvalidType,
718                                               schema::kBoolean,
719                                               schema::kInteger));
720
721   schema->SetString(schema::kType, schema::kNull);
722   ExpectNotValid(
723       TEST_SOURCE,
724       scoped_ptr<base::Value>(new base::FundamentalValue(false)).get(),
725       schema.get(),
726       NULL,
727       std::string(),
728       JSONSchemaValidator::FormatErrorMessage(
729           JSONSchemaValidator::kInvalidType, schema::kNull, schema::kBoolean));
730 }