12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072 |
- // 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. All rights reserved.
- //
- // 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.
- #include "unittest.h"
- #include "rapidjson/schema.h"
- #include "rapidjson/stringbuffer.h"
- #include "rapidjson/writer.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) \
- {\
- 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());\
- if ((expected) && !validator.IsValid()) {\
- StringBuffer sb;\
- validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);\
- printf("Invalid schema: %s\n", sb.GetString());\
- printf("Invalid keyword: %s\n", validator.GetInvalidSchemaKeyword());\
- 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, SchemaValidator, Pointer) \
- }
- #define INVALIDATE_(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error, \
- SchemaValidatorType, PointerType) \
- {\
- SchemaValidatorType validator(schema);\
- Document d;\
- /*printf("\n%s\n", json);*/\
- d.Parse(json);\
- EXPECT_FALSE(d.HasParseError());\
- EXPECT_FALSE(d.Accept(validator));\
- EXPECT_FALSE(validator.IsValid());\
- 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();\
- }\
- }
- 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\": {"
- " \"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\": { \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
- }
- TEST(SchemaValidator, Enum_Typless) {
- 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\": { \"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\": {"
- " \"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", "",
- "{ \"maxLength\": { "
- " \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/1\", "
- " \"expected\": 5, \"actual\": \"too long\""
- "}}");
- }
- {
- Document sd;
- sd.Parse("{\"allOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" } ] }");
- SchemaDocument s(sd);
- VALIDATE(s, "\"No way\"", false);
- INVALIDATE(s, "-1", "", "allOf", "",
- "{ \"type\": { \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\","
- " \"expected\": [\"string\"], \"actual\": \"integer\""
- "}}");
- }
- }
- 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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\", "
- " \"errors\": ["
- " { \"type\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#/anyOf/0\","
- " \"expected\": [\"string\"], \"actual\": \"object\""
- " }},"
- " { \"type\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"errors\": ["
- " { \"multipleOf\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#/oneOf/0\","
- " \"expected\": 5, \"actual\": 2"
- " }},"
- " { \"multipleOf\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#/oneOf/1\","
- " \"expected\": 3, \"actual\": 2"
- " }}"
- " ]"
- "}}");
- INVALIDATE(s, "15", "", "oneOf", "",
- "{ \"oneOf\": { \"instanceRef\": \"#\", \"schemaRef\": \"#\", \"errors\": [{}, {}]}}");
- }
- 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\": { \"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",
- "{ \"required\": {"
- " \"instanceRef\": \"#/shipping_address\","
- " \"schemaRef\": \"#/properties/shipping_address/allOf/1\","
- " \"missing\": [\"type\"]"
- "}}");
- 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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": [\"string\"], \"actual\": \"integer\""
- "}}");
- INVALIDATE(s, "2147483648", "", "type", "",
- "{ \"type\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": [\"string\"], \"actual\": \"integer\""
- "}}"); // 2^31 can only be fit in unsigned
- INVALIDATE(s, "-2147483649", "", "type", "",
- "{ \"type\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": [\"string\"], \"actual\": \"integer\""
- "}}"); // -2^31 - 1 can only be fit in int64_t
- INVALIDATE(s, "4294967296", "", "type", "",
- "{ \"type\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": [\"string\"], \"actual\": \"integer\""
- "}}"); // 2^32 can only be fit in int64_t
- INVALIDATE(s, "3.1415926", "", "type", "",
- "{ \"type\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 2, \"actual\": \"A\""
- "}}");
- VALIDATE(s, "\"AB\"", true);
- VALIDATE(s, "\"ABC\"", true);
- INVALIDATE(s, "\"ABCD\"", "", "maxLength", "",
- "{ \"maxLength\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"actual\": \"(888)555-1212 ext. 532\""
- "}}");
- INVALIDATE(s, "\"(800)FLOWERS\"", "", "pattern", "",
- "{ \"pattern\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"actual\": \"(800)FLOWERS\""
- "}}");
- }
- TEST(SchemaValidator, String_Pattern_Invalid) {
- Document sd;
- sd.Parse("{\"type\":\"string\",\"pattern\":\"a{0}\"}"); // TODO: report regex is invalid somehow
- SchemaDocument s(sd);
- VALIDATE(s, "\"\"", true);
- VALIDATE(s, "\"a\"", true);
- VALIDATE(s, "\"aa\"", true);
- }
- #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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": [\"integer\"], \"actual\": \"number\""
- "}}");
- INVALIDATE(s, "\"42\"", "", "type", "",
- "{ \"type\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 0, \"actual\": -1"
- "}}");
- VALIDATE(s, "0", true);
- VALIDATE(s, "10", true);
- VALIDATE(s, "99", true);
- INVALIDATE(s, "100", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 100"
- "}}");
- INVALIDATE(s, "101", "", "maximum", "",
- "{ \"maximum\": {"
- " \"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\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775806, \"actual\": 9223372036854775807"
- "}}");
- INVALIDATE(s, "18446744073709551615", "", "maximum", "",
- "{ \"maximum\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808, \"actual\": -9223372036854775808"
- "}}");
- INVALIDATE(s, "9223372036854775807", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808, \"actual\": 9223372036854775807"
- "}}");
- INVALIDATE(s, "-2147483648", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808, \"actual\": -2147483648"
- "}}"); // int min
- INVALIDATE(s, "0", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808, \"actual\": 0"
- "}}");
- INVALIDATE(s, "2147483647", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808, \"actual\": 2147483647"
- "}}"); // int max
- INVALIDATE(s, "2147483648", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808, \"actual\": 2147483648"
- "}}"); // unsigned first
- INVALIDATE(s, "4294967295", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808, \"actual\": 4294967295"
- "}}"); // unsigned max
- VALIDATE(s, "9223372036854775808", true);
- VALIDATE(s, "18446744073709551614", true);
- INVALIDATE(s, "18446744073709551615", "", "maximum", "",
- "{ \"maximum\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": -9223372036854775808, \"exclusiveMinimum\": true, "
- " \"actual\": -9223372036854775808"
- "}}");
- VALIDATE(s, "-9223372036854775807", true);
- VALIDATE(s, "18446744073709551614", true);
- INVALIDATE(s, "18446744073709551615", "", "maximum", "",
- "{ \"maximum\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 10, \"actual\": 23"
- "}}");
- INVALIDATE(s, "-23", "", "multipleOf", "",
- "{ \"multipleOf\": {"
- " \"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\": {"
- " \"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\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 100"
- "}}");
- INVALIDATE(s, "100.0", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 100.0"
- "}}");
- INVALIDATE(s, "101.5", "", "maximum", "",
- "{ \"maximum\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": -100, \"actual\": -101"
- "}}");
- INVALIDATE(s, "-100.1", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": -100, \"actual\": -100.1"
- "}}");
- VALIDATE(s, "-100", true);
- VALIDATE(s, "-2", true);
- INVALIDATE(s, "-1", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": -1"
- "}}");
- INVALIDATE(s, "-0.9", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": -0.9"
- "}}");
- INVALIDATE(s, "0", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 0"
- "}}");
- INVALIDATE(s, "2147483647", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 2147483647"
- "}}"); // int max
- INVALIDATE(s, "2147483648", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 2147483648"
- "}}"); // unsigned first
- INVALIDATE(s, "4294967295", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 4294967295"
- "}}"); // unsigned max
- INVALIDATE(s, "9223372036854775808", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 9223372036854775808"
- "}}");
- INVALIDATE(s, "18446744073709551614", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551614"
- "}}");
- INVALIDATE(s, "18446744073709551615", "", "maximum", "",
- "{ \"maximum\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 0.1, \"actual\": -9223372036854775808"
- "}}");
- INVALIDATE(s, "-2147483648", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 0.1, \"actual\": -2147483648"
- "}}"); // int min
- INVALIDATE(s, "-1", "", "minimum", "",
- "{ \"minimum\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 101"
- "}}");
- INVALIDATE(s, "101.5", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 101.5"
- "}}");
- INVALIDATE(s, "18446744073709551614", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551614"
- "}}");
- INVALIDATE(s, "18446744073709551615", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551615"
- "}}");
- INVALIDATE(s, "2147483647", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 2147483647"
- "}}"); // int max
- INVALIDATE(s, "2147483648", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 2147483648"
- "}}"); // unsigned first
- INVALIDATE(s, "4294967295", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 4294967295"
- "}}"); // unsigned max
- INVALIDATE(s, "9223372036854775808", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 9223372036854775808"
- "}}");
- INVALIDATE(s, "18446744073709551614", "", "maximum", "",
- "{ \"maximum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551614"
- "}}");
- INVALIDATE(s, "18446744073709551615", "", "maximum", "",
- "{ \"maximum\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808.0, \"actual\": -9223372036854775808"
- "}}");
- INVALIDATE(s, "-2147483648", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808.0, \"actual\": -2147483648"
- "}}"); // int min
- INVALIDATE(s, "0", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808.0, \"actual\": 0"
- "}}");
- INVALIDATE(s, "2147483647", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808.0, \"actual\": 2147483647"
- "}}"); // int max
- INVALIDATE(s, "2147483648", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808.0, \"actual\": 2147483648"
- "}}"); // unsigned first
- INVALIDATE(s, "4294967295", "", "minimum", "",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 9223372036854775808.0, \"actual\": 4294967295"
- "}}"); // unsigned max
- VALIDATE(s, "9223372036854775808", true);
- VALIDATE(s, "18446744073709540000", true);
- INVALIDATE(s, "18446744073709551615", "", "maximum", "",
- "{ \"maximum\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 10.0, \"actual\": 23"
- "}}");
- INVALIDATE(s, "-2147483648", "", "multipleOf", "",
- "{ \"multipleOf\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 10.0, \"actual\": -2147483648"
- "}}"); // int min
- VALIDATE(s, "-2147483640", true);
- INVALIDATE(s, "2147483647", "", "multipleOf", "",
- "{ \"multipleOf\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 10.0, \"actual\": 2147483647"
- "}}"); // int max
- INVALIDATE(s, "2147483648", "", "multipleOf", "",
- "{ \"multipleOf\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 10.0, \"actual\": 2147483648"
- "}}"); // unsigned first
- VALIDATE(s, "2147483650", true);
- INVALIDATE(s, "4294967295", "", "multipleOf", "",
- "{ \"multipleOf\": {"
- " \"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\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": [\"object\"], \"actual\": \"array\""
- "}}");
- INVALIDATE(s, "\"Not an object\"", "", "type", "",
- "{ \"type\": {"
- " \"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\": {"
- " \"instanceRef\": \"#/number\", \"schemaRef\": \"#/properties/number\","
- " \"expected\": [\"number\"], \"actual\": \"string\""
- "}}");
- INVALIDATE(s, "{ \"number\": \"One\", \"street_name\": \"Microsoft\", \"street_type\": \"Way\" }",
- "/properties/number", "type", "/number",
- "{ \"type\": {"
- " \"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\": {"
- " \"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\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"missing\": [\"email\"]"
- "}}");
- INVALIDATE(s, "{}", "", "required", "",
- "{ \"required\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"missing\": [\"email\"]"
- "}}");
- INVALIDATE(s, "{}", "", "required", "",
- "{ \"required\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 2, \"actual\": 0"
- "}}");
- INVALIDATE(s, "{\"a\":0}", "", "minProperties", "",
- "{ \"minProperties\": {"
- " \"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\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"errors\": {\"credit_card\": [\"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"errors\": {"
- " \"credit_card\": {"
- " \"required\": {"
- " \"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\": {"
- " \"instanceRef\": \"#/S_0\", \"schemaRef\": \"#/patternProperties/%5ES_\","
- " \"expected\": [\"string\"], \"actual\": \"integer\""
- "}}");
- INVALIDATE(s, "{ \"I_42\": \"This is a string\" }", "", "patternProperties", "/I_42",
- "{ \"type\": {"
- " \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/patternProperties/%5EI_\","
- " \"expected\": [\"integer\"], \"actual\": \"string\""
- "}}");
- VALIDATE(s, "{ \"keyword\": \"value\" }", true);
- }
- TEST(SchemaValidator, Object_PattternProperties_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\": ["
- " {"
- " \"instanceRef\": \"#/I_30\", \"schemaRef\": \"#/patternProperties/%5EI_\","
- " \"expected\": 5, \"actual\": 7"
- " }, {"
- " \"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\": {"
- " \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/properties/I_42\","
- " \"expected\": 73, \"actual\": 42"
- "}}");
- INVALIDATE(s, "{ \"I_42\": 7 }", "", "patternProperties", "/I_42",
- "{ \"minimum\": {"
- " \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/properties/I_42\","
- " \"expected\": 73, \"actual\": 7"
- " },"
- " \"multipleOf\": {"
- " \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/patternProperties/%5EI_\","
- " \"expected\": 6, \"actual\": 7"
- " }"
- "}");
- }
- TEST(SchemaValidator, Object_PatternProperties_AdditionalProperties) {
- 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\": {"
- " \"instanceRef\": \"#/keyword\", \"schemaRef\": \"#/additionalProperties\","
- " \"expected\": [\"string\"], \"actual\": \"integer\""
- "}}");
- }
- #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\": {"
- " \"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\": {"
- " \"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\": { \"instanceRef\": \"#/2\", \"schemaRef\": \"#/items/2\" }}");
- INVALIDATE(s, "[\"Palais de l'Elysee\"]", "/items/0", "type", "/0",
- "{ \"type\": {"
- " \"instanceRef\": \"#/0\", \"schemaRef\": \"#/items/0\","
- " \"expected\": [\"number\"], \"actual\": \"string\""
- "}}");
- INVALIDATE(s, "[\"Twenty-four\", \"Sussex\", \"Drive\"]", "/items/0", "type", "/0",
- "{ \"type\": {"
- " \"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_AdditionalItmes) {
- 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\"]", "", "items", "/4",
- "{ \"additionalItems\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": 2, \"actual\": 0"
- "}}");
- INVALIDATE(s, "[1]", "", "minItems", "",
- "{ \"minItems\": {"
- " \"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\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"duplicates\": [2, 3]"
- "}}");
- INVALIDATE(s, "[1, 2, 3, 3, 3]", "", "uniqueItems", "/3",
- "{ \"uniqueItems\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": [\"boolean\"], \"actual\": \"string\""
- "}}");
- INVALIDATE(s, "0", "", "type", "",
- "{ \"type\": {"
- " \"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\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": [\"null\"], \"actual\": \"boolean\""
- "}}");
- INVALIDATE(s, "0", "", "type", "",
- "{ \"type\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#\","
- " \"expected\": [\"null\"], \"actual\": \"integer\""
- "}}");
- INVALIDATE(s, "\"\"", "", "type", "",
- "{ \"type\": {"
- " \"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\": {"
- " \"instanceRef\": \"#/0\", \"schemaRef\": \"#/items\","
- " \"expected\": [\"string\"], \"actual\": \"integer\""
- "}}");
- INVALIDATE(s, "[{}]", "/items", "type", "/0",
- "{ \"type\": {"
- " \"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\": {"
- " \"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\": {"
- " \"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", "",
- "{ \"enum\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\""
- "}}");
- INVALIDATE(s, "\"o\"", "", "allOf", "",
- "{ \"minLength\": {"
- " \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\","
- " \"expected\": 2, \"actual\": \"o\""
- "}}");
- 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\"}"
- " ]"
- "}")
- 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\"}"
- " ]"
- "}");
- 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\"}"
- " ]"
- "}");
- }
- 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\": {"
- " \"instanceRef\": \"#/~0~1\", \"schemaRef\": \"#/properties/~0~1\","
- " \"expected\": [\"number\"], \"actual\": \"boolean\""
- "}}");
- }
- 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);
- if (!d.Accept(validator)) {
- StringBuffer sb;
- validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
- printf("Invalid schema: %s\n", sb.GetString());
- printf("Invalid keyword: %s\n", validator.GetInvalidSchemaKeyword());
- 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);
- if (!d.Accept(validator)) {
- 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"
- };
- 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"
- };
- 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) {
- for (size_t i = 0; i < kCount; i++)
- if (typename SchemaDocumentType::URIType(uri, length) == sd_[i]->GetURI())
- return sd_[i];
- return 0;
- }
- private:
- typedef GenericDocument<typename SchemaDocumentType::EncodingType, MemoryPoolAllocator<>, MemoryPoolAllocator<> > DocumentType;
- RemoteSchemaDocumentProvider(const RemoteSchemaDocumentProvider&);
- RemoteSchemaDocumentProvider& operator=(const RemoteSchemaDocumentProvider&);
- static const size_t kCount = 4;
- 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 {
- 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) {
- {
- SchemaDocumentType schema((*schemaItr)["schema"], filenames[i], static_cast<SizeType>(strlen(filenames[i])), &provider, &schemaAllocator);
- GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > validator(schema, &validatorAllocator);
- const char* description1 = (*schemaItr)["description"].GetString();
- const Value& tests = (*schemaItr)["tests"];
- for (Value::ConstValueIterator testItr = tests.Begin(); testItr != tests.End(); ++testItr) {
- const char* description2 = (*testItr)["description"].GetString();
- if (!onlyRunDescription || strcmp(description2, onlyRunDescription) == 0) {
- const Value& data = (*testItr)["data"];
- bool expected = (*testItr)["valid"].GetBool();
- testCount++;
- validator.Reset();
- bool actual = data.Accept(validator);
- if (expected != actual)
- printf("Fail: %30s \"%s\" \"%s\"\n", filename, description1, description2);
- else
- 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.GetInvalidSchemaPointer() == SchemaDocument::PointerType(""));
- EXPECT_TRUE(reader.GetInvalidDocumentPointer() == SchemaDocument::PointerType(""));
- EXPECT_TRUE(d.IsNull());
- Document e;
- e.Parse(
- "{ \"maxLength\": {"
- " \"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(""));
- Document e;
- e.Parse(
- "{ \"maxLength\": {"
- " \"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\": {"
- " \"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\": {"
- " \"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);
- 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\" ]}]}");
- 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\": {"
- " \"instanceRef\": \"#\","
- " \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\","
- " \"expected\": [\"integer\"], \"actual\": \"null\""
- "}}",
- SchemaValidatorType, PointerType);
- }
- TEST(SchemaValidator, Ref_remote_issue1210) {
- class SchemaDocumentProvider : public IRemoteSchemaDocumentProvider {
- SchemaDocument** collection;
- SchemaDocumentProvider(const SchemaDocumentProvider&);
- SchemaDocumentProvider& operator=(const SchemaDocumentProvider&);
- public:
- SchemaDocumentProvider(SchemaDocument** collection) : collection(collection) { }
- virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeType length) {
- int i = 0;
- while (collection[i] && SchemaDocument::URIType(uri, length) != collection[i]->GetURI()) ++i;
- 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);
- }
- #if defined(_MSC_VER) || defined(__clang__)
- RAPIDJSON_DIAG_POP
- #endif
|