| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  | // Tencent is pleased to support the open source community by making RapidJSON available.
 | 
					
						
							|  |  |  | // 
 | 
					
						
							|  |  |  | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Licensed under the MIT License (the "License"); you may not use this file except
 | 
					
						
							|  |  |  | // in compliance with the License. You may obtain a copy of the License at
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // http://opensource.org/licenses/MIT
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software distributed 
 | 
					
						
							|  |  |  | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
 | 
					
						
							|  |  |  | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 
 | 
					
						
							|  |  |  | // specific language governing permissions and limitations under the License.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define RAPIDJSON_SCHEMA_VERBOSE 0
 | 
					
						
							|  |  |  | #define RAPIDJSON_HAS_STDSTRING 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "unittest.h"
 | 
					
						
							|  |  |  | #include "rapidjson/schema.h"
 | 
					
						
							|  |  |  | #include "rapidjson/stringbuffer.h"
 | 
					
						
							|  |  |  | #include "rapidjson/writer.h"
 | 
					
						
							|  |  |  | #include "rapidjson/error/error.h"
 | 
					
						
							|  |  |  | #include "rapidjson/error/en.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef __clang__
 | 
					
						
							|  |  |  | RAPIDJSON_DIAG_PUSH | 
					
						
							|  |  |  | RAPIDJSON_DIAG_OFF(variadic-macros) | 
					
						
							|  |  |  | #elif defined(_MSC_VER)
 | 
					
						
							|  |  |  | RAPIDJSON_DIAG_PUSH | 
					
						
							|  |  |  | RAPIDJSON_DIAG_OFF(4822) // local class member function does not have a body
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using namespace rapidjson; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define TEST_HASHER(json1, json2, expected) \
 | 
					
						
							|  |  |  | {\ | 
					
						
							|  |  |  |     Document d1, d2;\ | 
					
						
							|  |  |  |     d1.Parse(json1);\ | 
					
						
							|  |  |  |     ASSERT_FALSE(d1.HasParseError());\ | 
					
						
							|  |  |  |     d2.Parse(json2);\ | 
					
						
							|  |  |  |     ASSERT_FALSE(d2.HasParseError());\ | 
					
						
							|  |  |  |     internal::Hasher<Value, CrtAllocator> h1, h2;\ | 
					
						
							|  |  |  |     d1.Accept(h1);\ | 
					
						
							|  |  |  |     d2.Accept(h2);\ | 
					
						
							|  |  |  |     ASSERT_TRUE(h1.IsValid());\ | 
					
						
							|  |  |  |     ASSERT_TRUE(h2.IsValid());\ | 
					
						
							|  |  |  |     /*printf("%s: 0x%016llx\n%s: 0x%016llx\n\n", json1, h1.GetHashCode(), json2, h2.GetHashCode());*/\ | 
					
						
							|  |  |  |     EXPECT_TRUE(expected == (h1.GetHashCode() == h2.GetHashCode()));\ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Hasher) { | 
					
						
							|  |  |  |     TEST_HASHER("null", "null", true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TEST_HASHER("true", "true", true); | 
					
						
							|  |  |  |     TEST_HASHER("false", "false", true); | 
					
						
							|  |  |  |     TEST_HASHER("true", "false", false); | 
					
						
							|  |  |  |     TEST_HASHER("false", "true", false); | 
					
						
							|  |  |  |     TEST_HASHER("true", "null", false); | 
					
						
							|  |  |  |     TEST_HASHER("false", "null", false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TEST_HASHER("1", "1", true); | 
					
						
							|  |  |  |     TEST_HASHER("2147483648", "2147483648", true); // 2^31 can only be fit in unsigned
 | 
					
						
							|  |  |  |     TEST_HASHER("-2147483649", "-2147483649", true); // -2^31 - 1 can only be fit in int64_t
 | 
					
						
							|  |  |  |     TEST_HASHER("2147483648", "2147483648", true); // 2^31 can only be fit in unsigned
 | 
					
						
							|  |  |  |     TEST_HASHER("4294967296", "4294967296", true); // 2^32 can only be fit in int64_t
 | 
					
						
							|  |  |  |     TEST_HASHER("9223372036854775808", "9223372036854775808", true); // 2^63 can only be fit in uint64_t
 | 
					
						
							|  |  |  |     TEST_HASHER("1.5", "1.5", true); | 
					
						
							|  |  |  |     TEST_HASHER("1", "1.0", true); | 
					
						
							|  |  |  |     TEST_HASHER("1", "-1", false); | 
					
						
							|  |  |  |     TEST_HASHER("0.0", "-0.0", false); | 
					
						
							|  |  |  |     TEST_HASHER("1", "true", false); | 
					
						
							|  |  |  |     TEST_HASHER("0", "false", false); | 
					
						
							|  |  |  |     TEST_HASHER("0", "null", false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TEST_HASHER("\"\"", "\"\"", true); | 
					
						
							|  |  |  |     TEST_HASHER("\"\"", "\"\\u0000\"", false); | 
					
						
							|  |  |  |     TEST_HASHER("\"Hello\"", "\"Hello\"", true); | 
					
						
							|  |  |  |     TEST_HASHER("\"Hello\"", "\"World\"", false); | 
					
						
							|  |  |  |     TEST_HASHER("\"Hello\"", "null", false); | 
					
						
							|  |  |  |     TEST_HASHER("\"Hello\\u0000\"", "\"Hello\"", false); | 
					
						
							|  |  |  |     TEST_HASHER("\"\"", "null", false); | 
					
						
							|  |  |  |     TEST_HASHER("\"\"", "true", false); | 
					
						
							|  |  |  |     TEST_HASHER("\"\"", "false", false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TEST_HASHER("[]", "[ ]", true); | 
					
						
							|  |  |  |     TEST_HASHER("[1, true, false]", "[1, true, false]", true); | 
					
						
							|  |  |  |     TEST_HASHER("[1, true, false]", "[1, true]", false); | 
					
						
							|  |  |  |     TEST_HASHER("[1, 2]", "[2, 1]", false); | 
					
						
							|  |  |  |     TEST_HASHER("[[1], 2]", "[[1, 2]]", false); | 
					
						
							|  |  |  |     TEST_HASHER("[1, 2]", "[1, [2]]", false); | 
					
						
							|  |  |  |     TEST_HASHER("[]", "null", false); | 
					
						
							|  |  |  |     TEST_HASHER("[]", "true", false); | 
					
						
							|  |  |  |     TEST_HASHER("[]", "false", false); | 
					
						
							|  |  |  |     TEST_HASHER("[]", "0", false); | 
					
						
							|  |  |  |     TEST_HASHER("[]", "0.0", false); | 
					
						
							|  |  |  |     TEST_HASHER("[]", "\"\"", false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TEST_HASHER("{}", "{ }", true); | 
					
						
							|  |  |  |     TEST_HASHER("{\"a\":1}", "{\"a\":1}", true); | 
					
						
							|  |  |  |     TEST_HASHER("{\"a\":1}", "{\"b\":1}", false); | 
					
						
							|  |  |  |     TEST_HASHER("{\"a\":1}", "{\"a\":2}", false); | 
					
						
							|  |  |  |     TEST_HASHER("{\"a\":1, \"b\":2}", "{\"b\":2, \"a\":1}", true); // Member order insensitive
 | 
					
						
							|  |  |  |     TEST_HASHER("{}", "null", false); | 
					
						
							|  |  |  |     TEST_HASHER("{}", "false", false); | 
					
						
							|  |  |  |     TEST_HASHER("{}", "true", false); | 
					
						
							|  |  |  |     TEST_HASHER("{}", "0", false); | 
					
						
							|  |  |  |     TEST_HASHER("{}", "0.0", false); | 
					
						
							|  |  |  |     TEST_HASHER("{}", "\"\"", false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test cases following http://spacetelescope.github.io/understanding-json-schema
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define VALIDATE(schema, json, expected) \
 | 
					
						
							|  |  |  | {\ | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |     VALIDATE_(schema, json, expected, true) \ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define VALIDATE_(schema, json, expected, expected2) \
 | 
					
						
							|  |  |  | {\ | 
					
						
							|  |  |  |     EXPECT_TRUE(expected2 == schema.GetError().ObjectEmpty());\ | 
					
						
							|  |  |  |     EXPECT_TRUE(schema.IsSupportedSpecification());\ | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |     SchemaValidator validator(schema);\ | 
					
						
							|  |  |  |     Document d;\ | 
					
						
							|  |  |  |     /*printf("\n%s\n", json);*/\ | 
					
						
							|  |  |  |     d.Parse(json);\ | 
					
						
							|  |  |  |     EXPECT_FALSE(d.HasParseError());\ | 
					
						
							|  |  |  |     EXPECT_TRUE(expected == d.Accept(validator));\ | 
					
						
							|  |  |  |     EXPECT_TRUE(expected == validator.IsValid());\ | 
					
						
							|  |  |  |     ValidateErrorCode code = validator.GetInvalidSchemaCode();\ | 
					
						
							|  |  |  |     if (expected) {\ | 
					
						
							|  |  |  |       EXPECT_TRUE(code == kValidateErrorNone);\ | 
					
						
							|  |  |  |       EXPECT_TRUE(validator.GetInvalidSchemaKeyword() == 0);\ | 
					
						
							|  |  |  |     }\ | 
					
						
							|  |  |  |     if ((expected) && !validator.IsValid()) {\ | 
					
						
							|  |  |  |         StringBuffer sb;\ | 
					
						
							|  |  |  |         validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);\ | 
					
						
							|  |  |  |         printf("Invalid schema: %s\n", sb.GetString());\ | 
					
						
							|  |  |  |         printf("Invalid keyword: %s\n", validator.GetInvalidSchemaKeyword());\ | 
					
						
							|  |  |  |         printf("Invalid code: %d\n", code);\ | 
					
						
							|  |  |  |         printf("Invalid message: %s\n", GetValidateError_En(code));\ | 
					
						
							|  |  |  |         sb.Clear();\ | 
					
						
							|  |  |  |         validator.GetInvalidDocumentPointer().StringifyUriFragment(sb);\ | 
					
						
							|  |  |  |         printf("Invalid document: %s\n", sb.GetString());\ | 
					
						
							|  |  |  |         sb.Clear();\ | 
					
						
							|  |  |  |         Writer<StringBuffer> w(sb);\ | 
					
						
							|  |  |  |         validator.GetError().Accept(w);\ | 
					
						
							|  |  |  |         printf("Validation error: %s\n", sb.GetString());\ | 
					
						
							|  |  |  |     }\ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define INVALIDATE(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error) \
 | 
					
						
							|  |  |  | {\ | 
					
						
							|  |  |  |     INVALIDATE_(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error, kValidateDefaultFlags, SchemaValidator, Pointer) \ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define INVALIDATE_(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error, \
 | 
					
						
							|  |  |  |     flags, SchemaValidatorType, PointerType) \ | 
					
						
							|  |  |  | {\ | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |     EXPECT_TRUE(schema.GetError().ObjectEmpty());\ | 
					
						
							|  |  |  |     EXPECT_TRUE(schema.IsSupportedSpecification());\ | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |     SchemaValidatorType validator(schema);\ | 
					
						
							|  |  |  |     validator.SetValidateFlags(flags);\ | 
					
						
							|  |  |  |     Document d;\ | 
					
						
							|  |  |  |     /*printf("\n%s\n", json);*/\ | 
					
						
							|  |  |  |     d.Parse(json);\ | 
					
						
							|  |  |  |     EXPECT_FALSE(d.HasParseError());\ | 
					
						
							|  |  |  |     d.Accept(validator);\ | 
					
						
							|  |  |  |     EXPECT_FALSE(validator.IsValid());\ | 
					
						
							|  |  |  |     ValidateErrorCode code = validator.GetInvalidSchemaCode();\ | 
					
						
							|  |  |  |     ASSERT_TRUE(code != kValidateErrorNone);\ | 
					
						
							|  |  |  |     ASSERT_TRUE(strcmp(GetValidateError_En(code), "Unknown error.") != 0);\ | 
					
						
							|  |  |  |     if (validator.GetInvalidSchemaPointer() != PointerType(invalidSchemaPointer)) {\ | 
					
						
							|  |  |  |         StringBuffer sb;\ | 
					
						
							|  |  |  |         validator.GetInvalidSchemaPointer().Stringify(sb);\ | 
					
						
							|  |  |  |         printf("GetInvalidSchemaPointer() Expected: %s Actual: %s\n", invalidSchemaPointer, sb.GetString());\ | 
					
						
							|  |  |  |         ADD_FAILURE();\ | 
					
						
							|  |  |  |     }\ | 
					
						
							|  |  |  |     ASSERT_TRUE(validator.GetInvalidSchemaKeyword() != 0);\ | 
					
						
							|  |  |  |     if (strcmp(validator.GetInvalidSchemaKeyword(), invalidSchemaKeyword) != 0) {\ | 
					
						
							|  |  |  |         printf("GetInvalidSchemaKeyword() Expected: %s Actual %s\n", invalidSchemaKeyword, validator.GetInvalidSchemaKeyword());\ | 
					
						
							|  |  |  |         ADD_FAILURE();\ | 
					
						
							|  |  |  |     }\ | 
					
						
							|  |  |  |     if (validator.GetInvalidDocumentPointer() != PointerType(invalidDocumentPointer)) {\ | 
					
						
							|  |  |  |         StringBuffer sb;\ | 
					
						
							|  |  |  |         validator.GetInvalidDocumentPointer().Stringify(sb);\ | 
					
						
							|  |  |  |         printf("GetInvalidDocumentPointer() Expected: %s Actual: %s\n", invalidDocumentPointer, sb.GetString());\ | 
					
						
							|  |  |  |         ADD_FAILURE();\ | 
					
						
							|  |  |  |     }\ | 
					
						
							|  |  |  |     Document e;\ | 
					
						
							|  |  |  |     e.Parse(error);\ | 
					
						
							|  |  |  |     if (validator.GetError() != e) {\ | 
					
						
							|  |  |  |         StringBuffer sb;\ | 
					
						
							|  |  |  |         Writer<StringBuffer> w(sb);\ | 
					
						
							|  |  |  |         validator.GetError().Accept(w);\ | 
					
						
							|  |  |  |         printf("GetError() Expected: %s Actual: %s\n", error, sb.GetString());\ | 
					
						
							|  |  |  |         ADD_FAILURE();\ | 
					
						
							|  |  |  |     }\ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  | // Use for checking whether a compiled schema document contains errors
 | 
					
						
							|  |  |  | #define SCHEMAERROR(schema, error) \
 | 
					
						
							|  |  |  | {\ | 
					
						
							|  |  |  |     Document e;\ | 
					
						
							|  |  |  |     e.Parse(error);\ | 
					
						
							|  |  |  |     if (schema.GetError() != e) {\ | 
					
						
							|  |  |  |         StringBuffer sb;\ | 
					
						
							|  |  |  |         Writer<StringBuffer> w(sb);\ | 
					
						
							|  |  |  |         schema.GetError().Accept(w);\ | 
					
						
							|  |  |  |         printf("GetError() Expected: %s Actual: %s\n", error, sb.GetString());\ | 
					
						
							|  |  |  |         ADD_FAILURE();\ | 
					
						
							|  |  |  |     }\ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  | TEST(SchemaValidator, Typeless) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     VALIDATE(s, "42", true); | 
					
						
							|  |  |  |     VALIDATE(s, "\"I'm a string\"", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"an\": [ \"arbitrarily\", \"nested\" ], \"data\": \"structure\" }", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, MultiType) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{ \"type\": [\"number\", \"string\"] }"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "42", true); | 
					
						
							|  |  |  |     VALIDATE(s, "\"Life, the universe, and everything\"", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "[\"Life\", \"the universe\", \"and everything\"]", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\", \"number\"], \"actual\": \"array\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Enum_Typed) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{ \"type\": \"string\", \"enum\" : [\"red\", \"amber\", \"green\"] }"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "\"red\"", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"blue\"", "", "enum", "", | 
					
						
							|  |  |  |         "{ \"enum\": { \"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  | TEST(SchemaValidator, Enum_Typeless) { | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{  \"enum\": [\"red\", \"amber\", \"green\", null, 42] }"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "\"red\"", true); | 
					
						
							|  |  |  |     VALIDATE(s, "null", true); | 
					
						
							|  |  |  |     VALIDATE(s, "42", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "0", "", "enum", "", | 
					
						
							|  |  |  |         "{ \"enum\": { \"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Enum_InvalidType) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{ \"type\": \"string\", \"enum\": [\"red\", \"amber\", \"green\", null] }"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "\"red\"", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "null", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, AllOf) { | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Document sd; | 
					
						
							|  |  |  |         sd.Parse("{\"allOf\": [{ \"type\": \"string\" }, { \"type\": \"string\", \"maxLength\": 5 }]}"); | 
					
						
							|  |  |  |         SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         VALIDATE(s, "\"ok\"", true); | 
					
						
							|  |  |  |         INVALIDATE(s, "\"too long\"", "", "allOf", "", | 
					
						
							|  |  |  |             "{ \"allOf\": {" | 
					
						
							|  |  |  |             "    \"errors\": [" | 
					
						
							|  |  |  |             "      {}," | 
					
						
							|  |  |  |             "      {\"maxLength\": {\"errorCode\": 6, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/1\", \"expected\": 5, \"actual\": \"too long\"}}" | 
					
						
							|  |  |  |             "    ]," | 
					
						
							|  |  |  |             "    \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\"" | 
					
						
							|  |  |  |             "}}"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Document sd; | 
					
						
							|  |  |  |         sd.Parse("{\"allOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" } ] }"); | 
					
						
							|  |  |  |         SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         VALIDATE(s, "\"No way\"", false); | 
					
						
							|  |  |  |         INVALIDATE(s, "-1", "", "allOf", "", | 
					
						
							|  |  |  |             "{ \"allOf\": {" | 
					
						
							|  |  |  |             "    \"errors\": [" | 
					
						
							|  |  |  |             "      {\"type\": { \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\", \"errorCode\": 20, \"expected\": [\"string\"], \"actual\": \"integer\"}}," | 
					
						
							|  |  |  |             "      {}" | 
					
						
							|  |  |  |             "    ]," | 
					
						
							|  |  |  |             "    \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\"" | 
					
						
							|  |  |  |             "}}"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, AnyOf) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"anyOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" } ] }"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "\"Yes\"", true); | 
					
						
							|  |  |  |     VALIDATE(s, "42", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"Not a\": \"string or number\" }", "", "anyOf", "", | 
					
						
							|  |  |  |         "{ \"anyOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 24," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\", " | 
					
						
							|  |  |  |         "    \"errors\": [" | 
					
						
							|  |  |  |         "      { \"type\": {" | 
					
						
							|  |  |  |         "          \"errorCode\": 20," | 
					
						
							|  |  |  |         "          \"instanceRef\": \"#\", \"schemaRef\": \"#/anyOf/0\"," | 
					
						
							|  |  |  |         "          \"expected\": [\"string\"], \"actual\": \"object\"" | 
					
						
							|  |  |  |         "      }}," | 
					
						
							|  |  |  |         "      { \"type\": {" | 
					
						
							|  |  |  |         "          \"errorCode\": 20," | 
					
						
							|  |  |  |         "          \"instanceRef\": \"#\", \"schemaRef\": \"#/anyOf/1\"," | 
					
						
							|  |  |  |         "          \"expected\": [\"number\"], \"actual\": \"object\"" | 
					
						
							|  |  |  |         "      }}" | 
					
						
							|  |  |  |         "    ]" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, OneOf) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"oneOf\": [{ \"type\": \"number\", \"multipleOf\": 5 }, { \"type\": \"number\", \"multipleOf\": 3 } ] }"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "10", true); | 
					
						
							|  |  |  |     VALIDATE(s, "9", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "2", "", "oneOf", "", | 
					
						
							|  |  |  |         "{ \"oneOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 21," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"errors\": [" | 
					
						
							|  |  |  |         "      { \"multipleOf\": {" | 
					
						
							|  |  |  |         "          \"errorCode\": 1," | 
					
						
							|  |  |  |         "          \"instanceRef\": \"#\", \"schemaRef\": \"#/oneOf/0\"," | 
					
						
							|  |  |  |         "          \"expected\": 5, \"actual\": 2" | 
					
						
							|  |  |  |         "      }}," | 
					
						
							|  |  |  |         "      { \"multipleOf\": {" | 
					
						
							|  |  |  |         "          \"errorCode\": 1," | 
					
						
							|  |  |  |         "          \"instanceRef\": \"#\", \"schemaRef\": \"#/oneOf/1\"," | 
					
						
							|  |  |  |         "          \"expected\": 3, \"actual\": 2" | 
					
						
							|  |  |  |         "      }}" | 
					
						
							|  |  |  |         "    ]" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "15", "", "oneOf", "", | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |         "{ \"oneOf\": { \"errorCode\": 22, \"instanceRef\": \"#\", \"schemaRef\": \"#\", \"matches\": [0,1]}}"); | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Not) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"not\":{ \"type\": \"string\"}}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "42", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"key\": \"value\" }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"I am a string\"", "", "not", "", | 
					
						
							|  |  |  |         "{ \"not\": { \"errorCode\": 25, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"$schema\": \"http://json-schema.org/draft-04/schema#\"," | 
					
						
							|  |  |  |         "" | 
					
						
							|  |  |  |         "  \"definitions\": {" | 
					
						
							|  |  |  |         "    \"address\": {" | 
					
						
							|  |  |  |         "      \"type\": \"object\"," | 
					
						
							|  |  |  |         "      \"properties\": {" | 
					
						
							|  |  |  |         "        \"street_address\": { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "        \"city\":           { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "        \"state\":          { \"type\": \"string\" }" | 
					
						
							|  |  |  |         "      }," | 
					
						
							|  |  |  |         "      \"required\": [\"street_address\", \"city\", \"state\"]" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"type\": \"object\"," | 
					
						
							|  |  |  |         "  \"properties\": {" | 
					
						
							|  |  |  |         "    \"billing_address\": { \"$ref\": \"#/definitions/address\" }," | 
					
						
							|  |  |  |         "    \"shipping_address\": { \"$ref\": \"#/definitions/address\" }" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{\"shipping_address\": {\"street_address\": \"1600 Pennsylvania Avenue NW\", \"city\": \"Washington\", \"state\": \"DC\"}, \"billing_address\": {\"street_address\": \"1st Street SE\", \"city\": \"Washington\", \"state\": \"DC\"} }", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_AllOf) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"$schema\": \"http://json-schema.org/draft-04/schema#\"," | 
					
						
							|  |  |  |         "" | 
					
						
							|  |  |  |         "  \"definitions\": {" | 
					
						
							|  |  |  |         "    \"address\": {" | 
					
						
							|  |  |  |         "      \"type\": \"object\"," | 
					
						
							|  |  |  |         "      \"properties\": {" | 
					
						
							|  |  |  |         "        \"street_address\": { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "        \"city\":           { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "        \"state\":          { \"type\": \"string\" }" | 
					
						
							|  |  |  |         "      }," | 
					
						
							|  |  |  |         "      \"required\": [\"street_address\", \"city\", \"state\"]" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"type\": \"object\"," | 
					
						
							|  |  |  |         "  \"properties\": {" | 
					
						
							|  |  |  |         "    \"billing_address\": { \"$ref\": \"#/definitions/address\" }," | 
					
						
							|  |  |  |         "    \"shipping_address\": {" | 
					
						
							|  |  |  |         "      \"allOf\": [" | 
					
						
							|  |  |  |         "        { \"$ref\": \"#/definitions/address\" }," | 
					
						
							|  |  |  |         "        { \"properties\":" | 
					
						
							|  |  |  |         "          { \"type\": { \"enum\": [ \"residential\", \"business\" ] } }," | 
					
						
							|  |  |  |         "          \"required\": [\"type\"]" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "      ]" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "{\"shipping_address\": {\"street_address\": \"1600 Pennsylvania Avenue NW\", \"city\": \"Washington\", \"state\": \"DC\"} }", "/properties/shipping_address", "allOf", "/shipping_address", | 
					
						
							|  |  |  |         "{ \"allOf\": {" | 
					
						
							|  |  |  |         "    \"errors\": [" | 
					
						
							|  |  |  |         "      {}," | 
					
						
							|  |  |  |         "      {\"required\": {\"errorCode\": 15, \"instanceRef\": \"#/shipping_address\", \"schemaRef\": \"#/properties/shipping_address/allOf/1\", \"missing\": [\"type\"]}}" | 
					
						
							|  |  |  |         "    ]," | 
					
						
							|  |  |  |         "    \"errorCode\":23,\"instanceRef\":\"#/shipping_address\",\"schemaRef\":\"#/properties/shipping_address\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "{\"shipping_address\": {\"street_address\": \"1600 Pennsylvania Avenue NW\", \"city\": \"Washington\", \"state\": \"DC\", \"type\": \"business\"} }", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, String) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"string\"}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "\"I'm a string\"", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "42", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"integer\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "2147483648", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"integer\"" | 
					
						
							|  |  |  |         "}}"); // 2^31 can only be fit in unsigned
 | 
					
						
							|  |  |  |     INVALIDATE(s, "-2147483649", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"integer\"" | 
					
						
							|  |  |  |         "}}"); // -2^31 - 1 can only be fit in int64_t
 | 
					
						
							|  |  |  |     INVALIDATE(s, "4294967296", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"integer\"" | 
					
						
							|  |  |  |         "}}"); // 2^32 can only be fit in int64_t
 | 
					
						
							|  |  |  |     INVALIDATE(s, "3.1415926", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"number\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, String_LengthRange) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"string\",\"minLength\":2,\"maxLength\":3}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "\"A\"", "", "minLength", "", | 
					
						
							|  |  |  |         "{ \"minLength\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 7," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 2, \"actual\": \"A\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "\"AB\"", true); | 
					
						
							|  |  |  |     VALIDATE(s, "\"ABC\"", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"ABCD\"", "", "maxLength", "", | 
					
						
							|  |  |  |         "{ \"maxLength\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 6," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 3, \"actual\": \"ABCD\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if RAPIDJSON_SCHEMA_HAS_REGEX
 | 
					
						
							|  |  |  | TEST(SchemaValidator, String_Pattern) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"string\",\"pattern\":\"^(\\\\([0-9]{3}\\\\))?[0-9]{3}-[0-9]{4}$\"}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "\"555-1212\"", true); | 
					
						
							|  |  |  |     VALIDATE(s, "\"(888)555-1212\"", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"(888)555-1212 ext. 532\"", "", "pattern", "", | 
					
						
							|  |  |  |         "{ \"pattern\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 8," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"actual\": \"(888)555-1212 ext. 532\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"(800)FLOWERS\"", "", "pattern", "", | 
					
						
							|  |  |  |         "{ \"pattern\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 8," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"actual\": \"(800)FLOWERS\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, String_Pattern_Invalid) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |     sd.Parse("{\"type\":\"string\",\"pattern\":\"a{0}\"}"); | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |     SchemaDocument s(sd); | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |     SCHEMAERROR(s, "{\"RegexInvalid\":{\"errorCode\":9,\"instanceRef\":\"#/pattern\",\"value\":\"a{0}\"}}"); | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |     VALIDATE_(s, "\"\"", true, false); | 
					
						
							|  |  |  |     VALIDATE_(s, "\"a\"", true, false); | 
					
						
							|  |  |  |     VALIDATE_(s, "\"aa\"", true, false); | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Integer) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"integer\"}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "42", true); | 
					
						
							|  |  |  |     VALIDATE(s, "-1", true); | 
					
						
							|  |  |  |     VALIDATE(s, "2147483648", true); // 2^31 can only be fit in unsigned
 | 
					
						
							|  |  |  |     VALIDATE(s, "-2147483649", true); // -2^31 - 1 can only be fit in int64_t
 | 
					
						
							|  |  |  |     VALIDATE(s, "2147483648", true); // 2^31 can only be fit in unsigned
 | 
					
						
							|  |  |  |     VALIDATE(s, "4294967296", true); // 2^32 can only be fit in int64_t
 | 
					
						
							|  |  |  |     INVALIDATE(s, "3.1415926", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"number\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"42\"", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Integer_Range) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"integer\",\"minimum\":0,\"maximum\":100,\"exclusiveMaximum\":true}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "-1", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 0, \"actual\": -1" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "0", true); | 
					
						
							|  |  |  |     VALIDATE(s, "10", true); | 
					
						
							|  |  |  |     VALIDATE(s, "99", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "100", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 100" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "101", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 101" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Integer_Range64Boundary) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"integer\",\"minimum\":-9223372036854775807,\"maximum\":9223372036854775806}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "-9223372036854775808", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -9223372036854775807, \"actual\": -9223372036854775808" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "-9223372036854775807", true); | 
					
						
							|  |  |  |     VALIDATE(s, "-2147483648", true); // int min
 | 
					
						
							|  |  |  |     VALIDATE(s, "0", true); | 
					
						
							|  |  |  |     VALIDATE(s, "2147483647", true);  // int max
 | 
					
						
							|  |  |  |     VALIDATE(s, "2147483648", true);  // unsigned first
 | 
					
						
							|  |  |  |     VALIDATE(s, "4294967295", true);  // unsigned max
 | 
					
						
							|  |  |  |     VALIDATE(s, "9223372036854775806", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "9223372036854775807", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 2," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775806, \"actual\": 9223372036854775807" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "18446744073709551615", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 2," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775806, \"actual\": 18446744073709551615" | 
					
						
							|  |  |  |         "}}");   // uint64_t max
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Integer_RangeU64Boundary) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"integer\",\"minimum\":9223372036854775808,\"maximum\":18446744073709551614}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "-9223372036854775808", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808, \"actual\": -9223372036854775808" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "9223372036854775807", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808, \"actual\": 9223372036854775807" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "-2147483648", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808, \"actual\": -2147483648" | 
					
						
							|  |  |  |         "}}"); // int min
 | 
					
						
							|  |  |  |     INVALIDATE(s, "0", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808, \"actual\": 0" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "2147483647", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808, \"actual\": 2147483647" | 
					
						
							|  |  |  |         "}}");  // int max
 | 
					
						
							|  |  |  |     INVALIDATE(s, "2147483648", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808, \"actual\": 2147483648" | 
					
						
							|  |  |  |         "}}");  // unsigned first
 | 
					
						
							|  |  |  |     INVALIDATE(s, "4294967295", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808, \"actual\": 4294967295" | 
					
						
							|  |  |  |         "}}");  // unsigned max
 | 
					
						
							|  |  |  |     VALIDATE(s, "9223372036854775808", true); | 
					
						
							|  |  |  |     VALIDATE(s, "18446744073709551614", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "18446744073709551615", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 2," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 18446744073709551614, \"actual\": 18446744073709551615" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Integer_Range64BoundaryExclusive) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"integer\",\"minimum\":-9223372036854775808,\"maximum\":18446744073709551615,\"exclusiveMinimum\":true,\"exclusiveMaximum\":true}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "-9223372036854775808", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 5," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -9223372036854775808, \"exclusiveMinimum\": true, " | 
					
						
							|  |  |  |         "    \"actual\": -9223372036854775808" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "-9223372036854775807", true); | 
					
						
							|  |  |  |     VALIDATE(s, "18446744073709551614", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "18446744073709551615", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 18446744073709551615, \"exclusiveMaximum\": true, " | 
					
						
							|  |  |  |         "    \"actual\": 18446744073709551615" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Integer_MultipleOf) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"integer\",\"multipleOf\":10}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "0", true); | 
					
						
							|  |  |  |     VALIDATE(s, "10", true); | 
					
						
							|  |  |  |     VALIDATE(s, "-10", true); | 
					
						
							|  |  |  |     VALIDATE(s, "20", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "23", "", "multipleOf", "", | 
					
						
							|  |  |  |         "{ \"multipleOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 1," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 10, \"actual\": 23" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "-23", "", "multipleOf", "", | 
					
						
							|  |  |  |         "{ \"multipleOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 1," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 10, \"actual\": -23" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Integer_MultipleOf64Boundary) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"integer\",\"multipleOf\":18446744073709551615}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "0", true); | 
					
						
							|  |  |  |     VALIDATE(s, "18446744073709551615", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "18446744073709551614", "", "multipleOf", "", | 
					
						
							|  |  |  |         "{ \"multipleOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 1," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 18446744073709551615, \"actual\": 18446744073709551614" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Number_Range) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"number\",\"minimum\":0,\"maximum\":100,\"exclusiveMaximum\":true}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "-1", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 0, \"actual\": -1" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "0", true); | 
					
						
							|  |  |  |     VALIDATE(s, "0.1", true); | 
					
						
							|  |  |  |     VALIDATE(s, "10", true); | 
					
						
							|  |  |  |     VALIDATE(s, "99", true); | 
					
						
							|  |  |  |     VALIDATE(s, "99.9", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "100", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 100" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "100.0", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 100.0" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "101.5", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 101.5" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Number_RangeInt) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"number\",\"minimum\":-100,\"maximum\":-1,\"exclusiveMaximum\":true}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "-101", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -100, \"actual\": -101" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "-100.1", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -100, \"actual\": -100.1" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "-100", true); | 
					
						
							|  |  |  |     VALIDATE(s, "-2", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "-1", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": -1" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "-0.9", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": -0.9" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "0", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 0" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "2147483647", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 2147483647" | 
					
						
							|  |  |  |         "}}");  // int max
 | 
					
						
							|  |  |  |     INVALIDATE(s, "2147483648", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 2147483648" | 
					
						
							|  |  |  |         "}}");  // unsigned first
 | 
					
						
							|  |  |  |     INVALIDATE(s, "4294967295", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 4294967295" | 
					
						
							|  |  |  |         "}}");  // unsigned max
 | 
					
						
							|  |  |  |     INVALIDATE(s, "9223372036854775808", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 9223372036854775808" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "18446744073709551614", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551614" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "18446744073709551615", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551615" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Number_RangeDouble) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"number\",\"minimum\":0.1,\"maximum\":100.1,\"exclusiveMaximum\":true}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "-9223372036854775808", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 0.1, \"actual\": -9223372036854775808" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "-2147483648", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 0.1, \"actual\": -2147483648" | 
					
						
							|  |  |  |         "}}"); // int min
 | 
					
						
							|  |  |  |     INVALIDATE(s, "-1", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 0.1, \"actual\": -1" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "0.1", true); | 
					
						
							|  |  |  |     VALIDATE(s, "10", true); | 
					
						
							|  |  |  |     VALIDATE(s, "99", true); | 
					
						
							|  |  |  |     VALIDATE(s, "100", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "101", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 101" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "101.5", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 101.5" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "18446744073709551614", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551614" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "18446744073709551615", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551615" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "2147483647", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 2147483647" | 
					
						
							|  |  |  |         "}}");  // int max
 | 
					
						
							|  |  |  |     INVALIDATE(s, "2147483648", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 2147483648" | 
					
						
							|  |  |  |         "}}");  // unsigned first
 | 
					
						
							|  |  |  |     INVALIDATE(s, "4294967295", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 4294967295" | 
					
						
							|  |  |  |         "}}");  // unsigned max
 | 
					
						
							|  |  |  |     INVALIDATE(s, "9223372036854775808", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 9223372036854775808" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "18446744073709551614", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551614" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "18446744073709551615", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551615" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Number_RangeDoubleU64Boundary) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"number\",\"minimum\":9223372036854775808.0,\"maximum\":18446744073709550000.0}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "-9223372036854775808", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808.0, \"actual\": -9223372036854775808" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "-2147483648", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808.0, \"actual\": -2147483648" | 
					
						
							|  |  |  |         "}}"); // int min
 | 
					
						
							|  |  |  |     INVALIDATE(s, "0", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808.0, \"actual\": 0" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "2147483647", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808.0, \"actual\": 2147483647" | 
					
						
							|  |  |  |         "}}");  // int max
 | 
					
						
							|  |  |  |     INVALIDATE(s, "2147483648", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808.0, \"actual\": 2147483648" | 
					
						
							|  |  |  |         "}}");  // unsigned first
 | 
					
						
							|  |  |  |     INVALIDATE(s, "4294967295", "", "minimum", "", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 9223372036854775808.0, \"actual\": 4294967295" | 
					
						
							|  |  |  |         "}}");  // unsigned max
 | 
					
						
							|  |  |  |     VALIDATE(s, "9223372036854775808", true); | 
					
						
							|  |  |  |     VALIDATE(s, "18446744073709540000", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "18446744073709551615", "", "maximum", "", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 2," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 18446744073709550000.0, \"actual\": 18446744073709551615" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Number_MultipleOf) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"number\",\"multipleOf\":10.0}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "0", true); | 
					
						
							|  |  |  |     VALIDATE(s, "10", true); | 
					
						
							|  |  |  |     VALIDATE(s, "-10", true); | 
					
						
							|  |  |  |     VALIDATE(s, "20", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "23", "", "multipleOf", "", | 
					
						
							|  |  |  |         "{ \"multipleOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 1," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 10.0, \"actual\": 23" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "-2147483648", "", "multipleOf", "", | 
					
						
							|  |  |  |         "{ \"multipleOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 1," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 10.0, \"actual\": -2147483648" | 
					
						
							|  |  |  |         "}}");  // int min
 | 
					
						
							|  |  |  |     VALIDATE(s, "-2147483640", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "2147483647", "", "multipleOf", "", | 
					
						
							|  |  |  |         "{ \"multipleOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 1," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 10.0, \"actual\": 2147483647" | 
					
						
							|  |  |  |         "}}");  // int max
 | 
					
						
							|  |  |  |     INVALIDATE(s, "2147483648", "", "multipleOf", "", | 
					
						
							|  |  |  |         "{ \"multipleOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 1," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 10.0, \"actual\": 2147483648" | 
					
						
							|  |  |  |         "}}");  // unsigned first
 | 
					
						
							|  |  |  |     VALIDATE(s, "2147483650", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "4294967295", "", "multipleOf", "", | 
					
						
							|  |  |  |         "{ \"multipleOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 1," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 10.0, \"actual\": 4294967295" | 
					
						
							|  |  |  |         "}}");  // unsigned max
 | 
					
						
							|  |  |  |     VALIDATE(s, "4294967300", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Number_MultipleOfOne) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"number\",\"multipleOf\":1}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "42", true); | 
					
						
							|  |  |  |     VALIDATE(s, "42.0", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "3.1415926", "", "multipleOf", "", | 
					
						
							|  |  |  |         "{ \"multipleOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 1," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 1, \"actual\": 3.1415926" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"object\"}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{\"key\":\"value\",\"another_key\":\"another_value\"}", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{\"Sun\":1.9891e30,\"Jupiter\":1.8986e27,\"Saturn\":5.6846e26,\"Neptune\":10.243e25,\"Uranus\":8.6810e25,\"Earth\":5.9736e24,\"Venus\":4.8685e24,\"Mars\":6.4185e23,\"Mercury\":3.3022e23,\"Moon\":7.349e22,\"Pluto\":1.25e22}", true);     | 
					
						
							|  |  |  |     INVALIDATE(s, "[\"An\", \"array\", \"not\", \"an\", \"object\"]", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"object\"], \"actual\": \"array\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"Not an object\"", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"object\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_Properties) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "    \"type\": \"object\"," | 
					
						
							|  |  |  |         "    \"properties\" : {" | 
					
						
							|  |  |  |         "        \"number\": { \"type\": \"number\" }," | 
					
						
							|  |  |  |         "        \"street_name\" : { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "        \"street_type\" : { \"type\": \"string\", \"enum\" : [\"Street\", \"Avenue\", \"Boulevard\"] }" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\" }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"number\": \"1600\", \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\" }", "/properties/number", "type", "/number", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/number\", \"schemaRef\": \"#/properties/number\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"number\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"number\": \"One\", \"street_name\": \"Microsoft\", \"street_type\": \"Way\" }", | 
					
						
							|  |  |  |         "/properties/number", "type", "/number", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/number\", \"schemaRef\": \"#/properties/number\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"number\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); // fail fast
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\" }", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{}", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\", \"direction\": \"NW\" }", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_AdditionalPropertiesBoolean) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "    \"type\": \"object\"," | 
					
						
							|  |  |  |         "        \"properties\" : {" | 
					
						
							|  |  |  |         "        \"number\": { \"type\": \"number\" }," | 
					
						
							|  |  |  |         "            \"street_name\" : { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "            \"street_type\" : { \"type\": \"string\"," | 
					
						
							|  |  |  |         "            \"enum\" : [\"Street\", \"Avenue\", \"Boulevard\"]" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    \"additionalProperties\": false" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\" }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\", \"direction\": \"NW\" }", "", "additionalProperties", "/direction", | 
					
						
							|  |  |  |         "{ \"additionalProperties\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 16," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"disallowed\": \"direction\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_AdditionalPropertiesObject) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "    \"type\": \"object\"," | 
					
						
							|  |  |  |         "    \"properties\" : {" | 
					
						
							|  |  |  |         "        \"number\": { \"type\": \"number\" }," | 
					
						
							|  |  |  |         "        \"street_name\" : { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "        \"street_type\" : { \"type\": \"string\"," | 
					
						
							|  |  |  |         "            \"enum\" : [\"Street\", \"Avenue\", \"Boulevard\"]" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    \"additionalProperties\": { \"type\": \"string\" }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\" }", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\", \"direction\": \"NW\" }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\", \"office_number\": 201 }", "/additionalProperties", "type", "/office_number", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/office_number\", \"schemaRef\": \"#/additionalProperties\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"integer\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_Required) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "    \"type\": \"object\"," | 
					
						
							|  |  |  |         "    \"properties\" : {" | 
					
						
							|  |  |  |         "        \"name\":      { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "        \"email\" : { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "        \"address\" : { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "        \"telephone\" : { \"type\": \"string\" }" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    \"required\":[\"name\", \"email\"]" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"name\": \"William Shakespeare\", \"email\" : \"bill@stratford-upon-avon.co.uk\" }", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"name\": \"William Shakespeare\", \"email\" : \"bill@stratford-upon-avon.co.uk\", \"address\" : \"Henley Street, Stratford-upon-Avon, Warwickshire, England\", \"authorship\" : \"in question\"}", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"name\": \"William Shakespeare\", \"address\" : \"Henley Street, Stratford-upon-Avon, Warwickshire, England\" }", "", "required", "", | 
					
						
							|  |  |  |         "{ \"required\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 15," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"missing\": [\"email\"]" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "{}", "", "required", "", | 
					
						
							|  |  |  |         "{ \"required\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 15," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"missing\": [\"name\", \"email\"]" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_Required_PassWithDefault) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "    \"type\": \"object\"," | 
					
						
							|  |  |  |         "    \"properties\" : {" | 
					
						
							|  |  |  |         "        \"name\":      { \"type\": \"string\", \"default\": \"William Shakespeare\" }," | 
					
						
							|  |  |  |         "        \"email\" : { \"type\": \"string\", \"default\": \"\" }," | 
					
						
							|  |  |  |         "        \"address\" : { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "        \"telephone\" : { \"type\": \"string\" }" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    \"required\":[\"name\", \"email\"]" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"email\" : \"bill@stratford-upon-avon.co.uk\", \"address\" : \"Henley Street, Stratford-upon-Avon, Warwickshire, England\", \"authorship\" : \"in question\"}", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"name\": \"William Shakespeare\", \"address\" : \"Henley Street, Stratford-upon-Avon, Warwickshire, England\" }", "", "required", "", | 
					
						
							|  |  |  |         "{ \"required\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 15," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"missing\": [\"email\"]" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "{}", "", "required", "", | 
					
						
							|  |  |  |         "{ \"required\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 15," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"missing\": [\"email\"]" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_PropertiesRange) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"object\", \"minProperties\":2, \"maxProperties\":3}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "{}", "", "minProperties", "", | 
					
						
							|  |  |  |         "{ \"minProperties\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 14," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 2, \"actual\": 0" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "{\"a\":0}", "", "minProperties", "", | 
					
						
							|  |  |  |         "{ \"minProperties\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 14," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 2, \"actual\": 1" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "{\"a\":0,\"b\":1}", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{\"a\":0,\"b\":1,\"c\":2}", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{\"a\":0,\"b\":1,\"c\":2,\"d\":3}", "", "maxProperties", "", | 
					
						
							|  |  |  |         "{ \"maxProperties\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 13," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\", " | 
					
						
							|  |  |  |         "    \"expected\": 3, \"actual\": 4" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_PropertyDependencies) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"type\": \"object\"," | 
					
						
							|  |  |  |         "  \"properties\": {" | 
					
						
							|  |  |  |         "    \"name\": { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "    \"credit_card\": { \"type\": \"number\" }," | 
					
						
							|  |  |  |         "    \"cvv_code\": { \"type\": \"number\" }," | 
					
						
							|  |  |  |         "    \"billing_address\": { \"type\": \"string\" }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"required\": [\"name\"]," | 
					
						
							|  |  |  |         "  \"dependencies\": {" | 
					
						
							|  |  |  |         "    \"credit_card\": [\"cvv_code\", \"billing_address\"]" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"name\": \"John Doe\", \"credit_card\": 5555555555555555, \"cvv_code\": 777, " | 
					
						
							|  |  |  |         "\"billing_address\": \"555 Debtor's Lane\" }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"name\": \"John Doe\", \"credit_card\": 5555555555555555 }", "", "dependencies", "", | 
					
						
							|  |  |  |         "{ \"dependencies\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 18," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"errors\": {" | 
					
						
							|  |  |  |         "       \"credit_card\": {" | 
					
						
							|  |  |  |         "        \"required\": {" | 
					
						
							|  |  |  |         "          \"errorCode\": 15," | 
					
						
							|  |  |  |         "          \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/credit_card\"," | 
					
						
							|  |  |  |         "          \"missing\": [\"cvv_code\", \"billing_address\"]" | 
					
						
							|  |  |  |         "    } } }" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"name\": \"John Doe\"}", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"name\": \"John Doe\", \"cvv_code\": 777, \"billing_address\": \"555 Debtor's Lane\" }", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_SchemaDependencies) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "    \"type\": \"object\"," | 
					
						
							|  |  |  |         "    \"properties\" : {" | 
					
						
							|  |  |  |         "        \"name\": { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "        \"credit_card\" : { \"type\": \"number\" }" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    \"required\" : [\"name\"]," | 
					
						
							|  |  |  |         "    \"dependencies\" : {" | 
					
						
							|  |  |  |         "        \"credit_card\": {" | 
					
						
							|  |  |  |         "            \"properties\": {" | 
					
						
							|  |  |  |         "                \"billing_address\": { \"type\": \"string\" }" | 
					
						
							|  |  |  |         "            }," | 
					
						
							|  |  |  |         "            \"required\" : [\"billing_address\"]" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{\"name\": \"John Doe\", \"credit_card\" : 5555555555555555,\"billing_address\" : \"555 Debtor's Lane\"}", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{\"name\": \"John Doe\", \"credit_card\" : 5555555555555555 }", "", "dependencies", "", | 
					
						
							|  |  |  |         "{ \"dependencies\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 18," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"errors\": {" | 
					
						
							|  |  |  |         "      \"credit_card\": {" | 
					
						
							|  |  |  |         "        \"required\": {" | 
					
						
							|  |  |  |         "          \"errorCode\": 15," | 
					
						
							|  |  |  |         "          \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/credit_card\"," | 
					
						
							|  |  |  |         "          \"missing\": [\"billing_address\"]" | 
					
						
							|  |  |  |         "    } } }" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "{\"name\": \"John Doe\", \"billing_address\" : \"555 Debtor's Lane\"}", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if RAPIDJSON_SCHEMA_HAS_REGEX
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_PatternProperties) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"type\": \"object\"," | 
					
						
							|  |  |  |         "  \"patternProperties\": {" | 
					
						
							|  |  |  |         "    \"^S_\": { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "    \"^I_\": { \"type\": \"integer\" }" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"S_25\": \"This is a string\" }", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"I_0\": 42 }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"S_0\": 42 }", "", "patternProperties", "/S_0", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/S_0\", \"schemaRef\": \"#/patternProperties/%5ES_\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"integer\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"I_42\": \"This is a string\" }", "", "patternProperties", "/I_42", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/patternProperties/%5EI_\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"keyword\": \"value\" }", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_PatternProperties_ErrorConflict) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"type\": \"object\"," | 
					
						
							|  |  |  |         "  \"patternProperties\": {" | 
					
						
							|  |  |  |         "    \"^I_\": { \"multipleOf\": 5 }," | 
					
						
							|  |  |  |         "    \"30$\": { \"multipleOf\": 6 }" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"I_30\": 30 }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"I_30\": 7 }", "", "patternProperties", "/I_30", | 
					
						
							|  |  |  |         "{ \"multipleOf\": [" | 
					
						
							|  |  |  |         "    {" | 
					
						
							|  |  |  |         "      \"errorCode\": 1," | 
					
						
							|  |  |  |         "      \"instanceRef\": \"#/I_30\", \"schemaRef\": \"#/patternProperties/%5EI_\"," | 
					
						
							|  |  |  |         "      \"expected\": 5, \"actual\": 7" | 
					
						
							|  |  |  |         "    }, {" | 
					
						
							|  |  |  |         "      \"errorCode\": 1," | 
					
						
							|  |  |  |         "      \"instanceRef\": \"#/I_30\", \"schemaRef\": \"#/patternProperties/30%24\"," | 
					
						
							|  |  |  |         "      \"expected\": 6, \"actual\": 7" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "]}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_Properties_PatternProperties) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"type\": \"object\"," | 
					
						
							|  |  |  |         "  \"properties\": {" | 
					
						
							|  |  |  |         "    \"I_42\": { \"type\": \"integer\", \"minimum\": 73 }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"patternProperties\": {" | 
					
						
							|  |  |  |         "    \"^I_\": { \"type\": \"integer\", \"multipleOf\": 6 }" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"I_6\": 6 }", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"I_42\": 78 }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"I_42\": 42 }", "", "patternProperties", "/I_42", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/properties/I_42\"," | 
					
						
							|  |  |  |         "    \"expected\": 73, \"actual\": 42" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"I_42\": 7 }", "", "patternProperties", "/I_42", | 
					
						
							|  |  |  |         "{ \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 4," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/properties/I_42\"," | 
					
						
							|  |  |  |         "    \"expected\": 73, \"actual\": 7" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"multipleOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 1," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/patternProperties/%5EI_\"," | 
					
						
							|  |  |  |         "    \"expected\": 6, \"actual\": 7" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_PatternProperties_AdditionalPropertiesObject) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"type\": \"object\"," | 
					
						
							|  |  |  |         "  \"properties\": {" | 
					
						
							|  |  |  |         "    \"builtin\": { \"type\": \"number\" }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"patternProperties\": {" | 
					
						
							|  |  |  |         "    \"^S_\": { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "    \"^I_\": { \"type\": \"integer\" }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"additionalProperties\": { \"type\": \"string\" }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"builtin\": 42 }", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"keyword\": \"value\" }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"keyword\": 42 }", "/additionalProperties", "type", "/keyword", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/keyword\", \"schemaRef\": \"#/additionalProperties\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"integer\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Replaces test Issue285 and tests failure as well as success
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Object_PatternProperties_AdditionalPropertiesBoolean) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"type\": \"object\"," | 
					
						
							|  |  |  |         "  \"patternProperties\": {" | 
					
						
							|  |  |  |         "    \"^S_\": { \"type\": \"string\" }," | 
					
						
							|  |  |  |         "    \"^I_\": { \"type\": \"integer\" }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"additionalProperties\": false" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"S_25\": \"This is a string\" }", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"I_0\": 42 }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"keyword\": \"value\" }", "", "additionalProperties", "/keyword", | 
					
						
							|  |  |  |         "{ \"additionalProperties\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 16," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"disallowed\": \"keyword\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Array) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"array\"}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "[1, 2, 3, 4, 5]", true); | 
					
						
							|  |  |  |     VALIDATE(s, "[3, \"different\", { \"types\" : \"of values\" }]", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{\"Not\": \"an array\"}", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"array\"], \"actual\": \"object\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Array_ItemsList) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "    \"type\": \"array\"," | 
					
						
							|  |  |  |         "    \"items\" : {" | 
					
						
							|  |  |  |         "        \"type\": \"number\"" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "[1, 2, 3, 4, 5]", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "[1, 2, \"3\", 4, 5]", "/items", "type", "/2", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/2\", \"schemaRef\": \"#/items\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"number\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "[]", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Array_ItemsTuple) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"type\": \"array\"," | 
					
						
							|  |  |  |         "  \"items\": [" | 
					
						
							|  |  |  |         "    {" | 
					
						
							|  |  |  |         "      \"type\": \"number\"" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    {" | 
					
						
							|  |  |  |         "      \"type\": \"string\"" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    {" | 
					
						
							|  |  |  |         "      \"type\": \"string\"," | 
					
						
							|  |  |  |         "      \"enum\": [\"Street\", \"Avenue\", \"Boulevard\"]" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    {" | 
					
						
							|  |  |  |         "      \"type\": \"string\"," | 
					
						
							|  |  |  |         "      \"enum\": [\"NW\", \"NE\", \"SW\", \"SE\"]" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "  ]" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\"]", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "[24, \"Sussex\", \"Drive\"]", "/items/2", "enum", "/2", | 
					
						
							|  |  |  |         "{ \"enum\": { \"errorCode\": 19, \"instanceRef\": \"#/2\", \"schemaRef\": \"#/items/2\" }}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "[\"Palais de l'Elysee\"]", "/items/0", "type", "/0", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/0\", \"schemaRef\": \"#/items/0\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"number\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "[\"Twenty-four\", \"Sussex\", \"Drive\"]", "/items/0", "type", "/0", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/0\", \"schemaRef\": \"#/items/0\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"number\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); // fail fast
 | 
					
						
							|  |  |  |     VALIDATE(s, "[10, \"Downing\", \"Street\"]", true); | 
					
						
							|  |  |  |     VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\", \"Washington\"]", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Array_AdditionalItems) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"type\": \"array\"," | 
					
						
							|  |  |  |         "  \"items\": [" | 
					
						
							|  |  |  |         "    {" | 
					
						
							|  |  |  |         "      \"type\": \"number\"" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    {" | 
					
						
							|  |  |  |         "      \"type\": \"string\"" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    {" | 
					
						
							|  |  |  |         "      \"type\": \"string\"," | 
					
						
							|  |  |  |         "      \"enum\": [\"Street\", \"Avenue\", \"Boulevard\"]" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    {" | 
					
						
							|  |  |  |         "      \"type\": \"string\"," | 
					
						
							|  |  |  |         "      \"enum\": [\"NW\", \"NE\", \"SW\", \"SE\"]" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "  ]," | 
					
						
							|  |  |  |         "  \"additionalItems\": false" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\"]", true); | 
					
						
							|  |  |  |     VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\"]", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\", \"Washington\"]", "", "additionalItems", "/4", | 
					
						
							|  |  |  |         "{ \"additionalItems\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 12," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"disallowed\": 4" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Array_ItemsRange) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"array\",\"minItems\": 2,\"maxItems\" : 3}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     INVALIDATE(s, "[]", "", "minItems", "", | 
					
						
							|  |  |  |         "{ \"minItems\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 10," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 2, \"actual\": 0" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "[1]", "", "minItems", "", | 
					
						
							|  |  |  |         "{ \"minItems\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 10," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 2, \"actual\": 1" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     VALIDATE(s, "[1, 2]", true); | 
					
						
							|  |  |  |     VALIDATE(s, "[1, 2, 3]", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "[1, 2, 3, 4]", "", "maxItems", "", | 
					
						
							|  |  |  |         "{ \"maxItems\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 9," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 3, \"actual\": 4" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Array_UniqueItems) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"array\", \"uniqueItems\": true}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "[1, 2, 3, 4, 5]", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "[1, 2, 3, 3, 4]", "", "uniqueItems", "/3", | 
					
						
							|  |  |  |         "{ \"uniqueItems\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 11," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"duplicates\": [2, 3]" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "[1, 2, 3, 3, 3]", "", "uniqueItems", "/3", | 
					
						
							|  |  |  |         "{ \"uniqueItems\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 11," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"duplicates\": [2, 3]" | 
					
						
							|  |  |  |         "}}"); // fail fast
 | 
					
						
							|  |  |  |     VALIDATE(s, "[]", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Boolean) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"boolean\"}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "true", true); | 
					
						
							|  |  |  |     VALIDATE(s, "false", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"true\"", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"boolean\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "0", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"boolean\"], \"actual\": \"integer\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Null) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"null\"}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "null", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "false", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"null\"], \"actual\": \"boolean\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "0", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"null\"], \"actual\": \"integer\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"\"", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"null\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Additional tests
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ObjectInArray) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"array\", \"items\": { \"type\":\"string\" }}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "[\"a\"]", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "[1]", "/items", "type", "/0", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/0\", \"schemaRef\": \"#/items\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"integer\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "[{}]", "/items", "type", "/0", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/0\", \"schemaRef\": \"#/items\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"object\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, MultiTypeInObject) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "    \"type\":\"object\"," | 
					
						
							|  |  |  |         "    \"properties\": {" | 
					
						
							|  |  |  |         "        \"tel\" : {" | 
					
						
							|  |  |  |         "            \"type\":[\"integer\", \"string\"]" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"tel\": 999 }", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"tel\": \"123-456\" }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"tel\": true }", "/properties/tel", "type", "/tel", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/tel\", \"schemaRef\": \"#/properties/tel\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\", \"integer\"], \"actual\": \"boolean\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, MultiTypeWithObject) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "    \"type\": [\"object\",\"string\"]," | 
					
						
							|  |  |  |         "    \"properties\": {" | 
					
						
							|  |  |  |         "        \"tel\" : {" | 
					
						
							|  |  |  |         "            \"type\": \"integer\"" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "\"Hello\"", true); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"tel\": 999 }", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{ \"tel\": \"fail\" }", "/properties/tel", "type", "/tel", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/tel\", \"schemaRef\": \"#/properties/tel\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, AllOf_Nested) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |     "{" | 
					
						
							|  |  |  |     "    \"allOf\": [" | 
					
						
							|  |  |  |     "        { \"type\": \"string\", \"minLength\": 2 }," | 
					
						
							|  |  |  |     "        { \"type\": \"string\", \"maxLength\": 5 }," | 
					
						
							|  |  |  |     "        { \"allOf\": [ { \"enum\" : [\"ok\", \"okay\", \"OK\", \"o\"] }, { \"enum\" : [\"ok\", \"OK\", \"o\"]} ] }" | 
					
						
							|  |  |  |     "    ]" | 
					
						
							|  |  |  |     "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "\"ok\"", true); | 
					
						
							|  |  |  |     VALIDATE(s, "\"OK\"", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"okay\"", "", "allOf", "", | 
					
						
							|  |  |  |         "{ \"allOf\": {" | 
					
						
							|  |  |  |         "    \"errors\": [" | 
					
						
							|  |  |  |         "    {},{}," | 
					
						
							|  |  |  |         "    { \"allOf\": {" | 
					
						
							|  |  |  |         "      \"errors\": [" | 
					
						
							|  |  |  |         "        {}," | 
					
						
							|  |  |  |         "        { \"enum\": {\"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\" }}" | 
					
						
							|  |  |  |         "      ]," | 
					
						
							|  |  |  |         "      \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2\"" | 
					
						
							|  |  |  |         "    }}]," | 
					
						
							|  |  |  |         "    \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"o\"", "", "allOf", "", | 
					
						
							|  |  |  |         "{ \"allOf\": {" | 
					
						
							|  |  |  |         "  \"errors\": [" | 
					
						
							|  |  |  |         "    { \"minLength\": {\"actual\": \"o\", \"expected\": 2, \"errorCode\": 7, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\" }}," | 
					
						
							|  |  |  |         "    {},{}" | 
					
						
							|  |  |  |         "  ]," | 
					
						
							|  |  |  |         "  \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"n\"", "", "allOf", "", | 
					
						
							|  |  |  |         "{ \"allOf\": {" | 
					
						
							|  |  |  |         "    \"errors\": [" | 
					
						
							|  |  |  |         "      { \"minLength\": {\"actual\": \"n\", \"expected\": 2, \"errorCode\": 7, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\" }}," | 
					
						
							|  |  |  |         "      {}," | 
					
						
							|  |  |  |         "      { \"allOf\": {" | 
					
						
							|  |  |  |         "          \"errors\": [" | 
					
						
							|  |  |  |         "            { \"enum\": {\"errorCode\": 19 ,\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/0\"}}," | 
					
						
							|  |  |  |         "            { \"enum\": {\"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\"}}" | 
					
						
							|  |  |  |         "          ]," | 
					
						
							|  |  |  |         "          \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2\"" | 
					
						
							|  |  |  |         "      }}" | 
					
						
							|  |  |  |         "    ]," | 
					
						
							|  |  |  |         "    \"errorCode\":23,\"instanceRef\":\"#\",\"schemaRef\":\"#\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"too long\"", "", "allOf", "", | 
					
						
							|  |  |  |         "{ \"allOf\": {" | 
					
						
							|  |  |  |         "    \"errors\": [" | 
					
						
							|  |  |  |         "      {}," | 
					
						
							|  |  |  |         "      { \"maxLength\": {\"actual\": \"too long\", \"expected\": 5, \"errorCode\": 6, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/1\" }}," | 
					
						
							|  |  |  |         "      { \"allOf\": {" | 
					
						
							|  |  |  |         "          \"errors\": [" | 
					
						
							|  |  |  |         "            { \"enum\": {\"errorCode\": 19 ,\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/0\"}}," | 
					
						
							|  |  |  |         "            { \"enum\": {\"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\"}}" | 
					
						
							|  |  |  |         "          ]," | 
					
						
							|  |  |  |         "          \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2\"" | 
					
						
							|  |  |  |         "      }}" | 
					
						
							|  |  |  |         "    ]," | 
					
						
							|  |  |  |         "    \"errorCode\":23,\"instanceRef\":\"#\",\"schemaRef\":\"#\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "123", "", "allOf", "", | 
					
						
							|  |  |  |         "{ \"allOf\": {" | 
					
						
							|  |  |  |         "    \"errors\": [" | 
					
						
							|  |  |  |         "      {\"type\": {\"expected\": [\"string\"], \"actual\": \"integer\", \"errorCode\": 20, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\"}}," | 
					
						
							|  |  |  |         "      {\"type\": {\"expected\": [\"string\"], \"actual\": \"integer\", \"errorCode\": 20, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/1\"}}," | 
					
						
							|  |  |  |         "      { \"allOf\": {" | 
					
						
							|  |  |  |         "          \"errors\": [" | 
					
						
							|  |  |  |         "            { \"enum\": {\"errorCode\": 19 ,\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/0\"}}," | 
					
						
							|  |  |  |         "            { \"enum\": {\"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\"}}" | 
					
						
							|  |  |  |         "          ]," | 
					
						
							|  |  |  |         "          \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2\"" | 
					
						
							|  |  |  |         "      }}" | 
					
						
							|  |  |  |         "    ]," | 
					
						
							|  |  |  |         "    \"errorCode\":23,\"instanceRef\":\"#\",\"schemaRef\":\"#\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, EscapedPointer) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"type\": \"object\"," | 
					
						
							|  |  |  |         "  \"properties\": {" | 
					
						
							|  |  |  |         "    \"~/\": { \"type\": \"number\" }" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     INVALIDATE(s, "{\"~/\":true}", "/properties/~0~1", "type", "/~0~1", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/~0~1\", \"schemaRef\": \"#/properties/~0~1\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"number\"], \"actual\": \"boolean\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, SchemaPointer) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"swagger\": \"2.0\"," | 
					
						
							|  |  |  |         "  \"paths\": {" | 
					
						
							|  |  |  |         "    \"/some/path\": {" | 
					
						
							|  |  |  |         "      \"post\": {" | 
					
						
							|  |  |  |         "        \"parameters\": [" | 
					
						
							|  |  |  |         "          {" | 
					
						
							|  |  |  |         "            \"in\": \"body\"," | 
					
						
							|  |  |  |         "            \"name\": \"body\"," | 
					
						
							|  |  |  |         "            \"schema\": {" | 
					
						
							|  |  |  |         "              \"properties\": {" | 
					
						
							|  |  |  |         "                \"a\": {" | 
					
						
							|  |  |  |         "                  \"$ref\": \"#/definitions/Prop_a\"" | 
					
						
							|  |  |  |         "                }," | 
					
						
							|  |  |  |         "                \"b\": {" | 
					
						
							|  |  |  |         "                  \"type\": \"integer\"" | 
					
						
							|  |  |  |         "                }" | 
					
						
							|  |  |  |         "              }," | 
					
						
							|  |  |  |         "              \"type\": \"object\"" | 
					
						
							|  |  |  |         "            }" | 
					
						
							|  |  |  |         "          }" | 
					
						
							|  |  |  |         "        ]," | 
					
						
							|  |  |  |         "        \"responses\": {" | 
					
						
							|  |  |  |         "          \"200\": {" | 
					
						
							|  |  |  |         "            \"schema\": {" | 
					
						
							|  |  |  |         "              \"$ref\": \"#/definitions/Resp_200\"" | 
					
						
							|  |  |  |         "            }" | 
					
						
							|  |  |  |         "          }" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "      }" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"definitions\": {" | 
					
						
							|  |  |  |         "    \"Prop_a\": {" | 
					
						
							|  |  |  |         "      \"properties\": {" | 
					
						
							|  |  |  |         "        \"c\": {" | 
					
						
							|  |  |  |         "          \"enum\": [" | 
					
						
							|  |  |  |         "            \"C1\"," | 
					
						
							|  |  |  |         "            \"C2\"," | 
					
						
							|  |  |  |         "            \"C3\"" | 
					
						
							|  |  |  |         "          ]," | 
					
						
							|  |  |  |         "          \"type\": \"string\"" | 
					
						
							|  |  |  |         "        }," | 
					
						
							|  |  |  |         "        \"d\": {" | 
					
						
							|  |  |  |         "          \"$ref\": \"#/definitions/Prop_d\"" | 
					
						
							|  |  |  |         "        }," | 
					
						
							|  |  |  |         "        \"s\": {" | 
					
						
							|  |  |  |         "          \"type\": \"string\"" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "      }," | 
					
						
							|  |  |  |         "      \"required\": [\"c\"]," | 
					
						
							|  |  |  |         "      \"type\": \"object\"" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    \"Prop_d\": {" | 
					
						
							|  |  |  |         "      \"properties\": {" | 
					
						
							|  |  |  |         "        \"a\": {" | 
					
						
							|  |  |  |         "          \"$ref\": \"#/definitions/Prop_a\"" | 
					
						
							|  |  |  |         "        }," | 
					
						
							|  |  |  |         "        \"c\": {" | 
					
						
							|  |  |  |         "          \"$ref\": \"#/definitions/Prop_a/properties/c\"" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "      }," | 
					
						
							|  |  |  |         "      \"type\": \"object\"" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    \"Resp_200\": {" | 
					
						
							|  |  |  |         "      \"properties\": {" | 
					
						
							|  |  |  |         "        \"e\": {" | 
					
						
							|  |  |  |         "          \"type\": \"string\"" | 
					
						
							|  |  |  |         "        }," | 
					
						
							|  |  |  |         "        \"f\": {" | 
					
						
							|  |  |  |         "          \"type\": \"boolean\"" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "      }," | 
					
						
							|  |  |  |         "      \"type\": \"object\"" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s1(sd, NULL, 0, NULL, NULL, Pointer("#/paths/~1some~1path/post/parameters/0/schema")); | 
					
						
							|  |  |  |     VALIDATE(s1, | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"a\": {" | 
					
						
							|  |  |  |         "    \"c\": \"C1\"," | 
					
						
							|  |  |  |         "    \"d\": {" | 
					
						
							|  |  |  |         "      \"a\": {" | 
					
						
							|  |  |  |         "        \"c\": \"C2\"" | 
					
						
							|  |  |  |         "      }," | 
					
						
							|  |  |  |         "      \"c\": \"C3\"" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"b\": 123" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |          true); | 
					
						
							|  |  |  |     INVALIDATE(s1, | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"a\": {" | 
					
						
							|  |  |  |         "    \"c\": \"C1\"," | 
					
						
							|  |  |  |         "    \"d\": {" | 
					
						
							|  |  |  |         "      \"a\": {" | 
					
						
							|  |  |  |         "        \"c\": \"C2\"" | 
					
						
							|  |  |  |         "      }," | 
					
						
							|  |  |  |         "      \"c\": \"C3\"" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"b\": \"should be an int\"" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         "#/paths/~1some~1path/post/parameters/0/schema/properties/b", "type", "#/b", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\":\"#/b\"," | 
					
						
							|  |  |  |         "    \"schemaRef\":\"#/paths/~1some~1path/post/parameters/0/schema/properties/b\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\":\"string\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s1, | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"a\": {" | 
					
						
							|  |  |  |         "    \"c\": \"C1\"," | 
					
						
							|  |  |  |         "    \"d\": {" | 
					
						
							|  |  |  |         "      \"a\": {" | 
					
						
							|  |  |  |         "        \"c\": \"should be within enum\"" | 
					
						
							|  |  |  |         "      }," | 
					
						
							|  |  |  |         "      \"c\": \"C3\"" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"b\": 123" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         "#/definitions/Prop_a/properties/c", "enum", "#/a/d/a/c", | 
					
						
							|  |  |  |         "{ \"enum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 19," | 
					
						
							|  |  |  |         "    \"instanceRef\":\"#/a/d/a/c\"," | 
					
						
							|  |  |  |         "    \"schemaRef\":\"#/definitions/Prop_a/properties/c\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s1, | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "  \"a\": {" | 
					
						
							|  |  |  |         "    \"c\": \"C1\"," | 
					
						
							|  |  |  |         "    \"d\": {" | 
					
						
							|  |  |  |         "      \"a\": {" | 
					
						
							|  |  |  |         "        \"s\": \"required 'c' is missing\"" | 
					
						
							|  |  |  |         "      }" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"b\": 123" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         "#/definitions/Prop_a", "required", "#/a/d/a", | 
					
						
							|  |  |  |         "{ \"required\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 15," | 
					
						
							|  |  |  |         "    \"missing\":[\"c\"]," | 
					
						
							|  |  |  |         "    \"instanceRef\":\"#/a/d/a\"," | 
					
						
							|  |  |  |         "    \"schemaRef\":\"#/definitions/Prop_a\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     SchemaDocument s2(sd, NULL, 0, NULL, NULL, Pointer("#/paths/~1some~1path/post/responses/200/schema")); | 
					
						
							|  |  |  |     VALIDATE(s2, | 
					
						
							|  |  |  |         "{ \"e\": \"some string\", \"f\": false }", | 
					
						
							|  |  |  |         true); | 
					
						
							|  |  |  |     INVALIDATE(s2, | 
					
						
							|  |  |  |         "{ \"e\": true, \"f\": false }", | 
					
						
							|  |  |  |         "#/definitions/Resp_200/properties/e", "type", "#/e", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\":\"#/e\"," | 
					
						
							|  |  |  |         "    \"schemaRef\":\"#/definitions/Resp_200/properties/e\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\":\"boolean\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s2, | 
					
						
							|  |  |  |         "{ \"e\": \"some string\", \"f\": 123 }", | 
					
						
							|  |  |  |         "#/definitions/Resp_200/properties/f", "type", "#/f", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\":\"#/f\"," | 
					
						
							|  |  |  |         "    \"schemaRef\":\"#/definitions/Resp_200/properties/f\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"boolean\"], \"actual\":\"integer\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename Allocator> | 
					
						
							|  |  |  | static char* ReadFile(const char* filename, Allocator& allocator) { | 
					
						
							|  |  |  |     const char *paths[] = { | 
					
						
							|  |  |  |         "", | 
					
						
							|  |  |  |         "bin/", | 
					
						
							|  |  |  |         "../bin/", | 
					
						
							|  |  |  |         "../../bin/", | 
					
						
							|  |  |  |         "../../../bin/" | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     char buffer[1024]; | 
					
						
							|  |  |  |     FILE *fp = 0; | 
					
						
							|  |  |  |     for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) { | 
					
						
							|  |  |  |         sprintf(buffer, "%s%s", paths[i], filename); | 
					
						
							|  |  |  |         fp = fopen(buffer, "rb"); | 
					
						
							|  |  |  |         if (fp) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!fp) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fseek(fp, 0, SEEK_END); | 
					
						
							|  |  |  |     size_t length = static_cast<size_t>(ftell(fp)); | 
					
						
							|  |  |  |     fseek(fp, 0, SEEK_SET); | 
					
						
							|  |  |  |     char* json = reinterpret_cast<char*>(allocator.Malloc(length + 1)); | 
					
						
							|  |  |  |     size_t readLength = fread(json, 1, length, fp); | 
					
						
							|  |  |  |     json[readLength] = '\0'; | 
					
						
							|  |  |  |     fclose(fp); | 
					
						
							|  |  |  |     return json; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ValidateMetaSchema) { | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* json = ReadFile("draft-04/schema", allocator); | 
					
						
							|  |  |  |     Document d; | 
					
						
							|  |  |  |     d.Parse(json); | 
					
						
							|  |  |  |     ASSERT_FALSE(d.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument sd(d); | 
					
						
							|  |  |  |     SchemaValidator validator(sd); | 
					
						
							|  |  |  |     d.Accept(validator); | 
					
						
							|  |  |  |     if (!validator.IsValid()) { | 
					
						
							|  |  |  |         StringBuffer sb; | 
					
						
							|  |  |  |         validator.GetInvalidSchemaPointer().StringifyUriFragment(sb); | 
					
						
							|  |  |  |         printf("Invalid schema: %s\n", sb.GetString()); | 
					
						
							|  |  |  |         printf("Invalid keyword: %s\n", validator.GetInvalidSchemaKeyword()); | 
					
						
							|  |  |  |         printf("Invalid code: %d\n", validator.GetInvalidSchemaCode()); | 
					
						
							|  |  |  |         printf("Invalid message: %s\n", GetValidateError_En(validator.GetInvalidSchemaCode())); | 
					
						
							|  |  |  |         sb.Clear(); | 
					
						
							|  |  |  |         validator.GetInvalidDocumentPointer().StringifyUriFragment(sb); | 
					
						
							|  |  |  |         printf("Invalid document: %s\n", sb.GetString()); | 
					
						
							|  |  |  |         sb.Clear(); | 
					
						
							|  |  |  |         Writer<StringBuffer> w(sb); | 
					
						
							|  |  |  |         validator.GetError().Accept(w); | 
					
						
							|  |  |  |         printf("Validation error: %s\n", sb.GetString()); | 
					
						
							|  |  |  |         ADD_FAILURE(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     CrtAllocator::Free(json); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ValidateMetaSchema_UTF16) { | 
					
						
							|  |  |  |     typedef GenericDocument<UTF16<> > D; | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<D::ValueType> SD; | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SD> SV; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* json = ReadFile("draft-04/schema", allocator); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     D d; | 
					
						
							|  |  |  |     StringStream ss(json); | 
					
						
							|  |  |  |     d.ParseStream<0, UTF8<> >(ss); | 
					
						
							|  |  |  |     ASSERT_FALSE(d.HasParseError()); | 
					
						
							|  |  |  |     SD sd(d); | 
					
						
							|  |  |  |     SV validator(sd); | 
					
						
							|  |  |  |     d.Accept(validator); | 
					
						
							|  |  |  |     if (!validator.IsValid()) { | 
					
						
							|  |  |  |         GenericStringBuffer<UTF16<> > sb; | 
					
						
							|  |  |  |         validator.GetInvalidSchemaPointer().StringifyUriFragment(sb); | 
					
						
							|  |  |  |         wprintf(L"Invalid schema: %ls\n", sb.GetString()); | 
					
						
							|  |  |  |         wprintf(L"Invalid keyword: %ls\n", validator.GetInvalidSchemaKeyword()); | 
					
						
							|  |  |  |         sb.Clear(); | 
					
						
							|  |  |  |         validator.GetInvalidDocumentPointer().StringifyUriFragment(sb); | 
					
						
							|  |  |  |         wprintf(L"Invalid document: %ls\n", sb.GetString()); | 
					
						
							|  |  |  |         sb.Clear(); | 
					
						
							|  |  |  |         Writer<GenericStringBuffer<UTF16<> >, UTF16<> > w(sb); | 
					
						
							|  |  |  |         validator.GetError().Accept(w); | 
					
						
							|  |  |  |         printf("Validation error: %ls\n", sb.GetString()); | 
					
						
							|  |  |  |         ADD_FAILURE(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     CrtAllocator::Free(json); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename SchemaDocumentType = SchemaDocument> | 
					
						
							|  |  |  | class RemoteSchemaDocumentProvider : public IGenericRemoteSchemaDocumentProvider<SchemaDocumentType> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider() :  | 
					
						
							|  |  |  |         documentAllocator_(documentBuffer_, sizeof(documentBuffer_)),  | 
					
						
							|  |  |  |         schemaAllocator_(schemaBuffer_, sizeof(schemaBuffer_))  | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         const char* filenames[kCount] = { | 
					
						
							|  |  |  |             "jsonschema/remotes/integer.json", | 
					
						
							|  |  |  |             "jsonschema/remotes/subSchemas.json", | 
					
						
							|  |  |  |             "jsonschema/remotes/folder/folderInteger.json", | 
					
						
							|  |  |  |             "draft-04/schema", | 
					
						
							|  |  |  |             "unittestschema/address.json" | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         const char* uris[kCount] = { | 
					
						
							|  |  |  |             "http://localhost:1234/integer.json", | 
					
						
							|  |  |  |             "http://localhost:1234/subSchemas.json", | 
					
						
							|  |  |  |             "http://localhost:1234/folder/folderInteger.json", | 
					
						
							|  |  |  |             "http://json-schema.org/draft-04/schema", | 
					
						
							|  |  |  |             "http://localhost:1234/address.json" | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (size_t i = 0; i < kCount; i++) { | 
					
						
							|  |  |  |             sd_[i] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             char jsonBuffer[8192]; | 
					
						
							|  |  |  |             MemoryPoolAllocator<> jsonAllocator(jsonBuffer, sizeof(jsonBuffer)); | 
					
						
							|  |  |  |             char* json = ReadFile(filenames[i], jsonAllocator); | 
					
						
							|  |  |  |             if (!json) { | 
					
						
							|  |  |  |                 printf("json remote file %s not found", filenames[i]); | 
					
						
							|  |  |  |                 ADD_FAILURE(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 char stackBuffer[4096]; | 
					
						
							|  |  |  |                 MemoryPoolAllocator<> stackAllocator(stackBuffer, sizeof(stackBuffer)); | 
					
						
							|  |  |  |                 DocumentType d(&documentAllocator_, 1024, &stackAllocator); | 
					
						
							|  |  |  |                 d.Parse(json); | 
					
						
							|  |  |  |                 sd_[i] = new SchemaDocumentType(d, uris[i], static_cast<SizeType>(strlen(uris[i])), 0, &schemaAllocator_); | 
					
						
							|  |  |  |                 MemoryPoolAllocator<>::Free(json); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ~RemoteSchemaDocumentProvider() { | 
					
						
							|  |  |  |         for (size_t i = 0; i < kCount; i++) | 
					
						
							|  |  |  |             delete sd_[i]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual const SchemaDocumentType* GetRemoteDocument(const char* uri, SizeType length) { | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |         //printf("GetRemoteDocument : %s\n", uri);
 | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |         for (size_t i = 0; i < kCount; i++) | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |             if (typename SchemaDocumentType::GValue(uri, length) == sd_[i]->GetURI()) { | 
					
						
							|  |  |  |                 //printf("Matched document");
 | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |                 return sd_[i]; | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         //printf("No matched document");
 | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     typedef GenericDocument<typename SchemaDocumentType::EncodingType, MemoryPoolAllocator<>, MemoryPoolAllocator<> > DocumentType; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider(const RemoteSchemaDocumentProvider&); | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider& operator=(const RemoteSchemaDocumentProvider&); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static const size_t kCount = 5; | 
					
						
							|  |  |  |     SchemaDocumentType* sd_[kCount]; | 
					
						
							|  |  |  |     typename DocumentType::AllocatorType documentAllocator_; | 
					
						
							|  |  |  |     typename SchemaDocumentType::AllocatorType schemaAllocator_; | 
					
						
							|  |  |  |     char documentBuffer_[16384]; | 
					
						
							|  |  |  |     char schemaBuffer_[128u * 1024]; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, TestSuite) { | 
					
						
							|  |  |  |     const char* filenames[] = { | 
					
						
							|  |  |  |         "additionalItems.json", | 
					
						
							|  |  |  |         "additionalProperties.json", | 
					
						
							|  |  |  |         "allOf.json", | 
					
						
							|  |  |  |         "anyOf.json", | 
					
						
							|  |  |  |         "default.json", | 
					
						
							|  |  |  |         "definitions.json", | 
					
						
							|  |  |  |         "dependencies.json", | 
					
						
							|  |  |  |         "enum.json", | 
					
						
							|  |  |  |         "items.json", | 
					
						
							|  |  |  |         "maximum.json", | 
					
						
							|  |  |  |         "maxItems.json", | 
					
						
							|  |  |  |         "maxLength.json", | 
					
						
							|  |  |  |         "maxProperties.json", | 
					
						
							|  |  |  |         "minimum.json", | 
					
						
							|  |  |  |         "minItems.json", | 
					
						
							|  |  |  |         "minLength.json", | 
					
						
							|  |  |  |         "minProperties.json", | 
					
						
							|  |  |  |         "multipleOf.json", | 
					
						
							|  |  |  |         "not.json", | 
					
						
							|  |  |  |         "oneOf.json", | 
					
						
							|  |  |  |         "pattern.json", | 
					
						
							|  |  |  |         "patternProperties.json", | 
					
						
							|  |  |  |         "properties.json", | 
					
						
							|  |  |  |         "ref.json", | 
					
						
							|  |  |  |         "refRemote.json", | 
					
						
							|  |  |  |         "required.json", | 
					
						
							|  |  |  |         "type.json", | 
					
						
							|  |  |  |         "uniqueItems.json" | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const char* onlyRunDescription = 0; | 
					
						
							|  |  |  |     //const char* onlyRunDescription = "a string is a string";
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned testCount = 0; | 
					
						
							|  |  |  |     unsigned passCount = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     char jsonBuffer[65536]; | 
					
						
							|  |  |  |     char documentBuffer[65536]; | 
					
						
							|  |  |  |     char documentStackBuffer[65536]; | 
					
						
							|  |  |  |     char schemaBuffer[65536]; | 
					
						
							|  |  |  |     char validatorBuffer[65536]; | 
					
						
							|  |  |  |     MemoryPoolAllocator<> jsonAllocator(jsonBuffer, sizeof(jsonBuffer)); | 
					
						
							|  |  |  |     MemoryPoolAllocator<> documentAllocator(documentBuffer, sizeof(documentBuffer)); | 
					
						
							|  |  |  |     MemoryPoolAllocator<> documentStackAllocator(documentStackBuffer, sizeof(documentStackBuffer)); | 
					
						
							|  |  |  |     MemoryPoolAllocator<> schemaAllocator(schemaBuffer, sizeof(schemaBuffer)); | 
					
						
							|  |  |  |     MemoryPoolAllocator<> validatorAllocator(validatorBuffer, sizeof(validatorBuffer)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (size_t i = 0; i < sizeof(filenames) / sizeof(filenames[0]); i++) { | 
					
						
							|  |  |  |         char filename[FILENAME_MAX]; | 
					
						
							|  |  |  |         sprintf(filename, "jsonschema/tests/draft4/%s", filenames[i]); | 
					
						
							|  |  |  |         char* json = ReadFile(filename, jsonAllocator); | 
					
						
							|  |  |  |         if (!json) { | 
					
						
							|  |  |  |             printf("json test suite file %s not found", filename); | 
					
						
							|  |  |  |             ADD_FAILURE(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |             //printf("\njson test suite file %s parsed ok\n", filename);
 | 
					
						
							|  |  |  |             GenericDocument<UTF8<>, MemoryPoolAllocator<>, MemoryPoolAllocator<> > d(&documentAllocator, 1024, &documentStackAllocator); | 
					
						
							|  |  |  |             d.Parse(json); | 
					
						
							|  |  |  |             if (d.HasParseError()) { | 
					
						
							|  |  |  |                 printf("json test suite file %s has parse error", filename); | 
					
						
							|  |  |  |                 ADD_FAILURE(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 for (Value::ConstValueIterator schemaItr = d.Begin(); schemaItr != d.End(); ++schemaItr) { | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         const char* description1 = (*schemaItr)["description"].GetString(); | 
					
						
							|  |  |  |                         //printf("\ncompiling schema for json test %s \n", description1);
 | 
					
						
							|  |  |  |                         SchemaDocumentType schema((*schemaItr)["schema"], filenames[i], static_cast<SizeType>(strlen(filenames[i])), &provider, &schemaAllocator); | 
					
						
							|  |  |  |                         GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > validator(schema, &validatorAllocator); | 
					
						
							|  |  |  |                         const Value& tests = (*schemaItr)["tests"]; | 
					
						
							|  |  |  |                         for (Value::ConstValueIterator testItr = tests.Begin(); testItr != tests.End(); ++testItr) { | 
					
						
							|  |  |  |                             const char* description2 = (*testItr)["description"].GetString(); | 
					
						
							|  |  |  |                             //printf("running json test %s \n", description2);
 | 
					
						
							|  |  |  |                             if (!onlyRunDescription || strcmp(description2, onlyRunDescription) == 0) { | 
					
						
							|  |  |  |                                 const Value& data = (*testItr)["data"]; | 
					
						
							|  |  |  |                                 bool expected = (*testItr)["valid"].GetBool(); | 
					
						
							|  |  |  |                                 testCount++; | 
					
						
							|  |  |  |                                 validator.Reset(); | 
					
						
							|  |  |  |                                 data.Accept(validator); | 
					
						
							|  |  |  |                                 bool actual = validator.IsValid(); | 
					
						
							|  |  |  |                                 if (expected != actual) | 
					
						
							|  |  |  |                                     printf("Fail: %30s \"%s\" \"%s\"\n", filename, description1, description2); | 
					
						
							|  |  |  |                                 else { | 
					
						
							|  |  |  |                                     //printf("Passed: %30s \"%s\" \"%s\"\n", filename, description1, description2);
 | 
					
						
							|  |  |  |                                     passCount++; | 
					
						
							|  |  |  |                                 } | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         //printf("%zu %zu %zu\n", documentAllocator.Size(), schemaAllocator.Size(), validatorAllocator.Size());
 | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     schemaAllocator.Clear(); | 
					
						
							|  |  |  |                     validatorAllocator.Clear(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         documentAllocator.Clear(); | 
					
						
							|  |  |  |         MemoryPoolAllocator<>::Free(json); | 
					
						
							|  |  |  |         jsonAllocator.Clear(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     printf("%d / %d passed (%2d%%)\n", passCount, testCount, passCount * 100 / testCount); | 
					
						
							|  |  |  |     if (passCount != testCount) | 
					
						
							|  |  |  |         ADD_FAILURE(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidatingReader, Simple) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{ \"type\": \"string\", \"enum\" : [\"red\", \"amber\", \"green\"] }"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Document d; | 
					
						
							|  |  |  |     StringStream ss("\"red\""); | 
					
						
							|  |  |  |     SchemaValidatingReader<kParseDefaultFlags, StringStream, UTF8<> > reader(ss, s); | 
					
						
							|  |  |  |     d.Populate(reader); | 
					
						
							|  |  |  |     EXPECT_TRUE(reader.GetParseResult()); | 
					
						
							|  |  |  |     EXPECT_TRUE(reader.IsValid()); | 
					
						
							|  |  |  |     EXPECT_TRUE(d.IsString()); | 
					
						
							|  |  |  |     EXPECT_STREQ("red", d.GetString()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidatingReader, Invalid) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"string\",\"minLength\":2,\"maxLength\":3}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Document d; | 
					
						
							|  |  |  |     StringStream ss("\"ABCD\""); | 
					
						
							|  |  |  |     SchemaValidatingReader<kParseDefaultFlags, StringStream, UTF8<> > reader(ss, s); | 
					
						
							|  |  |  |     d.Populate(reader); | 
					
						
							|  |  |  |     EXPECT_FALSE(reader.GetParseResult()); | 
					
						
							|  |  |  |     EXPECT_FALSE(reader.IsValid()); | 
					
						
							|  |  |  |     EXPECT_EQ(kParseErrorTermination, reader.GetParseResult().Code()); | 
					
						
							|  |  |  |     EXPECT_STREQ("maxLength", reader.GetInvalidSchemaKeyword()); | 
					
						
							|  |  |  |     EXPECT_TRUE(reader.GetInvalidSchemaCode() == kValidateErrorMaxLength); | 
					
						
							|  |  |  |     EXPECT_TRUE(reader.GetInvalidSchemaPointer() == SchemaDocument::PointerType("")); | 
					
						
							|  |  |  |     EXPECT_TRUE(reader.GetInvalidDocumentPointer() == SchemaDocument::PointerType("")); | 
					
						
							|  |  |  |     EXPECT_TRUE(d.IsNull()); | 
					
						
							|  |  |  |     Document e; | 
					
						
							|  |  |  |     e.Parse( | 
					
						
							|  |  |  |         "{ \"maxLength\": {" | 
					
						
							|  |  |  |         "     \"errorCode\": 6," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 3, \"actual\": \"ABCD\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     if (e != reader.GetError()) { | 
					
						
							|  |  |  |         ADD_FAILURE(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidatingWriter, Simple) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"string\",\"minLength\":2,\"maxLength\":3}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Document d; | 
					
						
							|  |  |  |     StringBuffer sb; | 
					
						
							|  |  |  |     Writer<StringBuffer> writer(sb); | 
					
						
							|  |  |  |     GenericSchemaValidator<SchemaDocument, Writer<StringBuffer> > validator(s, writer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     d.Parse("\"red\""); | 
					
						
							|  |  |  |     EXPECT_TRUE(d.Accept(validator)); | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.IsValid()); | 
					
						
							|  |  |  |     EXPECT_STREQ("\"red\"", sb.GetString()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sb.Clear(); | 
					
						
							|  |  |  |     validator.Reset(); | 
					
						
							|  |  |  |     d.Parse("\"ABCD\""); | 
					
						
							|  |  |  |     EXPECT_FALSE(d.Accept(validator)); | 
					
						
							|  |  |  |     EXPECT_FALSE(validator.IsValid()); | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.GetInvalidSchemaPointer() == SchemaDocument::PointerType("")); | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.GetInvalidDocumentPointer() == SchemaDocument::PointerType("")); | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.GetInvalidSchemaCode() == kValidateErrorMaxLength); | 
					
						
							|  |  |  |     Document e; | 
					
						
							|  |  |  |     e.Parse( | 
					
						
							|  |  |  |         "{ \"maxLength\": {" | 
					
						
							|  |  |  | "            \"errorCode\": 6," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": 3, \"actual\": \"ABCD\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     EXPECT_EQ(e, validator.GetError()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(Schema, Issue848) { | 
					
						
							|  |  |  |     rapidjson::Document d; | 
					
						
							|  |  |  |     rapidjson::SchemaDocument s(d); | 
					
						
							|  |  |  |     rapidjson::GenericSchemaValidator<rapidjson::SchemaDocument, rapidjson::Document> v(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static SchemaDocument ReturnSchemaDocument() { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{ \"type\": [\"number\", \"string\"] }"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     return s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(Schema, Issue552) { | 
					
						
							|  |  |  |     SchemaDocument s = ReturnSchemaDocument(); | 
					
						
							|  |  |  |     VALIDATE(s, "42", true); | 
					
						
							|  |  |  |     VALIDATE(s, "\"Life, the universe, and everything\"", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "[\"Life\", \"the universe\", \"and everything\"]", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\", \"number\"], \"actual\": \"array\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Issue608) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"required\": [\"a\", \"b\"] }"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "{\"a\" : null, \"b\": null}", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "{\"a\" : null, \"a\" : null}", "", "required", "", | 
					
						
							|  |  |  |         "{ \"required\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 15," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"missing\": [\"b\"]" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Fail to resolve $ref in allOf causes crash in SchemaValidator::StartObject()
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Issue728_AllOfRef) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"allOf\": [{\"$ref\": \"#/abc\"}]}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |     SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/allOf/0\",\"value\":\"#/abc\"}}"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE_(s, "{\"key1\": \"abc\", \"key2\": \"def\"}", true, false); | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Issue1017_allOfHandler) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"allOf\": [{\"type\": \"object\",\"properties\": {\"cyanArray2\": {\"type\": \"array\",\"items\": { \"type\": \"string\" }}}},{\"type\": \"object\",\"properties\": {\"blackArray\": {\"type\": \"array\",\"items\": { \"type\": \"string\" }}},\"required\": [ \"blackArray\" ]}]}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     StringBuffer sb; | 
					
						
							|  |  |  |     Writer<StringBuffer> writer(sb); | 
					
						
							|  |  |  |     GenericSchemaValidator<SchemaDocument, Writer<StringBuffer> > validator(s, writer); | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.StartObject()); | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.Key("cyanArray2", 10, false)); | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.StartArray());     | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.EndArray(0));     | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.Key("blackArray", 10, false)); | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.StartArray());     | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.EndArray(0));     | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.EndObject(0)); | 
					
						
							|  |  |  |     EXPECT_TRUE(validator.IsValid()); | 
					
						
							|  |  |  |     EXPECT_STREQ("{\"cyanArray2\":[],\"blackArray\":[]}", sb.GetString()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_remote) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$ref\": \"http://localhost:1234/subSchemas.json#/integer\"}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, 0, 0, &provider); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "null", "/integer", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Merge with id where $ref is full URI
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_remote_change_resolution_scope_uri) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"id\": \"http://ignore/blah#/ref\", \"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"http://localhost:1234/subSchemas.json#/integer\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, 0, 0, &provider); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/myInt\"," | 
					
						
							|  |  |  |         "    \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Merge with id where $ref is a relative path
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_remote_change_resolution_scope_relative_path) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"id\": \"http://localhost:1234/\", \"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"subSchemas.json#/integer\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, 0, 0, &provider); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/myInt\"," | 
					
						
							|  |  |  |         "    \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Merge with id where $ref is an absolute path
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_remote_change_resolution_scope_absolute_path) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"id\": \"http://localhost:1234/xxxx\", \"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/integer\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, 0, 0, &provider); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/myInt\"," | 
					
						
							|  |  |  |         "    \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Merge with id where $ref is an absolute path, and the document has a base URI
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_remote_change_resolution_scope_absolute_path_document) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/integer\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/myInt\"," | 
					
						
							|  |  |  |         "    \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is a non-JSON pointer fragment and there a matching id
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_internal_id_1) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myStr\": {\"type\": \"string\", \"id\": \"#myStrId\"}, \"myInt2\": {\"type\": \"integer\", \"id\": \"#myId\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"myInt1\": null}", "/properties/myInt2", "type", "/myInt1", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/myInt1\"," | 
					
						
							|  |  |  |         "    \"schemaRef\": \"#/properties/myInt2\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is a non-JSON pointer fragment and there are two matching ids so we take the first
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_internal_id_2) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myInt2\": {\"type\": \"integer\", \"id\": \"#myId\"}, \"myStr\": {\"type\": \"string\", \"id\": \"#myId\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"myInt1\": null}", "/properties/myInt2", "type", "/myInt1", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/myInt1\"," | 
					
						
							|  |  |  |         "    \"schemaRef\": \"#/properties/myInt2\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is a non-JSON pointer fragment and there is a matching id within array
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_internal_id_in_array) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myInt2\": {\"anyOf\": [{\"type\": \"string\", \"id\": \"#myStrId\"}, {\"type\": \"integer\", \"id\": \"#myId\"}]}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"myInt1\": null}", "/properties/myInt2/anyOf/1", "type", "/myInt1", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/myInt1\"," | 
					
						
							|  |  |  |         "    \"schemaRef\": \"#/properties/myInt2/anyOf/1\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is a non-JSON pointer fragment and there is a matching id, and the schema is embedded in the document
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_internal_id_and_schema_pointer) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{ \"schema\": {\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myInt2\": {\"anyOf\": [{\"type\": \"integer\", \"id\": \"#myId\"}]}}}}"); | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, 0, 0, 0, 0, PointerType("/schema")); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"myInt1\": null}", "/schema/properties/myInt2/anyOf/0", "type", "/myInt1", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#/myInt1\"," | 
					
						
							|  |  |  |         "    \"schemaRef\": \"#/schema/properties/myInt2/anyOf/0\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"integer\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that $refs are correctly resolved when intermediate multiple ids are present
 | 
					
						
							|  |  |  | // Includes $ref to a part of the document with a different in-scope id, which also contains $ref..
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_internal_multiple_ids) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     //RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
 | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* schema = ReadFile("unittestschema/idandref.json", allocator); | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse(schema); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, "http://xyz", 10/*, &provider*/); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"PA1\": \"s\", \"PA2\": \"t\", \"PA3\": \"r\", \"PX1\": 1, \"PX2Y\": 2, \"PX3Z\": 3, \"PX4\": 4, \"PX5\": 5, \"PX6\": 6, \"PX7W\": 7, \"PX8N\": { \"NX\": 8}}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{ \"type\": [" | 
					
						
							|  |  |  |         "    {\"errorCode\": 20, \"instanceRef\": \"#/PA1\", \"schemaRef\": \"http://xyz#/definitions/A\", \"expected\": [\"integer\"], \"actual\": \"string\"}," | 
					
						
							|  |  |  |         "    {\"errorCode\": 20, \"instanceRef\": \"#/PA2\", \"schemaRef\": \"http://xyz#/definitions/A\", \"expected\": [\"integer\"], \"actual\": \"string\"}," | 
					
						
							|  |  |  |         "    {\"errorCode\": 20, \"instanceRef\": \"#/PA3\", \"schemaRef\": \"http://xyz#/definitions/A\", \"expected\": [\"integer\"], \"actual\": \"string\"}," | 
					
						
							|  |  |  |         "    {\"errorCode\": 20, \"instanceRef\": \"#/PX1\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"}," | 
					
						
							|  |  |  |         "    {\"errorCode\": 20, \"instanceRef\": \"#/PX2Y\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"}," | 
					
						
							|  |  |  |         "    {\"errorCode\": 20, \"instanceRef\": \"#/PX3Z\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"}," | 
					
						
							|  |  |  |         "    {\"errorCode\": 20, \"instanceRef\": \"#/PX4\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"}," | 
					
						
							|  |  |  |         "    {\"errorCode\": 20, \"instanceRef\": \"#/PX5\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"}," | 
					
						
							|  |  |  |         "    {\"errorCode\": 20, \"instanceRef\": \"#/PX6\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"}," | 
					
						
							|  |  |  |         "    {\"errorCode\": 20, \"instanceRef\": \"#/PX7W\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"}," | 
					
						
							|  |  |  |         "    {\"errorCode\": 20, \"instanceRef\": \"#/PX8N/NX\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"}" | 
					
						
							|  |  |  |         "]}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  |     CrtAllocator::Free(schema); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Ref_remote_issue1210) { | 
					
						
							|  |  |  |     class SchemaDocumentProvider : public IRemoteSchemaDocumentProvider { | 
					
						
							|  |  |  |         SchemaDocument** collection; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Dummy private copy constructor & assignment operator.
 | 
					
						
							|  |  |  |         // Function bodies added so that they compile in MSVC 2019.
 | 
					
						
							|  |  |  |         SchemaDocumentProvider(const SchemaDocumentProvider&) : collection(NULL) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         SchemaDocumentProvider& operator=(const SchemaDocumentProvider&) { | 
					
						
							|  |  |  |             return *this; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public: | 
					
						
							|  |  |  |           SchemaDocumentProvider(SchemaDocument** collection) : collection(collection) { } | 
					
						
							|  |  |  |           virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeType length) { | 
					
						
							|  |  |  |             int i = 0; | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |             while (collection[i] && SchemaDocument::GValue(uri, length) != collection[i]->GetURI()) ++i; | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |             return collection[i]; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     SchemaDocument* collection[] = { 0, 0, 0 }; | 
					
						
							|  |  |  |     SchemaDocumentProvider provider(collection); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Document x, y, z; | 
					
						
							|  |  |  |     x.Parse("{\"properties\":{\"country\":{\"$ref\":\"y.json#/definitions/country_remote\"}},\"type\":\"object\"}"); | 
					
						
							|  |  |  |     y.Parse("{\"definitions\":{\"country_remote\":{\"$ref\":\"z.json#/definitions/country_list\"}}}"); | 
					
						
							|  |  |  |     z.Parse("{\"definitions\":{\"country_list\":{\"enum\":[\"US\"]}}}"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SchemaDocument sz(z, "z.json", 6, &provider); | 
					
						
							|  |  |  |     collection[0] = &sz; | 
					
						
							|  |  |  |     SchemaDocument sy(y, "y.json", 6, &provider); | 
					
						
							|  |  |  |     collection[1] = &sy; | 
					
						
							|  |  |  |     SchemaDocument sx(x, "x.json", 6, &provider); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(sx, "{\"country\":\"UK\"}", false); | 
					
						
							|  |  |  |     VALIDATE(sx, "{\"country\":\"US\"}", true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that when kValidateContinueOnErrorFlag is set, all errors are reported.
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ContinueOnErrors) { | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* schema = ReadFile("unittestschema/address.json", allocator); | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse(schema); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     VALIDATE(s, "{\"version\": 1.0, \"address\": {\"number\": 24, \"street1\": \"The Woodlands\", \"street3\": \"Ham\", \"city\": \"Romsey\", \"area\": \"Kent\", \"country\": \"UK\", \"postcode\": \"SO51 0GP\"}, \"phones\": [\"0111-222333\", \"0777-666888\"], \"names\": [\"Fred\", \"Bloggs\"]}", true); | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |     INVALIDATE_(s, "{\"version\": 1.01, \"address\": {\"number\": 0, \"street2\": false,  \"street3\": \"Ham\", \"city\": \"RomseyTownFC\", \"area\": \"Narnia\", \"country\": \"USA\", \"postcode\": \"999ABC\"}, \"phones\": [], \"planet\": \"Earth\", \"extra\": {\"S_xxx\": 123}}", "#", "errors", "#", | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |         "{ \"multipleOf\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 1, \"instanceRef\": \"#/version\", \"schemaRef\": \"#/definitions/decimal_type\", \"expected\": 1.0, \"actual\": 1.01" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"minimum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 5, \"instanceRef\": \"#/address/number\", \"schemaRef\": \"#/definitions/positiveInt_type\", \"expected\": 0, \"actual\": 0, \"exclusiveMinimum\": true" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"type\": [" | 
					
						
							|  |  |  |         "    {\"expected\": [\"null\", \"string\"], \"actual\": \"boolean\", \"errorCode\": 20, \"instanceRef\": \"#/address/street2\", \"schemaRef\": \"#/definitions/address_type/properties/street2\"}," | 
					
						
							|  |  |  |         "    {\"expected\": [\"string\"], \"actual\": \"integer\", \"errorCode\": 20, \"instanceRef\": \"#/extra/S_xxx\", \"schemaRef\": \"#/properties/extra/patternProperties/%5ES_\"}" | 
					
						
							|  |  |  |         "  ]," | 
					
						
							|  |  |  |         "  \"maxLength\": {" | 
					
						
							|  |  |  |         "    \"actual\": \"RomseyTownFC\", \"expected\": 10, \"errorCode\": 6, \"instanceRef\": \"#/address/city\", \"schemaRef\": \"#/definitions/address_type/properties/city\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"anyOf\": {" | 
					
						
							|  |  |  |         "    \"errors\":[" | 
					
						
							|  |  |  |         "      {\"pattern\": {\"actual\": \"999ABC\", \"errorCode\": 8, \"instanceRef\": \"#/address/postcode\", \"schemaRef\": \"#/definitions/address_type/properties/postcode/anyOf/0\"}}," | 
					
						
							|  |  |  |         "      {\"pattern\": {\"actual\": \"999ABC\", \"errorCode\": 8, \"instanceRef\": \"#/address/postcode\", \"schemaRef\": \"#/definitions/address_type/properties/postcode/anyOf/1\"}}" | 
					
						
							|  |  |  |         "    ]," | 
					
						
							|  |  |  |         "    \"errorCode\": 24, \"instanceRef\": \"#/address/postcode\", \"schemaRef\": \"#/definitions/address_type/properties/postcode\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"allOf\": {" | 
					
						
							|  |  |  |         "    \"errors\":[" | 
					
						
							|  |  |  |         "      {\"enum\":{\"errorCode\":19,\"instanceRef\":\"#/address/country\",\"schemaRef\":\"#/definitions/country_type\"}}" | 
					
						
							|  |  |  |         "    ]," | 
					
						
							|  |  |  |         "    \"errorCode\":23,\"instanceRef\":\"#/address/country\",\"schemaRef\":\"#/definitions/address_type/properties/country\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"minItems\": {" | 
					
						
							|  |  |  |         "    \"actual\": 0, \"expected\": 1, \"errorCode\": 10, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"additionalProperties\": {" | 
					
						
							|  |  |  |         "    \"disallowed\": \"planet\", \"errorCode\": 16, \"instanceRef\": \"#\", \"schemaRef\": \"#\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"required\": {" | 
					
						
							|  |  |  |         "    \"missing\": [\"street1\"], \"errorCode\": 15, \"instanceRef\": \"#/address\", \"schemaRef\": \"#/definitions/address_type\"" | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"oneOf\": {" | 
					
						
							|  |  |  |         "    \"matches\": [0, 1], \"errorCode\": 22, \"instanceRef\": \"#/address/area\", \"schemaRef\": \"#/definitions/address_type/properties/area\"" | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |         "  }" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"address\": {\"number\": 200, \"street1\": {}, \"street3\": null, \"city\": \"Rom\", \"area\": \"Dorset\", \"postcode\": \"SO51 0GP\"}, \"phones\": [\"0111-222333\", \"0777-666888\", \"0777-666888\"], \"names\": [\"Fred\", \"S\", \"M\", \"Bloggs\"]}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{ \"maximum\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 3, \"instanceRef\": \"#/address/number\", \"schemaRef\": \"#/definitions/positiveInt_type\", \"expected\": 100, \"actual\": 200, \"exclusiveMaximum\": true" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"type\": {" | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"object\", \"errorCode\": 20, \"instanceRef\": \"#/address/street1\", \"schemaRef\": \"#/definitions/address_type/properties/street1\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"not\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 25, \"instanceRef\": \"#/address/street3\", \"schemaRef\": \"#/definitions/address_type/properties/street3\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"minLength\": {" | 
					
						
							|  |  |  |         "    \"actual\": \"Rom\", \"expected\": 4, \"errorCode\": 7, \"instanceRef\": \"#/address/city\", \"schemaRef\": \"#/definitions/address_type/properties/city\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"maxItems\": {" | 
					
						
							|  |  |  |         "    \"actual\": 3, \"expected\": 2, \"errorCode\": 9, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"uniqueItems\": {" | 
					
						
							|  |  |  |         "    \"duplicates\": [1, 2], \"errorCode\": 11, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"minProperties\": {\"actual\": 6, \"expected\": 7, \"errorCode\": 14, \"instanceRef\": \"#/address\", \"schemaRef\": \"#/definitions/address_type\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"additionalItems\": [" | 
					
						
							|  |  |  |         "    {\"disallowed\": 2, \"errorCode\": 12, \"instanceRef\": \"#/names\", \"schemaRef\": \"#/properties/names\"}," | 
					
						
							|  |  |  |         "    {\"disallowed\": 3, \"errorCode\": 12, \"instanceRef\": \"#/names\", \"schemaRef\": \"#/properties/names\"}" | 
					
						
							|  |  |  |         "  ]," | 
					
						
							|  |  |  |         "  \"dependencies\": {" | 
					
						
							|  |  |  |         "    \"errors\": {" | 
					
						
							|  |  |  |         "      \"address\": {\"required\": {\"missing\": [\"version\"], \"errorCode\": 15, \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/address\"}}," | 
					
						
							|  |  |  |         "      \"names\": {\"required\": {\"missing\": [\"version\"], \"errorCode\": 15, \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/names\"}}" | 
					
						
							|  |  |  |         "    }," | 
					
						
							|  |  |  |         "    \"errorCode\": 18, \"instanceRef\": \"#\", \"schemaRef\": \"#\"" | 
					
						
							|  |  |  |         "  }," | 
					
						
							|  |  |  |         "  \"oneOf\": {" | 
					
						
							|  |  |  |         "    \"errors\": [" | 
					
						
							|  |  |  |         "      {\"enum\": {\"errorCode\": 19, \"instanceRef\": \"#/address/area\", \"schemaRef\": \"#/definitions/county_type\"}}," | 
					
						
							|  |  |  |         "      {\"enum\": {\"errorCode\": 19, \"instanceRef\": \"#/address/area\", \"schemaRef\": \"#/definitions/province_type\"}}" | 
					
						
							|  |  |  |         "    ]," | 
					
						
							|  |  |  |         "    \"errorCode\": 21, \"instanceRef\": \"#/address/area\", \"schemaRef\": \"#/definitions/address_type/properties/area\"" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         CrtAllocator::Free(schema); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that when kValidateContinueOnErrorFlag is set, it is not propagated to oneOf sub-validator so we only get the first error.
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ContinueOnErrors_OneOf) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* schema = ReadFile("unittestschema/oneOf_address.json", allocator); | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse(schema); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, 0, 0, &provider); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"version\": 1.01, \"address\": {\"number\": 0, \"street2\": false,  \"street3\": \"Ham\", \"city\": \"RomseyTownFC\", \"area\": \"BC\", \"country\": \"USA\", \"postcode\": \"999ABC\"}, \"phones\": [], \"planet\": \"Earth\", \"extra\": {\"S_xxx\": 123}}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{ \"oneOf\": {" | 
					
						
							|  |  |  |         "    \"errors\": [{" | 
					
						
							|  |  |  |         "      \"multipleOf\": {" | 
					
						
							|  |  |  |         "        \"errorCode\": 1, \"instanceRef\": \"#/version\", \"schemaRef\": \"http://localhost:1234/address.json#/definitions/decimal_type\", \"expected\": 1.0, \"actual\": 1.01" | 
					
						
							|  |  |  |         "      }" | 
					
						
							|  |  |  |         "    }]," | 
					
						
							|  |  |  |         "    \"errorCode\": 21, \"instanceRef\": \"#\", \"schemaRef\": \"#\"" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  |     CrtAllocator::Free(schema); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that when kValidateContinueOnErrorFlag is set, it is not propagated to allOf sub-validator so we only get the first error.
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ContinueOnErrors_AllOf) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* schema = ReadFile("unittestschema/allOf_address.json", allocator); | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse(schema); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, 0, 0, &provider); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"version\": 1.01, \"address\": {\"number\": 0, \"street2\": false,  \"street3\": \"Ham\", \"city\": \"RomseyTownFC\", \"area\": \"BC\", \"country\": \"USA\", \"postcode\": \"999ABC\"}, \"phones\": [], \"planet\": \"Earth\", \"extra\": {\"S_xxx\": 123}}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{ \"allOf\": {" | 
					
						
							|  |  |  |         "    \"errors\": [{" | 
					
						
							|  |  |  |         "      \"multipleOf\": {" | 
					
						
							|  |  |  |         "        \"errorCode\": 1, \"instanceRef\": \"#/version\", \"schemaRef\": \"http://localhost:1234/address.json#/definitions/decimal_type\", \"expected\": 1.0, \"actual\": 1.01" | 
					
						
							|  |  |  |         "      }" | 
					
						
							|  |  |  |         "    }]," | 
					
						
							|  |  |  |         "    \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\"" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  |     CrtAllocator::Free(schema); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that when kValidateContinueOnErrorFlag is set, it is not propagated to anyOf sub-validator so we only get the first error.
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ContinueOnErrors_AnyOf) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* schema = ReadFile("unittestschema/anyOf_address.json", allocator); | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse(schema); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, 0, 0, &provider); | 
					
						
							|  |  |  |     typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType; | 
					
						
							|  |  |  |     typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType; | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"version\": 1.01, \"address\": {\"number\": 0, \"street2\": false,  \"street3\": \"Ham\", \"city\": \"RomseyTownFC\", \"area\": \"BC\", \"country\": \"USA\", \"postcode\": \"999ABC\"}, \"phones\": [], \"planet\": \"Earth\", \"extra\": {\"S_xxx\": 123}}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{ \"anyOf\": {" | 
					
						
							|  |  |  |         "    \"errors\": [{" | 
					
						
							|  |  |  |         "      \"multipleOf\": {" | 
					
						
							|  |  |  |         "        \"errorCode\": 1, \"instanceRef\": \"#/version\", \"schemaRef\": \"http://localhost:1234/address.json#/definitions/decimal_type\", \"expected\": 1.0, \"actual\": 1.01" | 
					
						
							|  |  |  |         "      }" | 
					
						
							|  |  |  |         "    }]," | 
					
						
							|  |  |  |         "    \"errorCode\": 24, \"instanceRef\": \"#\", \"schemaRef\": \"#\"" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidatorType, PointerType); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CrtAllocator::Free(schema); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that when kValidateContinueOnErrorFlag is set, arrays with uniqueItems:true are correctly processed when an item is invalid.
 | 
					
						
							|  |  |  | // This tests that we don't blow up if a hasher does not get created.
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ContinueOnErrors_UniqueItems) { | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* schema = ReadFile("unittestschema/address.json", allocator); | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse(schema); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     VALIDATE(s, "{\"phones\":[\"12-34\",\"56-78\"]}", true); | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"phones\":[\"12-34\",\"12-34\"]}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{\"uniqueItems\": {\"duplicates\": [0,1], \"errorCode\": 11, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\"}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"phones\":[\"ab-34\",\"cd-78\"]}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{\"pattern\": [" | 
					
						
							|  |  |  |         "  {\"actual\": \"ab-34\", \"errorCode\": 8, \"instanceRef\": \"#/phones/0\", \"schemaRef\": \"#/definitions/phone_type\"}," | 
					
						
							|  |  |  |         "  {\"actual\": \"cd-78\", \"errorCode\": 8, \"instanceRef\": \"#/phones/1\", \"schemaRef\": \"#/definitions/phone_type\"}" | 
					
						
							|  |  |  |         "]}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  |     CrtAllocator::Free(schema); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that when kValidateContinueOnErrorFlag is set, an enum field is correctly processed when it has an invalid value.
 | 
					
						
							|  |  |  | // This tests that we don't blow up if a hasher does not get created.
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ContinueOnErrors_Enum) { | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* schema = ReadFile("unittestschema/address.json", allocator); | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse(schema); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     VALIDATE(s, "{\"gender\":\"M\"}", true); | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"gender\":\"X\"}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{\"enum\": {\"errorCode\": 19, \"instanceRef\": \"#/gender\", \"schemaRef\": \"#/properties/gender\"}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"gender\":1}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{\"type\": {\"expected\":[\"string\"], \"actual\": \"integer\", \"errorCode\": 20, \"instanceRef\": \"#/gender\", \"schemaRef\": \"#/properties/gender\"}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  |     CrtAllocator::Free(schema); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that when kValidateContinueOnErrorFlag is set, an array appearing for an object property is handled
 | 
					
						
							|  |  |  | // This tests that we don't blow up when there is a type mismatch.
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ContinueOnErrors_RogueArray) { | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* schema = ReadFile("unittestschema/address.json", allocator); | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse(schema); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"address\":[{\"number\": 0}]}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{\"type\": {\"expected\":[\"object\"], \"actual\": \"array\", \"errorCode\": 20, \"instanceRef\": \"#/address\", \"schemaRef\": \"#/definitions/address_type\"}," | 
					
						
							|  |  |  |         "  \"dependencies\": {" | 
					
						
							|  |  |  |         "    \"errors\": {" | 
					
						
							|  |  |  |         "      \"address\": {\"required\": {\"missing\": [\"version\"], \"errorCode\": 15, \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/address\"}}" | 
					
						
							|  |  |  |         "    },\"errorCode\": 18, \"instanceRef\": \"#\", \"schemaRef\": \"#\"}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  |     CrtAllocator::Free(schema); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that when kValidateContinueOnErrorFlag is set, an object appearing for an array property is handled
 | 
					
						
							|  |  |  | // This tests that we don't blow up when there is a type mismatch.
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ContinueOnErrors_RogueObject) { | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* schema = ReadFile("unittestschema/address.json", allocator); | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse(schema); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"phones\":{\"number\": 0}}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{\"type\": {\"expected\":[\"array\"], \"actual\": \"object\", \"errorCode\": 20, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\"}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  |     CrtAllocator::Free(schema); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that when kValidateContinueOnErrorFlag is set, a string appearing for an array or object property is handled
 | 
					
						
							|  |  |  | // This tests that we don't blow up when there is a type mismatch.
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ContinueOnErrors_RogueString) { | 
					
						
							|  |  |  |     CrtAllocator allocator; | 
					
						
							|  |  |  |     char* schema = ReadFile("unittestschema/address.json", allocator); | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse(schema); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"address\":\"number\"}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{\"type\": {\"expected\":[\"object\"], \"actual\": \"string\", \"errorCode\": 20, \"instanceRef\": \"#/address\", \"schemaRef\": \"#/definitions/address_type\"}," | 
					
						
							|  |  |  |         "  \"dependencies\": {" | 
					
						
							|  |  |  |         "    \"errors\": {" | 
					
						
							|  |  |  |         "      \"address\": {\"required\": {\"missing\": [\"version\"], \"errorCode\": 15, \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/address\"}}" | 
					
						
							|  |  |  |         "    },\"errorCode\": 18, \"instanceRef\": \"#\", \"schemaRef\": \"#\"}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  |     INVALIDATE_(s, "{\"phones\":\"number\"}", "#", "errors", "#", | 
					
						
							|  |  |  |         "{\"type\": {\"expected\":[\"array\"], \"actual\": \"string\", \"errorCode\": 20, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\"}}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  |     CrtAllocator::Free(schema); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that when kValidateContinueOnErrorFlag is set, an incorrect simple type with a sub-schema is handled correctly.
 | 
					
						
							|  |  |  | // This tests that we don't blow up when there is a type mismatch but there is a sub-schema present
 | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  | TEST(SchemaValidator, ContinueOnErrors_BadSimpleType) { | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\":\"string\", \"anyOf\":[{\"maxLength\":2}]}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     VALIDATE(s, "\"AB\"", true); | 
					
						
							|  |  |  |     INVALIDATE_(s, "\"ABC\"", "#", "errors", "#", | 
					
						
							|  |  |  |         "{ \"anyOf\": {" | 
					
						
							|  |  |  |         "    \"errors\": [{" | 
					
						
							|  |  |  |         "      \"maxLength\": {" | 
					
						
							|  |  |  |         "        \"errorCode\": 6, \"instanceRef\": \"#\", \"schemaRef\": \"#/anyOf/0\", \"expected\": 2, \"actual\": \"ABC\"" | 
					
						
							|  |  |  |         "      }" | 
					
						
							|  |  |  |         "    }]," | 
					
						
							|  |  |  |         "    \"errorCode\": 24, \"instanceRef\": \"#\", \"schemaRef\": \"#\"" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  |     // Invalid type
 | 
					
						
							|  |  |  |     INVALIDATE_(s, "333", "#", "errors", "#", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20, \"instanceRef\": \"#\", \"schemaRef\": \"#\", \"expected\": [\"string\"], \"actual\": \"integer\"" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, UnknownValidationError) { | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  |     ASSERT_TRUE(SchemaValidator::SchemaType::GetValidateErrorKeyword(kValidateErrors).GetString() == std::string("null")); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-05 09:13:29 +00:00
										 |  |  | // The first occurrence of a duplicate keyword is taken
 | 
					
						
							|  |  |  | TEST(SchemaValidator, DuplicateKeyword) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{ \"title\": \"test\",\"type\": \"number\", \"type\": \"string\" }"); | 
					
						
							|  |  |  |     EXPECT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     VALIDATE(s, "42", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "\"Life, the universe, and everything\"", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"number\"], \"actual\": \"string\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SchemaDocument tests
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Specification (schema draft, open api version)
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedNotObject) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("true"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     EXPECT_TRUE(s.GetError().ObjectEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedNoSpec) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     EXPECT_TRUE(s.GetError().ObjectEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedNoSpecStatic) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     Specification spec = SchemaDocumentType::GetSpecification(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(spec.IsSupported()); | 
					
						
							|  |  |  |     ASSERT_TRUE(spec.draft == kDraftNone); | 
					
						
							|  |  |  |     ASSERT_TRUE(spec.oapi == kVersionNone); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedDraft5Static) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\":\"http://json-schema.org/draft-05/schema#\", \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     Specification spec = SchemaDocumentType::GetSpecification(sd); | 
					
						
							|  |  |  |     ASSERT_TRUE(spec.IsSupported()); | 
					
						
							|  |  |  |     ASSERT_TRUE(spec.draft == kDraft05); | 
					
						
							|  |  |  |     ASSERT_TRUE(spec.oapi == kVersionNone); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedDraft4) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     EXPECT_TRUE(s.GetError().ObjectEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedDraft4NoFrag) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\":\"http://json-schema.org/draft-04/schema\", \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     EXPECT_TRUE(s.GetError().ObjectEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedDraft5) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\":\"http://json-schema.org/draft-05/schema#\", \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft05); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     EXPECT_TRUE(s.GetError().ObjectEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedDraft5NoFrag) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\":\"http://json-schema.org/draft-05/schema\", \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft05); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     EXPECT_TRUE(s.GetError().ObjectEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_IgnoreDraftEmbedded) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"root\": {\"$schema\":\"http://json-schema.org/draft-05/schema#\", \"type\": \"integer\"}}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, SchemaDocument::PointerType("/root")); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     EXPECT_TRUE(s.GetError().ObjectEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedDraftOverride) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kDraft04)); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     EXPECT_TRUE(s.GetError().ObjectEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnknownDraftOverride) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kDraftUnknown)); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraftUnknown); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnsupportedDraftOverride) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kDraft03)); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft03); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnknownDraft) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\":\"http://json-schema.org/draft-xxx/schema#\", \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraftUnknown); | 
					
						
							|  |  |  |      ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |    SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnknownDraftNotString) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\": 4, \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraftUnknown); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnsupportedDraft3) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\":\"http://json-schema.org/draft-03/schema#\", \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft03); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnsupportedDraft6) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\":\"http://json-schema.org/draft-06/schema#\", \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft06); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnsupportedDraft7) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\":\"http://json-schema.org/draft-07/schema#\", \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft07); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnsupportedDraft2019_09) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\":\"https://json-schema.org/draft/2019-09/schema\", \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft2019_09); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnsupportedDraft2020_12) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"$schema\":\"https://json-schema.org/draft/2020-12/schema\", \"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft2020_12); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedVersion20Static) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"swagger\":\"2.0\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     Specification spec = SchemaDocumentType::GetSpecification(sd); | 
					
						
							|  |  |  |     ASSERT_TRUE(spec.IsSupported()); | 
					
						
							|  |  |  |     ASSERT_TRUE(spec.draft == kDraft04); | 
					
						
							|  |  |  |     ASSERT_TRUE(spec.oapi == kVersion20); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedVersion20) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"swagger\":\"2.0\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersion20); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     EXPECT_TRUE(s.GetError().ObjectEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedVersion30x) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"openapi\":\"3.0.0\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersion30); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft05); | 
					
						
							|  |  |  |     EXPECT_TRUE(s.GetError().ObjectEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_SupportedVersionOverride) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion20)); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersion20); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     EXPECT_TRUE(s.GetError().ObjectEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnknownVersionOverride) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersionUnknown)); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnsupportedVersionOverride) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion31)); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersion31); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft2020_12); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnknownVersion) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"openapi\":\"1.0\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnknownVersionShort) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"openapi\":\"3.0.\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnknownVersionNotString) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"swagger\": 2}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft04); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_UnsupportedVersion31) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"openapi\":\"3.1.0\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_FALSE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().oapi == kVersion31); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.GetSpecification().draft == kDraft2020_12); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_DraftAndVersion) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"swagger\": \"2.0\", \"$schema\": \"http://json-schema.org/draft-04/schema#\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     ASSERT_TRUE(s.IsSupportedSpecification()); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"SpecIllegal\":{\"errorCode\":12,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_StartUnknown) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"integer\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, SchemaDocument::PointerType("/nowhere")); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"StartUnknown\":{\"errorCode\":1,\"instanceRef\":\"#\", \"value\":\"#/nowhere\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_MultipleErrors) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"swagger\": \"foo\", \"$schema\": \"bar\"}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s(sd); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{ \"SpecUnknown\": {\"errorCode\":10,\"instanceRef\":\"#\"}," | 
					
						
							|  |  |  |                    "  \"SpecIllegal\": {\"errorCode\":12,\"instanceRef\":\"#\"}" | 
					
						
							|  |  |  |                    "}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is a non-JSON pointer fragment - not allowed when OpenAPI
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_RefPlainNameOpenApi) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"swagger\": \"2.0\", \"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myStr\": {\"type\": \"string\", \"id\": \"#myStrId\"}, \"myInt2\": {\"type\": \"integer\", \"id\": \"#myId\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"RefPlainName\":{\"errorCode\":2,\"instanceRef\":\"#/properties/myInt1\",\"value\":\"#myId\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is a non-JSON pointer fragment - not allowed when remote document
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_RefPlainNameRemote) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#plainname\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"RefPlainName\":{\"errorCode\":2,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#plainname\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is an empty string
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_RefEmptyString) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"RefInvalid\":{\"errorCode\":3,\"instanceRef\":\"#/properties/myInt1\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is remote but no provider
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_RefNoRemoteProvider) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#plainname\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, 0); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"RefNoRemoteProvider\":{\"errorCode\":7,\"instanceRef\":\"#/properties/myInt\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is remote but no schema returned
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_RefNoRemoteSchema) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/will-not-resolve.json\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"RefNoRemoteSchema\":{\"errorCode\":8,\"instanceRef\":\"#/properties/myInt\",\"value\":\"http://localhost:1234/will-not-resolve.json\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref pointer is invalid
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_RefPointerInvalid) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"#/&&&&&\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"RefPointerInvalid\":{\"errorCode\":4,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#/&&&&&\",\"offset\":2}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is remote and pointer is invalid
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_RefPointerInvalidRemote) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/abc&&&&&\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"RefPointerInvalid\":{\"errorCode\":4,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#/abc&&&&&\",\"offset\":5}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is unknown non-pointer
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_RefUnknownPlainName) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"#plainname\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#plainname\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// $ref is unknown pointer
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_RefUnknownPointer) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"#/a/b\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#/a/b\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is remote and unknown pointer
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_RefUnknownPointerRemote) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     RemoteSchemaDocumentProvider<SchemaDocumentType> provider; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/a/b\"}}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/properties/myInt\",\"value\":\"http://localhost:1234/subSchemas.json#/a/b\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // $ref is cyclical
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_RefCyclical) { | 
					
						
							|  |  |  |     typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType; | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"object\", \"properties\": {" | 
					
						
							|  |  |  |              "    \"cyclic_source\": {" | 
					
						
							|  |  |  |              "         \"$ref\": \"#/properties/cyclic_target\"" | 
					
						
							|  |  |  |              "    }," | 
					
						
							|  |  |  |              "    \"cyclic_target\": {" | 
					
						
							|  |  |  |              "        \"$ref\": \"#/properties/cyclic_source\"" | 
					
						
							|  |  |  |              "    }" | 
					
						
							|  |  |  |              "}}"); | 
					
						
							|  |  |  |     SchemaDocumentType s(sd); | 
					
						
							|  |  |  |     SCHEMAERROR(s, "{\"RefCyclical\":{\"errorCode\":6,\"instanceRef\":\"#/properties/cyclic_target\",\"value\":\"#/properties/cyclic_source\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, Schema_ReadOnlyAndWriteOnly) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"integer\", \"readOnly\": true, \"writeOnly\": true}"); | 
					
						
							|  |  |  |     ASSERT_FALSE(sd.HasParseError()); | 
					
						
							|  |  |  |     SchemaDocument s1(sd, 0, 0, 0, 0, 0, Specification(kDraft04)); | 
					
						
							|  |  |  |     EXPECT_TRUE(s1.GetError().ObjectEmpty()); | 
					
						
							|  |  |  |     SchemaDocument s2(sd, 0, 0, 0, 0, 0, Specification(kVersion30)); | 
					
						
							|  |  |  |     SCHEMAERROR(s2, "{\"ReadOnlyAndWriteOnly\":{\"errorCode\":13,\"instanceRef\":\"#\"}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, ReadOnlyWhenWriting) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "    \"type\":\"object\"," | 
					
						
							|  |  |  |         "    \"properties\": {" | 
					
						
							|  |  |  |         "        \"rprop\" : {" | 
					
						
							|  |  |  |         "            \"type\": \"string\"," | 
					
						
							|  |  |  |         "            \"readOnly\": true" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion20)); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"rprop\": \"hello\" }", true); | 
					
						
							|  |  |  |     INVALIDATE_(s, "{ \"rprop\": \"hello\" }", "/properties/rprop", "readOnly", "/rprop", | 
					
						
							|  |  |  |         "{ \"readOnly\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 26, \"instanceRef\": \"#/rprop\", \"schemaRef\": \"#/properties/rprop\"" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateWriteFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, WriteOnlyWhenReading) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse( | 
					
						
							|  |  |  |         "{" | 
					
						
							|  |  |  |         "    \"type\":\"object\"," | 
					
						
							|  |  |  |         "    \"properties\": {" | 
					
						
							|  |  |  |         "        \"wprop\" : {" | 
					
						
							|  |  |  |         "            \"type\": \"boolean\"," | 
					
						
							|  |  |  |         "            \"writeOnly\": true" | 
					
						
							|  |  |  |         "        }" | 
					
						
							|  |  |  |         "    }" | 
					
						
							|  |  |  |         "}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion30)); | 
					
						
							|  |  |  |     VALIDATE(s, "{ \"wprop\": true }", true); | 
					
						
							|  |  |  |     INVALIDATE_(s, "{ \"wprop\": true }", "/properties/wprop", "writeOnly", "/wprop", | 
					
						
							|  |  |  |         "{ \"writeOnly\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 27, \"instanceRef\": \"#/wprop\", \"schemaRef\": \"#/properties/wprop\"" | 
					
						
							|  |  |  |         "  }" | 
					
						
							|  |  |  |         "}", | 
					
						
							|  |  |  |         kValidateDefaultFlags | kValidateReadFlag, SchemaValidator, Pointer); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, NullableTrue) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"string\", \"nullable\": true}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, 0, kVersion20); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "\"hello\"", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "null", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "false", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"boolean\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SchemaDocument s30(sd, 0, 0, 0, 0, 0, kVersion30); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s30, "\"hello\"", true); | 
					
						
							|  |  |  |     VALIDATE(s30, "null", true); | 
					
						
							|  |  |  |     INVALIDATE(s30, "false", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"null\", \"string\"], \"actual\": \"boolean\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(SchemaValidator, NullableFalse) { | 
					
						
							|  |  |  |     Document sd; | 
					
						
							|  |  |  |     sd.Parse("{\"type\": \"string\", \"nullable\": false}"); | 
					
						
							|  |  |  |     SchemaDocument s(sd, 0, 0, 0, 0, 0, kVersion20); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s, "\"hello\"", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "null", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s, "false", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"boolean\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SchemaDocument s30(sd, 0, 0, 0, 0, 0, kVersion30); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VALIDATE(s30, "\"hello\"", true); | 
					
						
							|  |  |  |     INVALIDATE(s, "null", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"null\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  |     INVALIDATE(s30, "false", "", "type", "", | 
					
						
							|  |  |  |         "{ \"type\": {" | 
					
						
							|  |  |  |         "    \"errorCode\": 20," | 
					
						
							|  |  |  |         "    \"instanceRef\": \"#\", \"schemaRef\": \"#\"," | 
					
						
							|  |  |  |         "    \"expected\": [\"string\"], \"actual\": \"boolean\"" | 
					
						
							|  |  |  |         "}}"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-06 15:39:12 +00:00
										 |  |  | #if defined(_MSC_VER) || defined(__clang__)
 | 
					
						
							|  |  |  | RAPIDJSON_DIAG_POP | 
					
						
							|  |  |  | #endif
 |