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