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