| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/policy/core/common/schema.h" | 5 #include "components/policy/core/common/schema.h" |
| 6 | 6 |
| 7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "base/strings/stringprintf.h" |
| 8 #include "components/policy/core/common/schema_internal.h" | 9 #include "components/policy/core/common/schema_internal.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| 10 | 11 |
| 11 namespace policy { | 12 namespace policy { |
| 12 | 13 |
| 13 namespace { | 14 namespace { |
| 14 | 15 |
| 16 #define TestSchemaValidation(a, b, c, d) \ |
| 17 TestSchemaValidationHelper( \ |
| 18 base::StringPrintf("%s:%i", __FILE__, __LINE__), a, b, c, d) |
| 19 |
| 15 const char kTestSchema[] = | 20 const char kTestSchema[] = |
| 16 "{" | 21 "{" |
| 17 " \"type\": \"object\"," | 22 " \"type\": \"object\"," |
| 18 " \"properties\": {" | 23 " \"properties\": {" |
| 19 " \"Boolean\": { \"type\": \"boolean\" }," | 24 " \"Boolean\": { \"type\": \"boolean\" }," |
| 20 " \"Integer\": { \"type\": \"integer\" }," | 25 " \"Integer\": { \"type\": \"integer\" }," |
| 21 " \"Null\": { \"type\": \"null\" }," | 26 " \"Null\": { \"type\": \"null\" }," |
| 22 " \"Number\": { \"type\": \"number\" }," | 27 " \"Number\": { \"type\": \"number\" }," |
| 23 " \"String\": { \"type\": \"string\" }," | 28 " \"String\": { \"type\": \"string\" }," |
| 24 " \"Array\": {" | 29 " \"Array\": {" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 " \"type\": \"array\"," | 97 " \"type\": \"array\"," |
| 93 " \"items\": {" | 98 " \"items\": {" |
| 94 " \"type\": \"object\"," | 99 " \"type\": \"object\"," |
| 95 " \"properties\": {" | 100 " \"properties\": {" |
| 96 " \"List\": {" | 101 " \"List\": {" |
| 97 " \"type\": \"array\"," | 102 " \"type\": \"array\"," |
| 98 " \"items\": { \"type\": \"string\" }" | 103 " \"items\": { \"type\": \"string\" }" |
| 99 " }" | 104 " }" |
| 100 " }" | 105 " }" |
| 101 " }" | 106 " }" |
| 107 " }," |
| 108 " \"StringWithPattern\": {" |
| 109 " \"type\": \"string\"," |
| 110 " \"pattern\": \"^foo+$\"" |
| 111 " }," |
| 112 " \"ObjectWithPatternProperties\": {" |
| 113 " \"type\": \"object\"," |
| 114 " \"patternProperties\": {" |
| 115 " \"^foo+$\": { \"type\": \"integer\" }," |
| 116 " \"^bar+$\": {" |
| 117 " \"type\": \"string\"," |
| 118 " \"enum\": [\"one\", \"two\"]" |
| 119 " }" |
| 120 " }," |
| 121 " \"properties\": {" |
| 122 " \"bar\": {" |
| 123 " \"type\": \"string\"," |
| 124 " \"enum\": [\"one\", \"three\"]" |
| 125 " }" |
| 126 " }" |
| 102 " }" | 127 " }" |
| 103 " }" | 128 " }" |
| 104 "}"; | 129 "}"; |
| 105 | 130 |
| 106 bool ParseFails(const std::string& content) { | 131 bool ParseFails(const std::string& content) { |
| 107 std::string error; | 132 std::string error; |
| 108 Schema schema = Schema::Parse(content, &error); | 133 Schema schema = Schema::Parse(content, &error); |
| 109 if (schema.valid()) | 134 if (schema.valid()) |
| 110 return false; | 135 return false; |
| 111 EXPECT_FALSE(error.empty()); | 136 EXPECT_FALSE(error.empty()); |
| 112 return true; | 137 return true; |
| 113 } | 138 } |
| 114 | 139 |
| 115 void TestSchemaValidation(Schema schema, | 140 void TestSchemaValidationHelper(const std::string& source, |
| 116 const base::Value& value, | 141 Schema schema, |
| 117 SchemaOnErrorStrategy strategy, | 142 const base::Value& value, |
| 118 bool expected_return_value) { | 143 SchemaOnErrorStrategy strategy, |
| 144 bool expected_return_value) { |
| 119 std::string error; | 145 std::string error; |
| 120 static const char kNoErrorReturned[] = "No error returned."; | 146 static const char kNoErrorReturned[] = "No error returned."; |
| 121 | 147 |
| 122 // Test that Schema::Validate() works as expected. | 148 // Test that Schema::Validate() works as expected. |
| 123 error = kNoErrorReturned; | 149 error = kNoErrorReturned; |
| 124 bool returned = schema.Validate(value, strategy, NULL, &error); | 150 bool returned = schema.Validate(value, strategy, NULL, &error); |
| 125 EXPECT_EQ(returned, expected_return_value) << error; | 151 ASSERT_EQ(expected_return_value, returned) << source << ": " << error; |
| 126 | 152 |
| 127 // Test that Schema::Normalize() will return the same value as | 153 // Test that Schema::Normalize() will return the same value as |
| 128 // Schema::Validate(). | 154 // Schema::Validate(). |
| 129 error = kNoErrorReturned; | 155 error = kNoErrorReturned; |
| 130 scoped_ptr<base::Value> cloned_value(value.DeepCopy()); | 156 scoped_ptr<base::Value> cloned_value(value.DeepCopy()); |
| 131 bool touched = false; | 157 bool touched = false; |
| 132 returned = | 158 returned = |
| 133 schema.Normalize(cloned_value.get(), strategy, NULL, &error, &touched); | 159 schema.Normalize(cloned_value.get(), strategy, NULL, &error, &touched); |
| 134 EXPECT_EQ(returned, expected_return_value) << error; | 160 EXPECT_EQ(expected_return_value, returned) << source << ": " << error; |
| 135 | 161 |
| 136 bool strictly_valid = schema.Validate(value, SCHEMA_STRICT, NULL, &error); | 162 bool strictly_valid = schema.Validate(value, SCHEMA_STRICT, NULL, &error); |
| 137 EXPECT_EQ(!strictly_valid && returned, touched); | 163 EXPECT_EQ(touched, !strictly_valid && returned) << source; |
| 138 | 164 |
| 139 // Test that Schema::Normalize() have actually dropped invalid and unknown | 165 // Test that Schema::Normalize() have actually dropped invalid and unknown |
| 140 // properties. | 166 // properties. |
| 141 if (expected_return_value) { | 167 if (expected_return_value) { |
| 142 EXPECT_TRUE( | 168 EXPECT_TRUE( |
| 143 schema.Validate(*cloned_value.get(), SCHEMA_STRICT, NULL, &error)); | 169 schema.Validate(*cloned_value.get(), SCHEMA_STRICT, NULL, &error)) |
| 144 EXPECT_TRUE(schema.Normalize( | 170 << source; |
| 145 cloned_value.get(), SCHEMA_STRICT, NULL, &error, NULL)); | 171 EXPECT_TRUE( |
| 172 schema.Normalize(cloned_value.get(), SCHEMA_STRICT, NULL, &error, NULL)) |
| 173 << source; |
| 146 } | 174 } |
| 147 } | 175 } |
| 148 | 176 |
| 149 void TestSchemaValidationWithPath(Schema schema, | 177 void TestSchemaValidationWithPath(Schema schema, |
| 150 const base::Value& value, | 178 const base::Value& value, |
| 151 const std::string& expected_failure_path) { | 179 const std::string& expected_failure_path) { |
| 152 std::string error_path = "NOT_SET"; | 180 std::string error_path = "NOT_SET"; |
| 153 std::string error; | 181 std::string error; |
| 154 | 182 |
| 155 bool returned = schema.Validate(value, SCHEMA_STRICT, &error_path, &error); | 183 bool returned = schema.Validate(value, SCHEMA_STRICT, &error_path, &error); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 ASSERT_EQ(base::Value::TYPE_INTEGER, sub.type()); | 371 ASSERT_EQ(base::Value::TYPE_INTEGER, sub.type()); |
| 344 | 372 |
| 345 sub = schema.GetProperty("StringWithEnums"); | 373 sub = schema.GetProperty("StringWithEnums"); |
| 346 ASSERT_TRUE(sub.valid()); | 374 ASSERT_TRUE(sub.valid()); |
| 347 ASSERT_EQ(base::Value::TYPE_STRING, sub.type()); | 375 ASSERT_EQ(base::Value::TYPE_STRING, sub.type()); |
| 348 | 376 |
| 349 sub = schema.GetProperty("IntegerWithRange"); | 377 sub = schema.GetProperty("IntegerWithRange"); |
| 350 ASSERT_TRUE(sub.valid()); | 378 ASSERT_TRUE(sub.valid()); |
| 351 ASSERT_EQ(base::Value::TYPE_INTEGER, sub.type()); | 379 ASSERT_EQ(base::Value::TYPE_INTEGER, sub.type()); |
| 352 | 380 |
| 381 sub = schema.GetProperty("StringWithPattern"); |
| 382 ASSERT_TRUE(sub.valid()); |
| 383 ASSERT_EQ(base::Value::TYPE_STRING, sub.type()); |
| 384 |
| 385 sub = schema.GetProperty("ObjectWithPatternProperties"); |
| 386 ASSERT_TRUE(sub.valid()); |
| 387 ASSERT_EQ(base::Value::TYPE_DICTIONARY, sub.type()); |
| 388 |
| 353 struct { | 389 struct { |
| 354 const char* expected_key; | 390 const char* expected_key; |
| 355 base::Value::Type expected_type; | 391 base::Value::Type expected_type; |
| 356 } kExpectedProperties[] = { | 392 } kExpectedProperties[] = { |
| 357 { "Array", base::Value::TYPE_LIST }, | 393 { "Array", base::Value::TYPE_LIST }, |
| 358 { "ArrayOfArray", base::Value::TYPE_LIST }, | 394 { "ArrayOfArray", base::Value::TYPE_LIST }, |
| 359 { "ArrayOfObjectOfArray", base::Value::TYPE_LIST }, | 395 { "ArrayOfObjectOfArray", base::Value::TYPE_LIST }, |
| 360 { "ArrayOfObjects", base::Value::TYPE_LIST }, | 396 { "ArrayOfObjects", base::Value::TYPE_LIST }, |
| 361 { "Boolean", base::Value::TYPE_BOOLEAN }, | 397 { "Boolean", base::Value::TYPE_BOOLEAN }, |
| 362 { "Integer", base::Value::TYPE_INTEGER }, | 398 { "Integer", base::Value::TYPE_INTEGER }, |
| 363 { "IntegerWithEnums", base::Value::TYPE_INTEGER }, | 399 { "IntegerWithEnums", base::Value::TYPE_INTEGER }, |
| 364 { "IntegerWithEnumsGaps", base::Value::TYPE_INTEGER }, | 400 { "IntegerWithEnumsGaps", base::Value::TYPE_INTEGER }, |
| 365 { "IntegerWithRange", base::Value::TYPE_INTEGER }, | 401 { "IntegerWithRange", base::Value::TYPE_INTEGER }, |
| 366 { "Null", base::Value::TYPE_NULL }, | 402 { "Null", base::Value::TYPE_NULL }, |
| 367 { "Number", base::Value::TYPE_DOUBLE }, | 403 { "Number", base::Value::TYPE_DOUBLE }, |
| 368 { "Object", base::Value::TYPE_DICTIONARY }, | 404 { "Object", base::Value::TYPE_DICTIONARY }, |
| 369 { "ObjectOfArray", base::Value::TYPE_DICTIONARY }, | 405 { "ObjectOfArray", base::Value::TYPE_DICTIONARY }, |
| 370 { "ObjectOfObject", base::Value::TYPE_DICTIONARY }, | 406 { "ObjectOfObject", base::Value::TYPE_DICTIONARY }, |
| 371 { "String", base::Value::TYPE_STRING }, | 407 { "ObjectWithPatternProperties", base::Value::TYPE_DICTIONARY }, |
| 372 { "StringWithEnums", base::Value::TYPE_STRING }, | 408 { "String", base::Value::TYPE_STRING }, |
| 409 { "StringWithEnums", base::Value::TYPE_STRING }, |
| 410 { "StringWithPattern", base::Value::TYPE_STRING }, |
| 373 }; | 411 }; |
| 374 Schema::Iterator it = schema.GetPropertiesIterator(); | 412 Schema::Iterator it = schema.GetPropertiesIterator(); |
| 375 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpectedProperties); ++i) { | 413 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpectedProperties); ++i) { |
| 376 ASSERT_FALSE(it.IsAtEnd()); | 414 ASSERT_FALSE(it.IsAtEnd()); |
| 377 EXPECT_STREQ(kExpectedProperties[i].expected_key, it.key()); | 415 EXPECT_STREQ(kExpectedProperties[i].expected_key, it.key()); |
| 378 ASSERT_TRUE(it.schema().valid()); | 416 ASSERT_TRUE(it.schema().valid()); |
| 379 EXPECT_EQ(kExpectedProperties[i].expected_type, it.schema().type()); | 417 EXPECT_EQ(kExpectedProperties[i].expected_type, it.schema().type()); |
| 380 it.Advance(); | 418 it.Advance(); |
| 381 } | 419 } |
| 382 EXPECT_TRUE(it.IsAtEnd()); | 420 EXPECT_TRUE(it.IsAtEnd()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 }; | 475 }; |
| 438 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpectedKeys); ++i) { | 476 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpectedKeys); ++i) { |
| 439 Schema sub = schema.GetKnownProperty(kExpectedKeys[i].expected_key); | 477 Schema sub = schema.GetKnownProperty(kExpectedKeys[i].expected_key); |
| 440 ASSERT_TRUE(sub.valid()); | 478 ASSERT_TRUE(sub.valid()); |
| 441 EXPECT_EQ(kExpectedKeys[i].expected_type, sub.type()); | 479 EXPECT_EQ(kExpectedKeys[i].expected_type, sub.type()); |
| 442 } | 480 } |
| 443 } | 481 } |
| 444 | 482 |
| 445 TEST(SchemaTest, Wrap) { | 483 TEST(SchemaTest, Wrap) { |
| 446 const internal::SchemaNode kSchemas[] = { | 484 const internal::SchemaNode kSchemas[] = { |
| 447 { base::Value::TYPE_DICTIONARY, 0 }, // 0: root node | 485 { base::Value::TYPE_DICTIONARY, 0 }, // 0: root node |
| 448 { base::Value::TYPE_BOOLEAN, -1 }, // 1 | 486 { base::Value::TYPE_BOOLEAN, -1 }, // 1 |
| 449 { base::Value::TYPE_INTEGER, -1 }, // 2 | 487 { base::Value::TYPE_INTEGER, -1 }, // 2 |
| 450 { base::Value::TYPE_DOUBLE, -1 }, // 3 | 488 { base::Value::TYPE_DOUBLE, -1 }, // 3 |
| 451 { base::Value::TYPE_STRING, -1 }, // 4 | 489 { base::Value::TYPE_STRING, -1 }, // 4 |
| 452 { base::Value::TYPE_LIST, 4 }, // 5: list of strings. | 490 { base::Value::TYPE_LIST, 4 }, // 5: list of strings. |
| 453 { base::Value::TYPE_LIST, 5 }, // 6: list of lists of strings. | 491 { base::Value::TYPE_LIST, 5 }, // 6: list of lists of strings. |
| 454 { base::Value::TYPE_INTEGER, 0 }, // 7: integer enumerations. | 492 { base::Value::TYPE_INTEGER, 0 }, // 7: integer enumerations. |
| 455 { base::Value::TYPE_INTEGER, 1 }, // 8: ranged integers. | 493 { base::Value::TYPE_INTEGER, 1 }, // 8: ranged integers. |
| 456 { base::Value::TYPE_STRING, 2 }, // 9: string enumerations. | 494 { base::Value::TYPE_STRING, 2 }, // 9: string enumerations. |
| 495 { base::Value::TYPE_STRING, 3 }, // 10: string with pattern. |
| 457 }; | 496 }; |
| 458 | 497 |
| 459 const internal::PropertyNode kPropertyNodes[] = { | 498 const internal::PropertyNode kPropertyNodes[] = { |
| 460 { "Boolean", 1 }, // 0 | 499 { "Boolean", 1 }, // 0 |
| 461 { "Integer", 2 }, // 1 | 500 { "Integer", 2 }, // 1 |
| 462 { "Number", 3 }, // 2 | 501 { "Number", 3 }, // 2 |
| 463 { "String", 4 }, // 3 | 502 { "String", 4 }, // 3 |
| 464 { "List", 5 }, // 4 | 503 { "List", 5 }, // 4 |
| 465 { "IntEnum", 7 }, // 5 | 504 { "IntEnum", 7 }, // 5 |
| 466 { "RangedInt", 8 }, // 6 | 505 { "RangedInt", 8 }, // 6 |
| 467 { "StrEnum", 9 }, // 7 | 506 { "StrEnum", 9 }, // 7 |
| 507 { "StrPat", 10 }, // 8 |
| 508 { "bar+$", 4 }, // 9 |
| 468 }; | 509 }; |
| 469 | 510 |
| 470 const internal::PropertiesNode kProperties[] = { | 511 const internal::PropertiesNode kProperties[] = { |
| 471 // 0 to 8 (exclusive) are the known properties in kPropertyNodes, and 6 is | 512 // 0 to 9 (exclusive) are the known properties in kPropertyNodes, 9 is |
| 472 // the addionalProperties node. | 513 // patternProperties and 6 is the additionalProperties node. |
| 473 { 0, 8, 6 }, | 514 { 0, 9, 10, 6 }, |
| 474 }; | 515 }; |
| 475 | 516 |
| 476 const internal::RestrictionNode kRestriction[] = { | 517 const internal::RestrictionNode kRestriction[] = { |
| 477 {{0, 3}}, // [1, 2, 3] | 518 {{0, 3}}, // 0: [1, 2, 3] |
| 478 {{5, 1}}, // minimum = 1, maximum = 5 | 519 {{5, 1}}, // 1: minimum = 1, maximum = 5 |
| 479 {{0, 3}}, // ["one", "two", "three"] | 520 {{0, 3}}, // 2: ["one", "two", "three"] |
| 521 {{3, 3}}, // 3: pattern "foo+" |
| 480 }; | 522 }; |
| 481 | 523 |
| 482 const int kIntEnums[] = {1, 2, 3}; | 524 const int kIntEnums[] = {1, 2, 3}; |
| 483 | 525 |
| 484 const char* kStringEnums[] = { | 526 const char* kStringEnums[] = { |
| 485 "one", | 527 "one", // 0 |
| 486 "two", | 528 "two", // 1 |
| 487 "three", | 529 "three", // 2 |
| 530 "foo+", // 3 |
| 488 }; | 531 }; |
| 489 | 532 |
| 490 const internal::SchemaData kData = { | 533 const internal::SchemaData kData = { |
| 491 kSchemas, | 534 kSchemas, |
| 492 kPropertyNodes, | 535 kPropertyNodes, |
| 493 kProperties, | 536 kProperties, |
| 494 kRestriction, | 537 kRestriction, |
| 495 kIntEnums, | 538 kIntEnums, |
| 496 kStringEnums, | 539 kStringEnums, |
| 497 }; | 540 }; |
| 498 | 541 |
| 499 Schema schema = Schema::Wrap(&kData); | 542 Schema schema = Schema::Wrap(&kData); |
| 500 ASSERT_TRUE(schema.valid()); | 543 ASSERT_TRUE(schema.valid()); |
| 501 EXPECT_EQ(base::Value::TYPE_DICTIONARY, schema.type()); | 544 EXPECT_EQ(base::Value::TYPE_DICTIONARY, schema.type()); |
| 502 | 545 |
| 503 struct { | 546 struct { |
| 504 const char* key; | 547 const char* key; |
| 505 base::Value::Type type; | 548 base::Value::Type type; |
| 506 } kExpectedProperties[] = { | 549 } kExpectedProperties[] = { |
| 507 { "Boolean", base::Value::TYPE_BOOLEAN }, | 550 { "Boolean", base::Value::TYPE_BOOLEAN }, |
| 508 { "Integer", base::Value::TYPE_INTEGER }, | 551 { "Integer", base::Value::TYPE_INTEGER }, |
| 509 { "Number", base::Value::TYPE_DOUBLE }, | 552 { "Number", base::Value::TYPE_DOUBLE }, |
| 510 { "String", base::Value::TYPE_STRING }, | 553 { "String", base::Value::TYPE_STRING }, |
| 511 { "List", base::Value::TYPE_LIST }, | 554 { "List", base::Value::TYPE_LIST }, |
| 512 { "IntEnum", base::Value::TYPE_INTEGER }, | 555 { "IntEnum", base::Value::TYPE_INTEGER }, |
| 513 { "RangedInt", base::Value::TYPE_INTEGER }, | 556 { "RangedInt", base::Value::TYPE_INTEGER }, |
| 514 { "StrEnum", base::Value::TYPE_STRING } | 557 { "StrEnum", base::Value::TYPE_STRING }, |
| 558 { "StrPat", base::Value::TYPE_STRING }, |
| 515 }; | 559 }; |
| 516 | 560 |
| 517 Schema::Iterator it = schema.GetPropertiesIterator(); | 561 Schema::Iterator it = schema.GetPropertiesIterator(); |
| 518 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpectedProperties); ++i) { | 562 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpectedProperties); ++i) { |
| 519 ASSERT_FALSE(it.IsAtEnd()); | 563 ASSERT_FALSE(it.IsAtEnd()); |
| 520 EXPECT_STREQ(kExpectedProperties[i].key, it.key()); | 564 EXPECT_STREQ(kExpectedProperties[i].key, it.key()); |
| 521 Schema sub = it.schema(); | 565 Schema sub = it.schema(); |
| 522 ASSERT_TRUE(sub.valid()); | 566 ASSERT_TRUE(sub.valid()); |
| 523 EXPECT_EQ(kExpectedProperties[i].type, sub.type()); | 567 EXPECT_EQ(kExpectedProperties[i].type, sub.type()); |
| 524 | 568 |
| 525 if (sub.type() == base::Value::TYPE_LIST) { | 569 if (sub.type() == base::Value::TYPE_LIST) { |
| 526 Schema items = sub.GetItems(); | 570 Schema items = sub.GetItems(); |
| 527 ASSERT_TRUE(items.valid()); | 571 ASSERT_TRUE(items.valid()); |
| 528 EXPECT_EQ(base::Value::TYPE_STRING, items.type()); | 572 EXPECT_EQ(base::Value::TYPE_STRING, items.type()); |
| 529 } | 573 } |
| 530 | 574 |
| 531 it.Advance(); | 575 it.Advance(); |
| 532 } | 576 } |
| 533 EXPECT_TRUE(it.IsAtEnd()); | 577 EXPECT_TRUE(it.IsAtEnd()); |
| 534 | 578 |
| 535 Schema sub = schema.GetAdditionalProperties(); | 579 Schema sub = schema.GetAdditionalProperties(); |
| 536 ASSERT_TRUE(sub.valid()); | 580 ASSERT_TRUE(sub.valid()); |
| 537 ASSERT_EQ(base::Value::TYPE_LIST, sub.type()); | 581 ASSERT_EQ(base::Value::TYPE_LIST, sub.type()); |
| 538 Schema subsub = sub.GetItems(); | 582 Schema subsub = sub.GetItems(); |
| 539 ASSERT_TRUE(subsub.valid()); | 583 ASSERT_TRUE(subsub.valid()); |
| 540 ASSERT_EQ(base::Value::TYPE_LIST, subsub.type()); | 584 ASSERT_EQ(base::Value::TYPE_LIST, subsub.type()); |
| 541 Schema subsubsub = subsub.GetItems(); | 585 Schema subsubsub = subsub.GetItems(); |
| 542 ASSERT_TRUE(subsubsub.valid()); | 586 ASSERT_TRUE(subsubsub.valid()); |
| 543 ASSERT_EQ(base::Value::TYPE_STRING, subsubsub.type()); | 587 ASSERT_EQ(base::Value::TYPE_STRING, subsubsub.type()); |
| 588 |
| 589 SchemaList schema_list = schema.GetPatternProperties("barr"); |
| 590 ASSERT_EQ(1u, schema_list.size()); |
| 591 sub = schema_list[0]; |
| 592 ASSERT_TRUE(sub.valid()); |
| 593 EXPECT_EQ(base::Value::TYPE_STRING, sub.type()); |
| 594 |
| 595 EXPECT_TRUE(schema.GetPatternProperties("ba").empty()); |
| 596 EXPECT_TRUE(schema.GetPatternProperties("bar+$").empty()); |
| 544 } | 597 } |
| 545 | 598 |
| 546 TEST(SchemaTest, Validate) { | 599 TEST(SchemaTest, Validate) { |
| 547 std::string error; | 600 std::string error; |
| 548 Schema schema = Schema::Parse(kTestSchema, &error); | 601 Schema schema = Schema::Parse(kTestSchema, &error); |
| 549 ASSERT_TRUE(schema.valid()) << error; | 602 ASSERT_TRUE(schema.valid()) << error; |
| 550 | 603 |
| 551 base::DictionaryValue bundle; | 604 base::DictionaryValue bundle; |
| 552 TestSchemaValidation(schema, bundle, SCHEMA_STRICT, true); | 605 TestSchemaValidation(schema, bundle, SCHEMA_STRICT, true); |
| 553 | 606 |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 // Invalid list item. | 839 // Invalid list item. |
| 787 list_value->Append(new base::FundamentalValue(12345)); | 840 list_value->Append(new base::FundamentalValue(12345)); |
| 788 TestSchemaValidation(subschema, root, SCHEMA_STRICT, false); | 841 TestSchemaValidation(subschema, root, SCHEMA_STRICT, false); |
| 789 TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, false); | 842 TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN_TOPLEVEL, false); |
| 790 TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, false); | 843 TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, false); |
| 791 TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID_TOPLEVEL, true); | 844 TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID_TOPLEVEL, true); |
| 792 TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID, true); | 845 TestSchemaValidation(subschema, root, SCHEMA_ALLOW_INVALID, true); |
| 793 TestSchemaValidationWithPath(subschema, root, "items[0].List.items[1]"); | 846 TestSchemaValidationWithPath(subschema, root, "items[0].List.items[1]"); |
| 794 } | 847 } |
| 795 | 848 |
| 849 // Tests on StringWithPattern. |
| 850 { |
| 851 Schema subschema = schema.GetProperty("StringWithPattern"); |
| 852 ASSERT_TRUE(subschema.valid()); |
| 853 |
| 854 TestSchemaValidation( |
| 855 subschema, base::StringValue("foobar"), SCHEMA_STRICT, false); |
| 856 TestSchemaValidation( |
| 857 subschema, base::StringValue("foo"), SCHEMA_STRICT, true); |
| 858 TestSchemaValidation( |
| 859 subschema, base::StringValue("fo"), SCHEMA_STRICT, false); |
| 860 TestSchemaValidation( |
| 861 subschema, base::StringValue("fooo"), SCHEMA_STRICT, true); |
| 862 TestSchemaValidation( |
| 863 subschema, base::StringValue("^foo+$"), SCHEMA_STRICT, false); |
| 864 } |
| 865 |
| 866 // Tests on ObjectWithPatternProperties. |
| 867 { |
| 868 Schema subschema = schema.GetProperty("ObjectWithPatternProperties"); |
| 869 ASSERT_TRUE(subschema.valid()); |
| 870 base::DictionaryValue root; |
| 871 |
| 872 ASSERT_EQ(1u, subschema.GetPatternProperties("fooo").size()); |
| 873 ASSERT_EQ(1u, subschema.GetPatternProperties("foo").size()); |
| 874 ASSERT_EQ(1u, subschema.GetPatternProperties("barr").size()); |
| 875 ASSERT_EQ(1u, subschema.GetPatternProperties("bar").size()); |
| 876 ASSERT_EQ(1u, subschema.GetMatchingProperties("fooo").size()); |
| 877 ASSERT_EQ(1u, subschema.GetMatchingProperties("foo").size()); |
| 878 ASSERT_EQ(1u, subschema.GetMatchingProperties("barr").size()); |
| 879 ASSERT_EQ(2u, subschema.GetMatchingProperties("bar").size()); |
| 880 ASSERT_TRUE(subschema.GetPatternProperties("foobar").empty()); |
| 881 |
| 882 root.SetInteger("fooo", 123); |
| 883 TestSchemaValidation(subschema, root, SCHEMA_STRICT, true); |
| 884 root.SetBoolean("fooo", false); |
| 885 TestSchemaValidation(subschema, root, SCHEMA_STRICT, false); |
| 886 root.Remove("fooo", NULL); |
| 887 |
| 888 root.SetInteger("foo", 123); |
| 889 TestSchemaValidation(subschema, root, SCHEMA_STRICT, true); |
| 890 root.SetBoolean("foo", false); |
| 891 TestSchemaValidation(subschema, root, SCHEMA_STRICT, false); |
| 892 root.Remove("foo", NULL); |
| 893 |
| 894 root.SetString("barr", "one"); |
| 895 TestSchemaValidation(subschema, root, SCHEMA_STRICT, true); |
| 896 root.SetString("barr", "three"); |
| 897 TestSchemaValidation(subschema, root, SCHEMA_STRICT, false); |
| 898 root.SetBoolean("barr", false); |
| 899 TestSchemaValidation(subschema, root, SCHEMA_STRICT, false); |
| 900 root.Remove("barr", NULL); |
| 901 |
| 902 root.SetString("bar", "one"); |
| 903 TestSchemaValidation(subschema, root, SCHEMA_STRICT, true); |
| 904 root.SetString("bar", "two"); |
| 905 TestSchemaValidation(subschema, root, SCHEMA_STRICT, false); |
| 906 root.SetString("bar", "three"); |
| 907 TestSchemaValidation(subschema, root, SCHEMA_STRICT, false); |
| 908 root.Remove("bar", NULL); |
| 909 |
| 910 root.SetInteger("foobar", 123); |
| 911 TestSchemaValidation(subschema, root, SCHEMA_STRICT, false); |
| 912 TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, true); |
| 913 root.Remove("foobar", NULL); |
| 914 } |
| 915 |
| 796 // Test that integer to double promotion is allowed. | 916 // Test that integer to double promotion is allowed. |
| 797 bundle.SetInteger("Number", 31415); | 917 bundle.SetInteger("Number", 31415); |
| 798 TestSchemaValidation(schema, bundle, SCHEMA_STRICT, true); | 918 TestSchemaValidation(schema, bundle, SCHEMA_STRICT, true); |
| 799 } | 919 } |
| 800 | 920 |
| 801 TEST(SchemaTest, InvalidReferences) { | 921 TEST(SchemaTest, InvalidReferences) { |
| 802 // References to undeclared schemas fail. | 922 // References to undeclared schemas fail. |
| 803 EXPECT_TRUE(ParseFails( | 923 EXPECT_TRUE(ParseFails( |
| 804 "{" | 924 "{" |
| 805 " \"type\": \"object\"," | 925 " \"type\": \"object\"," |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1050 | 1170 |
| 1051 EXPECT_FALSE(ParseFails(SchemaObjectWrapper( | 1171 EXPECT_FALSE(ParseFails(SchemaObjectWrapper( |
| 1052 "{" | 1172 "{" |
| 1053 " \"type\": \"integer\"," | 1173 " \"type\": \"integer\"," |
| 1054 " \"minimum\": 10," | 1174 " \"minimum\": 10," |
| 1055 " \"maximum\": 20" | 1175 " \"maximum\": 20" |
| 1056 "}"))); | 1176 "}"))); |
| 1057 } | 1177 } |
| 1058 | 1178 |
| 1059 } // namespace policy | 1179 } // namespace policy |
| OLD | NEW |