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