Chromium Code Reviews| Index: components/policy/core/common/schema_unittest.cc |
| diff --git a/components/policy/core/common/schema_unittest.cc b/components/policy/core/common/schema_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d5c3af141a1ddb32c4e520dd3bb09dc81c3eb4f0 |
| --- /dev/null |
| +++ b/components/policy/core/common/schema_unittest.cc |
| @@ -0,0 +1,355 @@ |
| +// 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/policy/core/common/schema.h" |
| + |
| +#include "components/policy/core/common/schema_internal.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace policy { |
| + |
| +namespace schema { |
| + |
| +namespace { |
| + |
| +#define SCHEMA_VERSION "\"$schema\":\"http://json-schema.org/draft-03/schema#\"" |
| +#define OBJECT_TYPE "\"type\":\"object\"" |
| + |
| +const internal::SchemaNode kTypeBoolean = { base::Value::TYPE_BOOLEAN, NULL, }; |
| +const internal::SchemaNode kTypeInteger = { base::Value::TYPE_INTEGER, NULL, }; |
| +const internal::SchemaNode kTypeNumber = { base::Value::TYPE_DOUBLE, NULL, }; |
| +const internal::SchemaNode kTypeString = { base::Value::TYPE_STRING, NULL, }; |
| + |
| +bool ParseFails(const std::string& content) { |
| + std::string error; |
| + scoped_ptr<PolicySchema> schema = PolicySchema::Parse(content, &error); |
| + if (schema) |
| + EXPECT_TRUE(schema->schema().valid()); |
| + else |
| + EXPECT_FALSE(error.empty()); |
| + return !schema; |
| +} |
| + |
| +} // namespace |
| + |
| +TEST(SchemaTest, MinimalSchema) { |
|
Mattias Nissler (ping if slow)
2013/09/13 12:56:48
Why not include this test in InvalidSchemas?
Joao da Silva
2013/09/13 14:02:54
This schema is valid, and this is just testing tha
Mattias Nissler (ping if slow)
2013/09/13 14:55:17
Right, sorry. I failed to parse the double negatio
|
| + EXPECT_FALSE(ParseFails( |
| + "{" |
| + SCHEMA_VERSION "," |
| + OBJECT_TYPE |
| + "}")); |
| +} |
| + |
| +TEST(SchemaTest, InvalidSchemas) { |
| + EXPECT_TRUE(ParseFails("")); |
| + EXPECT_TRUE(ParseFails("omg")); |
| + EXPECT_TRUE(ParseFails("\"omg\"")); |
| + EXPECT_TRUE(ParseFails("123")); |
| + EXPECT_TRUE(ParseFails("[]")); |
| + EXPECT_TRUE(ParseFails("null")); |
| + EXPECT_TRUE(ParseFails("{}")); |
| + EXPECT_TRUE(ParseFails("{" SCHEMA_VERSION "}")); |
| + EXPECT_TRUE(ParseFails("{" OBJECT_TYPE "}")); |
| + |
| + EXPECT_TRUE(ParseFails( |
| + "{" |
| + SCHEMA_VERSION "," |
| + OBJECT_TYPE "," |
| + "\"additionalProperties\": { \"type\":\"object\" }" |
| + "}")); |
| + |
| + EXPECT_TRUE(ParseFails( |
| + "{" |
| + SCHEMA_VERSION "," |
| + OBJECT_TYPE "," |
| + "\"patternProperties\": { \"a+b*\": { \"type\": \"object\" } }" |
| + "}")); |
| + |
| + EXPECT_TRUE(ParseFails( |
| + "{" |
| + SCHEMA_VERSION "," |
| + OBJECT_TYPE "," |
| + "\"properties\": { \"Policy\": { \"type\": \"bogus\" } }" |
| + "}")); |
| + |
| + EXPECT_TRUE(ParseFails( |
| + "{" |
| + SCHEMA_VERSION "," |
| + OBJECT_TYPE "," |
| + "\"properties\": { \"Policy\": { \"type\": [\"string\", \"number\"] } }" |
| + "}")); |
| + |
| + EXPECT_TRUE(ParseFails( |
| + "{" |
| + SCHEMA_VERSION "," |
| + OBJECT_TYPE "," |
| + "\"properties\": { \"Policy\": { \"type\": \"any\" } }" |
| + "}")); |
| +} |
| + |
| +TEST(SchemaTest, ValidSchema) { |
| + std::string error; |
| + scoped_ptr<PolicySchema> policy_schema = PolicySchema::Parse( |
| + "{" |
| + SCHEMA_VERSION "," |
| + OBJECT_TYPE "," |
| + "\"properties\": {" |
| + " \"Boolean\": { \"type\": \"boolean\" }," |
| + " \"Integer\": { \"type\": \"integer\" }," |
| + " \"Null\": { \"type\": \"null\" }," |
| + " \"Number\": { \"type\": \"number\" }," |
| + " \"String\": { \"type\": \"string\" }," |
| + " \"Array\": {" |
| + " \"type\": \"array\"," |
| + " \"items\": { \"type\": \"string\" }" |
| + " }," |
| + " \"ArrayOfObjects\": {" |
| + " \"type\": \"array\"," |
| + " \"items\": {" |
| + " \"type\": \"object\"," |
| + " \"properties\": {" |
| + " \"one\": { \"type\": \"string\" }," |
| + " \"two\": { \"type\": \"integer\" }" |
| + " }" |
| + " }" |
| + " }," |
| + " \"ArrayOfArray\": {" |
| + " \"type\": \"array\"," |
| + " \"items\": {" |
| + " \"type\": \"array\"," |
| + " \"items\": { \"type\": \"string\" }" |
| + " }" |
| + " }," |
| + " \"Object\": {" |
| + " \"type\": \"object\"," |
| + " \"properties\": {" |
| + " \"one\": { \"type\": \"boolean\" }," |
| + " \"two\": { \"type\": \"integer\" }" |
| + " }," |
| + " \"additionalProperties\": { \"type\": \"string\" }" |
| + " }" |
| + "}" |
| + "}", &error); |
| + ASSERT_TRUE(policy_schema) << error; |
| + ASSERT_TRUE(policy_schema->schema().valid()); |
| + |
| + Schema schema = policy_schema->schema(); |
| + ASSERT_EQ(base::Value::TYPE_DICTIONARY, schema.type()); |
| + EXPECT_FALSE(schema.GetProperty("invalid").valid()); |
| + |
| + Schema sub = schema.GetProperty("Boolean"); |
| + ASSERT_TRUE(sub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_BOOLEAN, sub.type()); |
| + |
| + sub = schema.GetProperty("Integer"); |
| + ASSERT_TRUE(sub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_INTEGER, sub.type()); |
| + |
| + sub = schema.GetProperty("Null"); |
| + ASSERT_TRUE(sub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_NULL, sub.type()); |
| + |
| + sub = schema.GetProperty("Number"); |
| + ASSERT_TRUE(sub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_DOUBLE, sub.type()); |
| + |
| + sub = schema.GetProperty("String"); |
| + ASSERT_TRUE(sub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_STRING, sub.type()); |
| + |
| + sub = schema.GetProperty("Array"); |
| + ASSERT_TRUE(sub.valid()); |
| + ASSERT_EQ(base::Value::TYPE_LIST, sub.type()); |
| + sub = sub.GetItems(); |
| + ASSERT_TRUE(sub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_STRING, sub.type()); |
| + |
| + sub = schema.GetProperty("ArrayOfObjects"); |
| + ASSERT_TRUE(sub.valid()); |
| + ASSERT_EQ(base::Value::TYPE_LIST, sub.type()); |
| + sub = sub.GetItems(); |
| + ASSERT_TRUE(sub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_DICTIONARY, sub.type()); |
| + Schema subsub = sub.GetProperty("one"); |
| + ASSERT_TRUE(subsub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_STRING, subsub.type()); |
| + subsub = sub.GetProperty("two"); |
| + ASSERT_TRUE(subsub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_INTEGER, subsub.type()); |
| + subsub = sub.GetProperty("invalid"); |
| + EXPECT_FALSE(subsub.valid()); |
| + |
| + sub = schema.GetProperty("ArrayOfArray"); |
| + ASSERT_TRUE(sub.valid()); |
| + ASSERT_EQ(base::Value::TYPE_LIST, sub.type()); |
| + sub = sub.GetItems(); |
| + ASSERT_TRUE(sub.valid()); |
| + ASSERT_EQ(base::Value::TYPE_LIST, sub.type()); |
| + sub = sub.GetItems(); |
| + ASSERT_TRUE(sub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_STRING, sub.type()); |
| + |
| + sub = schema.GetProperty("Object"); |
| + ASSERT_TRUE(sub.valid()); |
| + ASSERT_EQ(base::Value::TYPE_DICTIONARY, sub.type()); |
| + subsub = sub.GetProperty("one"); |
| + ASSERT_TRUE(subsub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_BOOLEAN, subsub.type()); |
| + subsub = sub.GetProperty("two"); |
| + ASSERT_TRUE(subsub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_INTEGER, subsub.type()); |
| + subsub = sub.GetProperty("undeclared"); |
| + ASSERT_TRUE(subsub.valid()); |
| + EXPECT_EQ(base::Value::TYPE_STRING, subsub.type()); |
| + |
| + struct { |
| + const char* expected_key; |
| + base::Value::Type expected_type; |
| + } kExpectedProperties[] = { |
| + { "Array", base::Value::TYPE_LIST }, |
| + { "ArrayOfArray", base::Value::TYPE_LIST }, |
| + { "ArrayOfObjects", base::Value::TYPE_LIST }, |
| + { "Boolean", base::Value::TYPE_BOOLEAN }, |
| + { "Integer", base::Value::TYPE_INTEGER }, |
| + { "Null", base::Value::TYPE_NULL }, |
| + { "Number", base::Value::TYPE_DOUBLE }, |
| + { "Object", base::Value::TYPE_DICTIONARY }, |
| + { "String", base::Value::TYPE_STRING }, |
| + }; |
| + Schema::Iterator it = schema.GetPropertiesIterator(); |
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpectedProperties); ++i) { |
| + ASSERT_FALSE(it.IsAtEnd()); |
| + EXPECT_STREQ(kExpectedProperties[i].expected_key, it.key()); |
| + ASSERT_TRUE(it.schema().valid()); |
| + EXPECT_EQ(kExpectedProperties[i].expected_type, it.schema().type()); |
| + it.Advance(); |
| + } |
| + EXPECT_TRUE(it.IsAtEnd()); |
| +} |
| + |
| +TEST(SchemaTest, Lookups) { |
| + std::string error; |
| + scoped_ptr<PolicySchema> policy_schema = PolicySchema::Parse( |
| + "{" |
| + SCHEMA_VERSION "," |
| + OBJECT_TYPE |
| + "}", &error); |
| + ASSERT_TRUE(policy_schema) << error; |
| + Schema schema = policy_schema->schema(); |
| + ASSERT_TRUE(schema.valid()); |
| + ASSERT_EQ(base::Value::TYPE_DICTIONARY, schema.type()); |
| + |
| + // This empty schema should never find named properties. |
| + EXPECT_FALSE(schema.GetKnownProperty("").valid()); |
| + EXPECT_FALSE(schema.GetKnownProperty("xyz").valid()); |
| + EXPECT_TRUE(schema.GetPropertiesIterator().IsAtEnd()); |
| + |
| + policy_schema = PolicySchema::Parse( |
| + "{" |
| + SCHEMA_VERSION "," |
| + OBJECT_TYPE "," |
| + "\"properties\": {" |
| + " \"Boolean\": { \"type\": \"boolean\" }" |
| + "}" |
| + "}", &error); |
| + ASSERT_TRUE(policy_schema) << error; |
| + schema = policy_schema->schema(); |
| + ASSERT_TRUE(schema.valid()); |
| + ASSERT_EQ(base::Value::TYPE_DICTIONARY, schema.type()); |
| + |
| + EXPECT_FALSE(schema.GetKnownProperty("").valid()); |
| + EXPECT_FALSE(schema.GetKnownProperty("xyz").valid()); |
| + EXPECT_TRUE(schema.GetKnownProperty("Boolean").valid()); |
| + |
| + policy_schema = PolicySchema::Parse( |
| + "{" |
| + SCHEMA_VERSION "," |
| + OBJECT_TYPE "," |
| + "\"properties\": {" |
| + " \"bb\" : { \"type\": \"null\" }," |
| + " \"aa\" : { \"type\": \"boolean\" }," |
| + " \"abab\" : { \"type\": \"string\" }," |
| + " \"ab\" : { \"type\": \"number\" }," |
| + " \"aba\" : { \"type\": \"integer\" }" |
| + "}" |
| + "}", &error); |
| + ASSERT_TRUE(policy_schema) << error; |
| + schema = policy_schema->schema(); |
| + ASSERT_TRUE(schema.valid()); |
| + ASSERT_EQ(base::Value::TYPE_DICTIONARY, schema.type()); |
| + |
| + EXPECT_FALSE(schema.GetKnownProperty("").valid()); |
| + EXPECT_FALSE(schema.GetKnownProperty("xyz").valid()); |
| + |
| + struct { |
| + const char* expected_key; |
| + base::Value::Type expected_type; |
| + } kExpectedKeys[] = { |
| + { "aa", base::Value::TYPE_BOOLEAN }, |
| + { "ab", base::Value::TYPE_DOUBLE }, |
| + { "aba", base::Value::TYPE_INTEGER }, |
| + { "abab", base::Value::TYPE_STRING }, |
| + { "bb", base::Value::TYPE_NULL }, |
| + }; |
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpectedKeys); ++i) { |
| + Schema sub = schema.GetKnownProperty(kExpectedKeys[i].expected_key); |
| + ASSERT_TRUE(sub.valid()); |
| + EXPECT_EQ(kExpectedKeys[i].expected_type, sub.type()); |
| + } |
| +} |
| + |
| +TEST(SchemaTest, WrapSimpleNode) { |
| + scoped_ptr<PolicySchema> policy_schema = PolicySchema::Wrap(&kTypeString); |
| + ASSERT_TRUE(policy_schema); |
| + Schema schema = policy_schema->schema(); |
| + ASSERT_TRUE(schema.valid()); |
| + EXPECT_EQ(base::Value::TYPE_STRING, schema.type()); |
| +} |
| + |
| +TEST(SchemaTest, WrapDictionary) { |
| + const internal::SchemaNode kList = { |
| + base::Value::TYPE_LIST, |
| + &kTypeString, |
| + }; |
| + |
| + const internal::PropertyNode kPropertyNodes[] = { |
| + { "Boolean", &kTypeBoolean }, |
| + { "Integer", &kTypeInteger }, |
| + { "List", &kList }, |
| + { "Number", &kTypeNumber }, |
| + { "String", &kTypeString }, |
| + }; |
| + |
| + const internal::PropertiesNode kProperties = { |
| + kPropertyNodes, |
| + kPropertyNodes + arraysize(kPropertyNodes), |
| + NULL, |
| + }; |
| + |
| + const internal::SchemaNode root = { |
| + base::Value::TYPE_DICTIONARY, |
| + &kProperties, |
| + }; |
| + |
| + scoped_ptr<PolicySchema> policy_schema = PolicySchema::Wrap(&root); |
| + ASSERT_TRUE(policy_schema); |
| + Schema schema = policy_schema->schema(); |
| + ASSERT_TRUE(schema.valid()); |
| + EXPECT_EQ(base::Value::TYPE_DICTIONARY, schema.type()); |
| + |
| + Schema::Iterator it = schema.GetPropertiesIterator(); |
| + for (size_t i = 0; i < arraysize(kPropertyNodes); ++i) { |
| + ASSERT_FALSE(it.IsAtEnd()); |
| + EXPECT_STREQ(kPropertyNodes[i].key, it.key()); |
| + Schema sub = it.schema(); |
| + ASSERT_TRUE(sub.valid()); |
| + EXPECT_EQ(kPropertyNodes[i].schema->type, sub.type()); |
| + it.Advance(); |
| + } |
| + EXPECT_TRUE(it.IsAtEnd()); |
| +} |
| + |
| +} // namespace schema |
| + |
| +} // namespace policy |