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