// Copyright (c) 2011 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 <cfloat> #include <cmath> #include <limits> #include "base/file_util.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/path_service.h" #include "base/stringprintf.h" #include "base/values.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/json_schema_validator.h" #include "content/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)); } } // namespace JSONSchemaValidatorTestBase::JSONSchemaValidatorTestBase( JSONSchemaValidatorTestBase::ValidatorType type) : type_(type) { } void JSONSchemaValidatorTestBase::RunTests() { TestComplex(); TestStringPattern(); TestEnum(); TestChoices(); TestExtends(); TestObject(); TestTypeReference(); TestArrayTuple(); TestArrayNonTuple(); TestString(); TestNumber(); TestTypeClassifier(); TestTypes(); } 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(new DictionaryValue()); schema->SetString("type", "string"); schema->SetString("pattern", "foo+"); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateStringValue("foo")).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateStringValue("foooooo")).get(), schema.get(), NULL); ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateStringValue("bar")).get(), schema.get(), NULL, "", 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(new DictionaryValue()); schema->SetString("type", "object"); schema->SetString("properties.foo.type", "string"); schema->SetString("properties.bar.type", "integer"); scoped_ptr<DictionaryValue> instance(new DictionaryValue()); instance->SetString("foo", "foo"); instance->SetInteger("bar", 42); 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; ASSERT_TRUE(schema->GetDictionary("properties", &properties)); ASSERT_TRUE(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")); ASSERT_TRUE(types.get()); scoped_ptr<DictionaryValue> schema(new DictionaryValue()); schema->SetString("type", "object"); schema->SetString("properties.foo.type", "string"); schema->SetString("properties.bar.$ref", "Max10Int"); schema->SetString("properties.baz.$ref", "MinLengthString"); scoped_ptr<DictionaryValue> schema_inline(new DictionaryValue()); schema_inline->SetString("type", "object"); schema_inline->SetString("properties.foo.type", "string"); schema_inline->SetString("properties.bar.id", "NegativeInt"); schema_inline->SetString("properties.bar.type", "integer"); schema_inline->SetInteger("properties.bar.maximum", 0); schema_inline->SetString("properties.baz.$ref", "NegativeInt"); scoped_ptr<DictionaryValue> instance(new DictionaryValue()); instance->SetString("foo", "foo"); instance->SetInteger("bar", 4); instance->SetString("baz", "ab"); scoped_ptr<DictionaryValue> instance_inline(new DictionaryValue()); instance_inline->SetString("foo", "foo"); instance_inline->SetInteger("bar", -4); instance_inline->SetInteger("baz", -2); 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")); } void JSONSchemaValidatorTestBase::TestArrayTuple() { scoped_ptr<DictionaryValue> schema(LoadDictionary("array_tuple_schema.json")); ASSERT_TRUE(schema.get()); scoped_ptr<ListValue> instance(new ListValue()); instance->Append(Value::CreateStringValue("42")); instance->Append(Value::CreateIntegerValue(42)); ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); instance->Append(Value::CreateStringValue("anything")); ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kArrayMaxItems, "2")); instance->Remove(1, NULL); instance->Remove(1, NULL); ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1", JSONSchemaValidator::kArrayItemRequired); instance->Set(0, Value::CreateIntegerValue(42)); instance->Append(Value::CreateIntegerValue(42)); ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "string", "integer")); DictionaryValue* additional_properties = new DictionaryValue(); additional_properties->SetString("type", "any"); schema->Set("additionalProperties", additional_properties); instance->Set(0, Value::CreateStringValue("42")); instance->Append(Value::CreateStringValue("anything")); ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); instance->Set(2, new ListValue()); ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); additional_properties->SetString("type", "boolean"); ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "2", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "boolean", "array")); instance->Set(2, Value::CreateBooleanValue(false)); ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); ListValue* items_schema = NULL; DictionaryValue* item0_schema = NULL; ASSERT_TRUE(schema->GetList("items", &items_schema)); ASSERT_TRUE(items_schema->GetDictionary(0, &item0_schema)); item0_schema->SetBoolean("optional", true); instance->Remove(2, NULL); ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); // TODO(aa): I think this is inconsistent with the handling of NULL+optional // for objects. instance->Set(0, Value::CreateNullValue()); ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); instance->Set(0, Value::CreateIntegerValue(42)); ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "string", "integer")); } void JSONSchemaValidatorTestBase::TestArrayNonTuple() { scoped_ptr<DictionaryValue> schema(new DictionaryValue()); schema->SetString("type", "array"); schema->SetString("items.type", "string"); schema->SetInteger("minItems", 2); schema->SetInteger("maxItems", 3); scoped_ptr<ListValue> instance(new ListValue()); instance->Append(Value::CreateStringValue("x")); instance->Append(Value::CreateStringValue("x")); ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); instance->Append(Value::CreateStringValue("x")); ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL); instance->Append(Value::CreateStringValue("x")); ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kArrayMaxItems, "3")); instance->Remove(1, NULL); instance->Remove(1, NULL); instance->Remove(1, NULL); ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kArrayMinItems, "2")); instance->Remove(1, NULL); instance->Append(Value::CreateIntegerValue(42)); ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "string", "integer")); } void JSONSchemaValidatorTestBase::TestString() { scoped_ptr<DictionaryValue> schema(new DictionaryValue()); schema->SetString("type", "string"); schema->SetInteger("minLength", 1); schema->SetInteger("maxLength", 10); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateStringValue("x")).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateStringValue("xxxxxxxxxx")).get(), schema.get(), NULL); ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateStringValue("")).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kStringMinLength, "1")); ExpectNotValid( TEST_SOURCE, scoped_ptr<Value>(Value::CreateStringValue("xxxxxxxxxxx")).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kStringMaxLength, "10")); } void JSONSchemaValidatorTestBase::TestNumber() { scoped_ptr<DictionaryValue> schema(new DictionaryValue()); schema->SetString("type", "number"); schema->SetInteger("minimum", 1); schema->SetInteger("maximum", 100); schema->SetInteger("maxDecimal", 2); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateIntegerValue(1)).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateIntegerValue(50)).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateIntegerValue(100)).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateDoubleValue(88.88)).get(), schema.get(), NULL); ExpectNotValid( TEST_SOURCE, scoped_ptr<Value>(Value::CreateDoubleValue(0.5)).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kNumberMinimum, "1")); ExpectNotValid( TEST_SOURCE, scoped_ptr<Value>(Value::CreateDoubleValue(100.1)).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kNumberMaximum, "100")); } void JSONSchemaValidatorTestBase::TestTypeClassifier() { EXPECT_EQ("boolean", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(Value::CreateBooleanValue(true)).get())); EXPECT_EQ("boolean", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(Value::CreateBooleanValue(false)).get())); // It doesn't matter whether the C++ type is 'integer' or 'real'. If the // number is integral and within the representable range of integers in // double, it's classified as 'integer'. EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(Value::CreateIntegerValue(42)).get())); EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(Value::CreateIntegerValue(0)).get())); EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(Value::CreateDoubleValue(42)).get())); EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>( Value::CreateDoubleValue(pow(2.0, DBL_MANT_DIG))).get())); EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>( Value::CreateDoubleValue(pow(-2.0, DBL_MANT_DIG))).get())); // "number" is only used for non-integral numbers, or numbers beyond what // double can accurately represent. EXPECT_EQ("number", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(Value::CreateDoubleValue(88.8)).get())); EXPECT_EQ("number", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(Value::CreateDoubleValue( pow(2.0, DBL_MANT_DIG) * 2)).get())); EXPECT_EQ("number", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(Value::CreateDoubleValue( pow(-2.0, DBL_MANT_DIG) * 2)).get())); EXPECT_EQ("string", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(Value::CreateStringValue("foo")).get())); EXPECT_EQ("array", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(new ListValue()).get())); EXPECT_EQ("object", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(new DictionaryValue()).get())); EXPECT_EQ("null", JSONSchemaValidator::GetJSONSchemaType( scoped_ptr<Value>(Value::CreateNullValue()).get())); } void JSONSchemaValidatorTestBase::TestTypes() { scoped_ptr<DictionaryValue> schema(new DictionaryValue()); // valid schema->SetString("type", "object"); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(new DictionaryValue()).get(), schema.get(), NULL); schema->SetString("type", "array"); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(new ListValue()).get(), schema.get(), NULL); schema->SetString("type", "string"); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateStringValue("foobar")).get(), schema.get(), NULL); schema->SetString("type", "number"); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateDoubleValue(88.8)).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateDoubleValue(42)).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateIntegerValue(0)).get(), schema.get(), NULL); schema->SetString("type", "integer"); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateDoubleValue(42)).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateIntegerValue(0)).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>( Value::CreateDoubleValue(pow(2.0, DBL_MANT_DIG))).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>( Value::CreateDoubleValue(pow(-2.0, DBL_MANT_DIG))).get(), schema.get(), NULL); schema->SetString("type", "boolean"); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateBooleanValue(false)).get(), schema.get(), NULL); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateBooleanValue(true)).get(), schema.get(), NULL); schema->SetString("type", "null"); ExpectValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateNullValue()).get(), schema.get(), NULL); // not valid schema->SetString("type", "object"); ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(new ListValue()).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "object", "array")); schema->SetString("type", "object"); ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateNullValue()).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "object", "null")); schema->SetString("type", "array"); ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "array", "integer")); schema->SetString("type", "string"); ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "string", "integer")); schema->SetString("type", "number"); ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateStringValue("42")).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "number", "string")); schema->SetString("type", "integer"); ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateDoubleValue(88.8)).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "integer", "number")); schema->SetString("type", "integer"); ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateDoubleValue(88.8)).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "integer", "number")); schema->SetString("type", "boolean"); ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateIntegerValue(1)).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "boolean", "integer")); schema->SetString("type", "null"); ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateBooleanValue(false)).get(), schema.get(), NULL, "", JSONSchemaValidator::FormatErrorMessage( JSONSchemaValidator::kInvalidType, "null", "boolean")); }