1// Copyright 2013 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 "base/values.h"
6#include "components/json_schema/json_schema_validator.h"
7#include "components/json_schema/json_schema_validator_unittest_base.h"
8#include "testing/gtest/include/gtest/gtest.h"
9
10class JSONSchemaValidatorCPPTest : public JSONSchemaValidatorTestBase {
11 public:
12  JSONSchemaValidatorCPPTest() : JSONSchemaValidatorTestBase() {}
13
14 protected:
15  virtual void ExpectValid(const std::string& test_source,
16                           base::Value* instance,
17                           base::DictionaryValue* schema,
18                           base::ListValue* types) OVERRIDE {
19    JSONSchemaValidator validator(schema, types);
20    if (validator.Validate(instance))
21      return;
22
23    for (size_t i = 0; i < validator.errors().size(); ++i) {
24      ADD_FAILURE() << test_source << ": "
25                    << validator.errors()[i].path << ": "
26                    << validator.errors()[i].message;
27    }
28  }
29
30  virtual void ExpectNotValid(
31      const std::string& test_source,
32      base::Value* instance, base::DictionaryValue* schema,
33      base::ListValue* types,
34      const std::string& expected_error_path,
35      const std::string& expected_error_message) OVERRIDE {
36    JSONSchemaValidator validator(schema, types);
37    if (validator.Validate(instance)) {
38      ADD_FAILURE() << test_source;
39      return;
40    }
41
42    ASSERT_EQ(1u, validator.errors().size()) << test_source;
43    EXPECT_EQ(expected_error_path, validator.errors()[0].path) << test_source;
44    EXPECT_EQ(expected_error_message, validator.errors()[0].message)
45        << test_source;
46  }
47};
48
49TEST_F(JSONSchemaValidatorCPPTest, Test) {
50  RunTests();
51}
52
53TEST(JSONSchemaValidator, IsValidSchema) {
54  std::string error;
55  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("", &error));
56  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("\0", &error));
57  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("string", &error));
58  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("\"string\"", &error));
59  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("[]", &error));
60  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema("{}", &error));
61  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
62      "{ \"type\": 123 }", &error));
63  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
64      "{ \"type\": \"invalid\" }", &error));
65  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
66      "{"
67      "  \"type\": \"object\","
68      "  \"properties\": []"  // Invalid properties type.
69      "}", &error));
70  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
71      "{"
72      "  \"type\": \"string\","
73      "  \"maxLength\": -1"  // Must be >= 0.
74      "}", &error));
75  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
76      "{"
77      "  \"type\": \"string\","
78      "  \"enum\": [ {} ]"  // "enum" dict values must contain "name".
79      "}", &error));
80  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
81      "{"
82      "  \"type\": \"string\","
83      "  \"enum\": [ { \"name\": {} } ]"  // "enum" name must be a simple value.
84      "}", &error));
85  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
86      "{"
87      "  \"type\": \"array\","
88      "  \"items\": [ 123 ],"  // "items" must contain a schema or schemas.
89      "}", &error));
90  EXPECT_TRUE(JSONSchemaValidator::IsValidSchema(
91      "{ \"type\": \"object\" }", &error)) << error;
92  EXPECT_TRUE(JSONSchemaValidator::IsValidSchema(
93      "{ \"type\": [\"object\", \"array\"] }", &error)) << error;
94  EXPECT_TRUE(JSONSchemaValidator::IsValidSchema(
95      "{"
96      "  \"type\": [\"object\", \"array\"],"
97      "  \"properties\": {"
98      "    \"string-property\": {"
99      "      \"type\": \"string\","
100      "      \"minLength\": 1,"
101      "      \"maxLength\": 100,"
102      "      \"title\": \"The String Policy\","
103      "      \"description\": \"This policy controls the String widget.\""
104      "    },"
105      "    \"integer-property\": {"
106      "      \"type\": \"number\","
107      "      \"minimum\": 1000.0,"
108      "      \"maximum\": 9999.0"
109      "    },"
110      "    \"enum-property\": {"
111      "      \"type\": \"integer\","
112      "      \"enum\": [0, 1, {\"name\": 10}, 100]"
113      "    },"
114      "    \"items-property\": {"
115      "      \"type\": \"array\","
116      "      \"items\": {"
117      "        \"type\": \"string\""
118      "      }"
119      "    },"
120      "    \"items-list-property\": {"
121      "      \"type\": \"array\","
122      "      \"items\": ["
123      "        { \"type\": \"string\" },"
124      "        { \"type\": \"integer\" }"
125      "      ]"
126      "    }"
127      "  },"
128      "  \"additionalProperties\": {"
129      "    \"type\": \"any\""
130      "  }"
131      "}", &error)) << error;
132  EXPECT_TRUE(JSONSchemaValidator::IsValidSchema(
133      "{"
134      "  \"type\": \"object\","
135      "  \"patternProperties\": {"
136      "    \".\": { \"type\": \"any\" },"
137      "    \"foo\": { \"type\": \"any\" },"
138      "    \"^foo$\": { \"type\": \"any\" },"
139      "    \"foo+\": { \"type\": \"any\" },"
140      "    \"foo?\": { \"type\": \"any\" },"
141      "    \"fo{2,4}\": { \"type\": \"any\" },"
142      "    \"(left)|(right)\": { \"type\": \"any\" }"
143      "  }"
144      "}", &error)) << error;
145  EXPECT_TRUE(JSONSchemaValidator::IsValidSchema(
146      "{"
147      "  \"type\": \"object\","
148      "  \"unknown attribute\": \"that should just be ignored\""
149      "}",
150      JSONSchemaValidator::OPTIONS_IGNORE_UNKNOWN_ATTRIBUTES,
151      &error)) << error;
152  EXPECT_FALSE(JSONSchemaValidator::IsValidSchema(
153      "{"
154      "  \"type\": \"object\","
155      "  \"unknown attribute\": \"that will cause a failure\""
156      "}", 0, &error)) << error;
157}
158