1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
5 #include "alloc-util.h"
9 #include "json-internal.h"
11 #include "string-util.h"
16 static void test_tokenizer(const char *data
, ...) {
17 unsigned line
= 0, column
= 0;
21 _cleanup_free_
char *cdata
;
22 assert_se(cdata
= cescape(data
));
23 log_info("/* %s data=\"%s\" */", __func__
, cdata
);
28 unsigned token_line
, token_column
;
29 _cleanup_free_
char *str
= NULL
;
30 JsonValue v
= JSON_VALUE_NULL
;
33 t
= json_tokenize(&data
, &str
, &v
, &token_line
, &token_column
, &state
, &line
, &column
);
38 if (t
== JSON_TOKEN_END
|| t
< 0)
41 else if (t
== JSON_TOKEN_STRING
) {
44 nn
= va_arg(ap
, const char *);
45 assert_se(streq_ptr(nn
, str
));
47 } else if (t
== JSON_TOKEN_REAL
) {
50 d
= va_arg(ap
, long double);
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.
57 assert_se(fabsl(d
- v
.real
) < 1e-10 ||
58 fabsl((d
- v
.real
) / v
.real
) < 1e-10);
60 } else if (t
== JSON_TOKEN_INTEGER
) {
63 i
= va_arg(ap
, intmax_t);
64 assert_se(i
== v
.integer
);
66 } else if (t
== JSON_TOKEN_UNSIGNED
) {
69 u
= va_arg(ap
, uintmax_t);
70 assert_se(u
== v
.unsig
);
72 } else if (t
== JSON_TOKEN_BOOLEAN
) {
76 assert_se(b
== v
.boolean
);
83 typedef void (*Test
)(JsonVariant
*);
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
;
90 _cleanup_free_
char *cdata
;
91 assert_se(cdata
= cescape(data
));
92 log_info("/* %s data=\"%s\" */", __func__
, cdata
);
94 r
= json_parse(data
, 0, &v
, NULL
, NULL
);
98 r
= json_variant_format(v
, 0, &s
);
101 assert_se((size_t) r
== strlen(s
));
103 log_info("formatted normally: %s\n", s
);
105 r
= json_parse(data
, JSON_PARSE_SENSITIVE
, &w
, NULL
, NULL
);
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
));
113 w
= json_variant_unref(w
);
115 r
= json_variant_format(v
, JSON_FORMAT_PRETTY
, &s
);
118 assert_se((size_t) r
== strlen(s
));
120 log_info("formatted prettily:\n%s", s
);
122 r
= json_parse(data
, 0, &w
, NULL
, NULL
);
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
));
131 r
= json_variant_format(v
, JSON_FORMAT_COLOR
, &s
);
134 assert_se((size_t) r
== strlen(s
));
135 printf("Normal with color: %s\n", s
);
138 r
= json_variant_format(v
, JSON_FORMAT_COLOR
|JSON_FORMAT_PRETTY
, &s
);
141 assert_se((size_t) r
== strlen(s
));
142 printf("Pretty with color:\n%s\n", s
);
148 static void test_1(JsonVariant
*v
) {
152 log_info("/* %s */", __func__
);
154 /* 3 keys + 3 values */
155 assert_se(json_variant_elements(v
) == 6);
158 p
= json_variant_by_key(v
, "k");
159 assert_se(p
&& json_variant_type(p
) == JSON_VARIANT_STRING
);
162 assert_se(streq(json_variant_string(p
), "v"));
165 p
= json_variant_by_key(v
, "foo");
166 assert_se(p
&& json_variant_type(p
) == JSON_VARIANT_ARRAY
&& json_variant_elements(p
) == 3);
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));
176 p
= json_variant_by_key(v
, "bar");
177 assert_se(p
&& json_variant_type(p
) == JSON_VARIANT_OBJECT
&& json_variant_elements(p
) == 2);
180 q
= json_variant_by_key(p
, "zap");
181 assert_se(q
&& json_variant_type(q
) == JSON_VARIANT_NULL
);
184 static void test_2(JsonVariant
*v
) {
187 log_info("/* %s */", __func__
);
189 /* 2 keys + 2 values */
190 assert_se(json_variant_elements(v
) == 4);
193 p
= json_variant_by_key(v
, "mutant");
194 assert_se(p
&& json_variant_type(p
) == JSON_VARIANT_ARRAY
&& json_variant_elements(p
) == 4);
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);
201 /* mutant[1] == null */
202 q
= json_variant_by_index(p
, 1);
203 assert_se(q
&& json_variant_type(q
) == JSON_VARIANT_NULL
);
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"));
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);
214 p
= json_variant_by_key(q
, "1");
215 assert_se(p
&& json_variant_type(p
) == JSON_VARIANT_ARRAY
&& json_variant_elements(p
) == 2);
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);
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"));
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);
231 static void test_zeroes(JsonVariant
*v
) {
232 /* Make sure zero is how we expect it. */
233 log_info("/* %s */", __func__
);
235 assert_se(json_variant_elements(v
) == 13);
237 for (size_t i
= 0; i
< json_variant_elements(v
); i
++) {
241 assert_se(w
= json_variant_by_index(v
, i
));
243 assert_se(json_variant_integer(w
) == 0);
244 assert_se(json_variant_unsigned(w
) == 0U);
246 DISABLE_WARNING_FLOAT_EQUAL
;
247 assert_se(json_variant_real(w
) == 0.0L);
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
));
255 assert_se(!json_variant_is_negative(w
));
257 assert_se(IN_SET(json_variant_type(w
), JSON_VARIANT_INTEGER
, JSON_VARIANT_UNSIGNED
, JSON_VARIANT_REAL
));
259 for (j
= 0; j
< json_variant_elements(v
); j
++) {
262 assert_se(q
= json_variant_by_index(v
, j
));
264 assert_se(json_variant_equal(w
, q
));
269 static void test_build(void) {
270 log_info("/* %s */", __func__
);
272 _cleanup_(json_variant_unrefp
) JsonVariant
*a
= NULL
, *b
= NULL
;
273 _cleanup_free_
char *s
= NULL
, *t
= NULL
;
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
));
279 b
= json_variant_unref(b
);
281 assert_se(json_build(&b
, JSON_BUILD_VARIANT(a
)) >= 0);
282 assert_se(json_variant_equal(a
, b
));
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
));
288 a
= json_variant_unref(a
);
289 b
= json_variant_unref(b
);
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);
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);
299 assert_se(json_variant_equal(a
, b
));
301 a
= json_variant_unref(a
);
302 b
= json_variant_unref(b
);
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
),
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);
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
));
321 a
= json_variant_unref(a
);
322 b
= json_variant_unref(b
);
324 assert_se(json_build(&a
, JSON_BUILD_REAL(M_PIl
)) >= 0);
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
);
333 assert_se(streq(s
, t
));
335 a
= json_variant_unref(a
);
336 b
= json_variant_unref(b
);
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"))
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"))
352 assert_se(json_variant_equal(a
, b
));
355 static void test_source(void) {
356 static const char data
[] =
360 "\"foo\" : \"bar\", \n"
361 "\"qüüx\" : [ 1, 2, 3,\n"
364 "\"miep\" : { \"hallo\" : 1 },\n"
372 log_info("/* %s */", __func__
);
374 _cleanup_fclose_
FILE *f
= NULL
;
375 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
377 printf("--- original begin ---\n"
379 "--- original end ---\n", data
);
381 assert_se(f
= fmemopen_unlocked((void*) data
, strlen(data
), "r"));
383 assert_se(json_parse_file(f
, "waldo", 0, &v
, NULL
, NULL
) >= 0);
385 printf("--- non-pretty begin ---\n");
386 json_variant_dump(v
, 0, stdout
, NULL
);
387 printf("\n--- non-pretty end ---\n");
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");
394 static void test_depth(void) {
395 log_info("/* %s */", __func__
);
397 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
400 v
= JSON_VARIANT_STRING_CONST("start");
402 /* Let's verify that the maximum depth checks work */
404 for (unsigned i
= 0;; i
++) {
405 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
407 assert_se(i
<= UINT16_MAX
);
409 r
= json_variant_new_array(&w
, &v
, 1);
411 r
= json_variant_new_object(&w
, (JsonVariant
*[]) { JSON_VARIANT_STRING_CONST("key"), v
}, 2);
413 log_info("max depth at %u", i
);
416 #if HAS_FEATURE_MEMORY_SANITIZER
417 /* msan doesn't like the stack nesting to be too deep. Let's quit early. */
419 log_info("quitting early at depth %u", i
);
426 json_variant_unref(v
);
430 json_variant_dump(v
, 0, stdout
, NULL
);
434 static void test_normalize(void) {
435 log_info("/* %s */", __func__
);
437 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
, *w
= NULL
;
438 _cleanup_free_
char *t
= NULL
;
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);
445 assert_se(!json_variant_is_sorted(v
));
446 assert_se(!json_variant_is_normalized(v
));
448 assert_se(json_variant_format(v
, 0, &t
) >= 0);
449 assert_se(streq(t
, "{\"b\":\"x\",\"c\":\"y\",\"a\":\"z\"}"));
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);
456 assert_se(json_variant_is_sorted(w
));
457 assert_se(!json_variant_is_normalized(w
));
459 assert_se(json_variant_format(w
, 0, &t
) >= 0);
460 assert_se(streq(t
, "{\"bar\":\"zzz\",\"foo\":{\"b\":\"x\",\"c\":\"y\",\"a\":\"z\"}}"));
463 assert_se(json_variant_sort(&v
) >= 0);
464 assert_se(json_variant_is_sorted(v
));
465 assert_se(json_variant_is_normalized(v
));
467 assert_se(json_variant_format(v
, 0, &t
) >= 0);
468 assert_se(streq(t
, "{\"a\":\"z\",\"b\":\"x\",\"c\":\"y\"}"));
471 assert_se(json_variant_normalize(&w
) >= 0);
472 assert_se(json_variant_is_sorted(w
));
473 assert_se(json_variant_is_normalized(w
));
475 assert_se(json_variant_format(w
, 0, &t
) >= 0);
476 assert_se(streq(t
, "{\"bar\":\"zzz\",\"foo\":{\"a\":\"z\",\"b\":\"x\",\"c\":\"y\"}}"));
480 static void test_bisect(void) {
481 log_info("/* %s */", __func__
);
483 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
485 /* Tests the bisection logic in json_variant_by_key() */
487 for (char c
= 'z'; c
>= 'a'; c
--) {
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);
497 json_variant_dump(v
, JSON_FORMAT_COLOR
|JSON_FORMAT_PRETTY
, NULL
, NULL
);
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
));
505 json_variant_dump(v
, JSON_FORMAT_COLOR
|JSON_FORMAT_PRETTY
, NULL
, NULL
);
507 for (char c
= 'a'; c
<= 'z'; c
++) {
511 k
= json_variant_by_key(v
, (char[2]) { c
, 0 });
512 assert_se(!k
== ((c
% 3) == 0));
517 assert_se(json_variant_is_string(k
));
519 z
= (char[5]){ '<', c
, c
, '>', 0};
520 assert_se(streq(json_variant_string(k
), z
));
524 int main(int argc
, char *argv
[]) {
525 test_setup_logging(LOG_DEBUG
);
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
);
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
);
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
);
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
);