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