Index: chrome/common/json_schema_validator_unittest_base.cc |
diff --git a/chrome/common/json_schema_validator_unittest_base.cc b/chrome/common/json_schema_validator_unittest_base.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..295f762cf6ff202d42ec9277b5f7988adb545922 |
--- /dev/null |
+++ b/chrome/common/json_schema_validator_unittest_base.cc |
@@ -0,0 +1,273 @@ |
+// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/common/json_schema_validator_unittest_base.h" |
+ |
+#include "base/file_util.h" |
+#include "base/path_service.h" |
+#include "base/scoped_ptr.h" |
+#include "base/stringprintf.h" |
+#include "base/values.h" |
+#include "chrome/common/chrome_paths.h" |
+#include "chrome/common/json_schema_validator.h" |
+#include "chrome/common/json_value_serializer.h" |
+ |
+namespace { |
+ |
+#define TEST_SOURCE base::StringPrintf("%s:%i", __FILE__, __LINE__) |
+ |
+Value* LoadValue(const std::string& filename) { |
+ FilePath path; |
+ PathService::Get(chrome::DIR_TEST_DATA, &path); |
+ path = path.AppendASCII("json_schema_validator").AppendASCII(filename); |
+ EXPECT_TRUE(file_util::PathExists(path)); |
+ |
+ std::string error_message; |
+ JSONFileValueSerializer serializer(path); |
+ Value* result = serializer.Deserialize(NULL, &error_message); |
+ if (!result) |
+ ADD_FAILURE() << "Could not parse JSON: " << error_message; |
+ return result; |
+} |
+ |
+Value* LoadValue(const std::string& filename, Value::ValueType type) { |
+ scoped_ptr<Value> result(LoadValue(filename)); |
+ if (!result.get()) |
+ return NULL; |
+ if (!result->IsType(type)) { |
+ ADD_FAILURE() << "Expected type " << type << ", got: " << result->GetType(); |
+ return NULL; |
+ } |
+ return result.release(); |
+} |
+ |
+ListValue* LoadList(const std::string& filename) { |
+ return static_cast<ListValue*>( |
+ LoadValue(filename, Value::TYPE_LIST)); |
+} |
+ |
+DictionaryValue* LoadDictionary(const std::string& filename) { |
+ return static_cast<DictionaryValue*>( |
+ LoadValue(filename, Value::TYPE_DICTIONARY)); |
+} |
+ |
+} |
+ |
+JSONSchemaValidatorTestBase::JSONSchemaValidatorTestBase( |
+ JSONSchemaValidatorTestBase::ValidatorType type) |
+ : type_(type) { |
+} |
+ |
+void JSONSchemaValidatorTestBase::RunTests() { |
+ TestComplex(); |
+ TestStringPattern(); |
+ TestEnum(); |
+ TestChoices(); |
+ TestExtends(); |
+ TestObject(); |
+ TestTypeReference(); |
+} |
+ |
+void JSONSchemaValidatorTestBase::TestComplex() { |
+ scoped_ptr<DictionaryValue> schema(LoadDictionary("complex_schema.json")); |
+ scoped_ptr<ListValue> instance(LoadList("complex_instance.json")); |
+ |
+ ASSERT_TRUE(schema.get()); |
+ ASSERT_TRUE(instance.get()); |
+ |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); |
+ instance->Remove(instance->GetSize() - 1, NULL); |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); |
+ instance->Append(new DictionaryValue()); |
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1", |
+ JSONSchemaValidator::FormatErrorMessage( |
+ JSONSchemaValidator::kInvalidType, "number", "object")); |
+ instance->Remove(instance->GetSize() - 1, NULL); |
+ |
+ DictionaryValue* item = NULL; |
+ ASSERT_TRUE(instance->GetDictionary(0, &item)); |
+ item->SetString("url", "xxxxxxxxxxx"); |
+ |
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, |
+ "0.url", |
+ JSONSchemaValidator::FormatErrorMessage( |
+ JSONSchemaValidator::kStringMaxLength, "10")); |
+} |
+ |
+void JSONSchemaValidatorTestBase::TestStringPattern() { |
+ // Regex patterns not supported in CPP validator. |
+ if (type_ == CPP) |
+ return; |
+ |
+ scoped_ptr<DictionaryValue> schema( |
+ LoadDictionary("string_pattern_schema.json")); |
+ scoped_ptr<DictionaryValue> instance( |
+ LoadDictionary("string_pattern_instance.json")); |
+ |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); |
+ instance->SetString("prop", "fooooooo"); |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); |
+ instance->SetString("prop", "bar"); |
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, |
+ "prop", JSONSchemaValidator::FormatErrorMessage( |
+ JSONSchemaValidator::kStringPattern, "foo+")); |
+} |
+ |
+void JSONSchemaValidatorTestBase::TestEnum() { |
+ scoped_ptr<DictionaryValue> schema(LoadDictionary("enum_schema.json")); |
+ |
+ ExpectValid(TEST_SOURCE, |
+ scoped_ptr<Value>(Value::CreateStringValue("foo")).get(), |
+ schema.get(), NULL); |
+ ExpectValid(TEST_SOURCE, |
+ scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(), |
+ schema.get(), NULL); |
+ ExpectValid(TEST_SOURCE, |
+ scoped_ptr<Value>(Value::CreateBooleanValue(false)).get(), |
+ schema.get(), NULL); |
+ |
+ ExpectNotValid(TEST_SOURCE, |
+ scoped_ptr<Value>(Value::CreateStringValue("42")).get(), |
+ schema.get(), NULL, "", JSONSchemaValidator::kInvalidEnum); |
+ ExpectNotValid(TEST_SOURCE, |
+ scoped_ptr<Value>(Value::CreateNullValue()).get(), |
+ schema.get(), NULL, "", JSONSchemaValidator::kInvalidEnum); |
+} |
+ |
+void JSONSchemaValidatorTestBase::TestChoices() { |
+ scoped_ptr<DictionaryValue> schema(LoadDictionary("choices_schema.json")); |
+ |
+ ExpectValid(TEST_SOURCE, |
+ scoped_ptr<Value>(Value::CreateNullValue()).get(), |
+ schema.get(), NULL); |
+ ExpectValid(TEST_SOURCE, |
+ scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(), |
+ schema.get(), NULL); |
+ |
+ scoped_ptr<DictionaryValue> instance(new DictionaryValue()); |
+ instance->SetString("foo", "bar"); |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); |
+ |
+ ExpectNotValid(TEST_SOURCE, |
+ scoped_ptr<Value>(Value::CreateStringValue("foo")).get(), |
+ schema.get(), NULL, "", JSONSchemaValidator::kInvalidChoice); |
+ ExpectNotValid(TEST_SOURCE, |
+ scoped_ptr<Value>(new ListValue()).get(), |
+ schema.get(), NULL, "", JSONSchemaValidator::kInvalidChoice); |
+ |
+ instance->SetInteger("foo", 42); |
+ ExpectNotValid(TEST_SOURCE, instance.get(), |
+ schema.get(), NULL, "", JSONSchemaValidator::kInvalidChoice); |
+} |
+ |
+void JSONSchemaValidatorTestBase::TestExtends() { |
+ // TODO(aa): JS only |
+} |
+ |
+void JSONSchemaValidatorTestBase::TestObject() { |
+ scoped_ptr<DictionaryValue> schema(LoadDictionary("object_schema.json")); |
+ scoped_ptr<DictionaryValue> instance(LoadDictionary("object_instance.json")); |
+ |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); |
+ |
+ instance->SetBoolean("extra", true); |
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, |
+ "extra", JSONSchemaValidator::kUnexpectedProperty); |
+ |
+ instance->Remove("extra", NULL); |
+ instance->Remove("bar", NULL); |
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "bar", |
+ JSONSchemaValidator::kObjectPropertyIsRequired); |
+ |
+ instance->SetString("bar", "42"); |
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "bar", |
+ JSONSchemaValidator::FormatErrorMessage( |
+ JSONSchemaValidator::kInvalidType, "integer", "string")); |
+ |
+ DictionaryValue* additional_properties = new DictionaryValue(); |
+ additional_properties->SetString("type", "any"); |
+ schema->Set("additionalProperties", additional_properties); |
+ |
+ instance->SetInteger("bar", 42); |
+ instance->SetBoolean("extra", true); |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); |
+ |
+ instance->SetString("extra", "foo"); |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); |
+ |
+ additional_properties->SetString("type", "boolean"); |
+ instance->SetBoolean("extra", true); |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); |
+ |
+ instance->SetString("extra", "foo"); |
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, |
+ "extra", JSONSchemaValidator::FormatErrorMessage( |
+ JSONSchemaValidator::kInvalidType, "boolean", "string")); |
+ |
+ DictionaryValue* properties = NULL; |
+ DictionaryValue* bar_property = NULL; |
+ CHECK(schema->GetDictionary("properties", &properties)); |
+ CHECK(properties->GetDictionary("bar", &bar_property)); |
+ |
+ bar_property->SetBoolean("optional", true); |
+ instance->Remove("extra", NULL); |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); |
+ instance->Remove("bar", NULL); |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); |
+ instance->Set("bar", Value::CreateNullValue()); |
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, |
+ "bar", JSONSchemaValidator::FormatErrorMessage( |
+ JSONSchemaValidator::kInvalidType, "integer", "null")); |
+ instance->SetString("bar", "42"); |
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, |
+ "bar", JSONSchemaValidator::FormatErrorMessage( |
+ JSONSchemaValidator::kInvalidType, "integer", "string")); |
+} |
+ |
+void JSONSchemaValidatorTestBase::TestTypeReference() { |
+ scoped_ptr<ListValue> types(LoadList("reference_types.json")); |
+ scoped_ptr<DictionaryValue> schema(LoadDictionary("reference_schema.json")); |
+ scoped_ptr<DictionaryValue> schema_inline( |
+ LoadDictionary("reference_schema_inline.json")); |
+ scoped_ptr<DictionaryValue> instance( |
+ LoadDictionary("reference_instance.json")); |
+ scoped_ptr<DictionaryValue> instance_inline( |
+ LoadDictionary("reference_instance_inline.json")); |
+ |
+ ASSERT_TRUE(types.get()); |
+ ASSERT_TRUE(schema.get()); |
+ ASSERT_TRUE(schema_inline.get()); |
+ ASSERT_TRUE(instance.get()); |
+ ASSERT_TRUE(instance_inline.get()); |
+ |
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), types.get()); |
+ ExpectValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL); |
+ |
+ // Validation failure, but successful schema reference. |
+ instance->SetString("baz", "a"); |
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), types.get(), |
+ "baz", JSONSchemaValidator::FormatErrorMessage( |
+ JSONSchemaValidator::kStringMinLength, "2")); |
+ |
+ instance_inline->SetInteger("bar", 20); |
+ ExpectNotValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL, |
+ "bar", JSONSchemaValidator::FormatErrorMessage( |
+ JSONSchemaValidator::kNumberMaximum, "0")); |
+ |
+ // Remove MinLengthString type. |
+ types->Remove(types->GetSize() - 1, NULL); |
+ instance->SetString("baz", "ab"); |
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), types.get(), |
+ "bar", JSONSchemaValidator::FormatErrorMessage( |
+ JSONSchemaValidator::kUnknownTypeReference, |
+ "Max10Int")); |
+ |
+ // Remove internal type "NegativeInt". |
+ schema_inline->Remove("properties.bar", NULL); |
+ instance_inline->Remove("bar", NULL); |
+ ExpectNotValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL, |
+ "baz", JSONSchemaValidator::FormatErrorMessage( |
+ JSONSchemaValidator::kUnknownTypeReference, |
+ "NegativeInt")); |
+} |