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