Minor fixes to res_json and test_json.
[asterisk/asterisk.git] / tests / test_json.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012 - 2013, Digium, Inc.
5  *
6  * David M. Lee, II <dlee@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file \brief Test JSON API.
21  *
22  * While some of these tests are actually testing our JSON library wrapper, the bulk of
23  * them are exploratory tests to determine what the behavior of the underlying JSON
24  * library is. This also gives us a good indicator if that behavior changes between
25  * Jansson revisions.
26  *
27  * \author\verbatim David M. Lee, II <dlee@digium.com> \endverbatim
28  *
29  * \ingroup tests
30  */
31
32 /*** MODULEINFO
33         <depend>TEST_FRAMEWORK</depend>
34         <depend>res_json</depend>
35         <support_level>core</support_level>
36  ***/
37
38 #include "asterisk.h"
39
40 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
41 #include "asterisk/json.h"
42 #include "asterisk/module.h"
43 #include "asterisk/test.h"
44
45 /*!
46  * Number of allocations from JSON library that have not yet been freed.
47  */
48 static size_t alloc_count;
49
50 /*!@{*/
51 /*!
52  * JSON library has its own reference counting, so we'll provide our own allocators to
53  * test that everything gets freed as expected.
54  */
55 static void *json_debug_malloc(size_t size)
56 {
57         void *p = ast_malloc(size);
58         if (p) {
59                 ++alloc_count;
60         }
61         return p;
62 }
63
64 static void json_debug_free(void *p)
65 {
66         if (p) {
67                 --alloc_count;
68         }
69         ast_free(p);
70 }
71
72 static void *json_test_init(struct ast_test *test)
73 {
74         ast_json_set_alloc_funcs(json_debug_malloc, json_debug_free);
75         alloc_count = 0;
76         return test;
77 }
78
79 static void json_test_finish(void *test)
80 {
81         struct ast_test *t = test;
82         ast_json_reset_alloc_funcs();
83         if (0 != alloc_count) {
84                 ast_test_status_update(t, "JSON test leaked %zd allocations!", alloc_count);
85         }
86 }
87
88 /*!@}*/
89
90 AST_TEST_DEFINE(json_test_false)
91 {
92         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
93         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
94
95         switch (cmd) {
96         case TEST_INIT:
97                 info->name = "false";
98                 info->category = "/main/json/";
99                 info->summary = "Testing fundamental JSON false value.";
100                 info->description = "Test JSON abstraction library.";
101                 return AST_TEST_NOT_RUN;
102         case TEST_EXECUTE:
103                 break;
104         }
105
106         uut = ast_json_false();
107         ast_test_validate(test, NULL != uut);
108         ast_test_validate(test, AST_JSON_FALSE == ast_json_typeof(uut));
109         ast_test_validate(test, !ast_json_is_null(uut));
110         ast_test_validate(test, !ast_json_is_true(uut));
111         ast_test_validate(test, ast_json_is_false(uut));
112
113         return AST_TEST_PASS;
114 }
115
116 AST_TEST_DEFINE(json_test_true)
117 {
118         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
119         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
120
121         switch (cmd) {
122         case TEST_INIT:
123                 info->name = "true";
124                 info->category = "/main/json/";
125                 info->summary = "Testing JSON true value.";
126                 info->description = "Test JSON abstraction library.";
127                 return AST_TEST_NOT_RUN;
128         case TEST_EXECUTE:
129                 break;
130         }
131
132         uut = ast_json_true();
133         ast_test_validate(test, NULL != uut);
134         ast_test_validate(test, AST_JSON_TRUE == ast_json_typeof(uut));
135         ast_test_validate(test, !ast_json_is_null(uut));
136         ast_test_validate(test, ast_json_is_true(uut));
137         ast_test_validate(test, !ast_json_is_false(uut));
138
139         return AST_TEST_PASS;
140 }
141
142 AST_TEST_DEFINE(json_test_bool0)
143 {
144         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
145         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
146
147         switch (cmd) {
148         case TEST_INIT:
149                 info->name = "bool0";
150                 info->category = "/main/json/";
151                 info->summary = "Testing JSON boolean function (false).";
152                 info->description = "Test JSON abstraction library.";
153                 return AST_TEST_NOT_RUN;
154         case TEST_EXECUTE:
155                 break;
156         }
157
158         uut = ast_json_boolean(0);
159         ast_test_validate(test, NULL != uut);
160         ast_test_validate(test, AST_JSON_FALSE == ast_json_typeof(uut));
161         ast_test_validate(test, !ast_json_is_null(uut));
162         ast_test_validate(test, !ast_json_is_true(uut));
163         ast_test_validate(test, ast_json_is_false(uut));
164         ast_test_validate(test, ast_json_equal(uut, ast_json_false()));
165         ast_test_validate(test, !ast_json_equal(uut, ast_json_true()));
166
167         return AST_TEST_PASS;
168 }
169
170 AST_TEST_DEFINE(json_test_bool1)
171 {
172         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
173         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
174
175         switch (cmd) {
176         case TEST_INIT:
177                 info->name = "bool1";
178                 info->category = "/main/json/";
179                 info->summary = "Testing JSON boolean function (true).";
180                 info->description = "Test JSON abstraction library.";
181                 return AST_TEST_NOT_RUN;
182         case TEST_EXECUTE:
183                 break;
184         }
185
186         uut = ast_json_boolean(1);
187         ast_test_validate(test, NULL != uut);
188         ast_test_validate(test, AST_JSON_TRUE == ast_json_typeof(uut));
189         ast_test_validate(test, !ast_json_is_null(uut));
190         ast_test_validate(test, ast_json_is_true(uut));
191         ast_test_validate(test, !ast_json_is_false(uut));
192         ast_test_validate(test, !ast_json_equal(uut, ast_json_false()));
193         ast_test_validate(test, ast_json_equal(uut, ast_json_true()));
194
195         return AST_TEST_PASS;
196 }
197
198 AST_TEST_DEFINE(json_test_null)
199 {
200         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
201         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
202
203         switch (cmd) {
204         case TEST_INIT:
205                 info->name = "null";
206                 info->category = "/main/json/";
207                 info->summary = "Testing JSON null value.";
208                 info->description = "Test JSON abstraction library.";
209                 return AST_TEST_NOT_RUN;
210         case TEST_EXECUTE:
211                 break;
212         }
213
214         uut = ast_json_null();
215         ast_test_validate(test, NULL != uut);
216         ast_test_validate(test, AST_JSON_NULL == ast_json_typeof(uut));
217         ast_test_validate(test, ast_json_is_null(uut));
218         ast_test_validate(test, !ast_json_is_true(uut));
219         ast_test_validate(test, !ast_json_is_false(uut));
220
221         return AST_TEST_PASS;
222 }
223
224 AST_TEST_DEFINE(json_test_null_val)
225 {
226         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
227         switch (cmd) {
228         case TEST_INIT:
229                 info->name = "null_val";
230                 info->category = "/main/json/";
231                 info->summary = "Testing JSON handling of NULL.";
232                 info->description = "Test JSON abstraction library.";
233                 return AST_TEST_NOT_RUN;
234         case TEST_EXECUTE:
235                 break;
236         }
237
238         /* NULL isn't null, true or false */
239         ast_test_validate(test, !ast_json_is_null(NULL));
240         ast_test_validate(test, !ast_json_is_false(NULL));
241         ast_test_validate(test, !ast_json_is_true(NULL));
242
243         /* ref and unref should be NULL safe */
244         ast_json_ref(NULL);
245         ast_json_unref(NULL);
246         /* no segfault; we're good. le sigh. */
247
248         return AST_TEST_PASS;
249 }
250
251 AST_TEST_DEFINE(json_test_string)
252 {
253         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
254         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
255         int uut_res;
256
257         switch (cmd) {
258         case TEST_INIT:
259                 info->name = "string";
260                 info->category = "/main/json/";
261                 info->summary = "Basic string tests.";
262                 info->description = "Test JSON abstraction library.";
263                 return AST_TEST_NOT_RUN;
264         case TEST_EXECUTE:
265                 break;
266         }
267
268         uut = ast_json_string_create("Hello, json");
269         ast_test_validate(test, NULL != uut);
270         ast_test_validate(test, AST_JSON_STRING == ast_json_typeof(uut));
271         ast_test_validate(test, 0 == strcmp("Hello, json", ast_json_string_get(uut)));
272
273         uut_res = ast_json_string_set(uut, NULL);
274         ast_test_validate(test, -1 == uut_res);
275         ast_test_validate(test, 0 == strcmp("Hello, json", ast_json_string_get(uut)));
276
277         uut_res = ast_json_string_set(uut, "Not UTF-8 - \xff");
278         ast_test_validate(test, -1 == uut_res);
279         ast_test_validate(test, 0 == strcmp("Hello, json", ast_json_string_get(uut)));
280
281         uut_res = ast_json_string_set(uut, "Is UTF-8 - \xE2\x98\xBA");
282         ast_test_validate(test, 0 == uut_res);
283         ast_test_validate(test, 0 == strcmp("Is UTF-8 - \xE2\x98\xBA", ast_json_string_get(uut)));
284
285         uut_res = ast_json_string_set(uut, "Goodbye, json");
286         ast_test_validate(test, 0 == uut_res);
287         ast_test_validate(test, 0 == strcmp("Goodbye, json", ast_json_string_get(uut)));
288
289         return AST_TEST_PASS;
290 }
291
292 AST_TEST_DEFINE(json_test_string_null)
293 {
294         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
295         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
296
297         switch (cmd) {
298         case TEST_INIT:
299                 info->name = "string_null";
300                 info->category = "/main/json/";
301                 info->summary = "JSON string NULL tests.";
302                 info->description = "Test JSON abstraction library.";
303                 return AST_TEST_NOT_RUN;
304         case TEST_EXECUTE:
305                 break;
306         }
307
308         /* NULL string */
309         uut = ast_json_string_create(NULL);
310         ast_test_validate(test, NULL == uut);
311
312         /* NULL JSON strings */
313         ast_test_validate(test, NULL == ast_json_string_create(NULL));
314         ast_test_validate(test, NULL == ast_json_string_get(NULL));
315         ast_test_validate(test, -1 == ast_json_string_set(NULL, "not null"));
316
317         /* string_value from non-string elements should return NULL */
318         ast_test_validate(test, NULL == ast_json_string_get(ast_json_null()));
319         ast_test_validate(test, NULL == ast_json_string_get(ast_json_false()));
320         ast_test_validate(test, NULL == ast_json_string_get(ast_json_true()));
321
322         return AST_TEST_PASS;
323 }
324
325 AST_TEST_DEFINE(json_test_stringf)
326 {
327         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
328         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
329         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
330
331         switch (cmd) {
332         case TEST_INIT:
333                 info->name = "stringf";
334                 info->category = "/main/json/";
335                 info->summary = "Basic string formatting tests.";
336                 info->description = "Test JSON abstraction library.";
337                 return AST_TEST_NOT_RUN;
338         case TEST_EXECUTE:
339                 break;
340         }
341
342         /* NULL format string */
343         uut = ast_json_stringf(NULL);
344         ast_test_validate(test, NULL == uut);
345
346         /* Non-UTF-8 strings are invalid */
347         uut = ast_json_stringf("Not UTF-8 - %s", "\xff");
348         ast_test_validate(test, NULL == uut);
349
350         /* formatted string */
351         uut = ast_json_stringf("Hello, %s", "json");
352         expected = ast_json_string_create("Hello, json");
353         ast_test_validate(test, NULL != uut);
354         ast_test_validate(test, ast_json_equal(expected, uut));
355
356         return AST_TEST_PASS;
357 }
358
359 AST_TEST_DEFINE(json_test_int)
360 {
361         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
362         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
363         int uut_res;
364
365         switch (cmd) {
366         case TEST_INIT:
367                 info->name = "int";
368                 info->category = "/main/json/";
369                 info->summary = "Basic JSON integer tests.";
370                 info->description = "Test JSON abstraction library.";
371                 return AST_TEST_NOT_RUN;
372         case TEST_EXECUTE:
373                 break;
374         }
375
376         /* Integer tests */
377         uut = ast_json_integer_create(0);
378         ast_test_validate(test, NULL != uut);
379         ast_test_validate(test, AST_JSON_INTEGER == ast_json_typeof(uut));
380         ast_test_validate(test, 0 == ast_json_integer_get(uut));
381
382         uut_res = ast_json_integer_set(uut, 1);
383         ast_test_validate(test, 0 == uut_res);
384         ast_test_validate(test, 1 == ast_json_integer_get(uut));
385
386         uut_res = ast_json_integer_set(uut, -1);
387         ast_test_validate(test, 0 == uut_res);
388         ast_test_validate(test, -1 == ast_json_integer_get(uut));
389
390         uut_res = ast_json_integer_set(uut, LLONG_MAX);
391         ast_test_validate(test, 0 == uut_res);
392         ast_test_validate(test, LLONG_MAX == ast_json_integer_get(uut));
393
394         uut_res = ast_json_integer_set(uut, LLONG_MIN);
395         ast_test_validate(test, 0 == uut_res);
396         ast_test_validate(test, LLONG_MIN == ast_json_integer_get(uut));
397
398         return AST_TEST_PASS;
399 }
400
401 AST_TEST_DEFINE(json_test_non_int)
402 {
403         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
404         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
405
406         switch (cmd) {
407         case TEST_INIT:
408                 info->name = "non_int";
409                 info->category = "/main/json/";
410                 info->summary = "Testing integer functions with non-integer types.";
411                 info->description = "Test JSON abstraction library.";
412                 return AST_TEST_NOT_RUN;
413         case TEST_EXECUTE:
414                 break;
415         }
416
417         /* Non-ints return 0 integer value */
418         ast_test_validate(test, 0 == ast_json_integer_get(ast_json_null()));
419         ast_test_validate(test, 0 == ast_json_integer_get(ast_json_true()));
420         ast_test_validate(test, 0 == ast_json_integer_get(ast_json_false()));
421
422         /* JSON NULL integers */
423         ast_test_validate(test, 0 == ast_json_integer_get(NULL));
424         ast_test_validate(test, -1 == ast_json_integer_set(NULL, 911));
425         ast_test_validate(test, 0 == ast_json_array_size(NULL));
426
427         /* No magical parsing of strings into ints */
428         uut = ast_json_string_create("314");
429         ast_test_validate(test, NULL != uut);
430         ast_test_validate(test, 0 == ast_json_integer_get(uut));
431
432         /* Or vice-versa */
433         ast_json_unref(uut);
434         uut = ast_json_integer_create(314);
435         ast_test_validate(test, NULL == ast_json_string_get(uut));
436
437         return AST_TEST_PASS;
438 }
439
440 AST_TEST_DEFINE(json_test_array_create)
441 {
442         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
443         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
444
445         switch (cmd) {
446         case TEST_INIT:
447                 info->name = "array_create";
448                 info->category = "/main/json/";
449                 info->summary = "Testing creating JSON arrays.";
450                 info->description = "Test JSON abstraction library.";
451                 return AST_TEST_NOT_RUN;
452         case TEST_EXECUTE:
453                 break;
454         }
455
456         /* array creation */
457         uut = ast_json_array_create();
458         ast_test_validate(test, NULL != uut);
459         ast_test_validate(test, AST_JSON_ARRAY == ast_json_typeof(uut));
460         ast_test_validate(test, 0 == ast_json_array_size(uut));
461
462         return AST_TEST_PASS;
463 }
464
465 AST_TEST_DEFINE(json_test_array_append)
466 {
467         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
468         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
469         int uut_res;
470
471         switch (cmd) {
472         case TEST_INIT:
473                 info->name = "array_append";
474                 info->category = "/main/json/";
475                 info->summary = "Testing appending to JSON arrays.";
476                 info->description = "Test JSON abstraction library.";
477                 return AST_TEST_NOT_RUN;
478         case TEST_EXECUTE:
479                 break;
480         }
481
482         /* array append */
483         uut = ast_json_array_create();
484         uut_res = ast_json_array_append(uut, ast_json_string_create("one"));
485         ast_test_validate(test, 0 == uut_res);
486         ast_test_validate(test, 1 == ast_json_array_size(uut));
487         ast_test_validate(test, 0 == strcmp("one", ast_json_string_get(ast_json_array_get(uut, 0))));
488         /* index out of range */
489         ast_test_validate(test, NULL == ast_json_array_get(uut, 1));
490         ast_test_validate(test, NULL == ast_json_array_get(uut, -1));
491
492         return AST_TEST_PASS;
493 }
494
495 AST_TEST_DEFINE(json_test_array_inset)
496 {
497         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
498         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
499         int uut_res;
500
501         switch (cmd) {
502         case TEST_INIT:
503                 info->name = "array_insert";
504                 info->category = "/main/json/";
505                 info->summary = "Testing inserting into JSON arrays.";
506                 info->description = "Test JSON abstraction library.";
507                 return AST_TEST_NOT_RUN;
508         case TEST_EXECUTE:
509                 break;
510         }
511
512         /* array insert */
513         uut = ast_json_pack("[s]", "one");
514         uut_res = ast_json_array_insert(uut, 0, ast_json_string_create("zero"));
515         ast_test_validate(test, 0 == uut_res);
516         ast_test_validate(test, 2 == ast_json_array_size(uut));
517         ast_test_validate(test, 0 == strcmp("zero", ast_json_string_get(ast_json_array_get(uut, 0))));
518         ast_test_validate(test, 0 == strcmp("one", ast_json_string_get(ast_json_array_get(uut, 1))));
519
520         return AST_TEST_PASS;
521 }
522
523 AST_TEST_DEFINE(json_test_array_set)
524 {
525         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
526         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
527         int uut_res;
528
529         switch (cmd) {
530         case TEST_INIT:
531                 info->name = "array_set";
532                 info->category = "/main/json/";
533                 info->summary = "Testing setting a value in JSON arrays.";
534                 info->description = "Test JSON abstraction library.";
535                 return AST_TEST_NOT_RUN;
536         case TEST_EXECUTE:
537                 break;
538         }
539
540         /* array set */
541         uut = ast_json_pack("[s, s]", "zero", "one");
542         uut_res = ast_json_array_set(uut, 1, ast_json_integer_create(1));
543         ast_test_validate(test, 0 == uut_res);
544         ast_test_validate(test, 2 == ast_json_array_size(uut));
545         ast_test_validate(test, 0 == strcmp("zero", ast_json_string_get(ast_json_array_get(uut, 0))));
546         ast_test_validate(test, 1 == ast_json_integer_get(ast_json_array_get(uut, 1)));
547
548         return AST_TEST_PASS;
549 }
550
551 AST_TEST_DEFINE(json_test_array_remove)
552 {
553         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
554         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
555         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
556         int uut_res;
557
558         switch (cmd) {
559         case TEST_INIT:
560                 info->name = "array_remove";
561                 info->category = "/main/json/";
562                 info->summary = "Testing removing a value from JSON arrays.";
563                 info->description = "Test JSON abstraction library.";
564                 return AST_TEST_NOT_RUN;
565         case TEST_EXECUTE:
566                 break;
567         }
568
569         /* array remove */
570         uut = ast_json_pack("[s, i]", "zero", 1);
571         expected = ast_json_pack("[i]", 1);
572         uut_res = ast_json_array_remove(uut, 0);
573         ast_test_validate(test, 0 == uut_res);
574         ast_test_validate(test, ast_json_equal(expected, uut));
575
576         return AST_TEST_PASS;
577 }
578
579 AST_TEST_DEFINE(json_test_array_clear)
580 {
581         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
582         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
583         int uut_res;
584
585         switch (cmd) {
586         case TEST_INIT:
587                 info->name = "array_clear";
588                 info->category = "/main/json/";
589                 info->summary = "Testing clearing JSON arrays.";
590                 info->description = "Test JSON abstraction library.";
591                 return AST_TEST_NOT_RUN;
592         case TEST_EXECUTE:
593                 break;
594         }
595
596         /* array clear */
597         uut = ast_json_pack("[s, s]", "zero", "one");
598         uut_res = ast_json_array_clear(uut);
599         ast_test_validate(test, 0 == uut_res);
600         ast_test_validate(test, 0 == ast_json_array_size(uut));
601
602         return AST_TEST_PASS;
603 }
604
605 AST_TEST_DEFINE(json_test_array_extend)
606 {
607         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
608         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
609         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
610         RAII_VAR(struct ast_json *, tail, NULL, ast_json_unref);
611         int uut_res;
612
613         switch (cmd) {
614         case TEST_INIT:
615                 info->name = "array_extend";
616                 info->category = "/main/json/";
617                 info->summary = "Testing extending JSON arrays.";
618                 info->description = "Test JSON abstraction library.";
619                 return AST_TEST_NOT_RUN;
620         case TEST_EXECUTE:
621                 break;
622         }
623
624         /* array extending */
625         expected = ast_json_array_create();
626         ast_json_array_append(expected, ast_json_string_create("a"));
627         ast_json_array_append(expected, ast_json_string_create("b"));
628         ast_json_array_append(expected, ast_json_string_create("c"));
629         ast_json_array_append(expected, ast_json_integer_create(1));
630         ast_json_array_append(expected, ast_json_integer_create(2));
631         ast_json_array_append(expected, ast_json_integer_create(3));
632
633         uut = ast_json_array_create();
634         ast_json_array_append(uut, ast_json_string_create("a"));
635         ast_json_array_append(uut, ast_json_string_create("b"));
636         ast_json_array_append(uut, ast_json_string_create("c"));
637
638         tail = ast_json_array_create();
639         ast_json_array_append(tail, ast_json_integer_create(1));
640         ast_json_array_append(tail, ast_json_integer_create(2));
641         ast_json_array_append(tail, ast_json_integer_create(3));
642
643         uut_res = ast_json_array_extend(uut, tail);
644         ast_test_validate(test, 0 == uut_res);
645         ast_test_validate(test, ast_json_equal(expected, uut));
646         /* tail is preserved */
647         ast_test_validate(test, 3 == ast_json_array_size(tail));
648
649         return AST_TEST_PASS;
650 }
651
652 AST_TEST_DEFINE(json_test_array_null)
653 {
654         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
655         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
656
657         switch (cmd) {
658         case TEST_INIT:
659                 info->name = "array_null";
660                 info->category = "/main/json/";
661                 info->summary = "Testing NULL conditions for JSON arrays.";
662                 info->description = "Test JSON abstraction library.";
663                 return AST_TEST_NOT_RUN;
664         case TEST_EXECUTE:
665                 break;
666         }
667
668         /* array NULL checks */
669         ast_test_validate(test, 0 == ast_json_array_size(NULL));
670         ast_test_validate(test, NULL == ast_json_array_get(NULL, 0));
671         ast_test_validate(test, -1 == ast_json_array_set(NULL, 0, ast_json_null()));
672         ast_test_validate(test, -1 == ast_json_array_append(NULL, ast_json_null()));
673         ast_test_validate(test, -1 == ast_json_array_insert(NULL, 0, ast_json_null()));
674         ast_test_validate(test, -1 == ast_json_array_remove(NULL, 0));
675         ast_test_validate(test, -1 == ast_json_array_clear(NULL));
676         uut = ast_json_array_create();
677         ast_test_validate(test, -1 == ast_json_array_extend(uut, NULL));
678         ast_test_validate(test, -1 == ast_json_array_extend(NULL, uut));
679         ast_test_validate(test, -1 == ast_json_array_extend(NULL, NULL));
680
681         return AST_TEST_PASS;
682 }
683
684 AST_TEST_DEFINE(json_test_object_alloc)
685 {
686         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
687         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
688
689         switch (cmd) {
690         case TEST_INIT:
691                 info->name = "object_alloc";
692                 info->category = "/main/json/";
693                 info->summary = "Testing creating JSON objects.";
694                 info->description = "Test JSON abstraction library.";
695                 return AST_TEST_NOT_RUN;
696         case TEST_EXECUTE:
697                 break;
698         }
699
700         /* object allocation */
701         uut = ast_json_object_create();
702         ast_test_validate(test, NULL != uut);
703         ast_test_validate(test, AST_JSON_OBJECT == ast_json_typeof(uut));
704         ast_test_validate(test, 0 == ast_json_object_size(uut));
705
706         return AST_TEST_PASS;
707 }
708
709 AST_TEST_DEFINE(json_test_object_set)
710 {
711         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
712         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
713         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
714         int uut_res;
715
716         switch (cmd) {
717         case TEST_INIT:
718                 info->name = "object_set";
719                 info->category = "/main/json/";
720                 info->summary = "Testing setting values in JSON objects.";
721                 info->description = "Test JSON abstraction library.";
722                 return AST_TEST_NOT_RUN;
723         case TEST_EXECUTE:
724                 break;
725         }
726
727         /* object set */
728         expected = ast_json_pack("{s: i, s: i, s: i}", "one", 1, "two", 2, "three", 3);
729         uut = ast_json_object_create();
730         uut_res = ast_json_object_set(uut, "one", ast_json_integer_create(1));
731         ast_test_validate(test, 0 == uut_res);
732         uut_res = ast_json_object_set(uut, "two", ast_json_integer_create(2));
733         ast_test_validate(test, 0 == uut_res);
734         uut_res = ast_json_object_set(uut, "three", ast_json_integer_create(3));
735         ast_test_validate(test, 0 == uut_res);
736         ast_test_validate(test, ast_json_equal(expected, uut));
737         ast_test_validate(test, NULL == ast_json_object_get(uut, "dne"));
738
739         return AST_TEST_PASS;
740 }
741
742 AST_TEST_DEFINE(json_test_object_set_overwrite)
743 {
744         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
745         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
746         int uut_res;
747
748         switch (cmd) {
749         case TEST_INIT:
750                 info->name = "object_set_overwriting";
751                 info->category = "/main/json/";
752                 info->summary = "Testing changing values in JSON objects.";
753                 info->description = "Test JSON abstraction library.";
754                 return AST_TEST_NOT_RUN;
755         case TEST_EXECUTE:
756                 break;
757         }
758
759         /* object set existing */
760         uut = ast_json_pack("{s: i, s: i, s: i}", "one", 1, "two", 2, "three", 3);
761         uut_res = ast_json_object_set(uut, "two", ast_json_integer_create(-2));
762         ast_test_validate(test, 0 == uut_res);
763         ast_test_validate(test, -2 == ast_json_integer_get(ast_json_object_get(uut, "two")));
764
765         return AST_TEST_PASS;
766 }
767
768 AST_TEST_DEFINE(json_test_object_get)
769 {
770         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
771         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
772
773         switch (cmd) {
774         case TEST_INIT:
775                 info->name = "object_get";
776                 info->category = "/main/json/";
777                 info->summary = "Testing getting values from JSON objects.";
778                 info->description = "Test JSON abstraction library.";
779                 return AST_TEST_NOT_RUN;
780         case TEST_EXECUTE:
781                 break;
782         }
783
784         /* object get */
785         uut = ast_json_pack("{s: i, s: i, s: i}", "one", 1, "two", 2, "three", 3);
786         ast_test_validate(test, 2 == ast_json_integer_get(ast_json_object_get(uut, "two")));
787         ast_test_validate(test, NULL == ast_json_object_get(uut, "dne"));
788         ast_test_validate(test, NULL == ast_json_object_get(uut, NULL));
789
790         return AST_TEST_PASS;
791 }
792
793 AST_TEST_DEFINE(json_test_object_del)
794 {
795         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
796         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
797         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
798         int uut_res;
799
800         switch (cmd) {
801         case TEST_INIT:
802                 info->name = "object_del";
803                 info->category = "/main/json/";
804                 info->summary = "Testing deleting values from JSON objects.";
805                 info->description = "Test JSON abstraction library.";
806                 return AST_TEST_NOT_RUN;
807         case TEST_EXECUTE:
808                 break;
809         }
810
811         /* object del */
812         expected = ast_json_object_create();
813         uut = ast_json_pack("{s: i}", "one", 1);
814         uut_res = ast_json_object_del(uut, "one");
815         ast_test_validate(test, 0 == uut_res);
816         ast_test_validate(test, ast_json_equal(expected, uut));
817         uut_res = ast_json_object_del(uut, "dne");
818         ast_test_validate(test, -1 == uut_res);
819
820         return AST_TEST_PASS;
821 }
822
823 AST_TEST_DEFINE(json_test_object_clear)
824 {
825         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
826         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
827         int uut_res;
828
829         switch (cmd) {
830         case TEST_INIT:
831                 info->name = "object_clear";
832                 info->category = "/main/json/";
833                 info->summary = "Testing clearing values from JSON objects.";
834                 info->description = "Test JSON abstraction library.";
835                 return AST_TEST_NOT_RUN;
836         case TEST_EXECUTE:
837                 break;
838         }
839
840         /* object clear */
841         uut = ast_json_object_create();
842         ast_json_object_set(uut, "one", ast_json_integer_create(1));
843         ast_json_object_set(uut, "two", ast_json_integer_create(2));
844         ast_json_object_set(uut, "three", ast_json_integer_create(3));
845         uut_res = ast_json_object_clear(uut);
846         ast_test_validate(test, 0 == uut_res);
847         ast_test_validate(test, 0 == ast_json_object_size(uut));
848
849         return AST_TEST_PASS;
850 }
851
852 AST_TEST_DEFINE(json_test_object_merge_all)
853 {
854         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
855         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
856         RAII_VAR(struct ast_json *, merge, NULL, ast_json_unref);
857         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
858         int uut_res;
859
860         switch (cmd) {
861         case TEST_INIT:
862                 info->name = "object_alloc";
863                 info->category = "/main/json/";
864                 info->summary = "Testing merging JSON objects.";
865                 info->description = "Test JSON abstraction library.";
866                 return AST_TEST_NOT_RUN;
867         case TEST_EXECUTE:
868                 break;
869         }
870
871         /* object merging - all */
872         uut = ast_json_object_create();
873         ast_json_object_set(uut, "one", ast_json_integer_create(1));
874         ast_json_object_set(uut, "two", ast_json_integer_create(2));
875         ast_json_object_set(uut, "three", ast_json_integer_create(3));
876
877         merge = ast_json_object_create();
878         ast_json_object_set(merge, "three", ast_json_integer_create(-3));
879         ast_json_object_set(merge, "four", ast_json_integer_create(-4));
880         ast_json_object_set(merge, "five", ast_json_integer_create(-5));
881
882         expected = ast_json_object_create();
883         ast_json_object_set(expected, "one", ast_json_integer_create(1));
884         ast_json_object_set(expected, "two", ast_json_integer_create(2));
885         ast_json_object_set(expected, "three", ast_json_integer_create(-3));
886         ast_json_object_set(expected, "four", ast_json_integer_create(-4));
887         ast_json_object_set(expected, "five", ast_json_integer_create(-5));
888
889         uut_res = ast_json_object_update(uut, merge);
890         ast_test_validate(test, 0 == uut_res);
891         ast_test_validate(test, ast_json_equal(expected, uut));
892         /* merge object is untouched */
893         ast_test_validate(test, 3 == ast_json_object_size(merge));
894
895         return AST_TEST_PASS;
896 }
897
898 AST_TEST_DEFINE(json_test_object_merge_existing)
899 {
900         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
901         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
902         RAII_VAR(struct ast_json *, merge, NULL, ast_json_unref);
903         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
904         int uut_res;
905
906         switch (cmd) {
907         case TEST_INIT:
908                 info->name = "object_alloc";
909                 info->category = "/main/json/";
910                 info->summary = "Testing merging JSON objects, updating only existing fields.";
911                 info->description = "Test JSON abstraction library.";
912                 return AST_TEST_NOT_RUN;
913         case TEST_EXECUTE:
914                 break;
915         }
916
917         /* object merging - existing */
918         uut = ast_json_object_create();
919         ast_json_object_set(uut, "one", ast_json_integer_create(1));
920         ast_json_object_set(uut, "two", ast_json_integer_create(2));
921         ast_json_object_set(uut, "three", ast_json_integer_create(3));
922
923         merge = ast_json_object_create();
924         ast_json_object_set(merge, "three", ast_json_integer_create(-3));
925         ast_json_object_set(merge, "four", ast_json_integer_create(-4));
926         ast_json_object_set(merge, "five", ast_json_integer_create(-5));
927
928         expected = ast_json_object_create();
929         ast_json_object_set(expected, "one", ast_json_integer_create(1));
930         ast_json_object_set(expected, "two", ast_json_integer_create(2));
931         ast_json_object_set(expected, "three", ast_json_integer_create(-3));
932
933         uut_res = ast_json_object_update_existing(uut, merge);
934         ast_test_validate(test, 0 == uut_res);
935         ast_test_validate(test, ast_json_equal(expected, uut));
936         /* merge object is untouched */
937         ast_test_validate(test, 3 == ast_json_object_size(merge));
938
939         return AST_TEST_PASS;
940 }
941
942 AST_TEST_DEFINE(json_test_object_merge_missing)
943 {
944         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
945         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
946         RAII_VAR(struct ast_json *, merge, NULL, ast_json_unref);
947         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
948         int uut_res;
949
950         switch (cmd) {
951         case TEST_INIT:
952                 info->name = "object_merge_missing";
953                 info->category = "/main/json/";
954                 info->summary = "Testing merging JSON objects, adding only missing fields.";
955                 info->description = "Test JSON abstraction library.";
956                 return AST_TEST_NOT_RUN;
957         case TEST_EXECUTE:
958                 break;
959         }
960
961         /* object merging - missing */
962         uut = ast_json_object_create();
963         ast_json_object_set(uut, "one", ast_json_integer_create(1));
964         ast_json_object_set(uut, "two", ast_json_integer_create(2));
965         ast_json_object_set(uut, "three", ast_json_integer_create(3));
966
967         merge = ast_json_object_create();
968         ast_json_object_set(merge, "three", ast_json_integer_create(-3));
969         ast_json_object_set(merge, "four", ast_json_integer_create(-4));
970         ast_json_object_set(merge, "five", ast_json_integer_create(-5));
971
972         expected = ast_json_object_create();
973         ast_json_object_set(expected, "one", ast_json_integer_create(1));
974         ast_json_object_set(expected, "two", ast_json_integer_create(2));
975         ast_json_object_set(expected, "three", ast_json_integer_create(3));
976         ast_json_object_set(expected, "four", ast_json_integer_create(-4));
977         ast_json_object_set(expected, "five", ast_json_integer_create(-5));
978
979         uut_res = ast_json_object_update_missing(uut, merge);
980         ast_test_validate(test, 0 == uut_res);
981         ast_test_validate(test, ast_json_equal(expected, uut));
982         /* merge object is untouched */
983         ast_test_validate(test, 3 == ast_json_object_size(merge));
984
985         return AST_TEST_PASS;
986 }
987
988 AST_TEST_DEFINE(json_test_object_null)
989 {
990         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
991         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
992
993         switch (cmd) {
994         case TEST_INIT:
995                 info->name = "object_null";
996                 info->category = "/main/json/";
997                 info->summary = "Testing JSON object NULL behavior.";
998                 info->description = "Test JSON abstraction library.";
999                 return AST_TEST_NOT_RUN;
1000         case TEST_EXECUTE:
1001                 break;
1002         }
1003
1004         /* Object NULL testing */
1005         ast_test_validate(test, 0 == ast_json_object_size(NULL));
1006         ast_test_validate(test, NULL == ast_json_object_get(NULL, "not null"));
1007         ast_test_validate(test, -1 == ast_json_object_set(NULL, "not null", ast_json_null()));
1008         ast_test_validate(test, -1 == ast_json_object_del(NULL, "not null"));
1009         ast_test_validate(test, -1 == ast_json_object_clear(NULL));
1010         uut = ast_json_object_create();
1011         ast_test_validate(test, -1 == ast_json_object_update(NULL, uut));
1012         ast_test_validate(test, -1 == ast_json_object_update(uut, NULL));
1013         ast_test_validate(test, -1 == ast_json_object_update(NULL, NULL));
1014         ast_test_validate(test, -1 == ast_json_object_update_existing(NULL, uut));
1015         ast_test_validate(test, -1 == ast_json_object_update_existing(uut, NULL));
1016         ast_test_validate(test, -1 == ast_json_object_update_existing(NULL, NULL));
1017         ast_test_validate(test, -1 == ast_json_object_update_missing(NULL, uut));
1018         ast_test_validate(test, -1 == ast_json_object_update_missing(uut, NULL));
1019         ast_test_validate(test, -1 == ast_json_object_update_missing(NULL, NULL));
1020
1021         return AST_TEST_PASS;
1022 }
1023
1024 AST_TEST_DEFINE(json_test_object_iter)
1025 {
1026         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1027         struct ast_json_iter *iter;
1028         int count;
1029         int uut_res;
1030         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1031
1032         switch (cmd) {
1033         case TEST_INIT:
1034                 info->name = "object_iter";
1035                 info->category = "/main/json/";
1036                 info->summary = "Testing iterating through JSON objects.";
1037                 info->description = "Test JSON abstraction library.";
1038                 return AST_TEST_NOT_RUN;
1039         case TEST_EXECUTE:
1040                 break;
1041         }
1042
1043         /* Object iterator testing */
1044         uut = ast_json_pack("{s: i, s: i, s: i, s: i, s: i}", "one", 1, "two", 2, "three", 3, "four", 4, "five", 5);
1045
1046         /* Iterate through the object; be aware that order isn't specified */
1047         iter = ast_json_object_iter(uut);
1048         ast_test_validate(test, NULL != iter);
1049         count = 0;
1050         while (NULL != iter) {
1051                 if (0 == strcmp("one", ast_json_object_iter_key(iter))) {
1052                         ast_test_validate(test, 1 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1053                 } else if (0 == strcmp("two", ast_json_object_iter_key(iter))) {
1054                         ast_test_validate(test, 2 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1055                 } else if (0 == strcmp("three", ast_json_object_iter_key(iter))) {
1056                         ast_test_validate(test, 3 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1057                 } else if (0 == strcmp("four", ast_json_object_iter_key(iter))) {
1058                         ast_test_validate(test, 4 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1059                 } else if (0 == strcmp("five", ast_json_object_iter_key(iter))) {
1060                         ast_test_validate(test, 5 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1061                 } else {
1062                         /* Unexpected key */
1063                         ast_test_validate(test, 0);
1064                 }
1065                 iter = ast_json_object_iter_next(uut, iter);
1066                 ++count;
1067         }
1068         ast_test_validate(test, 5 == count);
1069
1070         /* iterator non-existing key */
1071         iter = ast_json_object_iter_at(uut, "dne");
1072         ast_test_validate(test, NULL == iter);
1073
1074         /* iterator specific key */
1075         iter = ast_json_object_iter_at(uut, "three");
1076         ast_test_validate(test, NULL != iter);
1077         ast_test_validate(test, 3 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1078
1079         /* set via iter */
1080         iter = ast_json_object_iter_at(uut, "three");
1081         uut_res = ast_json_object_iter_set(uut, iter, ast_json_integer_create(-3));
1082         ast_test_validate(test, 0 == uut_res);
1083         ast_test_validate(test, -3 == ast_json_integer_get(ast_json_object_get(uut, "three")));
1084
1085         return AST_TEST_PASS;
1086 }
1087
1088 AST_TEST_DEFINE(json_test_object_iter_null)
1089 {
1090         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1091         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1092
1093         switch (cmd) {
1094         case TEST_INIT:
1095                 info->name = "object_iter_null";
1096                 info->category = "/main/json/";
1097                 info->summary = "Testing JSON object iterator NULL testings.";
1098                 info->description = "Test JSON abstraction library.";
1099                 return AST_TEST_NOT_RUN;
1100         case TEST_EXECUTE:
1101                 break;
1102         }
1103
1104         /* iterator NULL tests */
1105         uut = ast_json_object_create();
1106         ast_test_validate(test, NULL == ast_json_object_iter(NULL));
1107         ast_test_validate(test, NULL == ast_json_object_iter_at(NULL, "not null"));
1108         ast_test_validate(test, NULL == ast_json_object_iter_next(NULL, NULL));
1109         ast_test_validate(test, NULL == ast_json_object_iter_next(uut, NULL));
1110         ast_test_validate(test, NULL == ast_json_object_iter_key(NULL));
1111         ast_test_validate(test, NULL == ast_json_object_iter_value(NULL));
1112         ast_test_validate(test, -1 == ast_json_object_iter_set(NULL, NULL, ast_json_null()));
1113         ast_test_validate(test, -1 == ast_json_object_iter_set(uut, NULL, ast_json_null()));
1114
1115         return AST_TEST_PASS;
1116 }
1117
1118 AST_TEST_DEFINE(json_test_dump_load_string)
1119 {
1120         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1121         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1122         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1123         RAII_VAR(char *, str, NULL, json_debug_free);
1124
1125         switch (cmd) {
1126         case TEST_INIT:
1127                 info->name = "dump_load_string";
1128                 info->category = "/main/json/";
1129                 info->summary = "Testing dumping strings from JSON.";
1130                 info->description = "Test JSON abstraction library.";
1131                 return AST_TEST_NOT_RUN;
1132         case TEST_EXECUTE:
1133                 break;
1134         }
1135         expected = ast_json_pack("{ s: i }", "one", 1);
1136         str = ast_json_dump_string(expected);
1137         ast_test_validate(test, NULL != str);
1138         uut = ast_json_load_string(str, NULL);
1139         ast_test_validate(test, NULL != uut);
1140         ast_test_validate(test, ast_json_equal(expected, uut));
1141
1142         /* dump_string NULL */
1143         ast_test_validate(test, NULL == ast_json_dump_string(NULL));
1144
1145         return AST_TEST_PASS;
1146 }
1147
1148 AST_TEST_DEFINE(json_test_dump_load_str)
1149 {
1150         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1151         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1152         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1153         RAII_VAR(struct ast_str *, astr, NULL, ast_free);
1154         int uut_res;
1155
1156         switch (cmd) {
1157         case TEST_INIT:
1158                 info->name = "dump_load_str";
1159                 info->category = "/main/json/";
1160                 info->summary = "Testing dumping ast_str from JSON.";
1161                 info->description = "Test JSON abstraction library.";
1162                 return AST_TEST_NOT_RUN;
1163         case TEST_EXECUTE:
1164                 break;
1165         }
1166
1167         /* dump/load ast_str */
1168         expected = ast_json_pack("{ s: i }", "one", 1);
1169         astr = ast_str_create(1); /* should expand to hold output */
1170         uut_res = ast_json_dump_str(expected, &astr);
1171         ast_test_validate(test, 0 == uut_res);
1172         uut = ast_json_load_str(astr, NULL);
1173         ast_test_validate(test, NULL != uut);
1174         ast_test_validate(test, ast_json_equal(expected, uut));
1175
1176         return AST_TEST_PASS;
1177 }
1178
1179 AST_TEST_DEFINE(json_test_dump_str_fail)
1180 {
1181         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1182         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1183         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1184         struct ast_str *astr;
1185         int uut_res;
1186
1187         switch (cmd) {
1188         case TEST_INIT:
1189                 info->name = "dump_str_fail";
1190                 info->category = "/main/json/";
1191                 info->summary = "Testing dumping to ast_str when it can't grow.";
1192                 info->description = "Test JSON abstraction library.";
1193                 return AST_TEST_NOT_RUN;
1194         case TEST_EXECUTE:
1195                 break;
1196         }
1197
1198         /* dump ast_str growth failure */
1199         expected = ast_json_pack("{ s: i }", "one", 1);
1200         astr = ast_str_alloca(1); /* cannot grow */
1201         uut_res = ast_json_dump_str(expected, &astr);
1202         ast_test_validate(test, 0 != uut_res);
1203
1204         return AST_TEST_PASS;
1205 }
1206
1207 AST_TEST_DEFINE(json_test_load_buffer)
1208 {
1209         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1210         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1211         const char *str;
1212
1213         switch (cmd) {
1214         case TEST_INIT:
1215                 info->name = "load_buffer";
1216                 info->category = "/main/json/";
1217                 info->summary = "Testing loading JSON from buffer.";
1218                 info->description = "Test JSON abstraction library.";
1219                 return AST_TEST_NOT_RUN;
1220         case TEST_EXECUTE:
1221                 break;
1222         }
1223
1224         /* load buffer */
1225         str = "{ \"one\": 1 } trailing garbage";
1226         uut = ast_json_load_string(str, NULL);
1227         ast_test_validate(test, NULL == uut);
1228         uut = ast_json_load_buf(str, strlen("{ \"one\": 1 }"), NULL);
1229         ast_test_validate(test, NULL != uut);
1230
1231         return AST_TEST_PASS;
1232 }
1233
1234 /*! \brief \a fclose isn't NULL safe. */
1235 static int safe_fclose(FILE *f)
1236 {
1237         if (f) {
1238                 return fclose(f);
1239         }
1240         return 0;
1241 }
1242
1243 AST_TEST_DEFINE(json_test_dump_load_file)
1244 {
1245         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1246         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1247         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1248         RAII_VAR(char *, filename, NULL, free);
1249         RAII_VAR(FILE *, file, NULL, safe_fclose);
1250         int uut_res;
1251
1252         switch (cmd) {
1253         case TEST_INIT:
1254                 info->name = "dump_load_file";
1255                 info->category = "/main/json/";
1256                 info->summary = "Testing dumping/loading JSON to/from file by FILE *.";
1257                 info->description = "Test JSON abstraction library.";
1258                 return AST_TEST_NOT_RUN;
1259         case TEST_EXECUTE:
1260                 break;
1261         }
1262
1263         /* dump/load file */
1264         expected = ast_json_pack("{ s: i }", "one", 1);
1265         filename = tempnam(NULL, "ast-json");
1266         file = fopen(filename, "w");
1267         uut_res = ast_json_dump_file(expected, file);
1268         ast_test_validate(test, 0 == uut_res);
1269         fclose(file);
1270         file = fopen(filename, "r");
1271         uut = ast_json_load_file(file, NULL);
1272         ast_test_validate(test, ast_json_equal(expected, uut));
1273
1274         return AST_TEST_PASS;
1275 }
1276
1277 AST_TEST_DEFINE(json_test_dump_load_new_file)
1278 {
1279         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1280         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1281         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1282         RAII_VAR(char *, filename, NULL, free);
1283         int uut_res;
1284
1285         switch (cmd) {
1286         case TEST_INIT:
1287                 info->name = "dump_load_new_file";
1288                 info->category = "/main/json/";
1289                 info->summary = "Testing dumping/load JSON to/from file by filename.";
1290                 info->description = "Test JSON abstraction library.";
1291                 return AST_TEST_NOT_RUN;
1292         case TEST_EXECUTE:
1293                 break;
1294         }
1295
1296         /* dump/load filename */
1297         expected = ast_json_pack("{ s: i }", "one", 1);
1298         filename = tempnam(NULL, "ast-json");
1299         uut_res = ast_json_dump_new_file(expected, filename);
1300         ast_test_validate(test, 0 == uut_res);
1301         uut = ast_json_load_new_file(filename, NULL);
1302         ast_test_validate(test, ast_json_equal(expected, uut));
1303
1304         return AST_TEST_PASS;
1305 }
1306
1307 AST_TEST_DEFINE(json_test_dump_load_null)
1308 {
1309         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1310         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1311         RAII_VAR(char *, filename, NULL, free);
1312         RAII_VAR(FILE *, file, NULL, safe_fclose);
1313
1314         switch (cmd) {
1315         case TEST_INIT:
1316                 info->name = "dump_load_null";
1317                 info->category = "/main/json/";
1318                 info->summary = "Testing NULL handling of dump/load functions.";
1319                 info->description = "Test JSON abstraction library.";
1320                 return AST_TEST_NOT_RUN;
1321         case TEST_EXECUTE:
1322                 break;
1323         }
1324
1325         /* dump/load NULL tests */
1326         uut = ast_json_load_string("{ \"one\": 1 }", NULL);
1327         ast_test_validate(test, NULL != uut);
1328         filename = tempnam(NULL, "ast-json");
1329         file = fopen(filename, "w");
1330         ast_test_validate(test, NULL == ast_json_dump_string(NULL));
1331         ast_test_validate(test, -1 == ast_json_dump_file(NULL, file));
1332         ast_test_validate(test, -1 == ast_json_dump_file(uut, NULL));
1333         ast_test_validate(test, -1 == ast_json_dump_file(NULL, NULL));
1334         ast_test_validate(test, -1 == ast_json_dump_new_file(uut, NULL));
1335         ast_test_validate(test, -1 == ast_json_dump_new_file(NULL, filename));
1336         ast_test_validate(test, -1 == ast_json_dump_new_file(NULL, NULL));
1337         ast_test_validate(test, NULL == ast_json_load_string(NULL, NULL));
1338         ast_test_validate(test, NULL == ast_json_load_buf(NULL, 0, NULL));
1339         ast_test_validate(test, NULL == ast_json_load_file(NULL, NULL));
1340         ast_test_validate(test, NULL == ast_json_load_new_file(NULL, NULL));
1341
1342         return AST_TEST_PASS;
1343 }
1344
1345 AST_TEST_DEFINE(json_test_parse_errors)
1346 {
1347         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1348         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1349
1350         switch (cmd) {
1351         case TEST_INIT:
1352                 info->name = "parse_errors";
1353                 info->category = "/main/json/";
1354                 info->summary = "Testing various parse errors.";
1355                 info->description = "Test JSON abstraction library.";
1356                 return AST_TEST_NOT_RUN;
1357         case TEST_EXECUTE:
1358                 break;
1359         }
1360
1361         /* parse errors */
1362         ast_test_validate(test, NULL == ast_json_load_string("'singleton'", NULL));
1363         ast_test_validate(test, NULL == ast_json_load_string("{ no value }", NULL));
1364         ast_test_validate(test, NULL == ast_json_load_string("{ 'no': 'curly' ", NULL));
1365         ast_test_validate(test, NULL == ast_json_load_string("[ 'no', 'square'", NULL));
1366         ast_test_validate(test, NULL == ast_json_load_string("{ 1: 'int key' }", NULL));
1367         ast_test_validate(test, NULL == ast_json_load_string("", NULL));
1368         ast_test_validate(test, NULL == ast_json_load_string("{ 'missing' 'colon' }", NULL));
1369         ast_test_validate(test, NULL == ast_json_load_string("[ 'missing' 'comma' ]", NULL));
1370
1371         return AST_TEST_PASS;
1372 }
1373
1374 AST_TEST_DEFINE(json_test_pack)
1375 {
1376         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1377         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1378         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1379
1380         switch (cmd) {
1381         case TEST_INIT:
1382                 info->name = "pack";
1383                 info->category = "/main/json/";
1384                 info->summary = "Testing json_pack function.";
1385                 info->description = "Test JSON abstraction library.";
1386                 return AST_TEST_NOT_RUN;
1387         case TEST_EXECUTE:
1388                 break;
1389         }
1390
1391         /* pack test */
1392         expected = ast_json_array_create();
1393         ast_json_array_append(expected, ast_json_array_create());
1394         ast_json_array_append(expected, ast_json_object_create());
1395         ast_json_array_append(ast_json_array_get(expected, 0), ast_json_integer_create(1));
1396         ast_json_array_append(ast_json_array_get(expected, 0), ast_json_integer_create(2));
1397         ast_json_object_set(ast_json_array_get(expected, 1), "cool", ast_json_true());
1398         uut = ast_json_pack("[[i,i],{s:b}]", 1, 2, "cool", 1);
1399         ast_test_validate(test, NULL != uut);
1400         ast_test_validate(test, ast_json_equal(expected, uut));
1401
1402         return AST_TEST_PASS;
1403 }
1404
1405 AST_TEST_DEFINE(json_test_pack_ownership)
1406 {
1407         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1408         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1409
1410         switch (cmd) {
1411         case TEST_INIT:
1412                 info->name = "pack_ownership";
1413                 info->category = "/main/json/";
1414                 info->summary = "Testing json_pack failure conditions.";
1415                 info->description = "Test JSON abstraction library.";
1416                 return AST_TEST_NOT_RUN;
1417         case TEST_EXECUTE:
1418                 break;
1419         }
1420
1421         uut = ast_json_pack("[o]", ast_json_string_create("Am I freed?"));
1422
1423         return AST_TEST_PASS;
1424 }
1425
1426 AST_TEST_DEFINE(json_test_pack_errors)
1427 {
1428         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1429         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1430
1431         switch (cmd) {
1432         case TEST_INIT:
1433                 info->name = "object_alloc";
1434                 info->category = "/main/json/";
1435                 info->summary = "Testing json_pack failure conditions.";
1436                 info->description = "Test JSON abstraction library.";
1437                 return AST_TEST_NOT_RUN;
1438         case TEST_EXECUTE:
1439                 break;
1440         }
1441
1442         /* pack errors */
1443         ast_test_validate(test, NULL == ast_json_pack(NULL));
1444         ast_test_validate(test, NULL == ast_json_pack("{s:i", "no curly", 911));
1445         ast_test_validate(test, NULL == ast_json_pack("[s, s", "no", "square"));
1446
1447         return AST_TEST_PASS;
1448 }
1449
1450 AST_TEST_DEFINE(json_test_copy)
1451 {
1452         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1453         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1454         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1455
1456         switch (cmd) {
1457         case TEST_INIT:
1458                 info->name = "copy";
1459                 info->category = "/main/json/";
1460                 info->summary = "Testing copying JSON.";
1461                 info->description = "Test JSON abstraction library.";
1462                 return AST_TEST_NOT_RUN;
1463         case TEST_EXECUTE:
1464                 break;
1465         }
1466
1467         /* copy test */
1468         expected = ast_json_pack("{s: {s: i}}", "outer", "inner", 8675309);
1469         uut = ast_json_copy(expected);
1470         ast_test_validate(test, NULL != uut);
1471         ast_test_validate(test, ast_json_equal(expected, uut));
1472         ast_test_validate(test, ast_json_object_get(expected, "outer") == ast_json_object_get(uut, "outer"));
1473
1474         return AST_TEST_PASS;
1475 }
1476
1477 AST_TEST_DEFINE(json_test_deep_copy)
1478 {
1479         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1480         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1481         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1482
1483         switch (cmd) {
1484         case TEST_INIT:
1485                 info->name = "deep_copy";
1486                 info->category = "/main/json/";
1487                 info->summary = "Testing deep copying of JSON.";
1488                 info->description = "Test JSON abstraction library.";
1489                 return AST_TEST_NOT_RUN;
1490         case TEST_EXECUTE:
1491                 break;
1492         }
1493
1494         /* deep copy test */
1495         expected = ast_json_pack("{s: {s: i}}", "outer", "inner", 8675309);
1496         uut = ast_json_deep_copy(expected);
1497         ast_test_validate(test, NULL != uut);
1498         ast_test_validate(test, ast_json_equal(expected, uut));
1499         ast_test_validate(test, ast_json_object_get(expected, "outer") != ast_json_object_get(uut, "outer"));
1500         /* Changing the inner value of one should not change the other */
1501         ast_json_integer_set(ast_json_object_get(ast_json_object_get(uut, "outer"), "inner"), 411);
1502         ast_test_validate(test, !ast_json_equal(expected, uut));
1503
1504         return AST_TEST_PASS;
1505 }
1506
1507 AST_TEST_DEFINE(json_test_copy_null)
1508 {
1509         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1510         switch (cmd) {
1511         case TEST_INIT:
1512                 info->name = "copy_null";
1513                 info->category = "/main/json/";
1514                 info->summary = "Testing NULL handling of copy functions.";
1515                 info->description = "Test JSON abstraction library.";
1516                 return AST_TEST_NOT_RUN;
1517         case TEST_EXECUTE:
1518                 break;
1519         }
1520
1521         /* copy NULL */
1522         ast_test_validate(test, NULL == ast_json_copy(NULL));
1523         ast_test_validate(test, NULL == ast_json_deep_copy(NULL));
1524
1525         return AST_TEST_PASS;
1526 }
1527
1528 AST_TEST_DEFINE(json_test_circular_object)
1529 {
1530         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1531         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1532         int uut_res;
1533
1534         switch (cmd) {
1535         case TEST_INIT:
1536                 info->name = "circular_object";
1537                 info->category = "/main/json/";
1538                 info->summary = "Object cannot be added to itself.";
1539                 info->description = "Test JSON abstraction library.";
1540                 return AST_TEST_NOT_RUN;
1541         case TEST_EXECUTE:
1542                 break;
1543         }
1544
1545         /* circular reference testing */
1546         /* Cannot add self */
1547         uut = ast_json_object_create();
1548         uut_res = ast_json_object_set(uut, "myself", ast_json_ref(uut));
1549         ast_test_validate(test, -1 == uut_res);
1550         ast_test_validate(test, 0 == ast_json_object_size(uut));
1551
1552         return AST_TEST_PASS;
1553 }
1554
1555 AST_TEST_DEFINE(json_test_circular_array)
1556 {
1557         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1558         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1559         int uut_res;
1560
1561         switch (cmd) {
1562         case TEST_INIT:
1563                 info->name = "circular_array";
1564                 info->category = "/main/json/";
1565                 info->summary = "Array cannot be added to itself.";
1566                 info->description = "Test JSON abstraction library.";
1567                 return AST_TEST_NOT_RUN;
1568         case TEST_EXECUTE:
1569                 break;
1570         }
1571
1572         uut = ast_json_array_create();
1573         ast_test_validate(test, 0 == ast_json_array_size(uut));
1574         uut_res = ast_json_array_append(uut, ast_json_ref(uut));
1575         ast_test_validate(test, -1 == uut_res);
1576         ast_test_validate(test, 0 == ast_json_array_size(uut));
1577
1578         return AST_TEST_PASS;
1579 }
1580
1581 AST_TEST_DEFINE(json_test_clever_circle)
1582 {
1583         RAII_VAR(void *, alloc_debug, json_test_init(test), json_test_finish);
1584         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1585         RAII_VAR(struct ast_json *, inner_child, NULL, ast_json_unref);
1586         RAII_VAR(char *, str, NULL, json_debug_free);
1587         int uut_res;
1588
1589         switch (cmd) {
1590         case TEST_INIT:
1591                 info->name = "clever_circle";
1592                 info->category = "/main/json/";
1593                 info->summary = "JSON with circular references cannot be encoded.";
1594                 info->description = "Test JSON abstraction library.";
1595                 return AST_TEST_NOT_RUN;
1596         case TEST_EXECUTE:
1597                 break;
1598         }
1599
1600         /* can add to self if you're clever enough, but it should not encode */
1601         uut = ast_json_object_create();
1602         inner_child = ast_json_object_create();
1603         uut_res = ast_json_object_set(uut, "inner_child", ast_json_ref(inner_child));   /* incref to keep a reference */
1604         ast_test_validate(test, 0 == uut_res);
1605         uut_res = ast_json_object_set(inner_child, "parent", ast_json_ref(uut));   /* incref to keep a reference */
1606         ast_test_validate(test, 0 == uut_res);
1607         str = ast_json_dump_string(uut);
1608         ast_test_validate(test, NULL == str);
1609         /* Circular refs screw up reference counting, so break the cycle */
1610         ast_json_object_clear(inner_child);
1611
1612         return AST_TEST_PASS;
1613 }
1614
1615 static int unload_module(void)
1616 {
1617         AST_TEST_UNREGISTER(json_test_false);
1618         AST_TEST_UNREGISTER(json_test_true);
1619         AST_TEST_UNREGISTER(json_test_bool0);
1620         AST_TEST_UNREGISTER(json_test_bool1);
1621         AST_TEST_UNREGISTER(json_test_null);
1622         AST_TEST_UNREGISTER(json_test_null_val);
1623         AST_TEST_UNREGISTER(json_test_string);
1624         AST_TEST_UNREGISTER(json_test_string_null);
1625         AST_TEST_UNREGISTER(json_test_stringf);
1626         AST_TEST_UNREGISTER(json_test_int);
1627         AST_TEST_UNREGISTER(json_test_non_int);
1628         AST_TEST_UNREGISTER(json_test_array_create);
1629         AST_TEST_UNREGISTER(json_test_array_append);
1630         AST_TEST_UNREGISTER(json_test_array_inset);
1631         AST_TEST_UNREGISTER(json_test_array_set);
1632         AST_TEST_UNREGISTER(json_test_array_remove);
1633         AST_TEST_UNREGISTER(json_test_array_clear);
1634         AST_TEST_UNREGISTER(json_test_array_extend);
1635         AST_TEST_UNREGISTER(json_test_array_null);
1636         AST_TEST_UNREGISTER(json_test_object_alloc);
1637         AST_TEST_UNREGISTER(json_test_object_set);
1638         AST_TEST_UNREGISTER(json_test_object_set_overwrite);
1639         AST_TEST_UNREGISTER(json_test_object_get);
1640         AST_TEST_UNREGISTER(json_test_object_del);
1641         AST_TEST_UNREGISTER(json_test_object_clear);
1642         AST_TEST_UNREGISTER(json_test_object_merge_all);
1643         AST_TEST_UNREGISTER(json_test_object_merge_existing);
1644         AST_TEST_UNREGISTER(json_test_object_merge_missing);
1645         AST_TEST_UNREGISTER(json_test_object_null);
1646         AST_TEST_UNREGISTER(json_test_object_iter);
1647         AST_TEST_UNREGISTER(json_test_object_iter_null);
1648         AST_TEST_UNREGISTER(json_test_dump_load_string);
1649         AST_TEST_UNREGISTER(json_test_dump_load_str);
1650         AST_TEST_UNREGISTER(json_test_dump_str_fail);
1651         AST_TEST_UNREGISTER(json_test_load_buffer);
1652         AST_TEST_UNREGISTER(json_test_dump_load_file);
1653         AST_TEST_UNREGISTER(json_test_dump_load_new_file);
1654         AST_TEST_UNREGISTER(json_test_dump_load_null);
1655         AST_TEST_UNREGISTER(json_test_parse_errors);
1656         AST_TEST_UNREGISTER(json_test_pack);
1657         AST_TEST_UNREGISTER(json_test_pack_ownership);
1658         AST_TEST_UNREGISTER(json_test_pack_errors);
1659         AST_TEST_UNREGISTER(json_test_copy);
1660         AST_TEST_UNREGISTER(json_test_deep_copy);
1661         AST_TEST_UNREGISTER(json_test_copy_null);
1662         AST_TEST_UNREGISTER(json_test_circular_object);
1663         AST_TEST_UNREGISTER(json_test_circular_array);
1664         AST_TEST_UNREGISTER(json_test_clever_circle);
1665         return 0;
1666 }
1667
1668 static int load_module(void)
1669 {
1670         AST_TEST_REGISTER(json_test_false);
1671         AST_TEST_REGISTER(json_test_true);
1672         AST_TEST_REGISTER(json_test_bool0);
1673         AST_TEST_REGISTER(json_test_bool1);
1674         AST_TEST_REGISTER(json_test_null);
1675         AST_TEST_REGISTER(json_test_null_val);
1676         AST_TEST_REGISTER(json_test_string);
1677         AST_TEST_REGISTER(json_test_string_null);
1678         AST_TEST_REGISTER(json_test_stringf);
1679         AST_TEST_REGISTER(json_test_int);
1680         AST_TEST_REGISTER(json_test_non_int);
1681         AST_TEST_REGISTER(json_test_array_create);
1682         AST_TEST_REGISTER(json_test_array_append);
1683         AST_TEST_REGISTER(json_test_array_inset);
1684         AST_TEST_REGISTER(json_test_array_set);
1685         AST_TEST_REGISTER(json_test_array_remove);
1686         AST_TEST_REGISTER(json_test_array_clear);
1687         AST_TEST_REGISTER(json_test_array_extend);
1688         AST_TEST_REGISTER(json_test_array_null);
1689         AST_TEST_REGISTER(json_test_object_alloc);
1690         AST_TEST_REGISTER(json_test_object_set);
1691         AST_TEST_REGISTER(json_test_object_set_overwrite);
1692         AST_TEST_REGISTER(json_test_object_get);
1693         AST_TEST_REGISTER(json_test_object_del);
1694         AST_TEST_REGISTER(json_test_object_clear);
1695         AST_TEST_REGISTER(json_test_object_merge_all);
1696         AST_TEST_REGISTER(json_test_object_merge_existing);
1697         AST_TEST_REGISTER(json_test_object_merge_missing);
1698         AST_TEST_REGISTER(json_test_object_null);
1699         AST_TEST_REGISTER(json_test_object_iter);
1700         AST_TEST_REGISTER(json_test_object_iter_null);
1701         AST_TEST_REGISTER(json_test_dump_load_string);
1702         AST_TEST_REGISTER(json_test_dump_load_str);
1703         AST_TEST_REGISTER(json_test_dump_str_fail);
1704         AST_TEST_REGISTER(json_test_load_buffer);
1705         AST_TEST_REGISTER(json_test_dump_load_file);
1706         AST_TEST_REGISTER(json_test_dump_load_new_file);
1707         AST_TEST_REGISTER(json_test_dump_load_null);
1708         AST_TEST_REGISTER(json_test_parse_errors);
1709         AST_TEST_REGISTER(json_test_pack);
1710         AST_TEST_REGISTER(json_test_pack_ownership);
1711         AST_TEST_REGISTER(json_test_pack_errors);
1712         AST_TEST_REGISTER(json_test_copy);
1713         AST_TEST_REGISTER(json_test_deep_copy);
1714         AST_TEST_REGISTER(json_test_copy_null);
1715         AST_TEST_REGISTER(json_test_circular_object);
1716         AST_TEST_REGISTER(json_test_circular_array);
1717         AST_TEST_REGISTER(json_test_clever_circle);
1718         return AST_MODULE_LOAD_SUCCESS;
1719 }
1720
1721 AST_MODULE_INFO(ASTERISK_GPL_KEY, 0, "JSON testing",
1722                 .load = load_module,
1723                 .unload = unload_module,
1724                 .nonoptreq = "res_json");