]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-json.c
1d4b11945ec4c39de87150b8dd29b34e049b7f69
[thirdparty/systemd.git] / src / test / test-json.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <math.h>
4
5 #include "alloc-util.h"
6 #include "escape.h"
7 #include "fd-util.h"
8 #include "fileio.h"
9 #include "json-internal.h"
10 #include "json.h"
11 #include "string-util.h"
12 #include "strv.h"
13 #include "tests.h"
14 #include "util.h"
15
16 static void test_tokenizer(const char *data, ...) {
17 unsigned line = 0, column = 0;
18 void *state = NULL;
19 va_list ap;
20
21 _cleanup_free_ char *cdata;
22 assert_se(cdata = cescape(data));
23 log_info("/* %s data=\"%s\" */", __func__, cdata);
24
25 va_start(ap, data);
26
27 for (;;) {
28 unsigned token_line, token_column;
29 _cleanup_free_ char *str = NULL;
30 JsonValue v = JSON_VALUE_NULL;
31 int t, tt;
32
33 t = json_tokenize(&data, &str, &v, &token_line, &token_column, &state, &line, &column);
34 tt = va_arg(ap, int);
35
36 assert_se(t == tt);
37
38 if (t == JSON_TOKEN_END || t < 0)
39 break;
40
41 else if (t == JSON_TOKEN_STRING) {
42 const char *nn;
43
44 nn = va_arg(ap, const char *);
45 assert_se(streq_ptr(nn, str));
46
47 } else if (t == JSON_TOKEN_REAL) {
48 long double d;
49
50 d = va_arg(ap, long double);
51
52 /* Valgrind doesn't support long double calculations and automatically downgrades to 80bit:
53 * http://www.valgrind.org/docs/manual/manual-core.html#manual-core.limits.
54 * Some architectures might not support long double either.
55 */
56
57 assert_se(fabsl(d - v.real) < 1e-10 ||
58 fabsl((d - v.real) / v.real) < 1e-10);
59
60 } else if (t == JSON_TOKEN_INTEGER) {
61 intmax_t i;
62
63 i = va_arg(ap, intmax_t);
64 assert_se(i == v.integer);
65
66 } else if (t == JSON_TOKEN_UNSIGNED) {
67 uintmax_t u;
68
69 u = va_arg(ap, uintmax_t);
70 assert_se(u == v.unsig);
71
72 } else if (t == JSON_TOKEN_BOOLEAN) {
73 bool b;
74
75 b = va_arg(ap, int);
76 assert_se(b == v.boolean);
77 }
78 }
79
80 va_end(ap);
81 }
82
83 typedef void (*Test)(JsonVariant *);
84
85 static void test_variant(const char *data, Test test) {
86 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL;
87 _cleanup_free_ char *s = NULL;
88 int r;
89
90 _cleanup_free_ char *cdata;
91 assert_se(cdata = cescape(data));
92 log_info("/* %s data=\"%s\" */", __func__, cdata);
93
94 r = json_parse(data, 0, &v, NULL, NULL);
95 assert_se(r == 0);
96 assert_se(v);
97
98 r = json_variant_format(v, 0, &s);
99 assert_se(r >= 0);
100 assert_se(s);
101 assert_se((size_t) r == strlen(s));
102
103 log_info("formatted normally: %s\n", s);
104
105 r = json_parse(data, JSON_PARSE_SENSITIVE, &w, NULL, NULL);
106 assert_se(r == 0);
107 assert_se(w);
108 assert_se(json_variant_has_type(v, json_variant_type(w)));
109 assert_se(json_variant_has_type(w, json_variant_type(v)));
110 assert_se(json_variant_equal(v, w));
111
112 s = mfree(s);
113 w = json_variant_unref(w);
114
115 r = json_variant_format(v, JSON_FORMAT_PRETTY, &s);
116 assert_se(r >= 0);
117 assert_se(s);
118 assert_se((size_t) r == strlen(s));
119
120 log_info("formatted prettily:\n%s", s);
121
122 r = json_parse(data, 0, &w, NULL, NULL);
123 assert_se(r == 0);
124 assert_se(w);
125
126 assert_se(json_variant_has_type(v, json_variant_type(w)));
127 assert_se(json_variant_has_type(w, json_variant_type(v)));
128 assert_se(json_variant_equal(v, w));
129
130 s = mfree(s);
131 r = json_variant_format(v, JSON_FORMAT_COLOR, &s);
132 assert_se(r >= 0);
133 assert_se(s);
134 assert_se((size_t) r == strlen(s));
135 printf("Normal with color: %s\n", s);
136
137 s = mfree(s);
138 r = json_variant_format(v, JSON_FORMAT_COLOR|JSON_FORMAT_PRETTY, &s);
139 assert_se(r >= 0);
140 assert_se(s);
141 assert_se((size_t) r == strlen(s));
142 printf("Pretty with color:\n%s\n", s);
143
144 if (test)
145 test(v);
146 }
147
148 static void test_1(JsonVariant *v) {
149 JsonVariant *p, *q;
150 unsigned i;
151
152 log_info("/* %s */", __func__);
153
154 /* 3 keys + 3 values */
155 assert_se(json_variant_elements(v) == 6);
156
157 /* has k */
158 p = json_variant_by_key(v, "k");
159 assert_se(p && json_variant_type(p) == JSON_VARIANT_STRING);
160
161 /* k equals v */
162 assert_se(streq(json_variant_string(p), "v"));
163
164 /* has foo */
165 p = json_variant_by_key(v, "foo");
166 assert_se(p && json_variant_type(p) == JSON_VARIANT_ARRAY && json_variant_elements(p) == 3);
167
168 /* check foo[0] = 1, foo[1] = 2, foo[2] = 3 */
169 for (i = 0; i < 3; ++i) {
170 q = json_variant_by_index(p, i);
171 assert_se(q && json_variant_type(q) == JSON_VARIANT_UNSIGNED && json_variant_unsigned(q) == (i+1));
172 assert_se(q && json_variant_has_type(q, JSON_VARIANT_INTEGER) && json_variant_integer(q) == (i+1));
173 }
174
175 /* has bar */
176 p = json_variant_by_key(v, "bar");
177 assert_se(p && json_variant_type(p) == JSON_VARIANT_OBJECT && json_variant_elements(p) == 2);
178
179 /* zap is null */
180 q = json_variant_by_key(p, "zap");
181 assert_se(q && json_variant_type(q) == JSON_VARIANT_NULL);
182 }
183
184 static void test_2(JsonVariant *v) {
185 JsonVariant *p, *q;
186
187 log_info("/* %s */", __func__);
188
189 /* 2 keys + 2 values */
190 assert_se(json_variant_elements(v) == 4);
191
192 /* has mutant */
193 p = json_variant_by_key(v, "mutant");
194 assert_se(p && json_variant_type(p) == JSON_VARIANT_ARRAY && json_variant_elements(p) == 4);
195
196 /* mutant[0] == 1 */
197 q = json_variant_by_index(p, 0);
198 assert_se(q && json_variant_type(q) == JSON_VARIANT_UNSIGNED && json_variant_unsigned(q) == 1);
199 assert_se(q && json_variant_has_type(q, JSON_VARIANT_INTEGER) && json_variant_integer(q) == 1);
200
201 /* mutant[1] == null */
202 q = json_variant_by_index(p, 1);
203 assert_se(q && json_variant_type(q) == JSON_VARIANT_NULL);
204
205 /* mutant[2] == "1" */
206 q = json_variant_by_index(p, 2);
207 assert_se(q && json_variant_type(q) == JSON_VARIANT_STRING && streq(json_variant_string(q), "1"));
208
209 /* mutant[3] == JSON_VARIANT_OBJECT */
210 q = json_variant_by_index(p, 3);
211 assert_se(q && json_variant_type(q) == JSON_VARIANT_OBJECT && json_variant_elements(q) == 2);
212
213 /* has 1 */
214 p = json_variant_by_key(q, "1");
215 assert_se(p && json_variant_type(p) == JSON_VARIANT_ARRAY && json_variant_elements(p) == 2);
216
217 /* "1"[0] == 1 */
218 q = json_variant_by_index(p, 0);
219 assert_se(q && json_variant_type(q) == JSON_VARIANT_UNSIGNED && json_variant_unsigned(q) == 1);
220 assert_se(q && json_variant_has_type(q, JSON_VARIANT_INTEGER) && json_variant_integer(q) == 1);
221
222 /* "1"[1] == "1" */
223 q = json_variant_by_index(p, 1);
224 assert_se(q && json_variant_type(q) == JSON_VARIANT_STRING && streq(json_variant_string(q), "1"));
225
226 /* has thisisaverylongproperty */
227 p = json_variant_by_key(v, "thisisaverylongproperty");
228 assert_se(p && json_variant_type(p) == JSON_VARIANT_REAL && fabsl(json_variant_real(p) - 1.27) < 0.001);
229 }
230
231 static void test_zeroes(JsonVariant *v) {
232 /* Make sure zero is how we expect it. */
233 log_info("/* %s */", __func__);
234
235 assert_se(json_variant_elements(v) == 13);
236
237 for (size_t i = 0; i < json_variant_elements(v); i++) {
238 JsonVariant *w;
239 size_t j;
240
241 assert_se(w = json_variant_by_index(v, i));
242
243 assert_se(json_variant_integer(w) == 0);
244 assert_se(json_variant_unsigned(w) == 0U);
245
246 DISABLE_WARNING_FLOAT_EQUAL;
247 assert_se(json_variant_real(w) == 0.0L);
248 REENABLE_WARNING;
249
250 assert_se(json_variant_is_integer(w));
251 assert_se(json_variant_is_unsigned(w));
252 assert_se(json_variant_is_real(w));
253 assert_se(json_variant_is_number(w));
254
255 assert_se(!json_variant_is_negative(w));
256
257 assert_se(IN_SET(json_variant_type(w), JSON_VARIANT_INTEGER, JSON_VARIANT_UNSIGNED, JSON_VARIANT_REAL));
258
259 for (j = 0; j < json_variant_elements(v); j++) {
260 JsonVariant *q;
261
262 assert_se(q = json_variant_by_index(v, j));
263
264 assert_se(json_variant_equal(w, q));
265 }
266 }
267 }
268
269 static void test_build(void) {
270 log_info("/* %s */", __func__);
271
272 _cleanup_(json_variant_unrefp) JsonVariant *a = NULL, *b = NULL;
273 _cleanup_free_ char *s = NULL, *t = NULL;
274
275 assert_se(json_build(&a, JSON_BUILD_STRING("hallo")) >= 0);
276 assert_se(json_build(&b, JSON_BUILD_LITERAL(" \"hallo\" ")) >= 0);
277 assert_se(json_variant_equal(a, b));
278
279 b = json_variant_unref(b);
280
281 assert_se(json_build(&b, JSON_BUILD_VARIANT(a)) >= 0);
282 assert_se(json_variant_equal(a, b));
283
284 b = json_variant_unref(b);
285 assert_se(json_build(&b, JSON_BUILD_STRING("pief")) >= 0);
286 assert_se(!json_variant_equal(a, b));
287
288 a = json_variant_unref(a);
289 b = json_variant_unref(b);
290
291 assert_se(json_build(&a, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("one", JSON_BUILD_INTEGER(7)),
292 JSON_BUILD_PAIR("two", JSON_BUILD_REAL(2.0)),
293 JSON_BUILD_PAIR("three", JSON_BUILD_INTEGER(0)))) >= 0);
294
295 assert_se(json_build(&b, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("two", JSON_BUILD_INTEGER(2)),
296 JSON_BUILD_PAIR("three", JSON_BUILD_REAL(0)),
297 JSON_BUILD_PAIR("one", JSON_BUILD_REAL(7)))) >= 0);
298
299 assert_se(json_variant_equal(a, b));
300
301 a = json_variant_unref(a);
302 b = json_variant_unref(b);
303
304 const char* arr_1234[] = {"one", "two", "three", "four", NULL};
305 assert_se(json_build(&a, JSON_BUILD_ARRAY(JSON_BUILD_OBJECT(JSON_BUILD_PAIR("x", JSON_BUILD_BOOLEAN(true)),
306 JSON_BUILD_PAIR("y", JSON_BUILD_OBJECT(JSON_BUILD_PAIR("this", JSON_BUILD_NULL)))),
307 JSON_BUILD_VARIANT(NULL),
308 JSON_BUILD_LITERAL(NULL),
309 JSON_BUILD_STRING(NULL),
310 JSON_BUILD_NULL,
311 JSON_BUILD_INTEGER(77),
312 JSON_BUILD_ARRAY(JSON_BUILD_VARIANT(JSON_VARIANT_STRING_CONST("foobar")),
313 JSON_BUILD_VARIANT(JSON_VARIANT_STRING_CONST("zzz"))),
314 JSON_BUILD_STRV((char**) arr_1234))) >= 0);
315
316 assert_se(json_variant_format(a, 0, &s) >= 0);
317 log_info("GOT: %s\n", s);
318 assert_se(json_parse(s, 0, &b, NULL, NULL) >= 0);
319 assert_se(json_variant_equal(a, b));
320
321 a = json_variant_unref(a);
322 b = json_variant_unref(b);
323
324 assert_se(json_build(&a, JSON_BUILD_REAL(M_PIl)) >= 0);
325
326 s = mfree(s);
327 assert_se(json_variant_format(a, 0, &s) >= 0);
328 log_info("GOT: %s\n", s);
329 assert_se(json_parse(s, 0, &b, NULL, NULL) >= 0);
330 assert_se(json_variant_format(b, 0, &t) >= 0);
331 log_info("GOT: %s\n", t);
332
333 assert_se(streq(s, t));
334
335 a = json_variant_unref(a);
336 b = json_variant_unref(b);
337
338 assert_se(json_build(&a, JSON_BUILD_OBJECT(
339 JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")),
340 JSON_BUILD_PAIR("z", JSON_BUILD_STRING("a")),
341 JSON_BUILD_PAIR("b", JSON_BUILD_STRING("c"))
342 )) >= 0);
343
344 assert_se(json_build(&b, JSON_BUILD_OBJECT(
345 JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")),
346 JSON_BUILD_PAIR_CONDITION(false, "p", JSON_BUILD_STRING("q")),
347 JSON_BUILD_PAIR_CONDITION(true, "z", JSON_BUILD_STRING("a")),
348 JSON_BUILD_PAIR_CONDITION(false, "j", JSON_BUILD_ARRAY(JSON_BUILD_STRING("k"), JSON_BUILD_STRING("u"), JSON_BUILD_STRING("i"))),
349 JSON_BUILD_PAIR("b", JSON_BUILD_STRING("c"))
350 )) >= 0);
351
352 assert_se(json_variant_equal(a, b));
353 }
354
355 static void test_source(void) {
356 static const char data[] =
357 "\n"
358 "\n"
359 "{\n"
360 "\"foo\" : \"bar\", \n"
361 "\"qüüx\" : [ 1, 2, 3,\n"
362 "4,\n"
363 "5 ],\n"
364 "\"miep\" : { \"hallo\" : 1 },\n"
365 "\n"
366 "\"zzzzzz\" \n"
367 ":\n"
368 "[ true, \n"
369 "false, 7.5, {} ]\n"
370 "}\n";
371
372 log_info("/* %s */", __func__);
373
374 _cleanup_fclose_ FILE *f = NULL;
375 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
376
377 printf("--- original begin ---\n"
378 "%s"
379 "--- original end ---\n", data);
380
381 assert_se(f = fmemopen_unlocked((void*) data, strlen(data), "r"));
382
383 assert_se(json_parse_file(f, "waldo", 0, &v, NULL, NULL) >= 0);
384
385 printf("--- non-pretty begin ---\n");
386 json_variant_dump(v, 0, stdout, NULL);
387 printf("\n--- non-pretty end ---\n");
388
389 printf("--- pretty begin ---\n");
390 json_variant_dump(v, JSON_FORMAT_PRETTY|JSON_FORMAT_COLOR|JSON_FORMAT_SOURCE, stdout, NULL);
391 printf("--- pretty end ---\n");
392 }
393
394 static void test_depth(void) {
395 log_info("/* %s */", __func__);
396
397 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
398 int r;
399
400 v = JSON_VARIANT_STRING_CONST("start");
401
402 /* Let's verify that the maximum depth checks work */
403
404 for (unsigned i = 0;; i++) {
405 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
406
407 assert_se(i <= UINT16_MAX);
408 if (i & 1)
409 r = json_variant_new_array(&w, &v, 1);
410 else
411 r = json_variant_new_object(&w, (JsonVariant*[]) { JSON_VARIANT_STRING_CONST("key"), v }, 2);
412 if (r == -ELNRNG) {
413 log_info("max depth at %u", i);
414 break;
415 }
416 #if HAS_FEATURE_MEMORY_SANITIZER
417 /* msan doesn't like the stack nesting to be too deep. Let's quit early. */
418 if (i >= 128) {
419 log_info("quitting early at depth %u", i);
420 break;
421 }
422 #endif
423
424 assert_se(r >= 0);
425
426 json_variant_unref(v);
427 v = TAKE_PTR(w);
428 }
429
430 json_variant_dump(v, 0, stdout, NULL);
431 fputs("\n", stdout);
432 }
433
434 static void test_normalize(void) {
435 log_info("/* %s */", __func__);
436
437 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL;
438 _cleanup_free_ char *t = NULL;
439
440 assert_se(json_build(&v, JSON_BUILD_OBJECT(
441 JSON_BUILD_PAIR("b", JSON_BUILD_STRING("x")),
442 JSON_BUILD_PAIR("c", JSON_BUILD_STRING("y")),
443 JSON_BUILD_PAIR("a", JSON_BUILD_STRING("z")))) >= 0);
444
445 assert_se(!json_variant_is_sorted(v));
446 assert_se(!json_variant_is_normalized(v));
447
448 assert_se(json_variant_format(v, 0, &t) >= 0);
449 assert_se(streq(t, "{\"b\":\"x\",\"c\":\"y\",\"a\":\"z\"}"));
450 t = mfree(t);
451
452 assert_se(json_build(&w, JSON_BUILD_OBJECT(
453 JSON_BUILD_PAIR("bar", JSON_BUILD_STRING("zzz")),
454 JSON_BUILD_PAIR("foo", JSON_BUILD_VARIANT(v)))) >= 0);
455
456 assert_se(json_variant_is_sorted(w));
457 assert_se(!json_variant_is_normalized(w));
458
459 assert_se(json_variant_format(w, 0, &t) >= 0);
460 assert_se(streq(t, "{\"bar\":\"zzz\",\"foo\":{\"b\":\"x\",\"c\":\"y\",\"a\":\"z\"}}"));
461 t = mfree(t);
462
463 assert_se(json_variant_sort(&v) >= 0);
464 assert_se(json_variant_is_sorted(v));
465 assert_se(json_variant_is_normalized(v));
466
467 assert_se(json_variant_format(v, 0, &t) >= 0);
468 assert_se(streq(t, "{\"a\":\"z\",\"b\":\"x\",\"c\":\"y\"}"));
469 t = mfree(t);
470
471 assert_se(json_variant_normalize(&w) >= 0);
472 assert_se(json_variant_is_sorted(w));
473 assert_se(json_variant_is_normalized(w));
474
475 assert_se(json_variant_format(w, 0, &t) >= 0);
476 assert_se(streq(t, "{\"bar\":\"zzz\",\"foo\":{\"a\":\"z\",\"b\":\"x\",\"c\":\"y\"}}"));
477 t = mfree(t);
478 }
479
480 static void test_bisect(void) {
481 log_info("/* %s */", __func__);
482
483 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
484
485 /* Tests the bisection logic in json_variant_by_key() */
486
487 for (char c = 'z'; c >= 'a'; c--) {
488
489 if ((c % 3) == 0)
490 continue;
491
492 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
493 assert_se(json_variant_new_stringn(&w, (char[4]) { '<', c, c, '>' }, 4) >= 0);
494 assert_se(json_variant_set_field(&v, (char[2]) { c, 0 }, w) >= 0);
495 }
496
497 json_variant_dump(v, JSON_FORMAT_COLOR|JSON_FORMAT_PRETTY, NULL, NULL);
498
499 assert_se(!json_variant_is_sorted(v));
500 assert_se(!json_variant_is_normalized(v));
501 assert_se(json_variant_normalize(&v) >= 0);
502 assert_se(json_variant_is_sorted(v));
503 assert_se(json_variant_is_normalized(v));
504
505 json_variant_dump(v, JSON_FORMAT_COLOR|JSON_FORMAT_PRETTY, NULL, NULL);
506
507 for (char c = 'a'; c <= 'z'; c++) {
508 JsonVariant *k;
509 const char *z;
510
511 k = json_variant_by_key(v, (char[2]) { c, 0 });
512 assert_se(!k == ((c % 3) == 0));
513
514 if (!k)
515 continue;
516
517 assert_se(json_variant_is_string(k));
518
519 z = (char[5]){ '<', c, c, '>', 0};
520 assert_se(streq(json_variant_string(k), z));
521 }
522 }
523
524 int main(int argc, char *argv[]) {
525 test_setup_logging(LOG_DEBUG);
526
527 test_tokenizer("x", -EINVAL);
528 test_tokenizer("", JSON_TOKEN_END);
529 test_tokenizer(" ", JSON_TOKEN_END);
530 test_tokenizer("0", JSON_TOKEN_UNSIGNED, (uintmax_t) 0, JSON_TOKEN_END);
531 test_tokenizer("-0", JSON_TOKEN_INTEGER, (intmax_t) 0, JSON_TOKEN_END);
532 test_tokenizer("1234", JSON_TOKEN_UNSIGNED, (uintmax_t) 1234, JSON_TOKEN_END);
533 test_tokenizer("-1234", JSON_TOKEN_INTEGER, (intmax_t) -1234, JSON_TOKEN_END);
534 test_tokenizer("18446744073709551615", JSON_TOKEN_UNSIGNED, (uintmax_t) UINT64_MAX, JSON_TOKEN_END);
535 test_tokenizer("-9223372036854775808", JSON_TOKEN_INTEGER, (intmax_t) INT64_MIN, JSON_TOKEN_END);
536 test_tokenizer("18446744073709551616", JSON_TOKEN_REAL, (long double) 18446744073709551616.0L, JSON_TOKEN_END);
537 test_tokenizer("-9223372036854775809", JSON_TOKEN_REAL, (long double) -9223372036854775809.0L, JSON_TOKEN_END);
538 test_tokenizer("-1234", JSON_TOKEN_INTEGER, (intmax_t) -1234, JSON_TOKEN_END);
539 test_tokenizer("3.141", JSON_TOKEN_REAL, (long double) 3.141, JSON_TOKEN_END);
540 test_tokenizer("0.0", JSON_TOKEN_REAL, (long double) 0.0, JSON_TOKEN_END);
541 test_tokenizer("7e3", JSON_TOKEN_REAL, (long double) 7e3, JSON_TOKEN_END);
542 test_tokenizer("-7e-3", JSON_TOKEN_REAL, (long double) -7e-3, JSON_TOKEN_END);
543 test_tokenizer("true", JSON_TOKEN_BOOLEAN, true, JSON_TOKEN_END);
544 test_tokenizer("false", JSON_TOKEN_BOOLEAN, false, JSON_TOKEN_END);
545 test_tokenizer("null", JSON_TOKEN_NULL, JSON_TOKEN_END);
546 test_tokenizer("{}", JSON_TOKEN_OBJECT_OPEN, JSON_TOKEN_OBJECT_CLOSE, JSON_TOKEN_END);
547 test_tokenizer("\t {\n} \n", JSON_TOKEN_OBJECT_OPEN, JSON_TOKEN_OBJECT_CLOSE, JSON_TOKEN_END);
548 test_tokenizer("[]", JSON_TOKEN_ARRAY_OPEN, JSON_TOKEN_ARRAY_CLOSE, JSON_TOKEN_END);
549 test_tokenizer("\t [] \n\n", JSON_TOKEN_ARRAY_OPEN, JSON_TOKEN_ARRAY_CLOSE, JSON_TOKEN_END);
550 test_tokenizer("\"\"", JSON_TOKEN_STRING, "", JSON_TOKEN_END);
551 test_tokenizer("\"foo\"", JSON_TOKEN_STRING, "foo", JSON_TOKEN_END);
552 test_tokenizer("\"foo\\nfoo\"", JSON_TOKEN_STRING, "foo\nfoo", JSON_TOKEN_END);
553 test_tokenizer("{\"foo\" : \"bar\"}", JSON_TOKEN_OBJECT_OPEN, JSON_TOKEN_STRING, "foo", JSON_TOKEN_COLON, JSON_TOKEN_STRING, "bar", JSON_TOKEN_OBJECT_CLOSE, JSON_TOKEN_END);
554 test_tokenizer("{\"foo\" : [true, false]}", JSON_TOKEN_OBJECT_OPEN, JSON_TOKEN_STRING, "foo", JSON_TOKEN_COLON, JSON_TOKEN_ARRAY_OPEN, JSON_TOKEN_BOOLEAN, true, JSON_TOKEN_COMMA, JSON_TOKEN_BOOLEAN, false, JSON_TOKEN_ARRAY_CLOSE, JSON_TOKEN_OBJECT_CLOSE, JSON_TOKEN_END);
555 test_tokenizer("\"\xef\xbf\xbd\"", JSON_TOKEN_STRING, "\xef\xbf\xbd", JSON_TOKEN_END);
556 test_tokenizer("\"\\ufffd\"", JSON_TOKEN_STRING, "\xef\xbf\xbd", JSON_TOKEN_END);
557 test_tokenizer("\"\\uf\"", -EINVAL);
558 test_tokenizer("\"\\ud800a\"", -EINVAL);
559 test_tokenizer("\"\\udc00\\udc00\"", -EINVAL);
560 test_tokenizer("\"\\ud801\\udc37\"", JSON_TOKEN_STRING, "\xf0\x90\x90\xb7", JSON_TOKEN_END);
561
562 test_tokenizer("[1, 2, -3]", JSON_TOKEN_ARRAY_OPEN, JSON_TOKEN_UNSIGNED, (uintmax_t) 1, JSON_TOKEN_COMMA, JSON_TOKEN_UNSIGNED, (uintmax_t) 2, JSON_TOKEN_COMMA, JSON_TOKEN_INTEGER, (intmax_t) -3, JSON_TOKEN_ARRAY_CLOSE, JSON_TOKEN_END);
563
564 test_variant("{\"k\": \"v\", \"foo\": [1, 2, 3], \"bar\": {\"zap\": null}}", test_1);
565 test_variant("{\"mutant\": [1, null, \"1\", {\"1\": [1, \"1\"]}], \"thisisaverylongproperty\": 1.27}", test_2);
566 test_variant("{\"foo\" : \"\\u0935\\u093f\\u0935\\u0947\\u0915\\u0916\\u094d\\u092f\\u093e\\u0924\\u093f\\u0930\\u0935\\u093f\\u092a\\u094d\\u0932\\u0935\\u093e\\u0020\\u0939\\u093e\\u0928\\u094b\\u092a\\u093e\\u092f\\u0903\\u0964\"}", NULL);
567
568 test_variant("[ 0, -0, 0.0, -0.0, 0.000, -0.000, 0e0, -0e0, 0e+0, -0e-0, 0e-0, -0e000, 0e+000 ]", test_zeroes);
569
570 test_build();
571 test_source();
572 test_depth();
573
574 test_normalize();
575 test_bisect();
576
577 return 0;
578 }