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