blob: d96544c31d258e6e03beaefd6d6c585960ecaddb [file] [log] [blame]
// Copyright 2013 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 "components/json_schema/json_schema_validator_unittest_base.h"
#include <cfloat>
#include <cmath>
#include <limits>
#include <memory>
#include "base/base_paths.h"
#include "base/files/file_util.h"
#include "base/json/json_file_value_serializer.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "components/json_schema/json_schema_constants.h"
#include "components/json_schema/json_schema_validator.h"
namespace schema = json_schema_constants;
namespace {
#define TEST_SOURCE base::StringPrintf("%s:%i", __FILE__, __LINE__)
base::Value* LoadValue(const std::string& filename) {
base::FilePath path;
PathService::Get(base::DIR_SOURCE_ROOT, &path);
path = path.AppendASCII("components")
.AppendASCII("test")
.AppendASCII("data")
.AppendASCII("json_schema")
.AppendASCII(filename);
EXPECT_TRUE(base::PathExists(path));
std::string error_message;
JSONFileValueDeserializer deserializer(path);
base::Value* result =
deserializer.Deserialize(NULL, &error_message).release();
if (!result)
ADD_FAILURE() << "Could not parse JSON: " << error_message;
return result;
}
base::Value* LoadValue(const std::string& filename, base::Value::Type type) {
std::unique_ptr<base::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();
}
base::ListValue* LoadList(const std::string& filename) {
return static_cast<base::ListValue*>(
LoadValue(filename, base::Value::Type::LIST));
}
base::DictionaryValue* LoadDictionary(const std::string& filename) {
return static_cast<base::DictionaryValue*>(
LoadValue(filename, base::Value::Type::DICTIONARY));
}
} // namespace
JSONSchemaValidatorTestBase::JSONSchemaValidatorTestBase() {
}
void JSONSchemaValidatorTestBase::RunTests() {
TestComplex();
TestStringPattern();
TestEnum();
TestChoices();
TestExtends();
TestObject();
TestTypeReference();
TestArrayTuple();
TestArrayNonTuple();
TestString();
TestNumber();
TestTypeClassifier();
TestTypes();
}
void JSONSchemaValidatorTestBase::TestComplex() {
std::unique_ptr<base::DictionaryValue> schema(
LoadDictionary("complex_schema.json"));
std::unique_ptr<base::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(base::MakeUnique<base::DictionaryValue>());
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType,
schema::kNumber,
schema::kObject));
instance->Remove(instance->GetSize() - 1, NULL);
base::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() {
std::unique_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
schema->SetString(schema::kType, schema::kString);
schema->SetString(schema::kPattern, "foo+");
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value("foo")).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value("foooooo")).get(),
schema.get(), NULL);
ExpectNotValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value("bar")).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kStringPattern, "foo+"));
}
void JSONSchemaValidatorTestBase::TestEnum() {
std::unique_ptr<base::DictionaryValue> schema(
LoadDictionary("enum_schema.json"));
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value("foo")).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(42)).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(false)).get(),
schema.get(), NULL);
ExpectNotValid(
TEST_SOURCE, std::unique_ptr<base::Value>(new base::Value("42")).get(),
schema.get(), NULL, std::string(), JSONSchemaValidator::kInvalidEnum);
ExpectNotValid(TEST_SOURCE, base::MakeUnique<base::Value>().get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::kInvalidEnum);
}
void JSONSchemaValidatorTestBase::TestChoices() {
std::unique_ptr<base::DictionaryValue> schema(
LoadDictionary("choices_schema.json"));
ExpectValid(TEST_SOURCE, base::MakeUnique<base::Value>().get(), schema.get(),
NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(42)).get(),
schema.get(), NULL);
std::unique_ptr<base::DictionaryValue> instance(new base::DictionaryValue());
instance->SetString("foo", "bar");
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
ExpectNotValid(
TEST_SOURCE, std::unique_ptr<base::Value>(new base::Value("foo")).get(),
schema.get(), NULL, std::string(), JSONSchemaValidator::kInvalidChoice);
ExpectNotValid(
TEST_SOURCE, std::unique_ptr<base::Value>(new base::ListValue()).get(),
schema.get(), NULL, std::string(), JSONSchemaValidator::kInvalidChoice);
instance->SetInteger("foo", 42);
ExpectNotValid(TEST_SOURCE,
instance.get(),
schema.get(),
NULL,
std::string(),
JSONSchemaValidator::kInvalidChoice);
}
void JSONSchemaValidatorTestBase::TestExtends() {
// TODO(aa): JS only
}
void JSONSchemaValidatorTestBase::TestObject() {
std::unique_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
schema->SetString(schema::kType, schema::kObject);
schema->SetString("properties.foo.type", schema::kString);
schema->SetString("properties.bar.type", schema::kInteger);
std::unique_ptr<base::DictionaryValue> instance(new base::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,
schema::kInteger,
schema::kString));
instance->SetInteger("bar", 42);
// Test "patternProperties".
instance->SetInteger("extra", 42);
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
"extra", JSONSchemaValidator::kUnexpectedProperty);
schema->SetString("patternProperties.extra+.type",
schema::kInteger);
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
instance->Remove("extra", NULL);
instance->SetInteger("extraaa", 42);
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
instance->Remove("extraaa", NULL);
instance->SetInteger("extr", 42);
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
"extr", JSONSchemaValidator::kUnexpectedProperty);
instance->Remove("extr", NULL);
schema->Remove(schema::kPatternProperties, NULL);
// Test "patternProperties" and "properties" schemas are both checked if
// applicable.
schema->SetString("patternProperties.fo+.type", schema::kInteger);
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "foo",
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType,
schema::kInteger,
schema::kString));
instance->SetInteger("foo", 123);
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "foo",
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType,
schema::kString,
schema::kInteger));
instance->SetString("foo", "foo");
schema->Remove(schema::kPatternProperties, NULL);
// Test additional properties.
base::DictionaryValue* additional_properties = new base::DictionaryValue();
additional_properties->SetString(schema::kType, schema::kAny);
schema->Set(schema::kAdditionalProperties, additional_properties);
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(schema::kType, schema::kBoolean);
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,
schema::kBoolean,
schema::kString));
instance->Remove("extra", NULL);
base::DictionaryValue* properties = NULL;
base::DictionaryValue* bar_property = NULL;
ASSERT_TRUE(schema->GetDictionary(schema::kProperties, &properties));
ASSERT_TRUE(properties->GetDictionary("bar", &bar_property));
bar_property->SetBoolean(schema::kOptional, true);
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
instance->Remove("bar", NULL);
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
instance->Set("bar", base::MakeUnique<base::Value>());
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
"bar", JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType,
schema::kInteger,
schema::kNull));
instance->SetString("bar", "42");
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
"bar", JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType,
schema::kInteger,
schema::kString));
// Verify that JSON parser handles dot in "patternProperties" well.
schema.reset(LoadDictionary("pattern_properties_dot.json"));
ASSERT_TRUE(schema->GetDictionary(schema::kPatternProperties, &properties));
ASSERT_TRUE(properties->HasKey("^.$"));
instance.reset(new base::DictionaryValue());
instance->SetString("a", "whatever");
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
instance->SetString("foo", "bar");
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
"foo", JSONSchemaValidator::kUnexpectedProperty);
}
void JSONSchemaValidatorTestBase::TestTypeReference() {
std::unique_ptr<base::ListValue> types(LoadList("reference_types.json"));
ASSERT_TRUE(types.get());
std::unique_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
schema->SetString(schema::kType, schema::kObject);
schema->SetString("properties.foo.type", schema::kString);
schema->SetString("properties.bar.$ref", "Max10Int");
schema->SetString("properties.baz.$ref", "MinLengthString");
std::unique_ptr<base::DictionaryValue> schema_inline(
new base::DictionaryValue());
schema_inline->SetString(schema::kType, schema::kObject);
schema_inline->SetString("properties.foo.type", schema::kString);
schema_inline->SetString("properties.bar.id", "NegativeInt");
schema_inline->SetString("properties.bar.type", schema::kInteger);
schema_inline->SetInteger("properties.bar.maximum", 0);
schema_inline->SetString("properties.baz.$ref", "NegativeInt");
std::unique_ptr<base::DictionaryValue> instance(new base::DictionaryValue());
instance->SetString("foo", "foo");
instance->SetInteger("bar", 4);
instance->SetString("baz", "ab");
std::unique_ptr<base::DictionaryValue> instance_inline(
new base::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() {
std::unique_ptr<base::DictionaryValue> schema(
LoadDictionary("array_tuple_schema.json"));
ASSERT_TRUE(schema.get());
std::unique_ptr<base::ListValue> instance(new base::ListValue());
instance->AppendString("42");
instance->AppendInteger(42);
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
instance->AppendString("anything");
ExpectNotValid(TEST_SOURCE,
instance.get(),
schema.get(),
NULL,
std::string(),
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, new base::Value(42));
instance->AppendInteger(42);
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType,
schema::kString,
schema::kInteger));
base::DictionaryValue* additional_properties = new base::DictionaryValue();
additional_properties->SetString(schema::kType, schema::kAny);
schema->Set(schema::kAdditionalProperties, additional_properties);
instance->Set(0, new base::Value("42"));
instance->AppendString("anything");
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
instance->Set(2, new base::ListValue());
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
additional_properties->SetString(schema::kType, schema::kBoolean);
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "2",
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType,
schema::kBoolean,
schema::kArray));
instance->Set(2, new base::Value(false));
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
base::ListValue* items_schema = NULL;
base::DictionaryValue* item0_schema = NULL;
ASSERT_TRUE(schema->GetList(schema::kItems, &items_schema));
ASSERT_TRUE(items_schema->GetDictionary(0, &item0_schema));
item0_schema->SetBoolean(schema::kOptional, 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, base::MakeUnique<base::Value>());
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
instance->Set(0, new base::Value(42));
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType,
schema::kString,
schema::kInteger));
}
void JSONSchemaValidatorTestBase::TestArrayNonTuple() {
std::unique_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
schema->SetString(schema::kType, schema::kArray);
schema->SetString("items.type", schema::kString);
schema->SetInteger(schema::kMinItems, 2);
schema->SetInteger(schema::kMaxItems, 3);
std::unique_ptr<base::ListValue> instance(new base::ListValue());
instance->AppendString("x");
instance->AppendString("x");
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
instance->AppendString("x");
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
instance->AppendString("x");
ExpectNotValid(TEST_SOURCE,
instance.get(),
schema.get(),
NULL,
std::string(),
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,
std::string(),
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kArrayMinItems, "2"));
instance->Remove(1, NULL);
instance->AppendInteger(42);
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType,
schema::kString,
schema::kInteger));
}
void JSONSchemaValidatorTestBase::TestString() {
std::unique_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
schema->SetString(schema::kType, schema::kString);
schema->SetInteger(schema::kMinLength, 1);
schema->SetInteger(schema::kMaxLength, 10);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value("x")).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value("xxxxxxxxxx")).get(),
schema.get(), NULL);
ExpectNotValid(
TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(std::string())).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kStringMinLength, "1"));
ExpectNotValid(
TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value("xxxxxxxxxxx")).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kStringMaxLength, "10"));
}
void JSONSchemaValidatorTestBase::TestNumber() {
std::unique_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
schema->SetString(schema::kType, schema::kNumber);
schema->SetInteger(schema::kMinimum, 1);
schema->SetInteger(schema::kMaximum, 100);
schema->SetInteger("maxDecimal", 2);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(1)).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(50)).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(100)).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(88.88)).get(),
schema.get(), NULL);
ExpectNotValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(0.5)).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kNumberMinimum, "1"));
ExpectNotValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(100.1)).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kNumberMaximum, "100"));
}
void JSONSchemaValidatorTestBase::TestTypeClassifier() {
EXPECT_EQ(std::string(schema::kBoolean),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(new base::Value(true)).get()));
EXPECT_EQ(std::string(schema::kBoolean),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(new base::Value(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(std::string(schema::kInteger),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(new base::Value(42)).get()));
EXPECT_EQ(std::string(schema::kInteger),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(new base::Value(0)).get()));
EXPECT_EQ(std::string(schema::kInteger),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(new base::Value(42)).get()));
EXPECT_EQ(
std::string(schema::kInteger),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(new base::Value(pow(2.0, DBL_MANT_DIG)))
.get()));
EXPECT_EQ(
std::string(schema::kInteger),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(new base::Value(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(std::string(schema::kNumber),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(new base::Value(88.8)).get()));
EXPECT_EQ(std::string(schema::kNumber),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(
new base::Value(pow(2.0, DBL_MANT_DIG) * 2))
.get()));
EXPECT_EQ(std::string(schema::kNumber),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(
new base::Value(pow(-2.0, DBL_MANT_DIG) * 2))
.get()));
EXPECT_EQ(std::string(schema::kString),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(new base::Value("foo")).get()));
EXPECT_EQ(std::string(schema::kArray),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(new base::ListValue()).get()));
EXPECT_EQ(
std::string(schema::kObject),
JSONSchemaValidator::GetJSONSchemaType(
std::unique_ptr<base::Value>(new base::DictionaryValue()).get()));
EXPECT_EQ(std::string(schema::kNull),
JSONSchemaValidator::GetJSONSchemaType(
base::MakeUnique<base::Value>().get()));
}
void JSONSchemaValidatorTestBase::TestTypes() {
std::unique_ptr<base::DictionaryValue> schema(new base::DictionaryValue());
// valid
schema->SetString(schema::kType, schema::kObject);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::DictionaryValue()).get(),
schema.get(), NULL);
schema->SetString(schema::kType, schema::kArray);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::ListValue()).get(),
schema.get(), NULL);
schema->SetString(schema::kType, schema::kString);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value("foobar")).get(),
schema.get(), NULL);
schema->SetString(schema::kType, schema::kNumber);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(88.8)).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(42)).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(42)).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(0)).get(),
schema.get(), NULL);
schema->SetString(schema::kType, schema::kInteger);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(42)).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(42)).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(0)).get(),
schema.get(), NULL);
ExpectValid(
TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(pow(2.0, DBL_MANT_DIG)))
.get(),
schema.get(), NULL);
ExpectValid(
TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(pow(-2.0, DBL_MANT_DIG)))
.get(),
schema.get(), NULL);
schema->SetString(schema::kType, schema::kBoolean);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(false)).get(),
schema.get(), NULL);
ExpectValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(true)).get(),
schema.get(), NULL);
schema->SetString(schema::kType, schema::kNull);
ExpectValid(TEST_SOURCE, base::MakeUnique<base::Value>().get(), schema.get(),
NULL);
// not valid
schema->SetString(schema::kType, schema::kObject);
ExpectNotValid(
TEST_SOURCE, std::unique_ptr<base::Value>(new base::ListValue()).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::FormatErrorMessage(JSONSchemaValidator::kInvalidType,
schema::kObject, schema::kArray));
schema->SetString(schema::kType, schema::kObject);
ExpectNotValid(
TEST_SOURCE, base::MakeUnique<base::Value>().get(), schema.get(), NULL,
std::string(),
JSONSchemaValidator::FormatErrorMessage(JSONSchemaValidator::kInvalidType,
schema::kObject, schema::kNull));
schema->SetString(schema::kType, schema::kArray);
ExpectNotValid(
TEST_SOURCE, std::unique_ptr<base::Value>(new base::Value(42)).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType, schema::kArray, schema::kInteger));
schema->SetString(schema::kType, schema::kString);
ExpectNotValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(42)).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType, schema::kString,
schema::kInteger));
schema->SetString(schema::kType, schema::kNumber);
ExpectNotValid(
TEST_SOURCE, std::unique_ptr<base::Value>(new base::Value("42")).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType, schema::kNumber, schema::kString));
schema->SetString(schema::kType, schema::kInteger);
ExpectNotValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(88.8)).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::kInvalidTypeIntegerNumber);
schema->SetString(schema::kType, schema::kBoolean);
ExpectNotValid(TEST_SOURCE,
std::unique_ptr<base::Value>(new base::Value(1)).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType, schema::kBoolean,
schema::kInteger));
schema->SetString(schema::kType, schema::kNull);
ExpectNotValid(
TEST_SOURCE, std::unique_ptr<base::Value>(new base::Value(false)).get(),
schema.get(), NULL, std::string(),
JSONSchemaValidator::FormatErrorMessage(JSONSchemaValidator::kInvalidType,
schema::kNull, schema::kBoolean));
}