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 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 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 50 ListValue* LoadList(const std::string& filename) { 51 return static_cast<ListValue*>( 52 LoadValue(filename, Value::TYPE_LIST)); 53 } 54 55 DictionaryValue* LoadDictionary(const std::string& filename) { 56 return static_cast<DictionaryValue*>( 57 LoadValue(filename, Value::TYPE_DICTIONARY)); 58 } 59 60 } // namespace 61 62 63 JSONSchemaValidatorTestBase::JSONSchemaValidatorTestBase( 64 JSONSchemaValidatorTestBase::ValidatorType type) 65 : type_(type) { 66 } 67 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 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 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 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 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 179 void JSONSchemaValidatorTestBase::TestExtends() { 180 // TODO(aa): JS only 181 } 182 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 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 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 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 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 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 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 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