Json.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. #include "pch.h"
  2. #include "CppUnitTest.h"
  3. #include <Json.h>
  4. #define NO_MAIN
  5. #include <main.h>
  6. using namespace Microsoft::VisualStudio::CppUnitTestFramework;
  7. namespace FrameworkTests
  8. {
  9. TEST_CLASS(JSONParserTests)
  10. {
  11. public:
  12. TEST_METHOD(NullTest)
  13. {
  14. Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("null");
  15. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('null') should not return 0");
  16. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NULL_, L"Framework::JSON::Parser::getValue('null') should return a json null value");
  17. value->release();
  18. }
  19. TEST_METHOD(BooleanTest)
  20. {
  21. Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("false");
  22. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('false') should not return 0");
  23. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::BOOLEAN, L"Framework::JSON::Parser::getValue('false') should return a boolean");
  24. Assert::IsTrue(((Framework::JSON::JSONBool*)value)->getBool() == false, L"Framework::JSON::Parser::getValue('false') should return a boolean with value false");
  25. value->release();
  26. value = Framework::JSON::Parser::getValue("true");
  27. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('true') should not return 0");
  28. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::BOOLEAN, L"Framework::JSON::Parser::getValue('true') should return a boolean");
  29. Assert::IsTrue(((Framework::JSON::JSONBool*)value)->getBool() == true, L"Framework::JSON::Parser::getValue('true') should return a boolean with value true");
  30. value->release();
  31. }
  32. TEST_METHOD(StringTest)
  33. {
  34. Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("\"test\"");
  35. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('\"test\"') should not return 0");
  36. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::STRING, L"Framework::JSON::Parser::getValue('\"test\"') should return a string");
  37. Assert::IsTrue(((Framework::JSON::JSONString*)value)->getString().istGleich("test"), L"Framework::JSON::Parser::getValue('\"test\"') should return a string with value 'test'");
  38. value->release();
  39. value = Framework::JSON::Parser::getValue("\"\"");
  40. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('\"\"') should not return 0");
  41. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::STRING, L"Framework::JSON::Parser::getValue('\"\"') should return a string");
  42. Assert::IsTrue(((Framework::JSON::JSONString*)value)->getString().istGleich(""), L"Framework::JSON::Parser::getValue('\"\"') should return a string with value ''");
  43. value->release();
  44. }
  45. TEST_METHOD(NumberTest)
  46. {
  47. Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("0");
  48. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('0') should not return 0");
  49. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('0') should return a number");
  50. Assert::IsTrue(((Framework::JSON::JSONNumber*)value)->getNumber() == 0.0, L"Framework::JSON::Parser::getValue('0') should return a number with value '0'");
  51. value->release();
  52. value = Framework::JSON::Parser::getValue("1.5");
  53. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('1.5') should not return 0");
  54. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('1.5') should return a number");
  55. Assert::IsTrue(((Framework::JSON::JSONNumber*)value)->getNumber() == 1.5, L"Framework::JSON::Parser::getValue('1.5') should return a number with value '1.5'");
  56. value->release();
  57. value = Framework::JSON::Parser::getValue("-1.5");
  58. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('-1.5') should not return 0");
  59. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('-1.5') should return a number");
  60. Assert::IsTrue(((Framework::JSON::JSONNumber*)value)->getNumber() == -1.5, L"Framework::JSON::Parser::getValue('-1.5') should return a number with value '-1.5'");
  61. value->release();
  62. value = Framework::JSON::Parser::getValue("-5.0");
  63. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('-5.0') should not return 0");
  64. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('-5.0') should return a number");
  65. Assert::IsTrue(((Framework::JSON::JSONNumber*)value)->getNumber() == -5.0, L"Framework::JSON::Parser::getValue('-5.0') should return a number with value '-5.0'");
  66. value->release();
  67. }
  68. TEST_METHOD(ArrayTest)
  69. {
  70. Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("[]");
  71. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('[]') should not return 0");
  72. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[]') should return an array");
  73. Assert::IsTrue(((Framework::JSON::JSONArray*)value)->getLength() == 0, L"Framework::JSON::Parser::getValue('[]') should return an array with length 0");
  74. value->release();
  75. value = Framework::JSON::Parser::getValue(" \t[ \r\n\tnull , \r\n\t 1,true , \"\" ] ");
  76. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should not return 0");
  77. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should return an array");
  78. Assert::IsTrue(((Framework::JSON::JSONArray*)value)->getLength() == 4, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should return an array with length 4");
  79. Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(0, Framework::JSON::JSONType::NULL_), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain null at index 0");
  80. Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(1, Framework::JSON::JSONType::NUMBER), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a number at index 1");
  81. Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(2, Framework::JSON::JSONType::BOOLEAN), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a boolean at index 2");
  82. Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(3, Framework::JSON::JSONType::STRING), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a boolean at index 3");
  83. value->release();
  84. }
  85. TEST_METHOD(MultipleArrayTest)
  86. {
  87. Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("[[1],2,[[]]]");
  88. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should not return 0");
  89. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should return an array");
  90. Assert::IsTrue(((Framework::JSON::JSONArray*)value)->getLength() == 3, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should return an array with length 3");
  91. Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(0, Framework::JSON::JSONType::ARRAY), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain an array at index 0");
  92. Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(1, Framework::JSON::JSONType::NUMBER), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a number at index 1");
  93. Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(2, Framework::JSON::JSONType::ARRAY), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain an array at index 2");
  94. value->release();
  95. }
  96. TEST_METHOD(ObjectTest)
  97. {
  98. Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("{\" \": []}");
  99. Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('{\"\": []}') should not return 0");
  100. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::OBJECT, L"Framework::JSON::Parser::getValue('{\" \": []}') should return an object");
  101. Assert::IsTrue(((Framework::JSON::JSONObject*)value)->getFieldCount() == 1, L"Framework::JSON::Parser::getValue('{\" \": []}') should return an object with one attribute");
  102. Assert::IsTrue(((Framework::JSON::JSONObject*)value)->isValueOfType(" ", Framework::JSON::JSONType::ARRAY), L"Framework::JSON::Parser::getValue('{\" \": []}') should contain an array at attribute ' '");
  103. value->release();
  104. }
  105. TEST_METHOD(ToStringTest)
  106. {
  107. Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("{\" \": [1, true, false, 0.0, {}], \"t\": null}");
  108. Framework::JSON::JSONValue* value2 = Framework::JSON::Parser::getValue(value->toString());
  109. Assert::IsTrue(isEqual(value, value2), L"Framework::JSON::Parser::getValue(value.toString()) should return a json value eqal to value");
  110. value->release();
  111. value2->release();
  112. }
  113. static bool isEqual(Framework::JSON::JSONValue* a, Framework::JSON::JSONValue* b)
  114. {
  115. if (a->getType() != b->getType()) return 0;
  116. switch (a->getType())
  117. {
  118. case Framework::JSON::JSONType::NUMBER:
  119. return ((Framework::JSON::JSONNumber*)a)->getNumber() == ((Framework::JSON::JSONNumber*)b)->getNumber();
  120. case Framework::JSON::JSONType::BOOLEAN:
  121. return ((Framework::JSON::JSONBool*)a)->getBool() == ((Framework::JSON::JSONBool*)b)->getBool();
  122. case Framework::JSON::JSONType::STRING:
  123. return ((Framework::JSON::JSONString*)a)->getString().istGleich(((Framework::JSON::JSONString*)b)->getString());
  124. case Framework::JSON::JSONType::ARRAY:
  125. {
  126. Framework::JSON::JSONArray* arrayA = (Framework::JSON::JSONArray*)a;
  127. Framework::JSON::JSONArray* arrayB = (Framework::JSON::JSONArray*)b;
  128. if (arrayA->getLength() != arrayB->getLength()) return 0;
  129. for (int i = 0; i < arrayA->getLength(); i++)
  130. {
  131. Framework::JSON::JSONValue* entryA = arrayA->getValue(i);
  132. Framework::JSON::JSONValue* entryB = arrayB->getValue(i);
  133. bool eq = isEqual(entryA, entryB);
  134. entryA->release();
  135. entryB->release();
  136. if (!eq) return 0;
  137. }
  138. return 1;
  139. }
  140. case Framework::JSON::JSONType::OBJECT:
  141. {
  142. Framework::JSON::JSONObject* objA = (Framework::JSON::JSONObject*)a;
  143. Framework::JSON::JSONObject* objB = (Framework::JSON::JSONObject*)b;
  144. if (objA->getFieldCount() != objB->getFieldCount()) return 0;
  145. auto oaf = objA->getFields();
  146. while (oaf)
  147. {
  148. if (!objB->hasValue(oaf)) return 0;
  149. Framework::JSON::JSONValue* entryA = objA->getValue(oaf);
  150. Framework::JSON::JSONValue* entryB = objB->getValue(oaf);
  151. bool eq = isEqual(entryA, entryB);
  152. entryA->release();
  153. entryB->release();
  154. if (!eq) return 0;
  155. oaf++;
  156. }
  157. return 1;
  158. }
  159. }
  160. return 1;
  161. }
  162. TEST_METHOD(ToArrayTest)
  163. {
  164. Framework::JSON::JSONArray* jArray = Framework::JSON::Parser::getValue("[1,2,3,4,5,6,7,8,9,10]")->asArray();
  165. Framework::Array<int>* numberArray = jArray->toArray<int>([](Framework::JSON::JSONValue& v)
  166. {
  167. return (int)v.asNumber()->getNumber();
  168. });
  169. Assert::IsTrue(numberArray->getEintragAnzahl() == 10, L"Array hat die falsche Anzahl an elementen");
  170. Assert::IsTrue(numberArray->get(2) == 3, L"Array hat mindestens ein falsches element");
  171. Assert::IsTrue(numberArray->get(7) == 8, L"Array hat mindestens ein falsches element");
  172. numberArray->release();
  173. numberArray = jArray->toArray<int>([](Framework::JSON::JSONValue& v)
  174. {
  175. return (int)v.asNumber()->getNumber() % 2 == 0;
  176. }, [](Framework::JSON::JSONValue& v)
  177. {
  178. return (int)v.asNumber()->getNumber();
  179. });
  180. Assert::IsTrue(numberArray->get(0) == 2, L"Array hat mindestens ein falsches element");
  181. Assert::IsTrue(numberArray->get(3) == 8, L"Array hat mindestens ein falsches element");
  182. jArray->release();
  183. }
  184. TEST_METHOD(ToRCArrayTest)
  185. {
  186. Framework::JSON::JSONArray* jArray = Framework::JSON::Parser::getValue("[\"1\",\"2\",\"3\",\"4\",\"5\"]")->asArray();
  187. Framework::RCArray<Framework::Text>* numberArray = jArray->toRCArray<Framework::Text>([](Framework::JSON::JSONValue& v)
  188. {
  189. return new Framework::Text(v.asString()->getString());
  190. });
  191. Assert::IsTrue(numberArray->getEintragAnzahl() == 5, L"Array hat die falsche Anzahl an elementen");
  192. Assert::IsTrue(numberArray->z(1)->istGleich("2"), L"Array hat mindestens ein falsches element");
  193. Assert::IsTrue(numberArray->z(4)->istGleich("5"), L"Array hat mindestens ein falsches element");
  194. numberArray->release();
  195. numberArray = jArray->toRCArray<Framework::Text>([](Framework::JSON::JSONValue& v)
  196. {
  197. return (int)v.asString()->getString() % 2 == 0;
  198. }, [](Framework::JSON::JSONValue& v)
  199. {
  200. return new Framework::Text(v.asString()->getString());
  201. });
  202. Assert::IsTrue(numberArray->z(0)->istGleich("2"), L"Array hat mindestens ein falsches element");
  203. Assert::IsTrue(numberArray->z(1)->istGleich("4"), L"Array hat mindestens ein falsches element");
  204. jArray->release();
  205. }
  206. class TestObject
  207. {
  208. public:
  209. Framework::Text name;
  210. Framework::Text value;
  211. };
  212. TEST_METHOD(ParseObjectTest)
  213. {
  214. Framework::JSON::JSONObject* jObj = Framework::JSON::Parser::getValue("{\"name\": \"test\", \"value\": \"1234\"}")->asObject();
  215. TestObject* obj = jObj->parseTo<TestObject>(new TestObject(), [](TestObject* obj, Framework::Text attrName, Framework::JSON::JSONValue& v)
  216. {
  217. if (attrName.istGleich("name"))
  218. {
  219. obj->name = v.asString()->getString();
  220. }
  221. else
  222. {
  223. obj->value = v.asString()->getString();
  224. }
  225. });
  226. Assert::IsTrue(obj->name.istGleich("test"), L"Feld hat falschen wert");
  227. Assert::IsTrue(obj->value.istGleich("1234"), L"Feld hat falschen wert");
  228. delete obj;
  229. jObj->release();
  230. }
  231. TEST_METHOD(FromArrayTest)
  232. {
  233. Framework::Array<int> arr;
  234. arr.add(1);
  235. arr.add(2);
  236. arr.add(3);
  237. arr.add(4);
  238. Framework::JSON::JSONArray* jArray = Framework::JSON::JSONArray::fromArray<int>(arr, [](int v)
  239. {
  240. return new Framework::JSON::JSONNumber(v);
  241. });
  242. Assert::IsTrue(jArray->getLength() == 4, L"Array hat falsche länge");
  243. Framework::JSON::JSONNumber* n = jArray->getValue(1)->asNumber();
  244. Assert::IsTrue(n->getNumber() == 2, L"Array hat mindestens einen falschen Wert");
  245. n->release();
  246. jArray->release();
  247. Framework::RCArray<Framework::Text> rcArr;
  248. rcArr.add(new Framework::Text("1"));
  249. rcArr.add(new Framework::Text("2"));
  250. rcArr.add(new Framework::Text("3"));
  251. rcArr.add(new Framework::Text("4"));
  252. jArray = Framework::JSON::JSONArray::fromRCArray<Framework::Text>(rcArr, [](Framework::Text& v)
  253. {
  254. return new Framework::JSON::JSONString(v);
  255. });
  256. Assert::IsTrue(jArray->getLength() == 4, L"Array hat falsche länge");
  257. Framework::JSON::JSONString* s = jArray->getValue(2)->asString();
  258. Assert::IsTrue(s->getString().istGleich("3"), L"Array hat mindestens einen falschen Wert");
  259. s->release();
  260. jArray->release();
  261. }
  262. };
  263. TEST_CLASS(JSONValidatorTests)
  264. {
  265. private:
  266. static OutputDebugStringBuf<char, std::char_traits<char>> charDebugOutput;
  267. static std::streambuf* buf;
  268. public:
  269. TEST_CLASS_INITIALIZE(Init)
  270. {
  271. buf = std::cout.rdbuf();
  272. std::cout.rdbuf(&charDebugOutput);
  273. }
  274. TEST_METHOD(ValidTest)
  275. {
  276. Framework::JSON::Validator::JSONValidator* validator = Framework::JSON::Validator::JSONValidator::buildForArray()->
  277. addAcceptedObjectInArray()->
  278. withRequiredNumber("x")->
  279. whichIsLessThen(5)->
  280. finishNumber()->
  281. withRequiredBool("bla")->
  282. whichIsOptional()->
  283. withDefault(true)->
  284. finishBool()->
  285. finishObject()->finishArray();
  286. Framework::JSON::JSONArray* jArray = Framework::JSON::Parser::getValue("[{\"x\": 4, \"bla\": false}]")->asArray();
  287. Assert::IsTrue(validator->isValid(jArray), L"A valid json Array was marked as invalid by the validator");
  288. validator->release();
  289. }
  290. TEST_METHOD(ComplexTest)
  291. {
  292. 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();
  293. std::cout << validator->zConstraints()->toString().getText() << "\n";
  294. 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}]");
  295. std::cout << value->toString().getText() << "\n";
  296. Framework::JSON::Validator::JSONValidationResult* result = validator->validate(value);
  297. result->printInvalidInfo();
  298. Assert::IsTrue(!result->isValid(), L"Invalid Json was marked as valid");
  299. Framework::JSON::JSONValue* validValue = result->getValidPart();
  300. result->release();
  301. Assert::IsTrue(validValue == 0, L"getValidPart of invalid validation result without removeInvalidEntries or default values used in validation should return 0");
  302. value->release();
  303. validator->release();
  304. }
  305. TEST_METHOD(ComplexRemoveInvalidTest)
  306. {
  307. 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();
  308. std::cout << validator->zConstraints()->toString().getText() << "\n";
  309. 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}]");
  310. std::cout << value->toString().getText() << "\n";
  311. Framework::JSON::Validator::JSONValidationResult* result = validator->validate(value);
  312. result->printInvalidInfo();
  313. Assert::IsTrue(!result->isValid(), L"Invalid Json was marked as valid");
  314. Framework::JSON::JSONValue* validValue = result->getValidPart();
  315. result->release();
  316. 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}]");
  317. Assert::IsTrue(JSONParserTests::isEqual(validValue, expected), L"getValidPart of invalid validation result does not match the expected valid part");
  318. result = validator->validate(validValue);
  319. Assert::IsTrue(result->isValid(), L"Re validation of a value returned by getValidPart on a validation result should never return an invalid validation result");
  320. value->release();
  321. value = result->getValidPart();
  322. Assert::IsTrue(JSONParserTests::isEqual(validValue, value), L"getValidPart of a valid validation result should return the validated value");
  323. value->release();
  324. validValue->release();
  325. expected->release();
  326. validator->release();
  327. }
  328. TEST_METHOD(DefaultValuesTest)
  329. {
  330. Framework::JSON::Validator::JSONValidator* validator = Framework::JSON::Validator::JSONValidator::buildForArray()
  331. ->typeSpecifiedByAttribute("type")
  332. ->removeInvalidEntries()
  333. ->addAcceptedTypeInArray(
  334. Framework::JSON::Validator::JSONValidator::buildForObject()
  335. ->withRequiredString("type")->withExactMatch("shaped")->finishString()
  336. ->withRequiredString("group")->withDefault("test")->finishString()
  337. ->withRequiredNumber("width")->whichIsGreaterThen(0)->finishNumber()
  338. ->withRequiredNumber("height")->whichIsGreaterThen(0)->finishNumber()
  339. ->withRequiredAttribute("inputs",
  340. Framework::JSON::Validator::JSONValidator::buildForArray()
  341. ->withDefault(new Framework::JSON::JSONArray())
  342. ->addAcceptedTypeInArray(Framework::JSON::Validator::JSONValidator::buildForObject()
  343. ->withRequiredNumber("x")->whichIsGreaterOrEqual(0)->finishNumber()
  344. ->withRequiredNumber("y")->whichIsGreaterOrEqual(0)->finishNumber()
  345. ->withRequiredObject("filter")->withRequiredString("itemType")->finishString()->finishObject()
  346. ->finishObject())
  347. ->finishArray())
  348. ->withRequiredObject("output")->withRequiredString("itemType")->finishString()->finishObject()
  349. ->withRequiredNumber("outputCount")->withDefault(1)->whichIsGreaterThen(0)->finishNumber()
  350. ->finishObject())
  351. ->addAcceptedTypeInArray(
  352. Framework::JSON::Validator::JSONValidator::buildForObject()
  353. ->withRequiredString("type")->withExactMatch("unordered")->finishString()
  354. ->withRequiredString("group")->finishString()
  355. ->withRequiredAttribute("inputs",
  356. Framework::JSON::Validator::JSONValidator::buildForArray()
  357. ->withDefault(new Framework::JSON::JSONArray())
  358. ->addAcceptedTypeInArray(
  359. Framework::JSON::Validator::JSONValidator::buildForObject()
  360. ->withRequiredNumber("count")->withDefault(1)->whichIsGreaterThen(0)->finishNumber()
  361. ->withRequiredObject("filter")->withRequiredString("itemType")->finishString()->finishObject()
  362. ->finishObject())
  363. ->finishArray())
  364. ->withRequiredAttribute("output",
  365. Framework::JSON::Validator::JSONValidator::buildForArray()
  366. ->addAcceptedTypeInArray(Framework::JSON::Validator::JSONValidator::buildForObject()
  367. ->withRequiredObject("filter")->withRequiredString("itemType")->finishString()->finishObject()
  368. ->withRequiredNumber("count")->withDefault(1)->whichIsGreaterThen(0)->finishNumber()
  369. ->finishObject())
  370. ->finishArray())
  371. ->finishObject())
  372. ->finishArray();
  373. std::cout << validator->zConstraints()->toString().getText() << "\n";
  374. 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\"}}]}]");
  375. std::cout << value->toString().getText() << "\n";
  376. Framework::JSON::Validator::JSONValidationResult* result = validator->validate(value);
  377. result->printInvalidInfo();
  378. Assert::IsTrue(!result->isValid(), L"Invalid Json was marked as valid");
  379. Framework::JSON::JSONValue* validValue = result->getValidPart();
  380. result->release();
  381. 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\"}}]}]");
  382. Assert::IsTrue(JSONParserTests::isEqual(validValue, expected), L"getValidPart of invalid validation result does not match the expected valid part");
  383. result = validator->validate(validValue);
  384. Assert::IsTrue(result->isValid(), L"Re validation of a value returned by getValidPart on a validation result should never return an invalid validation result");
  385. value->release();
  386. value = result->getValidPart();
  387. Assert::IsTrue(JSONParserTests::isEqual(validValue, value), L"getValidPart of a valid validation result should return the validated value");
  388. value->release();
  389. validValue->release();
  390. expected->release();
  391. validator->release();
  392. }
  393. TEST_CLASS_CLEANUP(Cleanup)
  394. {
  395. std::cout.rdbuf(buf);
  396. }
  397. };
  398. OutputDebugStringBuf<char, std::char_traits<char>> JSONValidatorTests::charDebugOutput;
  399. std::streambuf* JSONValidatorTests::buf;
  400. }