Json.cpp 48 KB

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