Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/miloyip/rapidjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorSteve Hanson <smh@uk.ibm.com>2021-01-28 15:11:43 +0300
committerSteve Hanson <smh@uk.ibm.com>2021-01-28 15:11:43 +0300
commit05e7b3397758bd31032aa66620e15fd8ab2869f5 (patch)
tree25890750cb2bec922db8556571979251debfc236 /test
parent5d17b24e53e38f493d09bc44cee11fbfe55150a6 (diff)
code and tests
Diffstat (limited to 'test')
-rw-r--r--test/perftest/schematest.cpp13
-rw-r--r--test/unittest/schematest.cpp622
2 files changed, 556 insertions, 79 deletions
diff --git a/test/perftest/schematest.cpp b/test/perftest/schematest.cpp
index 7d27344b..82377449 100644
--- a/test/perftest/schematest.cpp
+++ b/test/perftest/schematest.cpp
@@ -51,6 +51,8 @@ RAPIDJSON_DIAG_POP
class Schema : public PerfTest {
public:
+ typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
+
Schema() {}
virtual void SetUp() {
@@ -89,6 +91,8 @@ public:
char jsonBuffer[65536];
MemoryPoolAllocator<> jsonAllocator(jsonBuffer, sizeof(jsonBuffer));
+ char schemaBuffer[65536];
+ MemoryPoolAllocator<> schemaAllocator(schemaBuffer, sizeof(schemaBuffer));
for (size_t i = 0; i < ARRAY_SIZE(filenames); i++) {
char filename[FILENAME_MAX];
@@ -112,7 +116,7 @@ public:
continue;
TestSuite* ts = new TestSuite;
- ts->schema = new SchemaDocument((*schemaItr)["schema"]);
+ ts->schema = new SchemaDocumentType((*schemaItr)["schema"], 0, 0, 0, &schemaAllocator);
const Value& tests = (*schemaItr)["tests"];
for (Value::ConstValueIterator testItr = tests.Begin(); testItr != tests.End(); ++testItr) {
@@ -187,7 +191,7 @@ protected:
for (DocumentList::iterator itr = tests.begin(); itr != tests.end(); ++itr)
delete *itr;
}
- SchemaDocument* schema;
+ SchemaDocumentType* schema;
DocumentList tests;
};
@@ -199,13 +203,14 @@ TEST_F(Schema, TestSuite) {
char validatorBuffer[65536];
MemoryPoolAllocator<> validatorAllocator(validatorBuffer, sizeof(validatorBuffer));
- const int trialCount = 100000;
+ // DCOLES - Reduce number by a factor of 100 to make it more reasonable and inline with other test counts
+ const int trialCount = 1000;
int testCount = 0;
clock_t start = clock();
for (int i = 0; i < trialCount; i++) {
for (TestSuiteList::const_iterator itr = testSuites.begin(); itr != testSuites.end(); ++itr) {
const TestSuite& ts = **itr;
- GenericSchemaValidator<SchemaDocument, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > validator(*ts.schema, &validatorAllocator);
+ GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > validator(*ts.schema, &validatorAllocator);
for (DocumentList::const_iterator testItr = ts.tests.begin(); testItr != ts.tests.end(); ++testItr) {
validator.Reset();
(*testItr)->Accept(validator);
diff --git a/test/unittest/schematest.cpp b/test/unittest/schematest.cpp
index 8a51b10e..459de1a6 100644
--- a/test/unittest/schematest.cpp
+++ b/test/unittest/schematest.cpp
@@ -12,10 +12,14 @@
// 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
+
#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
@@ -119,6 +123,8 @@ TEST(SchemaValidator, Hasher) {
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());\
@@ -131,19 +137,23 @@ TEST(SchemaValidator, Hasher) {
#define INVALIDATE(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error) \
{\
- INVALIDATE_(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error, SchemaValidator, Pointer) \
+ INVALIDATE_(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error, kValidateDefaultFlags, SchemaValidator, Pointer) \
}
#define INVALIDATE_(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error, \
- SchemaValidatorType, PointerType) \
+ flags, SchemaValidatorType, PointerType) \
{\
SchemaValidatorType validator(schema);\
+ validator.SetValidateFlags(flags);\
Document d;\
/*printf("\n%s\n", json);*/\
d.Parse(json);\
EXPECT_FALSE(d.HasParseError());\
- EXPECT_FALSE(d.Accept(validator));\
+ 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);\
@@ -191,6 +201,7 @@ TEST(SchemaValidator, MultiType) {
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\""
"}}");
@@ -203,7 +214,7 @@ TEST(SchemaValidator, Enum_Typed) {
VALIDATE(s, "\"red\"", true);
INVALIDATE(s, "\"blue\"", "", "enum", "",
- "{ \"enum\": { \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
+ "{ \"enum\": { \"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
}
TEST(SchemaValidator, Enum_Typless) {
@@ -215,7 +226,7 @@ TEST(SchemaValidator, Enum_Typless) {
VALIDATE(s, "null", true);
VALIDATE(s, "42", true);
INVALIDATE(s, "0", "", "enum", "",
- "{ \"enum\": { \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
+ "{ \"enum\": { \"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
}
TEST(SchemaValidator, Enum_InvalidType) {
@@ -226,6 +237,7 @@ TEST(SchemaValidator, Enum_InvalidType) {
VALIDATE(s, "\"red\"", true);
INVALIDATE(s, "null", "", "type", "",
"{ \"type\": {"
+ " \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"null\""
"}}");
@@ -239,9 +251,12 @@ TEST(SchemaValidator, AllOf) {
VALIDATE(s, "\"ok\"", true);
INVALIDATE(s, "\"too long\"", "", "allOf", "",
- "{ \"maxLength\": { "
- " \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/1\", "
- " \"expected\": 5, \"actual\": \"too long\""
+ "{ \"allOf\": {"
+ " \"errors\": ["
+ " {},"
+ " {\"maxLength\": {\"errorCode\": 6, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/1\", \"expected\": 5, \"actual\": \"too long\"}}"
+ " ],"
+ " \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
"}}");
}
{
@@ -251,8 +266,12 @@ TEST(SchemaValidator, AllOf) {
VALIDATE(s, "\"No way\"", false);
INVALIDATE(s, "-1", "", "allOf", "",
- "{ \"type\": { \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\","
- " \"expected\": [\"string\"], \"actual\": \"integer\""
+ "{ \"allOf\": {"
+ " \"errors\": ["
+ " {\"type\": { \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\", \"errorCode\": 20, \"expected\": [\"string\"], \"actual\": \"integer\"}},"
+ " {}"
+ " ],"
+ " \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
"}}");
}
}
@@ -266,13 +285,16 @@ TEST(SchemaValidator, AnyOf) {
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\""
" }}"
@@ -289,20 +311,23 @@ TEST(SchemaValidator, OneOf) {
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", "",
- "{ \"oneOf\": { \"instanceRef\": \"#\", \"schemaRef\": \"#\", \"errors\": [{}, {}]}}");
+ "{ \"oneOf\": { \"errorCode\": 22, \"instanceRef\": \"#\", \"schemaRef\": \"#\", \"errors\": [{}, {}]}}");
}
TEST(SchemaValidator, Not) {
@@ -313,7 +338,7 @@ TEST(SchemaValidator, Not) {
VALIDATE(s, "42", true);
VALIDATE(s, "{ \"key\": \"value\" }", true);
INVALIDATE(s, "\"I am a string\"", "", "not", "",
- "{ \"not\": { \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
+ "{ \"not\": { \"errorCode\": 25, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
}
TEST(SchemaValidator, Ref) {
@@ -378,10 +403,12 @@ TEST(SchemaValidator, Ref_AllOf) {
SchemaDocument s(sd);
INVALIDATE(s, "{\"shipping_address\": {\"street_address\": \"1600 Pennsylvania Avenue NW\", \"city\": \"Washington\", \"state\": \"DC\"} }", "/properties/shipping_address", "allOf", "/shipping_address",
- "{ \"required\": {"
- " \"instanceRef\": \"#/shipping_address\","
- " \"schemaRef\": \"#/properties/shipping_address/allOf/1\","
- " \"missing\": [\"type\"]"
+ "{ \"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);
}
@@ -394,26 +421,31 @@ TEST(SchemaValidator, String) {
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\""
"}}");
@@ -426,6 +458,7 @@ TEST(SchemaValidator, String_LengthRange) {
INVALIDATE(s, "\"A\"", "", "minLength", "",
"{ \"minLength\": {"
+ " \"errorCode\": 7,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 2, \"actual\": \"A\""
"}}");
@@ -433,6 +466,7 @@ TEST(SchemaValidator, String_LengthRange) {
VALIDATE(s, "\"ABC\"", true);
INVALIDATE(s, "\"ABCD\"", "", "maxLength", "",
"{ \"maxLength\": {"
+ " \"errorCode\": 6,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 3, \"actual\": \"ABCD\""
"}}");
@@ -448,11 +482,13 @@ TEST(SchemaValidator, String_Pattern) {
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\""
"}}");
@@ -482,11 +518,13 @@ TEST(SchemaValidator, Integer) {
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\""
"}}");
@@ -499,6 +537,7 @@ TEST(SchemaValidator, Integer_Range) {
INVALIDATE(s, "-1", "", "minimum", "",
"{ \"minimum\": {"
+ " \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 0, \"actual\": -1"
"}}");
@@ -507,11 +546,13 @@ TEST(SchemaValidator, Integer_Range) {
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"
"}}");
@@ -524,6 +565,7 @@ TEST(SchemaValidator, Integer_Range64Boundary) {
INVALIDATE(s, "-9223372036854775808", "", "minimum", "",
"{ \"minimum\": {"
+ " \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -9223372036854775807, \"actual\": -9223372036854775808"
"}}");
@@ -536,11 +578,13 @@ TEST(SchemaValidator, Integer_Range64Boundary) {
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
@@ -553,36 +597,43 @@ TEST(SchemaValidator, Integer_RangeU64Boundary) {
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
@@ -590,6 +641,7 @@ TEST(SchemaValidator, Integer_RangeU64Boundary) {
VALIDATE(s, "18446744073709551614", true);
INVALIDATE(s, "18446744073709551615", "", "maximum", "",
"{ \"maximum\": {"
+ " \"errorCode\": 2,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 18446744073709551614, \"actual\": 18446744073709551615"
"}}");
@@ -602,6 +654,7 @@ TEST(SchemaValidator, Integer_Range64BoundaryExclusive) {
INVALIDATE(s, "-9223372036854775808", "", "minimum", "",
"{ \"minimum\": {"
+ " \"errorCode\": 5,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -9223372036854775808, \"exclusiveMinimum\": true, "
" \"actual\": -9223372036854775808"
@@ -610,6 +663,7 @@ TEST(SchemaValidator, Integer_Range64BoundaryExclusive) {
VALIDATE(s, "18446744073709551614", true);
INVALIDATE(s, "18446744073709551615", "", "maximum", "",
"{ \"maximum\": {"
+ " \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 18446744073709551615, \"exclusiveMaximum\": true, "
" \"actual\": 18446744073709551615"
@@ -627,11 +681,13 @@ TEST(SchemaValidator, Integer_MultipleOf) {
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"
"}}");
@@ -646,6 +702,7 @@ TEST(SchemaValidator, Integer_MultipleOf64Boundary) {
VALIDATE(s, "18446744073709551615", true);
INVALIDATE(s, "18446744073709551614", "", "multipleOf", "",
"{ \"multipleOf\": {"
+ " \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 18446744073709551615, \"actual\": 18446744073709551614"
"}}");
@@ -658,6 +715,7 @@ TEST(SchemaValidator, Number_Range) {
INVALIDATE(s, "-1", "", "minimum", "",
"{ \"minimum\": {"
+ " \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 0, \"actual\": -1"
"}}");
@@ -668,16 +726,19 @@ TEST(SchemaValidator, Number_Range) {
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"
"}}");
@@ -690,11 +751,13 @@ TEST(SchemaValidator, Number_RangeInt) {
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"
"}}");
@@ -702,46 +765,55 @@ TEST(SchemaValidator, Number_RangeInt) {
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"
"}}");
@@ -754,16 +826,19 @@ TEST(SchemaValidator, Number_RangeDouble) {
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"
"}}");
@@ -773,51 +848,61 @@ TEST(SchemaValidator, Number_RangeDouble) {
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"
"}}");
@@ -830,31 +915,37 @@ TEST(SchemaValidator, Number_RangeDoubleU64Boundary) {
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
@@ -862,6 +953,7 @@ TEST(SchemaValidator, Number_RangeDoubleU64Boundary) {
VALIDATE(s, "18446744073709540000", true);
INVALIDATE(s, "18446744073709551615", "", "maximum", "",
"{ \"maximum\": {"
+ " \"errorCode\": 2,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 18446744073709550000.0, \"actual\": 18446744073709551615"
"}}");
@@ -878,28 +970,33 @@ TEST(SchemaValidator, Number_MultipleOf) {
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
@@ -915,6 +1012,7 @@ TEST(SchemaValidator, Number_MultipleOfOne) {
VALIDATE(s, "42.0", true);
INVALIDATE(s, "3.1415926", "", "multipleOf", "",
"{ \"multipleOf\": {"
+ " \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 1, \"actual\": 3.1415926"
"}}");
@@ -929,11 +1027,13 @@ TEST(SchemaValidator, Object) {
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\""
"}}");
@@ -956,12 +1056,14 @@ TEST(SchemaValidator, Object_Properties) {
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
@@ -990,6 +1092,7 @@ TEST(SchemaValidator, Object_AdditionalPropertiesBoolean) {
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\""
"}}");
@@ -1015,6 +1118,7 @@ TEST(SchemaValidator, Object_AdditionalPropertiesObject) {
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\""
"}}");
@@ -1039,11 +1143,13 @@ TEST(SchemaValidator, Object_Required) {
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\"]"
"}}");
@@ -1067,11 +1173,13 @@ TEST(SchemaValidator, Object_Required_PassWithDefault) {
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\"]"
"}}");
@@ -1084,11 +1192,13 @@ TEST(SchemaValidator, Object_PropertiesRange) {
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"
"}}");
@@ -1096,6 +1206,7 @@ TEST(SchemaValidator, Object_PropertiesRange) {
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"
"}}");
@@ -1123,8 +1234,15 @@ TEST(SchemaValidator, Object_PropertyDependencies) {
"\"billing_address\": \"555 Debtor's Lane\" }", true);
INVALIDATE(s, "{ \"name\": \"John Doe\", \"credit_card\": 5555555555555555 }", "", "dependencies", "",
"{ \"dependencies\": {"
+ " \"errorCode\": 18,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"errors\": {\"credit_card\": [\"cvv_code\", \"billing_address\"]}"
+ " \"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);
@@ -1154,10 +1272,12 @@ TEST(SchemaValidator, Object_SchemaDependencies) {
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\"]"
" } } }"
@@ -1182,18 +1302,20 @@ TEST(SchemaValidator, Object_PatternProperties) {
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_PattternProperties_ErrorConflict) {
+TEST(SchemaValidator, Object_PatternProperties_ErrorConflict) {
Document sd;
sd.Parse(
"{"
@@ -1209,9 +1331,11 @@ TEST(SchemaValidator, Object_PattternProperties_ErrorConflict) {
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"
" }"
@@ -1236,22 +1360,25 @@ TEST(SchemaValidator, Object_Properties_PatternProperties) {
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_AdditionalProperties) {
+TEST(SchemaValidator, Object_PatternProperties_AdditionalPropertiesObject) {
Document sd;
sd.Parse(
"{"
@@ -1271,10 +1398,35 @@ TEST(SchemaValidator, Object_PatternProperties_AdditionalProperties) {
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) {
@@ -1286,6 +1438,7 @@ TEST(SchemaValidator, Array) {
VALIDATE(s, "[3, \"different\", { \"types\" : \"of values\" }]", true);
INVALIDATE(s, "{\"Not\": \"an array\"}", "", "type", "",
"{ \"type\": {"
+ " \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"array\"], \"actual\": \"object\""
"}}");
@@ -1305,6 +1458,7 @@ TEST(SchemaValidator, Array_ItemsList) {
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\""
"}}");
@@ -1337,14 +1491,16 @@ TEST(SchemaValidator, Array_ItemsTuple) {
VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\"]", true);
INVALIDATE(s, "[24, \"Sussex\", \"Drive\"]", "/items/2", "enum", "/2",
- "{ \"enum\": { \"instanceRef\": \"#/2\", \"schemaRef\": \"#/items/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
@@ -1352,7 +1508,7 @@ TEST(SchemaValidator, Array_ItemsTuple) {
VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\", \"Washington\"]", true);
}
-TEST(SchemaValidator, Array_AdditionalItmes) {
+TEST(SchemaValidator, Array_AdditionalItems) {
Document sd;
sd.Parse(
"{"
@@ -1379,8 +1535,9 @@ TEST(SchemaValidator, Array_AdditionalItmes) {
VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\"]", true);
VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\"]", true);
- INVALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\", \"Washington\"]", "", "items", "/4",
+ INVALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\", \"Washington\"]", "", "additionalItems", "/4",
"{ \"additionalItems\": {"
+ " \"errorCode\": 12,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"disallowed\": 4"
"}}");
@@ -1393,11 +1550,13 @@ TEST(SchemaValidator, Array_ItemsRange) {
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"
"}}");
@@ -1405,6 +1564,7 @@ TEST(SchemaValidator, Array_ItemsRange) {
VALIDATE(s, "[1, 2, 3]", true);
INVALIDATE(s, "[1, 2, 3, 4]", "", "maxItems", "",
"{ \"maxItems\": {"
+ " \"errorCode\": 9,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 3, \"actual\": 4"
"}}");
@@ -1418,11 +1578,13 @@ TEST(SchemaValidator, Array_UniqueItems) {
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
@@ -1438,11 +1600,13 @@ TEST(SchemaValidator, Boolean) {
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\""
"}}");
@@ -1456,16 +1620,19 @@ TEST(SchemaValidator, Null) {
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\""
"}}");
@@ -1481,11 +1648,13 @@ TEST(SchemaValidator, ObjectInArray) {
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\""
"}}");
@@ -1508,6 +1677,7 @@ TEST(SchemaValidator, MultiTypeInObject) {
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\""
"}}");
@@ -1530,6 +1700,7 @@ TEST(SchemaValidator, MultiTypeWithObject) {
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\""
"}}");
@@ -1550,48 +1721,71 @@ TEST(SchemaValidator, AllOf_Nested) {
VALIDATE(s, "\"ok\"", true);
VALIDATE(s, "\"OK\"", true);
INVALIDATE(s, "\"okay\"", "", "allOf", "",
- "{ \"enum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\""
+ "{ \"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", "",
- "{ \"minLength\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\","
- " \"expected\": 2, \"actual\": \"o\""
+ "{ \"allOf\": {"
+ " \"errors\": ["
+ " { \"minLength\": {\"actual\": \"o\", \"expected\": 2, \"errorCode\": 7, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\" }},"
+ " {},{}"
+ " ],"
+ " \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
"}}");
INVALIDATE(s, "\"n\"", "", "allOf", "",
- "{ \"minLength\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\","
- " \"expected\": 2, \"actual\": \"n\""
- " },"
- " \"enum\": ["
- " {\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/0\"},"
- " {\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\"}"
- " ]"
- "}")
+ "{ \"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", "",
- "{ \"maxLength\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/1\","
- " \"expected\": 5, \"actual\": \"too long\""
- " },"
- " \"enum\": ["
- " {\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/0\"},"
- " {\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\"}"
- " ]"
- "}");
+ "{ \"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", "",
- "{ \"type\": ["
- " { \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\","
- " \"expected\": [\"string\"], \"actual\": \"integer\""
- " },"
- " { \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/1\","
- " \"expected\": [\"string\"], \"actual\": \"integer\""
- " }"
- " ],"
- " \"enum\": ["
- " {\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/0\"},"
- " {\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\"}"
- " ]"
- "}");
+ "{ \"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) {
@@ -1606,6 +1800,7 @@ TEST(SchemaValidator, EscapedPointer) {
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\""
"}}");
@@ -1650,11 +1845,14 @@ TEST(SchemaValidator, ValidateMetaSchema) {
ASSERT_FALSE(d.HasParseError());
SchemaDocument sd(d);
SchemaValidator validator(sd);
- if (!d.Accept(validator)) {
+ 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());
@@ -1681,7 +1879,8 @@ TEST(SchemaValidator, ValidateMetaSchema_UTF16) {
ASSERT_FALSE(d.HasParseError());
SD sd(d);
SV validator(sd);
- if (!d.Accept(validator)) {
+ d.Accept(validator);
+ if (!validator.IsValid()) {
GenericStringBuffer<UTF16<> > sb;
validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
wprintf(L"Invalid schema: %ls\n", sb.GetString());
@@ -1709,13 +1908,15 @@ public:
"jsonschema/remotes/integer.json",
"jsonschema/remotes/subSchemas.json",
"jsonschema/remotes/folder/folderInteger.json",
- "draft-04/schema"
+ "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://json-schema.org/draft-04/schema",
+ "http://localhost:1234/address.json"
};
for (size_t i = 0; i < kCount; i++) {
@@ -1757,7 +1958,7 @@ private:
RemoteSchemaDocumentProvider(const RemoteSchemaDocumentProvider&);
RemoteSchemaDocumentProvider& operator=(const RemoteSchemaDocumentProvider&);
- static const size_t kCount = 4;
+ static const size_t kCount = 5;
SchemaDocumentType* sd_[kCount];
typename DocumentType::AllocatorType documentAllocator_;
typename SchemaDocumentType::AllocatorType schemaAllocator_;
@@ -1826,6 +2027,7 @@ TEST(SchemaValidator, TestSuite) {
ADD_FAILURE();
}
else {
+ //printf("json test suite file %s parsed ok\n", filename);
GenericDocument<UTF8<>, MemoryPoolAllocator<>, MemoryPoolAllocator<> > d(&documentAllocator, 1024, &documentStackAllocator);
d.Parse(json);
if (d.HasParseError()) {
@@ -1846,11 +2048,14 @@ TEST(SchemaValidator, TestSuite) {
bool expected = (*testItr)["valid"].GetBool();
testCount++;
validator.Reset();
- bool actual = data.Accept(validator);
+ data.Accept(validator);
+ bool actual = validator.IsValid();
if (expected != actual)
printf("Fail: %30s \"%s\" \"%s\"\n", filename, description1, description2);
- else
+ else {
+ //printf("Passed: %30s \"%s\" \"%s\"\n", filename, description1, description2);
passCount++;
+ }
}
}
//printf("%zu %zu %zu\n", documentAllocator.Size(), schemaAllocator.Size(), validatorAllocator.Size());
@@ -1865,8 +2070,8 @@ TEST(SchemaValidator, TestSuite) {
jsonAllocator.Clear();
}
printf("%d / %d passed (%2d%%)\n", passCount, testCount, passCount * 100 / testCount);
- // if (passCount != testCount)
- // ADD_FAILURE();
+// if (passCount != testCount)
+// ADD_FAILURE();
}
TEST(SchemaValidatingReader, Simple) {
@@ -1897,12 +2102,14 @@ TEST(SchemaValidatingReader, Invalid) {
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\""
"}}");
@@ -1933,9 +2140,11 @@ TEST(SchemaValidatingWriter, Simple) {
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\""
"}}");
@@ -1963,6 +2172,7 @@ TEST(Schema, Issue552) {
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\""
"}}");
@@ -1978,6 +2188,7 @@ TEST(SchemaValidator, Issue608) {
VALIDATE(s, "{\"a\" : null, \"b\": null}", true);
INVALIDATE(s, "{\"a\" : null, \"a\" : null}", "", "required", "",
"{ \"required\": {"
+ " \"errorCode\": 15,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"missing\": [\"b\"]"
"}}");
@@ -1991,13 +2202,6 @@ TEST(SchemaValidator, Issue728_AllOfRef) {
VALIDATE(s, "{\"key1\": \"abc\", \"key2\": \"def\"}", true);
}
-TEST(SchemaValidator, Issue825) {
- Document sd;
- sd.Parse("{\"type\": \"object\", \"additionalProperties\": false, \"patternProperties\": {\"^i\": { \"type\": \"string\" } } }");
- SchemaDocument s(sd);
- VALIDATE(s, "{ \"item\": \"hello\" }", true);
-}
-
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\" ]}]}");
@@ -2027,11 +2231,12 @@ TEST(SchemaValidator, Ref_remote) {
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\""
"}}",
- SchemaValidatorType, PointerType);
+ kValidateDefaultFlags, SchemaValidatorType, PointerType);
}
TEST(SchemaValidator, Ref_remote_issue1210) {
@@ -2072,6 +2277,273 @@ TEST(SchemaValidator, Ref_remote_issue1210) {
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);
+ 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", "#",
+ "{ \"multipleOf\": {"
+ " \"errorCode\": 1, \"instanceRef\": \"#/version\", \"schemaRef\": \"#/definitions/decimal_type\", \"expected\": 0.1, \"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\""
+ " }"
+ "}",
+ 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\": 0.1, \"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\": 0.1, \"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\": 0.1, \"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);
+}
+
#if defined(_MSC_VER) || defined(__clang__)
RAPIDJSON_DIAG_POP
#endif