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 30START_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} 52END_TEST 53 54START_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} 94END_TEST 95 96START_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} 119END_TEST 120 121START_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} 158END_TEST 159 160START_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} 187END_TEST 188 189START_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} 227END_TEST 228 229START_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} 239END_TEST 240 241START_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} 258END_TEST 259 260START_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} 279END_TEST 280 281START_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} 319END_TEST 320 321START_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} 374END_TEST 375 376START_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} 427END_TEST 428 429START_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} 498END_TEST 499 500START_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} 533END_TEST 534 535START_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} 584END_TEST 585 586START_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} 674END_TEST 675 676START_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} 722END_TEST 723 724START_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} 809END_TEST 810 811START_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} 840END_TEST 841 842int 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