#include "pch.h" #define NO_MAIN #include #include #include "CppUnitTest.h" using namespace Microsoft::VisualStudio::CppUnitTestFramework; namespace FrameworkTests { TEST_CLASS(JSONParserTests) { public: TEST_METHOD(NullTest) { Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("null"); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('null') should not return " L"0"); Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NULL_, L"Framework::JSON::Parser::getValue('null') should return a " L"json null value"); value->release(); } TEST_METHOD(BooleanTest) { Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("false"); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('false') should not return " L"0"); Assert::IsTrue( value->getType() == Framework::JSON::JSONType::BOOLEAN, L"Framework::JSON::Parser::getValue('false') should return a " L"boolean"); Assert::IsTrue( ((Framework::JSON::JSONBool*)value)->getBool() == false, L"Framework::JSON::Parser::getValue('false') should return a " L"boolean with value false"); value->release(); value = Framework::JSON::Parser::getValue("true"); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('true') should not return " L"0"); Assert::IsTrue( value->getType() == Framework::JSON::JSONType::BOOLEAN, L"Framework::JSON::Parser::getValue('true') should return a " L"boolean"); Assert::IsTrue( ((Framework::JSON::JSONBool*)value)->getBool() == true, L"Framework::JSON::Parser::getValue('true') should return a " L"boolean with value true"); value->release(); } TEST_METHOD(StringTest) { Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("\"test\""); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('\"test\"') should not " L"return 0"); Assert::IsTrue( value->getType() == Framework::JSON::JSONType::STRING, L"Framework::JSON::Parser::getValue('\"test\"') should return " L"a string"); Assert::IsTrue(((Framework::JSON::JSONString*)value) ->getString() .istGleich("test"), L"Framework::JSON::Parser::getValue('\"test\"') should return " L"a string with value 'test'"); value->release(); value = Framework::JSON::Parser::getValue("\"\""); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('\"\"') should not return " L"0"); Assert::IsTrue( value->getType() == Framework::JSON::JSONType::STRING, L"Framework::JSON::Parser::getValue('\"\"') should return a " L"string"); Assert::IsTrue(((Framework::JSON::JSONString*)value) ->getString() .istGleich(""), L"Framework::JSON::Parser::getValue('\"\"') should return a " L"string with value ''"); value->release(); } TEST_METHOD(NumberTest) { Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("0"); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('0') should not return 0"); Assert::IsTrue( value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('0') should return a " L"number"); Assert::IsTrue( ((Framework::JSON::JSONNumber*)value)->getNumber() == 0.0, L"Framework::JSON::Parser::getValue('0') should return a " L"number with value '0'"); value->release(); value = Framework::JSON::Parser::getValue("1.5"); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('1.5') should not return " L"0"); Assert::IsTrue( value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('1.5') should return a " L"number"); Assert::IsTrue( ((Framework::JSON::JSONNumber*)value)->getNumber() == 1.5, L"Framework::JSON::Parser::getValue('1.5') should return a " L"number with value '1.5'"); value->release(); value = Framework::JSON::Parser::getValue("-1.5"); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('-1.5') should not return " L"0"); Assert::IsTrue( value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('-1.5') should return a " L"number"); Assert::IsTrue( ((Framework::JSON::JSONNumber*)value)->getNumber() == -1.5, L"Framework::JSON::Parser::getValue('-1.5') should return a " L"number with value '-1.5'"); value->release(); value = Framework::JSON::Parser::getValue("-5.0"); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('-5.0') should not return " L"0"); Assert::IsTrue( value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('-5.0') should return a " L"number"); Assert::IsTrue( ((Framework::JSON::JSONNumber*)value)->getNumber() == -5.0, L"Framework::JSON::Parser::getValue('-5.0') should return a " L"number with value '-5.0'"); value->release(); } TEST_METHOD(ArrayTest) { Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("[]"); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('[]') should not return 0"); Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[]') should return an " L"array"); Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->getLength() == 0, L"Framework::JSON::Parser::getValue('[]') should return an " L"array with length 0"); value->release(); value = Framework::JSON::Parser::getValue( " \t[ \r\n\tnull , \r\n\t 1,true , \"\" ] "); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') " L"should not return 0"); Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') " L"should return an array"); Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->getLength() == 4, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') " L"should return an array with length 4"); Assert::IsTrue( ((Framework::JSON::JSONArray*)value) ->isValueOfType(0, Framework::JSON::JSONType::NULL_), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') " L"should contain null at index 0"); Assert::IsTrue( ((Framework::JSON::JSONArray*)value) ->isValueOfType(1, Framework::JSON::JSONType::NUMBER), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') " L"should contain a number at index 1"); Assert::IsTrue( ((Framework::JSON::JSONArray*)value) ->isValueOfType(2, Framework::JSON::JSONType::BOOLEAN), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') " L"should contain a boolean at index 2"); Assert::IsTrue( ((Framework::JSON::JSONArray*)value) ->isValueOfType(3, Framework::JSON::JSONType::STRING), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') " L"should contain a boolean at index 3"); value->release(); } TEST_METHOD(MultipleArrayTest) { Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("[[1],2,[[]]]"); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should not " L"return 0"); Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should " L"return an array"); Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->getLength() == 3, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should " L"return an array with length 3"); Assert::IsTrue( ((Framework::JSON::JSONArray*)value) ->isValueOfType(0, Framework::JSON::JSONType::ARRAY), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') " L"should contain an array at index 0"); Assert::IsTrue( ((Framework::JSON::JSONArray*)value) ->isValueOfType(1, Framework::JSON::JSONType::NUMBER), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') " L"should contain a number at index 1"); Assert::IsTrue( ((Framework::JSON::JSONArray*)value) ->isValueOfType(2, Framework::JSON::JSONType::ARRAY), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') " L"should contain an array at index 2"); value->release(); } TEST_METHOD(ObjectTest) { Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("{\" \": []}"); Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('{\"\": []}') should not " L"return 0"); Assert::IsTrue( value->getType() == Framework::JSON::JSONType::OBJECT, L"Framework::JSON::Parser::getValue('{\" \": []}') should " L"return an object"); Assert::IsTrue( ((Framework::JSON::JSONObject*)value)->getFieldCount() == 1, L"Framework::JSON::Parser::getValue('{\" \": []}') should " L"return an object with one attribute"); Assert::IsTrue( ((Framework::JSON::JSONObject*)value) ->isValueOfType(" ", Framework::JSON::JSONType::ARRAY), L"Framework::JSON::Parser::getValue('{\" \": []}') should " L"contain an array at attribute ' '"); value->release(); } TEST_METHOD(ToStringTest) { Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "{\" \": [1, true, false, 0.0, {}], \"t\": null}"); Framework::JSON::JSONValue* value2 = Framework::JSON::Parser::getValue(value->toString()); Assert::IsTrue(isEqual(value, value2), L"Framework::JSON::Parser::getValue(value.toString()) should " L"return a json value eqal to value"); value->release(); value2->release(); } static bool isEqual( Framework::JSON::JSONValue * a, Framework::JSON::JSONValue * b) { if (a->getType() != b->getType()) return 0; switch (a->getType()) { case Framework::JSON::JSONType::NUMBER: return ((Framework::JSON::JSONNumber*)a)->getNumber() == ((Framework::JSON::JSONNumber*)b)->getNumber(); case Framework::JSON::JSONType::BOOLEAN: return ((Framework::JSON::JSONBool*)a)->getBool() == ((Framework::JSON::JSONBool*)b)->getBool(); case Framework::JSON::JSONType::STRING: return ((Framework::JSON::JSONString*)a) ->getString() .istGleich(((Framework::JSON::JSONString*)b)->getString()); case Framework::JSON::JSONType::ARRAY: { Framework::JSON::JSONArray* arrayA = (Framework::JSON::JSONArray*)a; Framework::JSON::JSONArray* arrayB = (Framework::JSON::JSONArray*)b; if (arrayA->getLength() != arrayB->getLength()) return 0; for (int i = 0; i < arrayA->getLength(); i++) { Framework::JSON::JSONValue* entryA = arrayA->getValue(i); Framework::JSON::JSONValue* entryB = arrayB->getValue(i); bool eq = isEqual(entryA, entryB); entryA->release(); entryB->release(); if (!eq) return 0; } return 1; } case Framework::JSON::JSONType::OBJECT: { Framework::JSON::JSONObject* objA = (Framework::JSON::JSONObject*)a; Framework::JSON::JSONObject* objB = (Framework::JSON::JSONObject*)b; if (objA->getFieldCount() != objB->getFieldCount()) return 0; auto oaf = objA->getFields(); while (oaf) { if (!objB->hasValue(oaf)) return 0; Framework::JSON::JSONValue* entryA = objA->getValue(oaf); Framework::JSON::JSONValue* entryB = objB->getValue(oaf); bool eq = isEqual(entryA, entryB); entryA->release(); entryB->release(); if (!eq) return 0; oaf++; } return 1; } } return 1; } TEST_METHOD(ToArrayTest) { Framework::JSON::JSONArray* jArray = Framework::JSON::Parser::getValue("[1,2,3,4,5,6,7,8,9,10]") ->asArray(); Framework::Array* numberArray = jArray->toArray([](Framework::JSON::JSONValue& v) { return (int)v.asNumber()->getNumber(); }); Assert::IsTrue(numberArray->getEintragAnzahl() == 10, L"Array hat die falsche Anzahl an elementen"); Assert::IsTrue(numberArray->get(2) == 3, L"Array hat mindestens ein falsches element"); Assert::IsTrue(numberArray->get(7) == 8, L"Array hat mindestens ein falsches element"); numberArray->release(); numberArray = jArray->toArray( [](Framework::JSON::JSONValue& v) { return (int)v.asNumber()->getNumber() % 2 == 0; }, [](Framework::JSON::JSONValue& v) { return (int)v.asNumber()->getNumber(); }); Assert::IsTrue(numberArray->get(0) == 2, L"Array hat mindestens ein falsches element"); Assert::IsTrue(numberArray->get(3) == 8, L"Array hat mindestens ein falsches element"); jArray->release(); } TEST_METHOD(ToRCArrayTest) { Framework::JSON::JSONArray* jArray = Framework::JSON::Parser::getValue( "[\"1\",\"2\",\"3\",\"4\",\"5\"]") ->asArray(); Framework::RCArray* numberArray = jArray->toRCArray( [](Framework::JSON::JSONValue& v) { return new Framework::Text(v.asString()->getString()); }); Assert::IsTrue(numberArray->getEintragAnzahl() == 5, L"Array hat die falsche Anzahl an elementen"); Assert::IsTrue(numberArray->z(1)->istGleich("2"), L"Array hat mindestens ein falsches element"); Assert::IsTrue(numberArray->z(4)->istGleich("5"), L"Array hat mindestens ein falsches element"); numberArray->release(); numberArray = jArray->toRCArray( [](Framework::JSON::JSONValue& v) { return (int)v.asString()->getString() % 2 == 0; }, [](Framework::JSON::JSONValue& v) { return new Framework::Text(v.asString()->getString()); }); Assert::IsTrue(numberArray->z(0)->istGleich("2"), L"Array hat mindestens ein falsches element"); Assert::IsTrue(numberArray->z(1)->istGleich("4"), L"Array hat mindestens ein falsches element"); jArray->release(); } class TestObject { public: Framework::Text name; Framework::Text value; }; TEST_METHOD(ParseObjectTest) { Framework::JSON::JSONObject* jObj = Framework::JSON::Parser::getValue( "{\"name\": \"test\", \"value\": \"1234\"}") ->asObject(); TestObject* obj = jObj->parseTo(new TestObject(), [](TestObject* obj, Framework::Text attrName, Framework::JSON::JSONValue& v) { if (attrName.istGleich("name")) { obj->name = v.asString()->getString(); } else { obj->value = v.asString()->getString(); } }); Assert::IsTrue( obj->name.istGleich("test"), L"Feld hat falschen wert"); Assert::IsTrue( obj->value.istGleich("1234"), L"Feld hat falschen wert"); delete obj; jObj->release(); } TEST_METHOD(FromArrayTest) { Framework::Array arr; arr.add(1); arr.add(2); arr.add(3); arr.add(4); Framework::JSON::JSONArray* jArray = Framework::JSON::JSONArray::fromArray(arr, [](int v) { return new Framework::JSON::JSONNumber(v); }); Assert::IsTrue( jArray->getLength() == 4, L"Array hat falsche länge"); Framework::JSON::JSONNumber* n = jArray->getValue(1)->asNumber(); Assert::IsTrue(n->getNumber() == 2, L"Array hat mindestens einen falschen Wert"); n->release(); jArray->release(); Framework::RCArray rcArr; rcArr.add(new Framework::Text("1")); rcArr.add(new Framework::Text("2")); rcArr.add(new Framework::Text("3")); rcArr.add(new Framework::Text("4")); jArray = Framework::JSON::JSONArray::fromRCArray( rcArr, [](Framework::Text& v) { return new Framework::JSON::JSONString(v); }); Assert::IsTrue( jArray->getLength() == 4, L"Array hat falsche länge"); Framework::JSON::JSONString* s = jArray->getValue(2)->asString(); Assert::IsTrue(s->getString().istGleich("3"), L"Array hat mindestens einen falschen Wert"); s->release(); jArray->release(); } }; TEST_CLASS(JSONValidatorTests) { private: static OutputDebugStringBuf> charDebugOutput; static std::streambuf* buf; public: TEST_CLASS_INITIALIZE(Init) { buf = std::cout.rdbuf(); std::cout.rdbuf(&charDebugOutput); } TEST_METHOD(ValidTest) { Framework::JSON::Validator::JSONValidator* validator = Framework::JSON::Validator::JSONValidator::buildForArray() ->addAcceptedObjectInArray() ->withRequiredNumber("x") ->whichIsLessThen(5) ->finishNumber() ->withRequiredBool("bla") ->whichIsOptional() ->withDefault(true) ->finishBool() ->finishObject() ->finishArray(); Framework::JSON::JSONArray* jArray = Framework::JSON::Parser::getValue( "[{\"x\": 4, \"bla\": false}]") ->asArray(); Assert::IsTrue(validator->isValid(jArray), L"A valid json Array was marked as invalid by the validator"); validator->release(); } TEST_METHOD(ComplexTest) { Framework::JSON::Validator::JSONValidator* validator = Framework::JSON::Validator::JSONValidator::buildForArray() ->typeSpecifiedByAttribute("type") ->addAcceptedObjectInArray() ->withRequiredString("type") ->withExactMatch("shaped") ->finishString() ->withRequiredString("group") ->finishString() ->withRequiredNumber("width") ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredNumber("height") ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredArray("inputs") ->addAcceptedObjectInArray() ->withRequiredNumber("x") ->whichIsGreaterOrEqual(0) ->finishNumber() ->withRequiredNumber("y") ->whichIsGreaterOrEqual(0) ->finishNumber() ->withRequiredObject("filter") ->withRequiredString("itemType") ->finishString() ->finishObject() ->finishObject() ->finishArray() ->withRequiredObject("output") ->withRequiredString("itemType") ->finishString() ->finishObject() ->withRequiredNumber("outputCount") ->whichIsGreaterThen(0) ->finishNumber() ->finishObject() ->addAcceptedObjectInArray() ->withRequiredString("type") ->withExactMatch("unordered") ->finishString() ->withRequiredString("group") ->finishString() ->withRequiredArray("inputs") ->addAcceptedObjectInArray() ->withRequiredNumber("count") ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredObject("filter") ->withRequiredString("itemType") ->finishString() ->finishObject() ->finishObject() ->finishArray() ->withRequiredArray("output") ->addAcceptedObjectInArray() ->withRequiredObject("filter") ->withRequiredString("itemType") ->finishString() ->finishObject() ->withRequiredNumber("count") ->whichIsGreaterThen(0) ->finishNumber() ->finishObject() ->finishArray() ->finishObject() ->finishArray(); std::cout << validator->zConstraints()->toString().getText() << "\n"; Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "[{\"type\": \"shaped\",\"group\": " "\"inventory\",\"width\": 1,\"height\": 2,\"inputs\": " "[{\"x\": 0,\"y\": 0,\"filter\": {\"itemType\": " "\"Cobble\"}},{\"x\": 0,\"y\": -1,\"filter\": " "{\"itemType\": \"Cobble\"}}],\"output\": {\"itemType\": " "\"StoneTool\"},\"outputCount\": 1},{\"type\": " "\"shaped\",\"group\": \"inventory\",\"width\": " "1,\"height\": 2,\"inputs\": [{\"x\": 0,\"y\": " "0,\"filter\": {\"itemType\": \"Cobble\"}},{\"x\": " "0,\"y\": 1,\"filter\": {\"itemType\": " "\"Cobble\"}}],\"output\": {\"itemType\": " "\"StoneTool\"},\"outputCount\": 1}]"); std::cout << value->toString().getText() << "\n"; Framework::JSON::Validator::JSONValidationResult* result = validator->validate(value); result->printInvalidInfo(); Assert::IsTrue( !result->isValid(), L"Invalid Json was marked as valid"); Framework::JSON::JSONValue* validValue = result->getValidPart(); result->release(); Assert::IsTrue(validValue == 0, L"getValidPart of invalid validation result without " L"removeInvalidEntries or default values used in validation " L"should return 0"); value->release(); validator->release(); } TEST_METHOD(ComplexRemoveInvalidTest) { Framework::JSON::Validator::JSONValidator* validator = Framework::JSON::Validator::JSONValidator::buildForArray() ->removeInvalidEntries() ->typeSpecifiedByAttribute("type") ->addAcceptedObjectInArray() ->withRequiredString("type") ->withExactMatch("shaped") ->finishString() ->withRequiredString("group") ->finishString() ->withRequiredNumber("width") ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredNumber("height") ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredArray("inputs") ->addAcceptedObjectInArray() ->withRequiredNumber("x") ->whichIsGreaterOrEqual(0) ->finishNumber() ->withRequiredNumber("y") ->whichIsGreaterOrEqual(0) ->finishNumber() ->withRequiredObject("filter") ->withRequiredString("itemType") ->finishString() ->finishObject() ->finishObject() ->finishArray() ->withRequiredObject("output") ->withRequiredString("itemType") ->finishString() ->finishObject() ->withRequiredNumber("outputCount") ->whichIsGreaterThen(0) ->finishNumber() ->finishObject() ->addAcceptedObjectInArray() ->withRequiredString("type") ->withExactMatch("unordered") ->finishString() ->withRequiredString("group") ->finishString() ->withRequiredArray("inputs") ->addAcceptedObjectInArray() ->withRequiredNumber("count") ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredObject("filter") ->withRequiredString("itemType") ->finishString() ->finishObject() ->finishObject() ->finishArray() ->withRequiredArray("output") ->addAcceptedObjectInArray() ->withRequiredObject("filter") ->withRequiredString("itemType") ->finishString() ->finishObject() ->withRequiredNumber("count") ->whichIsGreaterThen(0) ->finishNumber() ->finishObject() ->finishArray() ->finishObject() ->finishArray(); std::cout << validator->zConstraints()->toString().getText() << "\n"; Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "[{\"type\": \"shaped\",\"group\": " "\"inventory\",\"width\": 1,\"height\": 2,\"inputs\": " "[{\"x\": 0,\"y\": 0,\"filter\": {\"itemType\": " "\"Cobble\"}},{\"x\": 0,\"y\": -1,\"filter\": " "{\"itemType\": \"Cobble\"}}],\"output\": {\"itemType\": " "\"StoneTool\"},\"outputCount\": 1},{\"type\": " "\"shaped\",\"group\": \"inventory\",\"width\": " "1,\"height\": 2,\"inputs\": [{\"x\": 0,\"y\": " "0,\"filter\": {\"itemType\": \"Cobble\"}},{\"x\": " "0,\"y\": 1,\"filter\": {\"itemType\": " "\"Cobble\"}}],\"output\": {\"itemType\": " "\"StoneTool\"},\"outputCount\": 1}]"); std::cout << value->toString().getText() << "\n"; Framework::JSON::Validator::JSONValidationResult* result = validator->validate(value); result->printInvalidInfo(); Assert::IsTrue( !result->isValid(), L"Invalid Json was marked as valid"); Framework::JSON::JSONValue* validValue = result->getValidPart(); result->release(); Framework::JSON::JSONValue* expected = Framework::JSON::Parser::getValue( "[{\"type\": \"shaped\",\"group\": " "\"inventory\",\"width\": 1,\"height\": 2,\"inputs\": " "[{\"x\": 0,\"y\": 0,\"filter\": {\"itemType\": " "\"Cobble\"}},{\"x\": 0,\"y\": 1,\"filter\": " "{\"itemType\": \"Cobble\"}}],\"output\": {\"itemType\": " "\"StoneTool\"},\"outputCount\": 1}]"); Assert::IsTrue(JSONParserTests::isEqual(validValue, expected), L"getValidPart of invalid validation result does not match the " L"expected valid part"); result = validator->validate(validValue); Assert::IsTrue(result->isValid(), L"Re validation of a value returned by getValidPart on a " L"validation result should never return an invalid validation " L"result"); value->release(); value = result->getValidPart(); Assert::IsTrue(JSONParserTests::isEqual(validValue, value), L"getValidPart of a valid validation result should return the " L"validated value"); value->release(); validValue->release(); expected->release(); validator->release(); } TEST_METHOD(DefaultValuesTest) { Framework::JSON::Validator::JSONValidator* validator = Framework::JSON::Validator::JSONValidator::buildForArray() ->typeSpecifiedByAttribute("type") ->removeInvalidEntries() ->addAcceptedTypeInArray( Framework::JSON::Validator::JSONValidator::buildForObject() ->withRequiredString("type") ->withExactMatch("shaped") ->finishString() ->withRequiredString("group") ->withDefault("test") ->finishString() ->withRequiredNumber("width") ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredNumber("height") ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredAttribute("inputs", Framework::JSON::Validator::JSONValidator:: buildForArray() ->withDefault( new Framework::JSON::JSONArray()) ->addAcceptedTypeInArray( Framework::JSON::Validator:: JSONValidator::buildForObject() ->withRequiredNumber("x") ->whichIsGreaterOrEqual(0) ->finishNumber() ->withRequiredNumber("y") ->whichIsGreaterOrEqual(0) ->finishNumber() ->withRequiredObject( "filter") ->withRequiredString( "itemType") ->finishString() ->finishObject() ->finishObject()) ->finishArray()) ->withRequiredObject("output") ->withRequiredString("itemType") ->finishString() ->finishObject() ->withRequiredNumber("outputCount") ->withDefault(1) ->whichIsGreaterThen(0) ->finishNumber() ->finishObject()) ->addAcceptedTypeInArray( Framework::JSON::Validator::JSONValidator::buildForObject() ->withRequiredString("type") ->withExactMatch("unordered") ->finishString() ->withRequiredString("group") ->finishString() ->withRequiredAttribute("inputs", Framework::JSON::Validator::JSONValidator:: buildForArray() ->withDefault( new Framework::JSON::JSONArray()) ->addAcceptedTypeInArray( Framework::JSON::Validator:: JSONValidator:: buildForObject() ->withRequiredNumber( "count") ->withDefault(1) ->whichIsGreaterThen( 0) ->finishNumber() ->withRequiredObject( "filter") ->withRequiredString( "itemType") ->finishString() ->finishObject() ->finishObject()) ->finishArray()) ->withRequiredAttribute("output", Framework::JSON::Validator::JSONValidator:: buildForArray() ->addAcceptedTypeInArray( Framework::JSON::Validator:: JSONValidator:: buildForObject() ->withRequiredObject( "filter") ->withRequiredString( "itemType") ->finishString() ->finishObject() ->withRequiredNumber( "count") ->withDefault(1) ->whichIsGreaterThen( 0) ->finishNumber() ->finishObject()) ->finishArray()) ->finishObject()) ->finishArray(); std::cout << validator->zConstraints()->toString().getText() << "\n"; Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "[{\"type\": \"shaped\",\"width\": 1,\"height\": " "2,\"inputs\": [{\"x\": 0,\"y\": 0,\"filter\": " "{\"itemType\": \"Cobble\"}},{\"x\": 0,\"y\": " "1,\"filter\": {\"itemType\": \"Cobble\"}}],\"output\": " "{\"itemType\": \"StoneTool\"}},{\"type\": " "\"shaped\",\"width\": 1,\"height\": 2,\"inputs\": " "[{\"x\": 0,\"y\": 0,\"filter\": {\"itemType\": " "\"Cobble\"}},{\"x\": 0,\"y\": -1,\"filter\": " "{\"itemType\": \"Cobble\"}}],\"output\": {\"itemType\": " "\"StoneTool\"}},{\"type\": \"unordered\",\"group\": " "\"bla\", \"inputs\": [{\"filter\": {\"itemType\": " "\"Cobble\"}},{\"filter\": {\"itemType\": " "\"Cobble\"}}],\"output\": [{\"filter\": {\"itemType\": " "\"StoneTool\"}}]}]"); std::cout << value->toString().getText() << "\n"; Framework::JSON::Validator::JSONValidationResult* result = validator->validate(value); result->printInvalidInfo(); Assert::IsTrue( !result->isValid(), L"Invalid Json was marked as valid"); Framework::JSON::JSONValue* validValue = result->getValidPart(); result->release(); Framework::JSON::JSONValue* expected = Framework::JSON::Parser::getValue( "[{\"type\": \"shaped\", \"group\": \"test\",\"width\": " "1,\"height\": 2,\"inputs\": [{\"x\": 0,\"y\": " "0,\"filter\": {\"itemType\": \"Cobble\"}},{\"x\": " "0,\"y\": 1,\"filter\": {\"itemType\": " "\"Cobble\"}}],\"output\": {\"itemType\": \"StoneTool\"}, " "\"outputCount\": 1},{\"type\": \"unordered\",\"group\": " "\"bla\", \"inputs\": [{\"count\": 1, \"filter\": " "{\"itemType\": \"Cobble\"}},{\"count\": 1, \"filter\": " "{\"itemType\": \"Cobble\"}}],\"output\": [{\"count\": 1, " "\"filter\": {\"itemType\": \"StoneTool\"}}]}]"); Assert::IsTrue(JSONParserTests::isEqual(validValue, expected), L"getValidPart of invalid validation result does not match the " L"expected valid part"); result = validator->validate(validValue); Assert::IsTrue(result->isValid(), L"Re validation of a value returned by getValidPart on a " L"validation result should never return an invalid validation " L"result"); value->release(); value = result->getValidPart(); Assert::IsTrue(JSONParserTests::isEqual(validValue, value), L"getValidPart of a valid validation result should return the " L"validated value"); value->release(); validValue->release(); expected->release(); validator->release(); } TEST_METHOD(RecursiveValidatorTest) { Framework::JSON::Validator::JSONValidator* validator = Framework::JSON::Validator::JSONValidator::buildForObject() ->setObjectReferenceId("TreeNode") ->withRequiredAttribute("value", Framework::JSON::Validator::JSONValidator:: buildForString() ->whichCanBeNull() ->finishString()) ->withRequiredAttribute("children", Framework::JSON::Validator::JSONValidator:: buildForArray() ->whichIsOptional() ->addAcceptedTypeInArray(Framework::JSON:: Validator::JSONValidator:: buildForObjectReference( "TreeNode")) ->finishArray()) ->finishObject(); Framework::JSON::JSONObject* jArray = Framework::JSON::Parser::getValue( "{\"value\": \"1\", \"children\": [{\"value\": \"2\"}, " "{\"value\": \"3\", \"children\": [{\"value\": \"4\"}]}]}") ->asObject(); Assert::IsTrue(validator->isValid(jArray), L"A valid json Object was marked as invalid by the validator"); validator->release(); } TEST_CLASS_CLEANUP(Cleanup) { std::cout.rdbuf(buf); } }; OutputDebugStringBuf> JSONValidatorTests::charDebugOutput; std::streambuf* JSONValidatorTests::buf; } // namespace FrameworkTests