• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***
2   This file is part of PulseAudio.
3 
4   Copyright 2016 Arun Raghavan <mail@arunraghavan.net>
5 
6   PulseAudio is free software; you can redistribute it and/or modify
7   it under the terms of the GNU Lesser General Public License as published
8   by the Free Software Foundation; either version 2.1 of the License,
9   or (at your option) any later version.
10 
11   PulseAudio is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   General Public License for more details.
15 
16   You should have received a copy of the GNU Lesser General Public License
17   along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
18 ***/
19 
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 
24 #include <check.h>
25 
26 #include <pulse/xmalloc.h>
27 #include <pulsecore/core-util.h>
28 #include <pulsecore/json.h>
29 
START_TEST(string_test)30 START_TEST (string_test) {
31     pa_json_object *o;
32     unsigned int i;
33     const char *strings_parse[] = {
34         "\"\"", "\"test\"", "\"test123\"", "\"123\"", "\"newline\\n\"", "\"  spaces \"",
35         "   \"lots of spaces\"     ", "\"esc\\nape\"", "\"escape a \\\" quote\"",
36     };
37     const char *strings_compare[] = {
38         "", "test", "test123", "123", "newline\n", "  spaces ",
39         "lots of spaces", "esc\nape", "escape a \" quote",
40     };
41 
42     for (i = 0; i < PA_ELEMENTSOF(strings_parse); i++) {
43         o = pa_json_parse(strings_parse[i]);
44 
45         fail_unless(o != NULL);
46         fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_STRING);
47         fail_unless(pa_streq(pa_json_object_get_string(o), strings_compare[i]));
48 
49         pa_json_object_free(o);
50     }
51 }
52 END_TEST
53 
START_TEST(encoder_string_test)54 START_TEST (encoder_string_test) {
55     const char *test_strings[] = {
56         "", "test", "test123", "123", "newline\n", "  spaces ",
57         "lots of spaces", "esc\nape", "escape a \" quote",
58     };
59 
60     pa_json_object *o;
61     unsigned int i;
62     pa_json_encoder *encoder;
63     const pa_json_object *v;
64     char *received;
65 
66     encoder = pa_json_encoder_new();
67 
68     pa_json_encoder_begin_element_array(encoder);
69 
70     for (i = 0; i < PA_ELEMENTSOF(test_strings); i++) {
71         pa_json_encoder_add_element_string(encoder, test_strings[i]);
72     }
73 
74     pa_json_encoder_end_array(encoder);
75 
76     received = pa_json_encoder_to_string_free(encoder);
77     o = pa_json_parse(received);
78     pa_xfree(received);
79 
80     fail_unless(o != NULL);
81     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
82     fail_unless(pa_json_object_get_array_length(o) == PA_ELEMENTSOF(test_strings));
83 
84     for (i = 0; i < PA_ELEMENTSOF(test_strings); i++) {
85         v = pa_json_object_get_array_member(o, i);
86 
87         fail_unless(v != NULL);
88         fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_STRING);
89         fail_unless(pa_streq(pa_json_object_get_string(v), test_strings[i]));
90     }
91 
92     pa_json_object_free(o);
93 }
94 END_TEST
95 
START_TEST(int_test)96 START_TEST(int_test) {
97     pa_json_object *o;
98     unsigned int i;
99     const char *ints_parse[] = { "1", "-1", "1234", "0" };
100     const int64_t ints_compare[] = { 1, -1, 1234, 0 };
101     char *uint64_max_str;
102 
103     for (i = 0; i < PA_ELEMENTSOF(ints_parse); i++) {
104         o = pa_json_parse(ints_parse[i]);
105 
106         fail_unless(o != NULL);
107         fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_INT);
108         fail_unless(pa_json_object_get_int(o) == ints_compare[i]);
109 
110         pa_json_object_free(o);
111     }
112 
113     /* test that parser would fail on integer overflow */
114     uint64_max_str = pa_sprintf_malloc("%"PRIu64, UINT64_MAX);
115     o = pa_json_parse(uint64_max_str);
116     fail_unless(o == NULL);
117     pa_xfree(uint64_max_str);
118 }
119 END_TEST
120 
START_TEST(encoder_int_test)121 START_TEST(encoder_int_test) {
122     const int64_t test_ints[] = { 1, -1, 1234, 0, LONG_MIN, LONG_MAX };
123 
124     pa_json_object *o;
125     unsigned int i;
126     pa_json_encoder *encoder;
127     const pa_json_object *v;
128     char *received;
129 
130     encoder = pa_json_encoder_new();
131 
132     pa_json_encoder_begin_element_array(encoder);
133 
134     for (i = 0; i < PA_ELEMENTSOF(test_ints); i++) {
135         pa_json_encoder_add_element_int(encoder, test_ints[i]);
136     }
137 
138     pa_json_encoder_end_array(encoder);
139 
140     received = pa_json_encoder_to_string_free(encoder);
141     o = pa_json_parse(received);
142     pa_xfree(received);
143 
144     fail_unless(o != NULL);
145     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
146     fail_unless(pa_json_object_get_array_length(o) == PA_ELEMENTSOF(test_ints));
147 
148     for (i = 0; i < PA_ELEMENTSOF(test_ints); i++) {
149         v = pa_json_object_get_array_member(o, i);
150 
151         fail_unless(v != NULL);
152         fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_INT);
153         fail_unless(pa_json_object_get_int(v) == test_ints[i]);
154     }
155 
156     pa_json_object_free(o);
157 }
158 END_TEST
159 
START_TEST(double_test)160 START_TEST(double_test) {
161     pa_json_object *o;
162     unsigned int i;
163     char *very_large_double_str;
164     const char *doubles_parse[] = {
165         "1.0", "-1.1", "1234e2", "1234e0", "0.1234", "-0.1234", "1234e-1", "1234.5e-1", "1234.5e+2",
166     };
167     const double doubles_compare[] = {
168         1.0, -1.1, 123400.0, 1234.0, 0.1234, -0.1234, 123.4, 123.45, 123450.0,
169     };
170 
171     for (i = 0; i < PA_ELEMENTSOF(doubles_parse); i++) {
172         o = pa_json_parse(doubles_parse[i]);
173 
174         fail_unless(o != NULL);
175         fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_DOUBLE);
176         fail_unless(PA_DOUBLE_IS_EQUAL(pa_json_object_get_double(o), doubles_compare[i]));
177 
178         pa_json_object_free(o);
179     }
180 
181     /* test that parser would fail on double exponent overflow */
182     very_large_double_str = pa_sprintf_malloc("%"PRIu64"e%"PRIu64, UINT64_MAX, UINT64_MAX);
183     o = pa_json_parse(very_large_double_str);
184     fail_unless(o == NULL);
185     pa_xfree(very_large_double_str);
186 }
187 END_TEST
188 
START_TEST(encoder_double_test)189 START_TEST(encoder_double_test) {
190     const double test_doubles[] = {
191         1.0, -1.1, 123400.0, 1234.0, 0.1234, -0.1234, 123.4, 123.45, 123450.0,
192     };
193     pa_json_object *o;
194     unsigned int i;
195     pa_json_encoder *encoder;
196     const pa_json_object *v;
197     char *received;
198 
199     encoder = pa_json_encoder_new();
200 
201     pa_json_encoder_begin_element_array(encoder);
202 
203     for (i = 0; i < PA_ELEMENTSOF(test_doubles); i++) {
204         pa_json_encoder_add_element_double(encoder, test_doubles[i], 6);
205     }
206 
207     pa_json_encoder_end_array(encoder);
208 
209     received = pa_json_encoder_to_string_free(encoder);
210     o = pa_json_parse(received);
211     pa_xfree(received);
212 
213     fail_unless(o != NULL);
214     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
215     fail_unless(pa_json_object_get_array_length(o) == PA_ELEMENTSOF(test_doubles));
216 
217     for (i = 0; i < PA_ELEMENTSOF(test_doubles); i++) {
218         v = pa_json_object_get_array_member(o, i);
219 
220         fail_unless(v != NULL);
221         fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_DOUBLE);
222         fail_unless(PA_DOUBLE_IS_EQUAL(pa_json_object_get_double(v), test_doubles[i]));
223     }
224 
225     pa_json_object_free(o);
226 }
227 END_TEST
228 
START_TEST(null_test)229 START_TEST(null_test) {
230     pa_json_object *o;
231 
232     o = pa_json_parse("null");
233 
234     fail_unless(o != NULL);
235     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_NULL);
236 
237     pa_json_object_free(o);
238 }
239 END_TEST
240 
START_TEST(encoder_null_test)241 START_TEST(encoder_null_test) {
242     pa_json_object *o;
243     pa_json_encoder *encoder;
244     char *received;
245 
246     encoder = pa_json_encoder_new();
247     pa_json_encoder_add_element_null(encoder);
248 
249     received = pa_json_encoder_to_string_free(encoder);
250     o = pa_json_parse(received);
251     pa_xfree(received);
252 
253     fail_unless(o != NULL);
254     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_NULL);
255 
256     pa_json_object_free(o);
257 }
258 END_TEST
259 
START_TEST(bool_test)260 START_TEST(bool_test) {
261     pa_json_object *o;
262 
263     o = pa_json_parse("true");
264 
265     fail_unless(o != NULL);
266     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_BOOL);
267     fail_unless(pa_json_object_get_bool(o) == true);
268 
269     pa_json_object_free(o);
270 
271     o = pa_json_parse("false");
272 
273     fail_unless(o != NULL);
274     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_BOOL);
275     fail_unless(pa_json_object_get_bool(o) == false);
276 
277     pa_json_object_free(o);
278 }
279 END_TEST
280 
START_TEST(encoder_bool_test)281 START_TEST(encoder_bool_test) {
282     const bool test_bools[] = {
283         true, false
284     };
285     pa_json_object *o;
286     unsigned int i;
287     pa_json_encoder *encoder;
288     const pa_json_object *v;
289     char *received;
290 
291     encoder = pa_json_encoder_new();
292 
293     pa_json_encoder_begin_element_array(encoder);
294 
295     for (i = 0; i < PA_ELEMENTSOF(test_bools); i++) {
296         pa_json_encoder_add_element_bool(encoder, test_bools[i]);
297     }
298 
299     pa_json_encoder_end_array(encoder);
300 
301     received = pa_json_encoder_to_string_free(encoder);
302     o = pa_json_parse(received);
303     pa_xfree(received);
304 
305     fail_unless(o != NULL);
306     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
307     fail_unless(pa_json_object_get_array_length(o) == PA_ELEMENTSOF(test_bools));
308 
309     for (i = 0; i < PA_ELEMENTSOF(test_bools); i++) {
310         v = pa_json_object_get_array_member(o, i);
311 
312         fail_unless(v != NULL);
313         fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_BOOL);
314         fail_unless(PA_DOUBLE_IS_EQUAL(pa_json_object_get_bool(v), test_bools[i]));
315     }
316 
317     pa_json_object_free(o);
318 }
319 END_TEST
320 
START_TEST(object_test)321 START_TEST(object_test) {
322     pa_json_object *o;
323     const pa_json_object *v;
324 
325     o = pa_json_parse(" { \"name\" : \"A Person\" } ");
326 
327     fail_unless(o != NULL);
328     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
329 
330     v = pa_json_object_get_object_member(o, "name");
331     fail_unless(v != NULL);
332     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_STRING);
333     fail_unless(pa_streq(pa_json_object_get_string(v), "A Person"));
334 
335     pa_json_object_free(o);
336 
337     o = pa_json_parse(" { \"age\" : -45.3e-0 } ");
338 
339     fail_unless(o != NULL);
340     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
341 
342     v = pa_json_object_get_object_member(o, "age");
343     fail_unless(v != NULL);
344     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_DOUBLE);
345     fail_unless(PA_DOUBLE_IS_EQUAL(pa_json_object_get_double(v), -45.3));
346 
347     pa_json_object_free(o);
348 
349     o = pa_json_parse("{\"person\":true}");
350 
351     fail_unless(o != NULL);
352     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
353 
354     v = pa_json_object_get_object_member(o, "person");
355     fail_unless(v != NULL);
356     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_BOOL);
357     fail_unless(pa_json_object_get_bool(v) == true);
358 
359     pa_json_object_free(o);
360 
361     o = pa_json_parse("{ \"parent\": { \"child\": false } }");
362     fail_unless(o != NULL);
363     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
364 
365     v = pa_json_object_get_object_member(o, "parent");
366     fail_unless(v != NULL);
367     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_OBJECT);
368     v = pa_json_object_get_object_member(v, "child");
369     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_BOOL);
370     fail_unless(pa_json_object_get_bool(v) == false);
371 
372     pa_json_object_free(o);
373 }
374 END_TEST
375 
START_TEST(object_member_iterator_test)376 START_TEST(object_member_iterator_test) {
377     pa_json_object *o;
378     const pa_json_object *v;
379     const char *k;
380     void *state;
381     size_t i;
382 
383     struct {
384         bool visited;
385         const char *key;
386         pa_json_type type;
387         union {
388             const char *str;
389             int64_t n;
390         } value;
391     } expected_entries[] = {
392             { .key = "name", .type = PA_JSON_TYPE_STRING, .value.str = "sample 1" },
393             { .key = "number", .type = PA_JSON_TYPE_INT, .value.n = 42 },
394     };
395 
396     o = pa_json_parse(" { \"name\" : \"sample 1\", \"number\": 42 } ");
397 
398     fail_unless(o != NULL);
399     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
400 
401     PA_HASHMAP_FOREACH_KV(k, v, pa_json_object_get_object_member_hashmap(o), state) {
402         fail_unless(k != NULL);
403         fail_unless(v != NULL);
404         for (i = 0; i < PA_ELEMENTSOF(expected_entries); ++i) {
405             if (pa_streq(expected_entries[i].key, k)) {
406                 fail_unless(!expected_entries[i].visited);
407                 fail_unless(expected_entries[i].type == pa_json_object_get_type(v));
408                 switch (expected_entries[i].type) {
409                     case PA_JSON_TYPE_STRING:
410                         fail_unless(pa_streq(expected_entries[i].value.str, pa_json_object_get_string(v)));
411                         break;
412                     case PA_JSON_TYPE_INT:
413                         fail_unless(expected_entries[i].value.n == pa_json_object_get_int(v));
414                         break;
415                     default:
416                         /* unreachable */
417                         fail_unless(false);
418                         break;
419                 }
420                 expected_entries[i].visited = true;
421             }
422         }
423     }
424 
425     pa_json_object_free(o);
426 }
427 END_TEST
428 
START_TEST(encoder_object_test)429 START_TEST(encoder_object_test) {
430     pa_json_object *o;
431     const pa_json_object *v;
432     pa_json_encoder *encoder;
433     char *received;
434 
435     /* { "name" : "A Person" } */
436 
437     encoder = pa_json_encoder_new();
438     pa_json_encoder_begin_element_object(encoder);
439     pa_json_encoder_add_member_string(encoder, "name", "A Person");
440     pa_json_encoder_end_object(encoder);
441 
442     received = pa_json_encoder_to_string_free(encoder);
443     o = pa_json_parse(received);
444     pa_xfree(received);
445 
446     fail_unless(o != NULL);
447     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
448 
449     v = pa_json_object_get_object_member(o, "name");
450     fail_unless(v != NULL);
451     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_STRING);
452     fail_unless(pa_streq(pa_json_object_get_string(v), "A Person"));
453 
454     pa_json_object_free(o);
455 
456     /* { "age" : -45.3e-0 } */
457 
458     encoder = pa_json_encoder_new();
459     pa_json_encoder_begin_element_object(encoder);
460     pa_json_encoder_add_member_double(encoder, "age", -45.3e-0, 2);
461     pa_json_encoder_end_object(encoder);
462 
463     received = pa_json_encoder_to_string_free(encoder);
464     o = pa_json_parse(received);
465     pa_xfree(received);
466 
467     fail_unless(o != NULL);
468     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
469 
470     v = pa_json_object_get_object_member(o, "age");
471     fail_unless(v != NULL);
472     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_DOUBLE);
473     fail_unless(PA_DOUBLE_IS_EQUAL(pa_json_object_get_double(v), -45.3));
474 
475     pa_json_object_free(o);
476 
477     /* {"person":true} */
478 
479     encoder = pa_json_encoder_new();
480     pa_json_encoder_begin_element_object(encoder);
481     pa_json_encoder_add_member_bool(encoder, "person", true);
482     pa_json_encoder_end_object(encoder);
483 
484     received = pa_json_encoder_to_string_free(encoder);
485     o = pa_json_parse(received);
486     pa_xfree(received);
487 
488     fail_unless(o != NULL);
489     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
490 
491     v = pa_json_object_get_object_member(o, "person");
492     fail_unless(v != NULL);
493     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_BOOL);
494     fail_unless(pa_json_object_get_bool(v) == true);
495 
496     pa_json_object_free(o);
497 }
498 END_TEST
499 
START_TEST(encoder_member_object_test)500 START_TEST(encoder_member_object_test) {
501     pa_json_object *o;
502     const pa_json_object *v;
503     pa_json_encoder *encoder;
504     char *received;
505 
506     /* { "parent": { "child": false } } */
507 
508     encoder = pa_json_encoder_new();
509     pa_json_encoder_begin_element_object(encoder);
510 
511     pa_json_encoder_begin_member_object(encoder, "parent");
512     pa_json_encoder_add_member_bool(encoder, "child", false);
513     pa_json_encoder_end_object(encoder);
514 
515     pa_json_encoder_end_object(encoder);
516 
517     received = pa_json_encoder_to_string_free(encoder);
518     o = pa_json_parse(received);
519     pa_xfree(received);
520 
521     fail_unless(o != NULL);
522     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
523 
524     v = pa_json_object_get_object_member(o, "parent");
525     fail_unless(v != NULL);
526     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_OBJECT);
527     v = pa_json_object_get_object_member(v, "child");
528     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_BOOL);
529     fail_unless(pa_json_object_get_bool(v) == false);
530 
531     pa_json_object_free(o);
532 }
533 END_TEST
534 
START_TEST(array_test)535 START_TEST(array_test) {
536     pa_json_object *o;
537     const pa_json_object *v, *v2;
538 
539     o = pa_json_parse(" [  ] ");
540 
541     fail_unless(o != NULL);
542     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
543     fail_unless(pa_json_object_get_array_length(o) == 0);
544 
545     pa_json_object_free(o);
546 
547     o = pa_json_parse("[\"a member\"]");
548 
549     fail_unless(o != NULL);
550     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
551     fail_unless(pa_json_object_get_array_length(o) == 1);
552 
553     v = pa_json_object_get_array_member(o, 0);
554     fail_unless(v != NULL);
555     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_STRING);
556     fail_unless(pa_streq(pa_json_object_get_string(v), "a member"));
557 
558     pa_json_object_free(o);
559 
560     o = pa_json_parse("[\"a member\", 1234.5, { \"another\": true } ]");
561 
562     fail_unless(o != NULL);
563     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
564     fail_unless(pa_json_object_get_array_length(o) == 3);
565 
566     v = pa_json_object_get_array_member(o, 0);
567     fail_unless(v != NULL);
568     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_STRING);
569     fail_unless(pa_streq(pa_json_object_get_string(v), "a member"));
570     v = pa_json_object_get_array_member(o, 1);
571     fail_unless(v != NULL);
572     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_DOUBLE);
573     fail_unless(PA_DOUBLE_IS_EQUAL(pa_json_object_get_double(v), 1234.5));
574     v = pa_json_object_get_array_member(o, 2);
575     fail_unless(v != NULL);
576     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_OBJECT);
577     v2 =pa_json_object_get_object_member(v, "another");
578     fail_unless(v2 != NULL);
579     fail_unless(pa_json_object_get_type(v2) == PA_JSON_TYPE_BOOL);
580     fail_unless(pa_json_object_get_bool(v2) == true);
581 
582     pa_json_object_free(o);
583 }
584 END_TEST
585 
START_TEST(encoder_element_array_test)586 START_TEST(encoder_element_array_test) {
587     pa_json_object *o;
588     const pa_json_object *v, *v2;
589 
590     pa_json_encoder *encoder;
591     char *received;
592     pa_json_encoder *subobject;
593     char *subobject_string;
594 
595     /* [  ] */
596     encoder = pa_json_encoder_new();
597     pa_json_encoder_begin_element_array(encoder);
598     pa_json_encoder_end_array(encoder);
599 
600     received = pa_json_encoder_to_string_free(encoder);
601     o = pa_json_parse(received);
602     pa_xfree(received);
603 
604     fail_unless(o != NULL);
605     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
606     fail_unless(pa_json_object_get_array_length(o) == 0);
607 
608     pa_json_object_free(o);
609 
610     /* ["a member"] */
611 
612     encoder = pa_json_encoder_new();
613     pa_json_encoder_begin_element_array(encoder);
614     pa_json_encoder_add_element_string(encoder, "a member");
615     pa_json_encoder_end_array(encoder);
616 
617     received = pa_json_encoder_to_string_free(encoder);
618     o = pa_json_parse(received);
619     pa_xfree(received);
620 
621     fail_unless(o != NULL);
622     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
623     fail_unless(pa_json_object_get_array_length(o) == 1);
624 
625     v = pa_json_object_get_array_member(o, 0);
626     fail_unless(v != NULL);
627     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_STRING);
628     fail_unless(pa_streq(pa_json_object_get_string(v), "a member"));
629 
630     pa_json_object_free(o);
631 
632     /* [\"a member\", 1234.5, { \"another\": true } ] */
633 
634     subobject = pa_json_encoder_new();
635     pa_json_encoder_begin_element_object(subobject);
636     pa_json_encoder_add_member_bool(subobject, "another", true);
637     pa_json_encoder_end_object(subobject);
638     subobject_string = pa_json_encoder_to_string_free(subobject);
639 
640     encoder = pa_json_encoder_new();
641     pa_json_encoder_begin_element_array(encoder);
642     pa_json_encoder_add_element_string(encoder, "a member");
643     pa_json_encoder_add_element_double(encoder, 1234.5, 1);
644     pa_json_encoder_add_element_raw_json(encoder, subobject_string);
645     pa_xfree(subobject_string);
646     pa_json_encoder_end_array(encoder);
647 
648     received = pa_json_encoder_to_string_free(encoder);
649     o = pa_json_parse(received);
650     pa_xfree(received);
651 
652     fail_unless(o != NULL);
653     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
654     fail_unless(pa_json_object_get_array_length(o) == 3);
655 
656     v = pa_json_object_get_array_member(o, 0);
657     fail_unless(v != NULL);
658     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_STRING);
659     fail_unless(pa_streq(pa_json_object_get_string(v), "a member"));
660     v = pa_json_object_get_array_member(o, 1);
661     fail_unless(v != NULL);
662     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_DOUBLE);
663     fail_unless(PA_DOUBLE_IS_EQUAL(pa_json_object_get_double(v), 1234.5));
664     v = pa_json_object_get_array_member(o, 2);
665     fail_unless(v != NULL);
666     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_OBJECT);
667     v2 =pa_json_object_get_object_member(v, "another");
668     fail_unless(v2 != NULL);
669     fail_unless(pa_json_object_get_type(v2) == PA_JSON_TYPE_BOOL);
670     fail_unless(pa_json_object_get_bool(v2) == true);
671 
672     pa_json_object_free(o);
673 }
674 END_TEST
675 
START_TEST(encoder_member_array_test)676 START_TEST(encoder_member_array_test) {
677     pa_json_object *o;
678     unsigned int i;
679     const pa_json_object *v;
680     const pa_json_object *e;
681     pa_json_encoder *encoder;
682     char *received;
683 
684     const int64_t test_ints[] = { 1, -1, 1234, 0, LONG_MIN, LONG_MAX };
685 
686     /* { "parameters": [ 1, -1, 1234, 0, -9223372036854775808, 9223372036854775807 ] } */
687 
688 
689     encoder = pa_json_encoder_new();
690     pa_json_encoder_begin_element_object(encoder);
691 
692     pa_json_encoder_begin_member_array(encoder, "parameters");
693     for (i = 0; i < PA_ELEMENTSOF(test_ints); i++) {
694         pa_json_encoder_add_element_int(encoder, test_ints[i]);
695     }
696     pa_json_encoder_end_array(encoder);
697 
698     pa_json_encoder_end_object(encoder);
699 
700     received = pa_json_encoder_to_string_free(encoder);
701     o = pa_json_parse(received);
702     pa_xfree(received);
703 
704     fail_unless(o != NULL);
705     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
706 
707     v = pa_json_object_get_object_member(o, "parameters");
708     fail_unless(v != NULL);
709     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_ARRAY);
710     fail_unless(pa_json_object_get_array_length(v) == PA_ELEMENTSOF(test_ints));
711 
712     for (i = 0; i < PA_ELEMENTSOF(test_ints); i++) {
713         e = pa_json_object_get_array_member(v, i);
714 
715         fail_unless(e != NULL);
716         fail_unless(pa_json_object_get_type(e) == PA_JSON_TYPE_INT);
717         fail_unless(pa_json_object_get_int(e) == test_ints[i]);
718     }
719 
720     pa_json_object_free(o);
721 }
722 END_TEST
723 
START_TEST(encoder_member_raw_json_test)724 START_TEST(encoder_member_raw_json_test) {
725     pa_json_object *o;
726     const pa_json_object *v;
727     const pa_json_object *e;
728     pa_json_encoder *encoder;
729     char *received;
730     pa_json_encoder *subobject;
731     char *subobject_string;
732 
733     /* { "parameters": [1, "a", 2.0] } */
734 
735     subobject = pa_json_encoder_new();
736     pa_json_encoder_begin_element_array(subobject);
737     pa_json_encoder_add_element_int(subobject, 1);
738     pa_json_encoder_add_element_string(subobject, "a");
739     pa_json_encoder_add_element_double(subobject, 2.0, 6);
740     pa_json_encoder_end_array(subobject);
741     subobject_string = pa_json_encoder_to_string_free(subobject);
742 
743     encoder = pa_json_encoder_new();
744     pa_json_encoder_begin_element_object(encoder);
745 
746     pa_json_encoder_add_member_raw_json(encoder, "parameters", subobject_string);
747     pa_xfree(subobject_string);
748 
749     pa_json_encoder_end_object(encoder);
750 
751     received = pa_json_encoder_to_string_free(encoder);
752     o = pa_json_parse(received);
753     pa_xfree(received);
754 
755     fail_unless(o != NULL);
756     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
757 
758     v = pa_json_object_get_object_member(o, "parameters");
759     fail_unless(v != NULL);
760     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_ARRAY);
761     fail_unless(pa_json_object_get_array_length(v) == 3);
762     e = pa_json_object_get_array_member(v, 0);
763     fail_unless(e != NULL);
764     fail_unless(pa_json_object_get_type(e) == PA_JSON_TYPE_INT);
765     fail_unless(pa_json_object_get_int(e) == 1);
766     e = pa_json_object_get_array_member(v, 1);
767     fail_unless(e != NULL);
768     fail_unless(pa_json_object_get_type(e) == PA_JSON_TYPE_STRING);
769     fail_unless(pa_streq(pa_json_object_get_string(e), "a"));
770     e = pa_json_object_get_array_member(v, 2);
771     fail_unless(e != NULL);
772     fail_unless(pa_json_object_get_type(e) == PA_JSON_TYPE_DOUBLE);
773     fail_unless(PA_DOUBLE_IS_EQUAL(pa_json_object_get_double(e), 2.0));
774 
775     pa_json_object_free(o);
776 
777     /* { "parent": { "child": false } } */
778 
779     subobject = pa_json_encoder_new();
780     pa_json_encoder_begin_element_object(subobject);
781     pa_json_encoder_add_member_bool(subobject, "child", false);
782     pa_json_encoder_end_object(subobject);
783     subobject_string = pa_json_encoder_to_string_free(subobject);
784 
785     encoder = pa_json_encoder_new();
786     pa_json_encoder_begin_element_object(encoder);
787 
788     pa_json_encoder_add_member_raw_json(encoder, "parent", subobject_string);
789     pa_xfree(subobject_string);
790 
791     pa_json_encoder_end_object(encoder);
792 
793     received = pa_json_encoder_to_string_free(encoder);
794     o = pa_json_parse(received);
795     pa_xfree(received);
796 
797     fail_unless(o != NULL);
798     fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
799 
800     v = pa_json_object_get_object_member(o, "parent");
801     fail_unless(v != NULL);
802     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_OBJECT);
803     v = pa_json_object_get_object_member(v, "child");
804     fail_unless(pa_json_object_get_type(v) == PA_JSON_TYPE_BOOL);
805     fail_unless(pa_json_object_get_bool(v) == false);
806 
807     pa_json_object_free(o);
808 }
809 END_TEST
810 
START_TEST(bad_test)811 START_TEST(bad_test) {
812     unsigned int i;
813     const char *bad_parse[] = {
814         "\"" /* Quote not closed */,
815         "123456789012345678901234567890" /* Overflow */,
816 #if 0   /* TODO: check rounding the value is OK */
817         "0.123456789012345678901234567890" /* Overflow */,
818 #endif
819         "1e123456789012345678901234567890" /* Overflow */,
820         "1e-10000" /* Underflow */,
821         "1e" /* Bad number string */,
822         "1." /* Bad number string */,
823         "1.e3" /* Bad number string */,
824         "-" /* Bad number string */,
825         "{ \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": {  \"a\": { } } } } } } } } } } } } } } } } } } } } } }" /* Nested too deep */,
826         "[ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ { \"a\": \"b\" } ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ]" /* Nested too deep */,
827         "asdf" /* Unquoted string */,
828         "{ a: true }" /* Unquoted key in object */,
829         "\"    \a\"" /* Alarm is not a valid character */
830     };
831 
832     for (i = 0; i < PA_ELEMENTSOF(bad_parse); i++) {
833         pa_json_object *obj;
834 
835         fail_unless((obj = pa_json_parse(bad_parse[i])) == NULL);
836         if (obj)
837             pa_json_object_free(obj);
838     }
839 }
840 END_TEST
841 
main(int argc,char * argv[])842 int main(int argc, char *argv[]) {
843     int failed = 0;
844     Suite *s;
845     TCase *tc;
846     SRunner *sr;
847 
848     s = suite_create("JSON");
849     tc = tcase_create("json");
850     tcase_add_test(tc, string_test);
851     tcase_add_test(tc, encoder_string_test);
852     tcase_add_test(tc, int_test);
853     tcase_add_test(tc, encoder_int_test);
854     tcase_add_test(tc, double_test);
855     tcase_add_test(tc, encoder_double_test);
856     tcase_add_test(tc, null_test);
857     tcase_add_test(tc, encoder_null_test);
858     tcase_add_test(tc, bool_test);
859     tcase_add_test(tc, encoder_bool_test);
860     tcase_add_test(tc, object_test);
861     tcase_add_test(tc, encoder_member_object_test);
862     tcase_add_test(tc, object_member_iterator_test);
863     tcase_add_test(tc, encoder_object_test);
864     tcase_add_test(tc, array_test);
865     tcase_add_test(tc, encoder_element_array_test);
866     tcase_add_test(tc, encoder_member_array_test);
867     tcase_add_test(tc, encoder_member_raw_json_test);
868     tcase_add_test(tc, bad_test);
869     suite_add_tcase(s, tc);
870 
871     sr = srunner_create(s);
872     srunner_run_all(sr, CK_NORMAL);
873     failed = srunner_ntests_failed(sr);
874     srunner_free(sr);
875 
876     return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
877 }
878