1/* $NetBSD: jsmn_test.c,v 1.5 2020/05/25 20:47:24 christos Exp $ */ 2 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6 7static int test_passed = 0; 8static int test_failed = 0; 9 10/* Terminate current test with error */ 11#define fail() return __LINE__ 12 13/* Successfull end of the test case */ 14#define done() return 0 15 16/* Check single condition */ 17#define check(cond) do { if (!(cond)) fail(); } while (0) 18 19/* Test runner */ 20static void test(int (*func)(void), const char *name) { 21 int r = func(); 22 if (r == 0) { 23 test_passed++; 24 } else { 25 test_failed++; 26 printf("FAILED: %s (at line %d)\n", name, r); 27 } 28} 29 30#define TOKEN_EQ(t, tok_start, tok_end, tok_type) \ 31 ((t).start == tok_start \ 32 && (t).end == tok_end \ 33 && (t).type == (tok_type)) 34 35#define TOKEN_STRING(js, t, s) \ 36 (strncmp(js+(t).start, s, (t).end - (t).start) == 0 \ 37 && strlen(s) == (t).end - (t).start) 38 39#define TOKEN_PRINT(t) \ 40 printf("start: %d, end: %d, type: %d, size: %d\n", \ 41 (t).start, (t).end, (t).type, (t).size) 42 43#define JSMN_STRICT 44#include "jsmn.c" 45 46int test_empty() { 47 const char *js; 48 int r; 49 jsmn_parser p; 50 jsmntok_t t[10]; 51 52 js = "{}"; 53 jsmn_init(&p); 54 r = jsmn_parse(&p, js, strlen(js), t, 10); 55 check(r >= 0); 56 check(t[0].type == JSMN_OBJECT); 57 check(t[0].start == 0 && t[0].end == 2); 58 59 js = "[]"; 60 jsmn_init(&p); 61 r = jsmn_parse(&p, js, strlen(js), t, 10); 62 check(r >= 0); 63 check(t[0].type == JSMN_ARRAY); 64 check(t[0].start == 0 && t[0].end == 2); 65 66 js = "{\"a\":[]}"; 67 jsmn_init(&p); 68 r = jsmn_parse(&p, js, strlen(js), t, 10); 69 check(r >= 0); 70 check(t[0].type == JSMN_OBJECT && t[0].start == 0 && t[0].end == 8); 71 check(t[1].type == JSMN_STRING && t[1].start == 2 && t[1].end == 3); 72 check(t[2].type == JSMN_ARRAY && t[2].start == 5 && t[2].end == 7); 73 74 js = "[{},{}]"; 75 jsmn_init(&p); 76 r = jsmn_parse(&p, js, strlen(js), t, 10); 77 check(r >= 0); 78 check(t[0].type == JSMN_ARRAY && t[0].start == 0 && t[0].end == 7); 79 check(t[1].type == JSMN_OBJECT && t[1].start == 1 && t[1].end == 3); 80 check(t[2].type == JSMN_OBJECT && t[2].start == 4 && t[2].end == 6); 81 return 0; 82} 83 84int test_simple() { 85 const char *js; 86 int r; 87 jsmn_parser p; 88 jsmntok_t tokens[10]; 89 90 js = "{\"a\": 0}"; 91 92 jsmn_init(&p); 93 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 94 check(r >= 0); 95 check(TOKEN_EQ(tokens[0], 0, 8, JSMN_OBJECT)); 96 check(TOKEN_EQ(tokens[1], 2, 3, JSMN_STRING)); 97 check(TOKEN_EQ(tokens[2], 6, 7, JSMN_PRIMITIVE)); 98 99 check(TOKEN_STRING(js, tokens[0], js)); 100 check(TOKEN_STRING(js, tokens[1], "a")); 101 check(TOKEN_STRING(js, tokens[2], "0")); 102 103 jsmn_init(&p); 104 js = "[\"a\":{},\"b\":{}]"; 105 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 106 check(r >= 0); 107 108 jsmn_init(&p); 109 js = "{\n \"Day\": 26,\n \"Month\": 9,\n \"Year\": 12\n }"; 110 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 111 check(r >= 0); 112 113 return 0; 114} 115 116int test_primitive() { 117#ifndef JSMN_STRICT 118 int r; 119 jsmn_parser p; 120 jsmntok_t tok[10]; 121 const char *js; 122 js = "\"boolVar\" : true"; 123 jsmn_init(&p); 124 r = jsmn_parse(&p, js, strlen(js), tok, 10); 125 check(r >= 0 && tok[0].type == JSMN_STRING 126 && tok[1].type == JSMN_PRIMITIVE); 127 check(TOKEN_STRING(js, tok[0], "boolVar")); 128 check(TOKEN_STRING(js, tok[1], "true")); 129 130 js = "\"boolVar\" : false"; 131 jsmn_init(&p); 132 r = jsmn_parse(&p, js, strlen(js), tok, 10); 133 check(r >= 0 && tok[0].type == JSMN_STRING 134 && tok[1].type == JSMN_PRIMITIVE); 135 check(TOKEN_STRING(js, tok[0], "boolVar")); 136 check(TOKEN_STRING(js, tok[1], "false")); 137 138 js = "\"intVar\" : 12345"; 139 jsmn_init(&p); 140 r = jsmn_parse(&p, js, strlen(js), tok, 10); 141 check(r >= 0 && tok[0].type == JSMN_STRING 142 && tok[1].type == JSMN_PRIMITIVE); 143 check(TOKEN_STRING(js, tok[0], "intVar")); 144 check(TOKEN_STRING(js, tok[1], "12345")); 145 146 js = "\"floatVar\" : 12.345"; 147 jsmn_init(&p); 148 r = jsmn_parse(&p, js, strlen(js), tok, 10); 149 check(r >= 0 && tok[0].type == JSMN_STRING 150 && tok[1].type == JSMN_PRIMITIVE); 151 check(TOKEN_STRING(js, tok[0], "floatVar")); 152 check(TOKEN_STRING(js, tok[1], "12.345")); 153 154 js = "\"nullVar\" : null"; 155 jsmn_init(&p); 156 r = jsmn_parse(&p, js, strlen(js), tok, 10); 157 check(r >= 0 && tok[0].type == JSMN_STRING 158 && tok[1].type == JSMN_PRIMITIVE); 159 check(TOKEN_STRING(js, tok[0], "nullVar")); 160 check(TOKEN_STRING(js, tok[1], "null")); 161#endif 162 return 0; 163} 164 165int test_string() { 166 int r; 167 jsmn_parser p; 168 jsmntok_t tok[10]; 169 const char *js; 170 171 js = "\"strVar\" : \"hello world\""; 172 jsmn_init(&p); 173 r = jsmn_parse(&p, js, strlen(js), tok, 10); 174 check(r >= 0 && tok[0].type == JSMN_STRING 175 && tok[1].type == JSMN_STRING); 176 check(TOKEN_STRING(js, tok[0], "strVar")); 177 check(TOKEN_STRING(js, tok[1], "hello world")); 178 179 js = "\"strVar\" : \"escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\\""; 180 jsmn_init(&p); 181 r = jsmn_parse(&p, js, strlen(js), tok, 10); 182 check(r >= 0 && tok[0].type == JSMN_STRING 183 && tok[1].type == JSMN_STRING); 184 check(TOKEN_STRING(js, tok[0], "strVar")); 185 check(TOKEN_STRING(js, tok[1], "escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\")); 186 187 js = "\"strVar\" : \"\""; 188 jsmn_init(&p); 189 r = jsmn_parse(&p, js, strlen(js), tok, 10); 190 check(r >= 0 && tok[0].type == JSMN_STRING 191 && tok[1].type == JSMN_STRING); 192 check(TOKEN_STRING(js, tok[0], "strVar")); 193 check(TOKEN_STRING(js, tok[1], "")); 194 195 return 0; 196} 197 198int test_partial_string() { 199 int r; 200 jsmn_parser p; 201 jsmntok_t tok[10]; 202 const char *js; 203 204 jsmn_init(&p); 205 js = "\"x\": \"va"; 206 r = jsmn_parse(&p, js, strlen(js), tok, 10); 207 check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING); 208 check(TOKEN_STRING(js, tok[0], "x")); 209 check(p.toknext == 1); 210 211 jsmn_init(&p); 212 char js_slash[9] = "\"x\": \"va\\"; 213 r = jsmn_parse(&p, js_slash, sizeof(js_slash), tok, 10); 214 check(r == JSMN_ERROR_PART); 215 216 jsmn_init(&p); 217 char js_unicode[10] = "\"x\": \"va\\u"; 218 r = jsmn_parse(&p, js_unicode, sizeof(js_unicode), tok, 10); 219 check(r == JSMN_ERROR_PART); 220 221 js = "\"x\": \"valu"; 222 r = jsmn_parse(&p, js, strlen(js), tok, 10); 223 check(r == JSMN_ERROR_PART && tok[0].type == JSMN_STRING); 224 check(TOKEN_STRING(js, tok[0], "x")); 225 check(p.toknext == 1); 226 227 js = "\"x\": \"value\""; 228 r = jsmn_parse(&p, js, strlen(js), tok, 10); 229 check(r >= 0 && tok[0].type == JSMN_STRING 230 && tok[1].type == JSMN_STRING); 231 check(TOKEN_STRING(js, tok[0], "x")); 232 check(TOKEN_STRING(js, tok[1], "value")); 233 234 js = "\"x\": \"value\", \"y\": \"value y\""; 235 r = jsmn_parse(&p, js, strlen(js), tok, 10); 236 check(r >= 0 && tok[0].type == JSMN_STRING 237 && tok[1].type == JSMN_STRING && tok[2].type == JSMN_STRING 238 && tok[3].type == JSMN_STRING); 239 check(TOKEN_STRING(js, tok[0], "x")); 240 check(TOKEN_STRING(js, tok[1], "value")); 241 check(TOKEN_STRING(js, tok[2], "y")); 242 check(TOKEN_STRING(js, tok[3], "value y")); 243 244 return 0; 245} 246 247int test_unquoted_keys() { 248#ifndef JSMN_STRICT 249 int r; 250 jsmn_parser p; 251 jsmntok_t tok[10]; 252 const char *js; 253 254 jsmn_init(&p); 255 js = "key1: \"value\"\nkey2 : 123"; 256 257 r = jsmn_parse(&p, js, strlen(js), tok, 10); 258 check(r >= 0 && tok[0].type == JSMN_PRIMITIVE 259 && tok[1].type == JSMN_STRING && tok[2].type == JSMN_PRIMITIVE 260 && tok[3].type == JSMN_PRIMITIVE); 261 check(TOKEN_STRING(js, tok[0], "key1")); 262 check(TOKEN_STRING(js, tok[1], "value")); 263 check(TOKEN_STRING(js, tok[2], "key2")); 264 check(TOKEN_STRING(js, tok[3], "123")); 265#endif 266 return 0; 267} 268 269int test_partial_array() { 270 int r; 271 jsmn_parser p; 272 jsmntok_t tok[10]; 273 const char *js; 274 275 jsmn_init(&p); 276 js = " [ 1, true, "; 277 r = jsmn_parse(&p, js, strlen(js), tok, 10); 278 check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY 279 && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE); 280 281 js = " [ 1, true, [123, \"hello"; 282 r = jsmn_parse(&p, js, strlen(js), tok, 10); 283 check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY 284 && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE 285 && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE); 286 287 js = " [ 1, true, [123, \"hello\"]"; 288 r = jsmn_parse(&p, js, strlen(js), tok, 10); 289 check(r == JSMN_ERROR_PART && tok[0].type == JSMN_ARRAY 290 && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE 291 && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE 292 && tok[5].type == JSMN_STRING); 293 /* check child nodes of the 2nd array */ 294 check(tok[3].size == 2); 295 296 js = " [ 1, true, [123, \"hello\"]]"; 297 r = jsmn_parse(&p, js, strlen(js), tok, 10); 298 check(r >= 0 && tok[0].type == JSMN_ARRAY 299 && tok[1].type == JSMN_PRIMITIVE && tok[2].type == JSMN_PRIMITIVE 300 && tok[3].type == JSMN_ARRAY && tok[4].type == JSMN_PRIMITIVE 301 && tok[5].type == JSMN_STRING); 302 check(tok[3].size == 2); 303 check(tok[0].size == 3); 304 return 0; 305} 306 307int test_array_nomem() { 308 int i; 309 int r; 310 jsmn_parser p; 311 jsmntok_t toksmall[10], toklarge[10]; 312 const char *js; 313 314 js = " [ 1, true, [123, \"hello\"]]"; 315 316 for (i = 0; i < 6; i++) { 317 jsmn_init(&p); 318 memset(toksmall, 0, sizeof(toksmall)); 319 memset(toklarge, 0, sizeof(toklarge)); 320 r = jsmn_parse(&p, js, strlen(js), toksmall, i); 321 check(r == JSMN_ERROR_NOMEM); 322 323 memcpy(toklarge, toksmall, sizeof(toksmall)); 324 325 r = jsmn_parse(&p, js, strlen(js), toklarge, 10); 326 check(r >= 0); 327 328 check(toklarge[0].type == JSMN_ARRAY && toklarge[0].size == 3); 329 check(toklarge[3].type == JSMN_ARRAY && toklarge[3].size == 2); 330 } 331 return 0; 332} 333 334int test_objects_arrays() { 335 int r; 336 jsmn_parser p; 337 jsmntok_t tokens[10]; 338 const char *js; 339 340 js = "[10}"; 341 jsmn_init(&p); 342 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 343 check(r == JSMN_ERROR_INVAL); 344 345 js = "[10]"; 346 jsmn_init(&p); 347 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 348 check(r >= 0); 349 350 js = "{\"a\": 1]"; 351 jsmn_init(&p); 352 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 353 check(r == JSMN_ERROR_INVAL); 354 355 js = "{\"a\": 1}"; 356 jsmn_init(&p); 357 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 358 check(r >= 0); 359 360 return 0; 361} 362 363int test_issue_22() { 364 int r; 365 jsmn_parser p; 366 jsmntok_t tokens[128]; 367 const char *js; 368 369 js = "{ \"height\":10, \"layers\":[ { \"data\":[6,6], \"height\":10, " 370 "\"name\":\"Calque de Tile 1\", \"opacity\":1, \"type\":\"tilelayer\", " 371 "\"visible\":true, \"width\":10, \"x\":0, \"y\":0 }], " 372 "\"orientation\":\"orthogonal\", \"properties\": { }, \"tileheight\":32, " 373 "\"tilesets\":[ { \"firstgid\":1, \"image\":\"..\\/images\\/tiles.png\", " 374 "\"imageheight\":64, \"imagewidth\":160, \"margin\":0, \"name\":\"Tiles\", " 375 "\"properties\":{}, \"spacing\":0, \"tileheight\":32, \"tilewidth\":32 }], " 376 "\"tilewidth\":32, \"version\":1, \"width\":10 }"; 377 jsmn_init(&p); 378 r = jsmn_parse(&p, js, strlen(js), tokens, 128); 379 check(r >= 0); 380#if 0 381 for (i = 1; tokens[i].end < tokens[0].end; i++) { 382 if (tokens[i].type == JSMN_STRING || tokens[i].type == JSMN_PRIMITIVE) { 383 printf("%.*s\n", tokens[i].end - tokens[i].start, js + tokens[i].start); 384 } else if (tokens[i].type == JSMN_ARRAY) { 385 printf("[%d elems]\n", tokens[i].size); 386 } else if (tokens[i].type == JSMN_OBJECT) { 387 printf("{%d elems}\n", tokens[i].size); 388 } else { 389 TOKEN_PRINT(tokens[i]); 390 } 391 } 392#endif 393 return 0; 394} 395 396int test_unicode_characters() { 397 jsmn_parser p; 398 jsmntok_t tokens[10]; 399 const char *js; 400 401 int r; 402 js = "{\"a\":\"\\uAbcD\"}"; 403 jsmn_init(&p); 404 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 405 check(r >= 0); 406 407 js = "{\"a\":\"str\\u0000\"}"; 408 jsmn_init(&p); 409 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 410 check(r >= 0); 411 412 js = "{\"a\":\"\\uFFFFstr\"}"; 413 jsmn_init(&p); 414 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 415 check(r >= 0); 416 417 js = "{\"a\":\"str\\uFFGFstr\"}"; 418 jsmn_init(&p); 419 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 420 check(r == JSMN_ERROR_INVAL); 421 422 js = "{\"a\":\"str\\u@FfF\"}"; 423 jsmn_init(&p); 424 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 425 check(r == JSMN_ERROR_INVAL); 426 427 js = "{\"a\":[\"\\u028\"]}"; 428 jsmn_init(&p); 429 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 430 check(r == JSMN_ERROR_INVAL); 431 432 js = "{\"a\":[\"\\u0280\"]}"; 433 jsmn_init(&p); 434 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 435 check(r >= 0); 436 437 return 0; 438} 439 440int test_input_length() { 441 const char *js; 442 int r; 443 jsmn_parser p; 444 jsmntok_t tokens[10]; 445 446 js = "{\"a\": 0}garbage"; 447 448 jsmn_init(&p); 449 r = jsmn_parse(&p, js, 8, tokens, 10); 450 check(r == 3); 451 check(TOKEN_STRING(js, tokens[0], "{\"a\": 0}")); 452 check(TOKEN_STRING(js, tokens[1], "a")); 453 check(TOKEN_STRING(js, tokens[2], "0")); 454 455 return 0; 456} 457 458int test_count() { 459 jsmn_parser p; 460 const char *js; 461 462 js = "{}"; 463 jsmn_init(&p); 464 check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1); 465 466 js = "[]"; 467 jsmn_init(&p); 468 check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1); 469 470 js = "[[]]"; 471 jsmn_init(&p); 472 check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 2); 473 474 js = "[[], []]"; 475 jsmn_init(&p); 476 check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3); 477 478 js = "[[], []]"; 479 jsmn_init(&p); 480 check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3); 481 482 js = "[[], [[]], [[], []]]"; 483 jsmn_init(&p); 484 check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7); 485 486 js = "[\"a\", [[], []]]"; 487 jsmn_init(&p); 488 check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5); 489 490 js = "[[], \"[], [[]]\", [[]]]"; 491 jsmn_init(&p); 492 check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5); 493 494 js = "[1, 2, 3]"; 495 jsmn_init(&p); 496 check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 4); 497 498 js = "[1, 2, [3, \"a\"], null]"; 499 jsmn_init(&p); 500 check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7); 501 502 return 0; 503} 504 505int test_keyvalue() { 506 const char *js; 507 int r; 508 jsmn_parser p; 509 jsmntok_t tokens[10]; 510 511 js = "{\"a\": 0, \"b\": \"c\"}"; 512 513 jsmn_init(&p); 514 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 515 check(r == 5); 516 check(tokens[0].size == 2); /* two keys */ 517 check(tokens[1].size == 1 && tokens[3].size == 1); /* one value per key */ 518 check(tokens[2].size == 0 && tokens[4].size == 0); /* values have zero size */ 519 520 js = "{\"a\"\n0}"; 521 jsmn_init(&p); 522 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 523 check(r == JSMN_ERROR_INVAL); 524 525 js = "{\"a\", 0}"; 526 jsmn_init(&p); 527 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 528 check(r == JSMN_ERROR_INVAL); 529 530 js = "{\"a\": {2}}"; 531 jsmn_init(&p); 532 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 533 check(r == JSMN_ERROR_INVAL); 534 535 js = "{\"a\": {2: 3}}"; 536 jsmn_init(&p); 537 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 538 check(r == JSMN_ERROR_INVAL); 539 540 541 js = "{\"a\": {\"a\": 2 3}}"; 542 jsmn_init(&p); 543 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 544 check(r == JSMN_ERROR_INVAL); 545 return 0; 546} 547 548/** A huge redefinition of everything to include jsmn in non-script mode */ 549#define jsmn_init jsmn_init_nonstrict 550#define jsmn_parse jsmn_parse_nonstrict 551#define jsmn_parser jsmn_parser_nonstrict 552#define jsmn_alloc_token jsmn_alloc_token_nonstrict 553#define jsmn_fill_token jsmn_fill_token_nonstrict 554#define jsmn_parse_primitive jsmn_parse_primitive_nonstrict 555#define jsmn_parse_string jsmn_parse_string_nonstrict 556#define jsmntype_t jsmntype_nonstrict_t 557#define jsmnerr_t jsmnerr_nonstrict_t 558#define jsmntok_t jsmntok_nonstrict_t 559#define JSMN_PRIMITIVE JSMN_PRIMITIVE_NONSTRICT 560#define JSMN_OBJECT JSMN_OBJECT_NONSTRICT 561#define JSMN_ARRAY JSMN_ARRAY_NONSTRICT 562#define JSMN_STRING JSMN_STRING_NONSTRICT 563#define JSMN_ERROR_NOMEM JSMN_ERROR_NOMEM_NONSTRICT 564#define JSMN_ERROR_INVAL JSMN_ERROR_INVAL_NONSTRICT 565#define JSMN_ERROR_PART JSMN_ERROR_PART_NONSTRICT 566#undef __JSMN_H_ 567#undef JSMN_STRICT 568#include "jsmn.c" 569 570int test_nonstrict() { 571 const char *js; 572 int r; 573 jsmn_parser p; 574 jsmntok_t tokens[10]; 575 576 js = "a: 0garbage"; 577 578 jsmn_init(&p); 579 r = jsmn_parse(&p, js, 4, tokens, 10); 580 check(r == 2); 581 check(TOKEN_STRING(js, tokens[0], "a")); 582 check(TOKEN_STRING(js, tokens[1], "0")); 583 584 js = "Day : 26\nMonth : Sep\n\nYear: 12"; 585 jsmn_init(&p); 586 r = jsmn_parse(&p, js, strlen(js), tokens, 10); 587 check(r == 6); 588 return 0; 589} 590 591int main() { 592 test(test_empty, "general test for a empty JSON objects/arrays"); 593 test(test_simple, "general test for a simple JSON string"); 594 test(test_primitive, "test primitive JSON data types"); 595 test(test_string, "test string JSON data types"); 596 test(test_partial_string, "test partial JSON string parsing"); 597 test(test_partial_array, "test partial array reading"); 598 test(test_array_nomem, "test array reading with a smaller number of tokens"); 599 test(test_unquoted_keys, "test unquoted keys (like in JavaScript)"); 600 test(test_objects_arrays, "test objects and arrays"); 601 test(test_unicode_characters, "test unicode characters"); 602 test(test_input_length, "test strings that are not null-terminated"); 603 test(test_issue_22, "test issue #22"); 604 test(test_count, "test tokens count estimation"); 605 test(test_nonstrict, "test for non-strict mode"); 606 test(test_keyvalue, "test for keys/values"); 607 printf("\nPASSED: %d\nFAILED: %d\n", test_passed, test_failed); 608 return 0; 609} 610 611