test_object.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. /*
  2. * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>
  3. *
  4. * Jansson is free software; you can redistribute it and/or modify
  5. * it under the terms of the MIT license. See LICENSE for details.
  6. */
  7. #include <jansson.h>
  8. #include <string.h>
  9. #include "util.h"
  10. static void test_clear()
  11. {
  12. json_t *object, *ten;
  13. object = json_object();
  14. ten = json_integer(10);
  15. if(!object)
  16. fail("unable to create object");
  17. if(!ten)
  18. fail("unable to create integer");
  19. if(json_object_set(object, "a", ten) ||
  20. json_object_set(object, "b", ten) ||
  21. json_object_set(object, "c", ten) ||
  22. json_object_set(object, "d", ten) ||
  23. json_object_set(object, "e", ten))
  24. fail("unable to set value");
  25. if(json_object_size(object) != 5)
  26. fail("invalid size");
  27. json_object_clear(object);
  28. if(json_object_size(object) != 0)
  29. fail("invalid size after clear");
  30. json_decref(ten);
  31. json_decref(object);
  32. }
  33. static void test_update()
  34. {
  35. json_t *object, *other, *nine, *ten;
  36. object = json_object();
  37. other = json_object();
  38. nine = json_integer(9);
  39. ten = json_integer(10);
  40. if(!object || !other)
  41. fail("unable to create object");
  42. if(!nine || !ten)
  43. fail("unable to create integer");
  44. /* update an empty object with an empty object */
  45. if(json_object_update(object, other))
  46. fail("unable to update an emtpy object with an empty object");
  47. if(json_object_size(object) != 0)
  48. fail("invalid size after update");
  49. if(json_object_size(other) != 0)
  50. fail("invalid size for updater after update");
  51. /* update an empty object with a nonempty object */
  52. if(json_object_set(other, "a", ten) ||
  53. json_object_set(other, "b", ten) ||
  54. json_object_set(other, "c", ten) ||
  55. json_object_set(other, "d", ten) ||
  56. json_object_set(other, "e", ten))
  57. fail("unable to set value");
  58. if(json_object_update(object, other))
  59. fail("unable to update an empty object");
  60. if(json_object_size(object) != 5)
  61. fail("invalid size after update");
  62. if(json_object_get(object, "a") != ten ||
  63. json_object_get(object, "b") != ten ||
  64. json_object_get(object, "c") != ten ||
  65. json_object_get(object, "d") != ten ||
  66. json_object_get(object, "e") != ten)
  67. fail("update works incorrectly");
  68. /* perform the same update again */
  69. if(json_object_update(object, other))
  70. fail("unable to update a non-empty object");
  71. if(json_object_size(object) != 5)
  72. fail("invalid size after update");
  73. if(json_object_get(object, "a") != ten ||
  74. json_object_get(object, "b") != ten ||
  75. json_object_get(object, "c") != ten ||
  76. json_object_get(object, "d") != ten ||
  77. json_object_get(object, "e") != ten)
  78. fail("update works incorrectly");
  79. /* update a nonempty object with a nonempty object with both old
  80. and new keys */
  81. if(json_object_clear(other))
  82. fail("clear failed");
  83. if(json_object_set(other, "a", nine) ||
  84. json_object_set(other, "b", nine) ||
  85. json_object_set(other, "f", nine) ||
  86. json_object_set(other, "g", nine) ||
  87. json_object_set(other, "h", nine))
  88. fail("unable to set value");
  89. if(json_object_update(object, other))
  90. fail("unable to update a nonempty object");
  91. if(json_object_size(object) != 8)
  92. fail("invalid size after update");
  93. if(json_object_get(object, "a") != nine ||
  94. json_object_get(object, "b") != nine ||
  95. json_object_get(object, "f") != nine ||
  96. json_object_get(object, "g") != nine ||
  97. json_object_get(object, "h") != nine)
  98. fail("update works incorrectly");
  99. json_decref(nine);
  100. json_decref(ten);
  101. json_decref(other);
  102. json_decref(object);
  103. }
  104. static void test_set_many_keys()
  105. {
  106. json_t *object, *value;
  107. const char *keys = "abcdefghijklmnopqrstuvwxyz";
  108. char buf[2];
  109. size_t i;
  110. object = json_object();
  111. if (!object)
  112. fail("unable to create object");
  113. value = json_string("a");
  114. if (!value)
  115. fail("unable to create string");
  116. buf[1] = '\0';
  117. for (i = 0; i < strlen(keys); i++) {
  118. buf[0] = keys[i];
  119. if (json_object_set(object, buf, value))
  120. fail("unable to set object key");
  121. }
  122. json_decref(object);
  123. json_decref(value);
  124. }
  125. static void test_conditional_updates()
  126. {
  127. json_t *object, *other;
  128. object = json_pack("{sisi}", "foo", 1, "bar", 2);
  129. other = json_pack("{sisi}", "foo", 3, "baz", 4);
  130. if(json_object_update_existing(object, other))
  131. fail("json_object_update_existing failed");
  132. if(json_object_size(object) != 2)
  133. fail("json_object_update_existing added new items");
  134. if(json_integer_value(json_object_get(object, "foo")) != 3)
  135. fail("json_object_update_existing failed to update existing key");
  136. if(json_integer_value(json_object_get(object, "bar")) != 2)
  137. fail("json_object_update_existing updated wrong key");
  138. json_decref(object);
  139. object = json_pack("{sisi}", "foo", 1, "bar", 2);
  140. if(json_object_update_missing(object, other))
  141. fail("json_object_update_missing failed");
  142. if(json_object_size(object) != 3)
  143. fail("json_object_update_missing didn't add new items");
  144. if(json_integer_value(json_object_get(object, "foo")) != 1)
  145. fail("json_object_update_missing updated existing key");
  146. if(json_integer_value(json_object_get(object, "bar")) != 2)
  147. fail("json_object_update_missing updated wrong key");
  148. if(json_integer_value(json_object_get(object, "baz")) != 4)
  149. fail("json_object_update_missing didn't add new items");
  150. json_decref(object);
  151. json_decref(other);
  152. }
  153. static void test_circular()
  154. {
  155. json_t *object1, *object2;
  156. object1 = json_object();
  157. object2 = json_object();
  158. if(!object1 || !object2)
  159. fail("unable to create object");
  160. /* the simple case is checked */
  161. if(json_object_set(object1, "a", object1) == 0)
  162. fail("able to set self");
  163. /* create circular references */
  164. if(json_object_set(object1, "a", object2) ||
  165. json_object_set(object2, "a", object1))
  166. fail("unable to set value");
  167. /* circularity is detected when dumping */
  168. if(json_dumps(object1, 0) != NULL)
  169. fail("able to dump circulars");
  170. /* decref twice to deal with the circular references */
  171. json_decref(object1);
  172. json_decref(object2);
  173. json_decref(object1);
  174. }
  175. static void test_set_nocheck()
  176. {
  177. json_t *object, *string;
  178. object = json_object();
  179. string = json_string("bar");
  180. if(!object)
  181. fail("unable to create object");
  182. if(!string)
  183. fail("unable to create string");
  184. if(json_object_set_nocheck(object, "foo", string))
  185. fail("json_object_set_nocheck failed");
  186. if(json_object_get(object, "foo") != string)
  187. fail("json_object_get after json_object_set_nocheck failed");
  188. /* invalid UTF-8 in key */
  189. if(json_object_set_nocheck(object, "a\xefz", string))
  190. fail("json_object_set_nocheck failed for invalid UTF-8");
  191. if(json_object_get(object, "a\xefz") != string)
  192. fail("json_object_get after json_object_set_nocheck failed");
  193. if(json_object_set_new_nocheck(object, "bax", json_integer(123)))
  194. fail("json_object_set_new_nocheck failed");
  195. if(json_integer_value(json_object_get(object, "bax")) != 123)
  196. fail("json_object_get after json_object_set_new_nocheck failed");
  197. /* invalid UTF-8 in key */
  198. if(json_object_set_new_nocheck(object, "asdf\xfe", json_integer(321)))
  199. fail("json_object_set_new_nocheck failed for invalid UTF-8");
  200. if(json_integer_value(json_object_get(object, "asdf\xfe")) != 321)
  201. fail("json_object_get after json_object_set_new_nocheck failed");
  202. json_decref(string);
  203. json_decref(object);
  204. }
  205. static void test_iterators()
  206. {
  207. json_t *object, *foo, *bar, *baz;
  208. void *iter;
  209. if(json_object_iter(NULL))
  210. fail("able to iterate over NULL");
  211. if(json_object_iter_next(NULL, NULL))
  212. fail("able to increment an iterator on a NULL object");
  213. object = json_object();
  214. foo = json_string("foo");
  215. bar = json_string("bar");
  216. baz = json_string("baz");
  217. if(!object || !foo || !bar || !baz)
  218. fail("unable to create values");
  219. if(json_object_iter_next(object, NULL))
  220. fail("able to increment a NULL iterator");
  221. if(json_object_set(object, "a", foo) ||
  222. json_object_set(object, "b", bar) ||
  223. json_object_set(object, "c", baz))
  224. fail("unable to populate object");
  225. iter = json_object_iter(object);
  226. if(!iter)
  227. fail("unable to get iterator");
  228. if (strcmp(json_object_iter_key(iter), "a") != 0)
  229. fail("iterating doesn't yield keys in order");
  230. if (json_object_iter_value(iter) != foo)
  231. fail("iterating doesn't yield values in order");
  232. iter = json_object_iter_next(object, iter);
  233. if(!iter)
  234. fail("unable to increment iterator");
  235. if (strcmp(json_object_iter_key(iter), "b") != 0)
  236. fail("iterating doesn't yield keys in order");
  237. if (json_object_iter_value(iter) != bar)
  238. fail("iterating doesn't yield values in order");
  239. iter = json_object_iter_next(object, iter);
  240. if(!iter)
  241. fail("unable to increment iterator");
  242. if (strcmp(json_object_iter_key(iter), "c") != 0)
  243. fail("iterating doesn't yield keys in order");
  244. if (json_object_iter_value(iter) != baz)
  245. fail("iterating doesn't yield values in order");
  246. if(json_object_iter_next(object, iter) != NULL)
  247. fail("able to iterate over the end");
  248. if(json_object_iter_at(object, "foo"))
  249. fail("json_object_iter_at() succeeds for non-existent key");
  250. iter = json_object_iter_at(object, "b");
  251. if(!iter)
  252. fail("json_object_iter_at() fails for an existing key");
  253. if(strcmp(json_object_iter_key(iter), "b"))
  254. fail("iterating failed: wrong key");
  255. if(json_object_iter_value(iter) != bar)
  256. fail("iterating failed: wrong value");
  257. if(json_object_iter_set(object, iter, baz))
  258. fail("unable to set value at iterator");
  259. if(strcmp(json_object_iter_key(iter), "b"))
  260. fail("json_object_iter_key() fails after json_object_iter_set()");
  261. if(json_object_iter_value(iter) != baz)
  262. fail("json_object_iter_value() fails after json_object_iter_set()");
  263. if(json_object_get(object, "b") != baz)
  264. fail("json_object_get() fails after json_object_iter_set()");
  265. json_decref(object);
  266. json_decref(foo);
  267. json_decref(bar);
  268. json_decref(baz);
  269. }
  270. static void test_misc()
  271. {
  272. json_t *object, *string, *other_string, *value;
  273. object = json_object();
  274. string = json_string("test");
  275. other_string = json_string("other");
  276. if(!object)
  277. fail("unable to create object");
  278. if(!string || !other_string)
  279. fail("unable to create string");
  280. if(json_object_get(object, "a"))
  281. fail("value for nonexisting key");
  282. if(json_object_set(object, "a", string))
  283. fail("unable to set value");
  284. if(!json_object_set(object, NULL, string))
  285. fail("able to set NULL key");
  286. if(json_object_del(object, "a"))
  287. fail("unable to del the only key");
  288. if(json_object_set(object, "a", string))
  289. fail("unable to set value");
  290. if(!json_object_set(object, "a", NULL))
  291. fail("able to set NULL value");
  292. /* invalid UTF-8 in key */
  293. if(!json_object_set(object, "a\xefz", string))
  294. fail("able to set invalid unicode key");
  295. value = json_object_get(object, "a");
  296. if(!value)
  297. fail("no value for existing key");
  298. if(value != string)
  299. fail("got different value than what was added");
  300. /* "a", "lp" and "px" collide in a five-bucket hashtable */
  301. if(json_object_set(object, "b", string) ||
  302. json_object_set(object, "lp", string) ||
  303. json_object_set(object, "px", string))
  304. fail("unable to set value");
  305. value = json_object_get(object, "a");
  306. if(!value)
  307. fail("no value for existing key");
  308. if(value != string)
  309. fail("got different value than what was added");
  310. if(json_object_set(object, "a", other_string))
  311. fail("unable to replace an existing key");
  312. value = json_object_get(object, "a");
  313. if(!value)
  314. fail("no value for existing key");
  315. if(value != other_string)
  316. fail("got different value than what was set");
  317. if(!json_object_del(object, "nonexisting"))
  318. fail("able to delete a nonexisting key");
  319. if(json_object_del(object, "px"))
  320. fail("unable to delete an existing key");
  321. if(json_object_del(object, "a"))
  322. fail("unable to delete an existing key");
  323. if(json_object_del(object, "lp"))
  324. fail("unable to delete an existing key");
  325. /* add many keys to initiate rehashing */
  326. if(json_object_set(object, "a", string))
  327. fail("unable to set value");
  328. if(json_object_set(object, "lp", string))
  329. fail("unable to set value");
  330. if(json_object_set(object, "px", string))
  331. fail("unable to set value");
  332. if(json_object_set(object, "c", string))
  333. fail("unable to set value");
  334. if(json_object_set(object, "d", string))
  335. fail("unable to set value");
  336. if(json_object_set(object, "e", string))
  337. fail("unable to set value");
  338. if(json_object_set_new(object, "foo", json_integer(123)))
  339. fail("unable to set new value");
  340. value = json_object_get(object, "foo");
  341. if(!json_is_integer(value) || json_integer_value(value) != 123)
  342. fail("json_object_set_new works incorrectly");
  343. if(!json_object_set_new(object, NULL, json_integer(432)))
  344. fail("able to set_new NULL key");
  345. if(!json_object_set_new(object, "foo", NULL))
  346. fail("able to set_new NULL value");
  347. json_decref(string);
  348. json_decref(other_string);
  349. json_decref(object);
  350. }
  351. static void test_preserve_order()
  352. {
  353. json_t *object;
  354. char *result;
  355. const char *expected = "{\"foobar\": 1, \"bazquux\": 6, \"lorem ipsum\": 3, \"sit amet\": 5, \"helicopter\": 7}";
  356. object = json_object();
  357. json_object_set_new(object, "foobar", json_integer(1));
  358. json_object_set_new(object, "bazquux", json_integer(2));
  359. json_object_set_new(object, "lorem ipsum", json_integer(3));
  360. json_object_set_new(object, "dolor", json_integer(4));
  361. json_object_set_new(object, "sit amet", json_integer(5));
  362. /* changing a value should preserve the order */
  363. json_object_set_new(object, "bazquux", json_integer(6));
  364. /* deletion shouldn't change the order of others */
  365. json_object_del(object, "dolor");
  366. /* add a new item just to make sure */
  367. json_object_set_new(object, "helicopter", json_integer(7));
  368. result = json_dumps(object, JSON_PRESERVE_ORDER);
  369. if(strcmp(expected, result) != 0) {
  370. fprintf(stderr, "%s != %s", expected, result);
  371. fail("JSON_PRESERVE_ORDER doesn't work");
  372. }
  373. free(result);
  374. json_decref(object);
  375. }
  376. static void test_object_foreach()
  377. {
  378. const char *key;
  379. json_t *object1, *object2, *value;
  380. object1 = json_pack("{sisisi}", "foo", 1, "bar", 2, "baz", 3);
  381. object2 = json_object();
  382. json_object_foreach(object1, key, value)
  383. json_object_set(object2, key, value);
  384. if(!json_equal(object1, object2))
  385. fail("json_object_foreach failed to iterate all key-value pairs");
  386. json_decref(object1);
  387. json_decref(object2);
  388. }
  389. static void test_object_foreach_safe()
  390. {
  391. const char *key;
  392. void *tmp;
  393. json_t *object, *value;
  394. object = json_pack("{sisisi}", "foo", 1, "bar", 2, "baz", 3);
  395. json_object_foreach_safe(object, tmp, key, value) {
  396. json_object_del(object, key);
  397. }
  398. if(json_object_size(object) != 0)
  399. fail("json_object_foreach_safe failed to iterate all key-value pairs");
  400. json_decref(object);
  401. }
  402. static void run_tests()
  403. {
  404. test_misc();
  405. test_clear();
  406. test_update();
  407. test_set_many_keys();
  408. test_conditional_updates();
  409. test_circular();
  410. test_set_nocheck();
  411. test_iterators();
  412. test_preserve_order();
  413. test_object_foreach();
  414. test_object_foreach_safe();
  415. }