Json.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. #include "pch.h"
  2. #define NO_MAIN
  3. #include <Json.h>
  4. #include <main.h>
  5. #include "CppUnitTest.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
  15. = Framework::JSON::Parser::getValue("null");
  16. Assert::IsTrue(value != 0,
  17. L"Framework::JSON::Parser::getValue('null') should not return "
  18. L"0");
  19. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NULL_,
  20. L"Framework::JSON::Parser::getValue('null') should return a "
  21. L"json null value");
  22. value->release();
  23. }
  24. TEST_METHOD (BooleanTest)
  25. {
  26. Framework::JSON::JSONValue* value
  27. = Framework::JSON::Parser::getValue("false");
  28. Assert::IsTrue(value != 0,
  29. L"Framework::JSON::Parser::getValue('false') should not return "
  30. L"0");
  31. Assert::IsTrue(
  32. value->getType() == Framework::JSON::JSONType::BOOLEAN,
  33. L"Framework::JSON::Parser::getValue('false') should return a "
  34. L"boolean");
  35. Assert::IsTrue(
  36. ((Framework::JSON::JSONBool*)value)->getBool() == false,
  37. L"Framework::JSON::Parser::getValue('false') should return a "
  38. L"boolean with value false");
  39. value->release();
  40. value = Framework::JSON::Parser::getValue("true");
  41. Assert::IsTrue(value != 0,
  42. L"Framework::JSON::Parser::getValue('true') should not return "
  43. L"0");
  44. Assert::IsTrue(
  45. value->getType() == Framework::JSON::JSONType::BOOLEAN,
  46. L"Framework::JSON::Parser::getValue('true') should return a "
  47. L"boolean");
  48. Assert::IsTrue(
  49. ((Framework::JSON::JSONBool*)value)->getBool() == true,
  50. L"Framework::JSON::Parser::getValue('true') should return a "
  51. L"boolean with value true");
  52. value->release();
  53. }
  54. TEST_METHOD (StringTest)
  55. {
  56. Framework::JSON::JSONValue* value
  57. = Framework::JSON::Parser::getValue("\"test\"");
  58. Assert::IsTrue(value != 0,
  59. L"Framework::JSON::Parser::getValue('\"test\"') should not "
  60. L"return 0");
  61. Assert::IsTrue(
  62. value->getType() == Framework::JSON::JSONType::STRING,
  63. L"Framework::JSON::Parser::getValue('\"test\"') should return "
  64. L"a string");
  65. Assert::IsTrue(((Framework::JSON::JSONString*)value)
  66. ->getString()
  67. .istGleich("test"),
  68. L"Framework::JSON::Parser::getValue('\"test\"') should return "
  69. L"a string with value 'test'");
  70. value->release();
  71. value = Framework::JSON::Parser::getValue("\"\"");
  72. Assert::IsTrue(value != 0,
  73. L"Framework::JSON::Parser::getValue('\"\"') should not return "
  74. L"0");
  75. Assert::IsTrue(
  76. value->getType() == Framework::JSON::JSONType::STRING,
  77. L"Framework::JSON::Parser::getValue('\"\"') should return a "
  78. L"string");
  79. Assert::IsTrue(((Framework::JSON::JSONString*)value)
  80. ->getString()
  81. .istGleich(""),
  82. L"Framework::JSON::Parser::getValue('\"\"') should return a "
  83. L"string with value ''");
  84. value->release();
  85. }
  86. TEST_METHOD (NumberTest)
  87. {
  88. Framework::JSON::JSONValue* value
  89. = Framework::JSON::Parser::getValue("0");
  90. Assert::IsTrue(value != 0,
  91. L"Framework::JSON::Parser::getValue('0') should not return 0");
  92. Assert::IsTrue(
  93. value->getType() == Framework::JSON::JSONType::NUMBER,
  94. L"Framework::JSON::Parser::getValue('0') should return a "
  95. L"number");
  96. Assert::IsTrue(
  97. ((Framework::JSON::JSONNumber*)value)->getNumber() == 0.0,
  98. L"Framework::JSON::Parser::getValue('0') should return a "
  99. L"number with value '0'");
  100. value->release();
  101. value = Framework::JSON::Parser::getValue("1.5");
  102. Assert::IsTrue(value != 0,
  103. L"Framework::JSON::Parser::getValue('1.5') should not return "
  104. L"0");
  105. Assert::IsTrue(
  106. value->getType() == Framework::JSON::JSONType::NUMBER,
  107. L"Framework::JSON::Parser::getValue('1.5') should return a "
  108. L"number");
  109. Assert::IsTrue(
  110. ((Framework::JSON::JSONNumber*)value)->getNumber() == 1.5,
  111. L"Framework::JSON::Parser::getValue('1.5') should return a "
  112. L"number with value '1.5'");
  113. value->release();
  114. value = Framework::JSON::Parser::getValue("-1.5");
  115. Assert::IsTrue(value != 0,
  116. L"Framework::JSON::Parser::getValue('-1.5') should not return "
  117. L"0");
  118. Assert::IsTrue(
  119. value->getType() == Framework::JSON::JSONType::NUMBER,
  120. L"Framework::JSON::Parser::getValue('-1.5') should return a "
  121. L"number");
  122. Assert::IsTrue(
  123. ((Framework::JSON::JSONNumber*)value)->getNumber() == -1.5,
  124. L"Framework::JSON::Parser::getValue('-1.5') should return a "
  125. L"number with value '-1.5'");
  126. value->release();
  127. value = Framework::JSON::Parser::getValue("-5.0");
  128. Assert::IsTrue(value != 0,
  129. L"Framework::JSON::Parser::getValue('-5.0') should not return "
  130. L"0");
  131. Assert::IsTrue(
  132. value->getType() == Framework::JSON::JSONType::NUMBER,
  133. L"Framework::JSON::Parser::getValue('-5.0') should return a "
  134. L"number");
  135. Assert::IsTrue(
  136. ((Framework::JSON::JSONNumber*)value)->getNumber() == -5.0,
  137. L"Framework::JSON::Parser::getValue('-5.0') should return a "
  138. L"number with value '-5.0'");
  139. value->release();
  140. }
  141. TEST_METHOD (ArrayTest)
  142. {
  143. Framework::JSON::JSONValue* value
  144. = Framework::JSON::Parser::getValue("[]");
  145. Assert::IsTrue(value != 0,
  146. L"Framework::JSON::Parser::getValue('[]') should not return 0");
  147. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY,
  148. L"Framework::JSON::Parser::getValue('[]') should return an "
  149. L"array");
  150. Assert::IsTrue(
  151. ((Framework::JSON::JSONArray*)value)->getLength() == 0,
  152. L"Framework::JSON::Parser::getValue('[]') should return an "
  153. L"array with length 0");
  154. value->release();
  155. value = Framework::JSON::Parser::getValue(
  156. " \t[ \r\n\tnull , \r\n\t 1,true , \"\" ] ");
  157. Assert::IsTrue(value != 0,
  158. L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') "
  159. L"should not return 0");
  160. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY,
  161. L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') "
  162. L"should return an array");
  163. Assert::IsTrue(
  164. ((Framework::JSON::JSONArray*)value)->getLength() == 4,
  165. L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') "
  166. L"should return an array with length 4");
  167. Assert::IsTrue(
  168. ((Framework::JSON::JSONArray*)value)
  169. ->isValueOfType(0, Framework::JSON::JSONType::NULL_),
  170. L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') "
  171. L"should contain null at index 0");
  172. Assert::IsTrue(
  173. ((Framework::JSON::JSONArray*)value)
  174. ->isValueOfType(1, Framework::JSON::JSONType::NUMBER),
  175. L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') "
  176. L"should contain a number at index 1");
  177. Assert::IsTrue(
  178. ((Framework::JSON::JSONArray*)value)
  179. ->isValueOfType(2, Framework::JSON::JSONType::BOOLEAN),
  180. L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') "
  181. L"should contain a boolean at index 2");
  182. Assert::IsTrue(
  183. ((Framework::JSON::JSONArray*)value)
  184. ->isValueOfType(3, Framework::JSON::JSONType::STRING),
  185. L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') "
  186. L"should contain a boolean at index 3");
  187. value->release();
  188. }
  189. TEST_METHOD (MultipleArrayTest)
  190. {
  191. Framework::JSON::JSONValue* value
  192. = Framework::JSON::Parser::getValue("[[1],2,[[]]]");
  193. Assert::IsTrue(value != 0,
  194. L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should not "
  195. L"return 0");
  196. Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY,
  197. L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should "
  198. L"return an array");
  199. Assert::IsTrue(
  200. ((Framework::JSON::JSONArray*)value)->getLength() == 3,
  201. L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should "
  202. L"return an array with length 3");
  203. Assert::IsTrue(
  204. ((Framework::JSON::JSONArray*)value)
  205. ->isValueOfType(0, Framework::JSON::JSONType::ARRAY),
  206. L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') "
  207. L"should contain an array at index 0");
  208. Assert::IsTrue(
  209. ((Framework::JSON::JSONArray*)value)
  210. ->isValueOfType(1, Framework::JSON::JSONType::NUMBER),
  211. L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') "
  212. L"should contain a number at index 1");
  213. Assert::IsTrue(
  214. ((Framework::JSON::JSONArray*)value)
  215. ->isValueOfType(2, Framework::JSON::JSONType::ARRAY),
  216. L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') "
  217. L"should contain an array at index 2");
  218. value->release();
  219. }
  220. TEST_METHOD (ObjectTest)
  221. {
  222. Framework::JSON::JSONValue* value
  223. = Framework::JSON::Parser::getValue("{\" \": []}");
  224. Assert::IsTrue(value != 0,
  225. L"Framework::JSON::Parser::getValue('{\"\": []}') should not "
  226. L"return 0");
  227. Assert::IsTrue(
  228. value->getType() == Framework::JSON::JSONType::OBJECT,
  229. L"Framework::JSON::Parser::getValue('{\" \": []}') should "
  230. L"return an object");
  231. Assert::IsTrue(
  232. ((Framework::JSON::JSONObject*)value)->getFieldCount() == 1,
  233. L"Framework::JSON::Parser::getValue('{\" \": []}') should "
  234. L"return an object with one attribute");
  235. Assert::IsTrue(
  236. ((Framework::JSON::JSONObject*)value)
  237. ->isValueOfType(" ", Framework::JSON::JSONType::ARRAY),
  238. L"Framework::JSON::Parser::getValue('{\" \": []}') should "
  239. L"contain an array at attribute ' '");
  240. value->release();
  241. }
  242. TEST_METHOD (ToStringTest)
  243. {
  244. Framework::JSON::JSONValue* value
  245. = Framework::JSON::Parser::getValue(
  246. "{\" \": [1, true, false, 0.0, {}], \"t\": null}");
  247. Framework::JSON::JSONValue* value2
  248. = Framework::JSON::Parser::getValue(value->toString());
  249. Assert::IsTrue(isEqual(value, value2),
  250. L"Framework::JSON::Parser::getValue(value.toString()) should "
  251. L"return a json value eqal to value");
  252. value->release();
  253. value2->release();
  254. }
  255. static bool isEqual(
  256. Framework::JSON::JSONValue * a, Framework::JSON::JSONValue * b)
  257. {
  258. if (a->getType() != b->getType()) return 0;
  259. switch (a->getType())
  260. {
  261. case Framework::JSON::JSONType::NUMBER:
  262. return ((Framework::JSON::JSONNumber*)a)->getNumber()
  263. == ((Framework::JSON::JSONNumber*)b)->getNumber();
  264. case Framework::JSON::JSONType::BOOLEAN:
  265. return ((Framework::JSON::JSONBool*)a)->getBool()
  266. == ((Framework::JSON::JSONBool*)b)->getBool();
  267. case Framework::JSON::JSONType::STRING:
  268. return ((Framework::JSON::JSONString*)a)
  269. ->getString()
  270. .istGleich(((Framework::JSON::JSONString*)b)->getString());
  271. case Framework::JSON::JSONType::ARRAY:
  272. {
  273. Framework::JSON::JSONArray* arrayA
  274. = (Framework::JSON::JSONArray*)a;
  275. Framework::JSON::JSONArray* arrayB
  276. = (Framework::JSON::JSONArray*)b;
  277. if (arrayA->getLength() != arrayB->getLength()) return 0;
  278. for (int i = 0; i < arrayA->getLength(); i++)
  279. {
  280. Framework::JSON::JSONValue* entryA
  281. = arrayA->getValue(i);
  282. Framework::JSON::JSONValue* entryB
  283. = arrayB->getValue(i);
  284. bool eq = isEqual(entryA, entryB);
  285. entryA->release();
  286. entryB->release();
  287. if (!eq) return 0;
  288. }
  289. return 1;
  290. }
  291. case Framework::JSON::JSONType::OBJECT:
  292. {
  293. Framework::JSON::JSONObject* objA
  294. = (Framework::JSON::JSONObject*)a;
  295. Framework::JSON::JSONObject* objB
  296. = (Framework::JSON::JSONObject*)b;
  297. if (objA->getFieldCount() != objB->getFieldCount())
  298. return 0;
  299. auto oaf = objA->getFields();
  300. while (oaf)
  301. {
  302. if (!objB->hasValue(oaf)) return 0;
  303. Framework::JSON::JSONValue* entryA
  304. = objA->getValue(oaf);
  305. Framework::JSON::JSONValue* entryB
  306. = objB->getValue(oaf);
  307. bool eq = isEqual(entryA, entryB);
  308. entryA->release();
  309. entryB->release();
  310. if (!eq) return 0;
  311. oaf++;
  312. }
  313. return 1;
  314. }
  315. }
  316. return 1;
  317. }
  318. TEST_METHOD (ToArrayTest)
  319. {
  320. Framework::JSON::JSONArray* jArray
  321. = Framework::JSON::Parser::getValue("[1,2,3,4,5,6,7,8,9,10]")
  322. ->asArray();
  323. Framework::Array<int>* numberArray
  324. = jArray->toArray<int>([](Framework::JSON::JSONValue& v) {
  325. return (int)v.asNumber()->getNumber();
  326. });
  327. Assert::IsTrue(numberArray->getEintragAnzahl() == 10,
  328. L"Array hat die falsche Anzahl an elementen");
  329. Assert::IsTrue(numberArray->get(2) == 3,
  330. L"Array hat mindestens ein falsches element");
  331. Assert::IsTrue(numberArray->get(7) == 8,
  332. L"Array hat mindestens ein falsches element");
  333. numberArray->release();
  334. numberArray = jArray->toArray<int>(
  335. [](Framework::JSON::JSONValue& v) {
  336. return (int)v.asNumber()->getNumber() % 2 == 0;
  337. },
  338. [](Framework::JSON::JSONValue& v) {
  339. return (int)v.asNumber()->getNumber();
  340. });
  341. Assert::IsTrue(numberArray->get(0) == 2,
  342. L"Array hat mindestens ein falsches element");
  343. Assert::IsTrue(numberArray->get(3) == 8,
  344. L"Array hat mindestens ein falsches element");
  345. jArray->release();
  346. }
  347. TEST_METHOD (ToRCArrayTest)
  348. {
  349. Framework::JSON::JSONArray* jArray
  350. = Framework::JSON::Parser::getValue(
  351. "[\"1\",\"2\",\"3\",\"4\",\"5\"]")
  352. ->asArray();
  353. Framework::RCArray<Framework::Text>* numberArray
  354. = jArray->toRCArray<Framework::Text>(
  355. [](Framework::JSON::JSONValue& v) {
  356. return new Framework::Text(v.asString()->getString());
  357. });
  358. Assert::IsTrue(numberArray->getEintragAnzahl() == 5,
  359. L"Array hat die falsche Anzahl an elementen");
  360. Assert::IsTrue(numberArray->z(1)->istGleich("2"),
  361. L"Array hat mindestens ein falsches element");
  362. Assert::IsTrue(numberArray->z(4)->istGleich("5"),
  363. L"Array hat mindestens ein falsches element");
  364. numberArray->release();
  365. numberArray = jArray->toRCArray<Framework::Text>(
  366. [](Framework::JSON::JSONValue& v) {
  367. return (int)v.asString()->getString() % 2 == 0;
  368. },
  369. [](Framework::JSON::JSONValue& v) {
  370. return new Framework::Text(v.asString()->getString());
  371. });
  372. Assert::IsTrue(numberArray->z(0)->istGleich("2"),
  373. L"Array hat mindestens ein falsches element");
  374. Assert::IsTrue(numberArray->z(1)->istGleich("4"),
  375. L"Array hat mindestens ein falsches element");
  376. jArray->release();
  377. }
  378. class TestObject
  379. {
  380. public:
  381. Framework::Text name;
  382. Framework::Text value;
  383. };
  384. TEST_METHOD (ParseObjectTest)
  385. {
  386. Framework::JSON::JSONObject* jObj
  387. = Framework::JSON::Parser::getValue(
  388. "{\"name\": \"test\", \"value\": \"1234\"}")
  389. ->asObject();
  390. TestObject* obj = jObj->parseTo<TestObject>(new TestObject(),
  391. [](TestObject* obj,
  392. Framework::Text attrName,
  393. Framework::JSON::JSONValue& v) {
  394. if (attrName.istGleich("name"))
  395. {
  396. obj->name = v.asString()->getString();
  397. }
  398. else
  399. {
  400. obj->value = v.asString()->getString();
  401. }
  402. });
  403. Assert::IsTrue(
  404. obj->name.istGleich("test"), L"Feld hat falschen wert");
  405. Assert::IsTrue(
  406. obj->value.istGleich("1234"), L"Feld hat falschen wert");
  407. delete obj;
  408. jObj->release();
  409. }
  410. TEST_METHOD (FromArrayTest)
  411. {
  412. Framework::Array<int> arr;
  413. arr.add(1);
  414. arr.add(2);
  415. arr.add(3);
  416. arr.add(4);
  417. Framework::JSON::JSONArray* jArray
  418. = Framework::JSON::JSONArray::fromArray<int>(arr,
  419. [](int v) { return new Framework::JSON::JSONNumber(v); });
  420. Assert::IsTrue(
  421. jArray->getLength() == 4, L"Array hat falsche länge");
  422. Framework::JSON::JSONNumber* n = jArray->getValue(1)->asNumber();
  423. Assert::IsTrue(n->getNumber() == 2,
  424. L"Array hat mindestens einen falschen Wert");
  425. n->release();
  426. jArray->release();
  427. Framework::RCArray<Framework::Text> rcArr;
  428. rcArr.add(new Framework::Text("1"));
  429. rcArr.add(new Framework::Text("2"));
  430. rcArr.add(new Framework::Text("3"));
  431. rcArr.add(new Framework::Text("4"));
  432. jArray = Framework::JSON::JSONArray::fromRCArray<Framework::Text>(
  433. rcArr, [](Framework::Text& v) {
  434. return new Framework::JSON::JSONString(v);
  435. });
  436. Assert::IsTrue(
  437. jArray->getLength() == 4, L"Array hat falsche länge");
  438. Framework::JSON::JSONString* s = jArray->getValue(2)->asString();
  439. Assert::IsTrue(s->getString().istGleich("3"),
  440. L"Array hat mindestens einen falschen Wert");
  441. s->release();
  442. jArray->release();
  443. }
  444. };
  445. TEST_CLASS (JSONValidatorTests)
  446. {
  447. private:
  448. static OutputDebugStringBuf<char, std::char_traits<char>>
  449. charDebugOutput;
  450. static std::streambuf* buf;
  451. public:
  452. TEST_CLASS_INITIALIZE(Init)
  453. {
  454. buf = std::cout.rdbuf();
  455. std::cout.rdbuf(&charDebugOutput);
  456. }
  457. TEST_METHOD (ValidTest)
  458. {
  459. Framework::JSON::Validator::JSONValidator* validator
  460. = Framework::JSON::Validator::JSONValidator::buildForArray()
  461. ->addAcceptedObjectInArray()
  462. ->withRequiredNumber("x")
  463. ->whichIsLessThen(5)
  464. ->finishNumber()
  465. ->withRequiredBool("bla")
  466. ->whichIsOptional()
  467. ->withDefault(true)
  468. ->finishBool()
  469. ->finishObject()
  470. ->finishArray();
  471. Framework::JSON::JSONArray* jArray
  472. = Framework::JSON::Parser::getValue(
  473. "[{\"x\": 4, \"bla\": false}]")
  474. ->asArray();
  475. Assert::IsTrue(validator->isValid(jArray),
  476. L"A valid json Array was marked as invalid by the validator");
  477. validator->release();
  478. }
  479. TEST_METHOD (ComplexTest)
  480. {
  481. Framework::JSON::Validator::JSONValidator* validator
  482. = Framework::JSON::Validator::JSONValidator::buildForArray()
  483. ->typeSpecifiedByAttribute("type")
  484. ->addAcceptedObjectInArray()
  485. ->withRequiredString("type")
  486. ->withExactMatch("shaped")
  487. ->finishString()
  488. ->withRequiredString("group")
  489. ->finishString()
  490. ->withRequiredNumber("width")
  491. ->whichIsGreaterThen(0)
  492. ->finishNumber()
  493. ->withRequiredNumber("height")
  494. ->whichIsGreaterThen(0)
  495. ->finishNumber()
  496. ->withRequiredArray("inputs")
  497. ->addAcceptedObjectInArray()
  498. ->withRequiredNumber("x")
  499. ->whichIsGreaterOrEqual(0)
  500. ->finishNumber()
  501. ->withRequiredNumber("y")
  502. ->whichIsGreaterOrEqual(0)
  503. ->finishNumber()
  504. ->withRequiredObject("filter")
  505. ->withRequiredString("itemType")
  506. ->finishString()
  507. ->finishObject()
  508. ->finishObject()
  509. ->finishArray()
  510. ->withRequiredObject("output")
  511. ->withRequiredString("itemType")
  512. ->finishString()
  513. ->finishObject()
  514. ->withRequiredNumber("outputCount")
  515. ->whichIsGreaterThen(0)
  516. ->finishNumber()
  517. ->finishObject()
  518. ->addAcceptedObjectInArray()
  519. ->withRequiredString("type")
  520. ->withExactMatch("unordered")
  521. ->finishString()
  522. ->withRequiredString("group")
  523. ->finishString()
  524. ->withRequiredArray("inputs")
  525. ->addAcceptedObjectInArray()
  526. ->withRequiredNumber("count")
  527. ->whichIsGreaterThen(0)
  528. ->finishNumber()
  529. ->withRequiredObject("filter")
  530. ->withRequiredString("itemType")
  531. ->finishString()
  532. ->finishObject()
  533. ->finishObject()
  534. ->finishArray()
  535. ->withRequiredArray("output")
  536. ->addAcceptedObjectInArray()
  537. ->withRequiredObject("filter")
  538. ->withRequiredString("itemType")
  539. ->finishString()
  540. ->finishObject()
  541. ->withRequiredNumber("count")
  542. ->whichIsGreaterThen(0)
  543. ->finishNumber()
  544. ->finishObject()
  545. ->finishArray()
  546. ->finishObject()
  547. ->finishArray();
  548. std::cout << validator->zConstraints()->toString().getText()
  549. << "\n";
  550. Framework::JSON::JSONValue* value
  551. = Framework::JSON::Parser::getValue(
  552. "[{\"type\": \"shaped\",\"group\": "
  553. "\"inventory\",\"width\": 1,\"height\": 2,\"inputs\": "
  554. "[{\"x\": 0,\"y\": 0,\"filter\": {\"itemType\": "
  555. "\"Cobble\"}},{\"x\": 0,\"y\": -1,\"filter\": "
  556. "{\"itemType\": \"Cobble\"}}],\"output\": {\"itemType\": "
  557. "\"StoneTool\"},\"outputCount\": 1},{\"type\": "
  558. "\"shaped\",\"group\": \"inventory\",\"width\": "
  559. "1,\"height\": 2,\"inputs\": [{\"x\": 0,\"y\": "
  560. "0,\"filter\": {\"itemType\": \"Cobble\"}},{\"x\": "
  561. "0,\"y\": 1,\"filter\": {\"itemType\": "
  562. "\"Cobble\"}}],\"output\": {\"itemType\": "
  563. "\"StoneTool\"},\"outputCount\": 1}]");
  564. std::cout << value->toString().getText() << "\n";
  565. Framework::JSON::Validator::JSONValidationResult* result
  566. = validator->validate(value);
  567. result->printInvalidInfo();
  568. Assert::IsTrue(
  569. !result->isValid(), L"Invalid Json was marked as valid");
  570. Framework::JSON::JSONValue* validValue = result->getValidPart();
  571. result->release();
  572. Assert::IsTrue(validValue == 0,
  573. L"getValidPart of invalid validation result without "
  574. L"removeInvalidEntries or default values used in validation "
  575. L"should return 0");
  576. value->release();
  577. validator->release();
  578. }
  579. TEST_METHOD (ComplexRemoveInvalidTest)
  580. {
  581. Framework::JSON::Validator::JSONValidator* validator
  582. = Framework::JSON::Validator::JSONValidator::buildForArray()
  583. ->removeInvalidEntries()
  584. ->typeSpecifiedByAttribute("type")
  585. ->addAcceptedObjectInArray()
  586. ->withRequiredString("type")
  587. ->withExactMatch("shaped")
  588. ->finishString()
  589. ->withRequiredString("group")
  590. ->finishString()
  591. ->withRequiredNumber("width")
  592. ->whichIsGreaterThen(0)
  593. ->finishNumber()
  594. ->withRequiredNumber("height")
  595. ->whichIsGreaterThen(0)
  596. ->finishNumber()
  597. ->withRequiredArray("inputs")
  598. ->addAcceptedObjectInArray()
  599. ->withRequiredNumber("x")
  600. ->whichIsGreaterOrEqual(0)
  601. ->finishNumber()
  602. ->withRequiredNumber("y")
  603. ->whichIsGreaterOrEqual(0)
  604. ->finishNumber()
  605. ->withRequiredObject("filter")
  606. ->withRequiredString("itemType")
  607. ->finishString()
  608. ->finishObject()
  609. ->finishObject()
  610. ->finishArray()
  611. ->withRequiredObject("output")
  612. ->withRequiredString("itemType")
  613. ->finishString()
  614. ->finishObject()
  615. ->withRequiredNumber("outputCount")
  616. ->whichIsGreaterThen(0)
  617. ->finishNumber()
  618. ->finishObject()
  619. ->addAcceptedObjectInArray()
  620. ->withRequiredString("type")
  621. ->withExactMatch("unordered")
  622. ->finishString()
  623. ->withRequiredString("group")
  624. ->finishString()
  625. ->withRequiredArray("inputs")
  626. ->addAcceptedObjectInArray()
  627. ->withRequiredNumber("count")
  628. ->whichIsGreaterThen(0)
  629. ->finishNumber()
  630. ->withRequiredObject("filter")
  631. ->withRequiredString("itemType")
  632. ->finishString()
  633. ->finishObject()
  634. ->finishObject()
  635. ->finishArray()
  636. ->withRequiredArray("output")
  637. ->addAcceptedObjectInArray()
  638. ->withRequiredObject("filter")
  639. ->withRequiredString("itemType")
  640. ->finishString()
  641. ->finishObject()
  642. ->withRequiredNumber("count")
  643. ->whichIsGreaterThen(0)
  644. ->finishNumber()
  645. ->finishObject()
  646. ->finishArray()
  647. ->finishObject()
  648. ->finishArray();
  649. std::cout << validator->zConstraints()->toString().getText()
  650. << "\n";
  651. Framework::JSON::JSONValue* value
  652. = Framework::JSON::Parser::getValue(
  653. "[{\"type\": \"shaped\",\"group\": "
  654. "\"inventory\",\"width\": 1,\"height\": 2,\"inputs\": "
  655. "[{\"x\": 0,\"y\": 0,\"filter\": {\"itemType\": "
  656. "\"Cobble\"}},{\"x\": 0,\"y\": -1,\"filter\": "
  657. "{\"itemType\": \"Cobble\"}}],\"output\": {\"itemType\": "
  658. "\"StoneTool\"},\"outputCount\": 1},{\"type\": "
  659. "\"shaped\",\"group\": \"inventory\",\"width\": "
  660. "1,\"height\": 2,\"inputs\": [{\"x\": 0,\"y\": "
  661. "0,\"filter\": {\"itemType\": \"Cobble\"}},{\"x\": "
  662. "0,\"y\": 1,\"filter\": {\"itemType\": "
  663. "\"Cobble\"}}],\"output\": {\"itemType\": "
  664. "\"StoneTool\"},\"outputCount\": 1}]");
  665. std::cout << value->toString().getText() << "\n";
  666. Framework::JSON::Validator::JSONValidationResult* result
  667. = validator->validate(value);
  668. result->printInvalidInfo();
  669. Assert::IsTrue(
  670. !result->isValid(), L"Invalid Json was marked as valid");
  671. Framework::JSON::JSONValue* validValue = result->getValidPart();
  672. result->release();
  673. Framework::JSON::JSONValue* expected
  674. = Framework::JSON::Parser::getValue(
  675. "[{\"type\": \"shaped\",\"group\": "
  676. "\"inventory\",\"width\": 1,\"height\": 2,\"inputs\": "
  677. "[{\"x\": 0,\"y\": 0,\"filter\": {\"itemType\": "
  678. "\"Cobble\"}},{\"x\": 0,\"y\": 1,\"filter\": "
  679. "{\"itemType\": \"Cobble\"}}],\"output\": {\"itemType\": "
  680. "\"StoneTool\"},\"outputCount\": 1}]");
  681. Assert::IsTrue(JSONParserTests::isEqual(validValue, expected),
  682. L"getValidPart of invalid validation result does not match the "
  683. L"expected valid part");
  684. result = validator->validate(validValue);
  685. Assert::IsTrue(result->isValid(),
  686. L"Re validation of a value returned by getValidPart on a "
  687. L"validation result should never return an invalid validation "
  688. L"result");
  689. value->release();
  690. value = result->getValidPart();
  691. Assert::IsTrue(JSONParserTests::isEqual(validValue, value),
  692. L"getValidPart of a valid validation result should return the "
  693. L"validated value");
  694. value->release();
  695. validValue->release();
  696. expected->release();
  697. validator->release();
  698. }
  699. TEST_METHOD (DefaultValuesTest)
  700. {
  701. Framework::JSON::Validator::JSONValidator* validator
  702. = Framework::JSON::Validator::JSONValidator::buildForArray()
  703. ->typeSpecifiedByAttribute("type")
  704. ->removeInvalidEntries()
  705. ->addAcceptedTypeInArray(
  706. Framework::JSON::Validator::JSONValidator::buildForObject()
  707. ->withRequiredString("type")
  708. ->withExactMatch("shaped")
  709. ->finishString()
  710. ->withRequiredString("group")
  711. ->withDefault("test")
  712. ->finishString()
  713. ->withRequiredNumber("width")
  714. ->whichIsGreaterThen(0)
  715. ->finishNumber()
  716. ->withRequiredNumber("height")
  717. ->whichIsGreaterThen(0)
  718. ->finishNumber()
  719. ->withRequiredAttribute("inputs",
  720. Framework::JSON::Validator::JSONValidator::
  721. buildForArray()
  722. ->withDefault(
  723. new Framework::JSON::JSONArray())
  724. ->addAcceptedTypeInArray(
  725. Framework::JSON::Validator::
  726. JSONValidator::buildForObject()
  727. ->withRequiredNumber("x")
  728. ->whichIsGreaterOrEqual(0)
  729. ->finishNumber()
  730. ->withRequiredNumber("y")
  731. ->whichIsGreaterOrEqual(0)
  732. ->finishNumber()
  733. ->withRequiredObject(
  734. "filter")
  735. ->withRequiredString(
  736. "itemType")
  737. ->finishString()
  738. ->finishObject()
  739. ->finishObject())
  740. ->finishArray())
  741. ->withRequiredObject("output")
  742. ->withRequiredString("itemType")
  743. ->finishString()
  744. ->finishObject()
  745. ->withRequiredNumber("outputCount")
  746. ->withDefault(1)
  747. ->whichIsGreaterThen(0)
  748. ->finishNumber()
  749. ->finishObject())
  750. ->addAcceptedTypeInArray(
  751. Framework::JSON::Validator::JSONValidator::buildForObject()
  752. ->withRequiredString("type")
  753. ->withExactMatch("unordered")
  754. ->finishString()
  755. ->withRequiredString("group")
  756. ->finishString()
  757. ->withRequiredAttribute("inputs",
  758. Framework::JSON::Validator::JSONValidator::
  759. buildForArray()
  760. ->withDefault(
  761. new Framework::JSON::JSONArray())
  762. ->addAcceptedTypeInArray(
  763. Framework::JSON::Validator::
  764. JSONValidator::
  765. buildForObject()
  766. ->withRequiredNumber(
  767. "count")
  768. ->withDefault(1)
  769. ->whichIsGreaterThen(
  770. 0)
  771. ->finishNumber()
  772. ->withRequiredObject(
  773. "filter")
  774. ->withRequiredString(
  775. "itemType")
  776. ->finishString()
  777. ->finishObject()
  778. ->finishObject())
  779. ->finishArray())
  780. ->withRequiredAttribute("output",
  781. Framework::JSON::Validator::JSONValidator::
  782. buildForArray()
  783. ->addAcceptedTypeInArray(
  784. Framework::JSON::Validator::
  785. JSONValidator::
  786. buildForObject()
  787. ->withRequiredObject(
  788. "filter")
  789. ->withRequiredString(
  790. "itemType")
  791. ->finishString()
  792. ->finishObject()
  793. ->withRequiredNumber(
  794. "count")
  795. ->withDefault(1)
  796. ->whichIsGreaterThen(
  797. 0)
  798. ->finishNumber()
  799. ->finishObject())
  800. ->finishArray())
  801. ->finishObject())
  802. ->finishArray();
  803. std::cout << validator->zConstraints()->toString().getText()
  804. << "\n";
  805. Framework::JSON::JSONValue* value
  806. = Framework::JSON::Parser::getValue(
  807. "[{\"type\": \"shaped\",\"width\": 1,\"height\": "
  808. "2,\"inputs\": [{\"x\": 0,\"y\": 0,\"filter\": "
  809. "{\"itemType\": \"Cobble\"}},{\"x\": 0,\"y\": "
  810. "1,\"filter\": {\"itemType\": \"Cobble\"}}],\"output\": "
  811. "{\"itemType\": \"StoneTool\"}},{\"type\": "
  812. "\"shaped\",\"width\": 1,\"height\": 2,\"inputs\": "
  813. "[{\"x\": 0,\"y\": 0,\"filter\": {\"itemType\": "
  814. "\"Cobble\"}},{\"x\": 0,\"y\": -1,\"filter\": "
  815. "{\"itemType\": \"Cobble\"}}],\"output\": {\"itemType\": "
  816. "\"StoneTool\"}},{\"type\": \"unordered\",\"group\": "
  817. "\"bla\", \"inputs\": [{\"filter\": {\"itemType\": "
  818. "\"Cobble\"}},{\"filter\": {\"itemType\": "
  819. "\"Cobble\"}}],\"output\": [{\"filter\": {\"itemType\": "
  820. "\"StoneTool\"}}]}]");
  821. std::cout << value->toString().getText() << "\n";
  822. Framework::JSON::Validator::JSONValidationResult* result
  823. = validator->validate(value);
  824. result->printInvalidInfo();
  825. Assert::IsTrue(
  826. !result->isValid(), L"Invalid Json was marked as valid");
  827. Framework::JSON::JSONValue* validValue = result->getValidPart();
  828. result->release();
  829. Framework::JSON::JSONValue* expected
  830. = Framework::JSON::Parser::getValue(
  831. "[{\"type\": \"shaped\", \"group\": \"test\",\"width\": "
  832. "1,\"height\": 2,\"inputs\": [{\"x\": 0,\"y\": "
  833. "0,\"filter\": {\"itemType\": \"Cobble\"}},{\"x\": "
  834. "0,\"y\": 1,\"filter\": {\"itemType\": "
  835. "\"Cobble\"}}],\"output\": {\"itemType\": \"StoneTool\"}, "
  836. "\"outputCount\": 1},{\"type\": \"unordered\",\"group\": "
  837. "\"bla\", \"inputs\": [{\"count\": 1, \"filter\": "
  838. "{\"itemType\": \"Cobble\"}},{\"count\": 1, \"filter\": "
  839. "{\"itemType\": \"Cobble\"}}],\"output\": [{\"count\": 1, "
  840. "\"filter\": {\"itemType\": \"StoneTool\"}}]}]");
  841. Assert::IsTrue(JSONParserTests::isEqual(validValue, expected),
  842. L"getValidPart of invalid validation result does not match the "
  843. L"expected valid part");
  844. result = validator->validate(validValue);
  845. Assert::IsTrue(result->isValid(),
  846. L"Re validation of a value returned by getValidPart on a "
  847. L"validation result should never return an invalid validation "
  848. L"result");
  849. value->release();
  850. value = result->getValidPart();
  851. Assert::IsTrue(JSONParserTests::isEqual(validValue, value),
  852. L"getValidPart of a valid validation result should return the "
  853. L"validated value");
  854. value->release();
  855. validValue->release();
  856. expected->release();
  857. validator->release();
  858. }
  859. TEST_METHOD (RecursiveValidatorTest)
  860. {
  861. Framework::JSON::Validator::JSONValidator* validator
  862. = Framework::JSON::Validator::JSONValidator::buildForObject()
  863. ->setObjectReferenceId("TreeNode")
  864. ->withRequiredAttribute("value",
  865. Framework::JSON::Validator::JSONValidator::
  866. buildForString()
  867. ->whichCanBeNull()
  868. ->finishString())
  869. ->withRequiredAttribute("children",
  870. Framework::JSON::Validator::JSONValidator::
  871. buildForArray()
  872. ->whichIsOptional()
  873. ->addAcceptedTypeInArray(Framework::JSON::
  874. Validator::JSONValidator::
  875. buildForObjectReference(
  876. "TreeNode"))
  877. ->finishArray())
  878. ->finishObject();
  879. Framework::JSON::JSONObject* jArray
  880. = Framework::JSON::Parser::getValue(
  881. "{\"value\": \"1\", \"children\": [{\"value\": \"2\"}, "
  882. "{\"value\": \"3\", \"children\": [{\"value\": \"4\"}]}]}")
  883. ->asObject();
  884. Assert::IsTrue(validator->isValid(jArray),
  885. L"A valid json Object was marked as invalid by the validator");
  886. validator->release();
  887. }
  888. TEST_CLASS_CLEANUP(Cleanup)
  889. {
  890. std::cout.rdbuf(buf);
  891. }
  892. };
  893. OutputDebugStringBuf<char, std::char_traits<char>>
  894. JSONValidatorTests::charDebugOutput;
  895. std::streambuf* JSONValidatorTests::buf;
  896. } // namespace FrameworkTests