]>
git.ipfire.org Git - thirdparty/git.git/blob - t/helper/test-json-writer.c
3 #include "json-writer.h"
5 static const char *expect_obj1
= "{\"a\":\"abc\",\"b\":42,\"c\":true}";
6 static const char *expect_obj2
= "{\"a\":-1,\"b\":2147483647,\"c\":0}";
7 static const char *expect_obj3
= "{\"a\":0,\"b\":4294967295,\"c\":9223372036854775807}";
8 static const char *expect_obj4
= "{\"t\":true,\"f\":false,\"n\":null}";
9 static const char *expect_obj5
= "{\"abc\\tdef\":\"abc\\\\def\"}";
10 static const char *expect_obj6
= "{\"a\":3.14}";
12 static const char *pretty_obj1
= ("{\n"
17 static const char *pretty_obj2
= ("{\n"
19 " \"b\": 2147483647,\n"
22 static const char *pretty_obj3
= ("{\n"
24 " \"b\": 4294967295,\n"
25 " \"c\": 9223372036854775807\n"
27 static const char *pretty_obj4
= ("{\n"
33 static struct json_writer obj1
= JSON_WRITER_INIT
;
34 static struct json_writer obj2
= JSON_WRITER_INIT
;
35 static struct json_writer obj3
= JSON_WRITER_INIT
;
36 static struct json_writer obj4
= JSON_WRITER_INIT
;
37 static struct json_writer obj5
= JSON_WRITER_INIT
;
38 static struct json_writer obj6
= JSON_WRITER_INIT
;
40 static void make_obj1(int pretty
)
42 jw_object_begin(&obj1
, pretty
);
44 jw_object_string(&obj1
, "a", "abc");
45 jw_object_intmax(&obj1
, "b", 42);
46 jw_object_true(&obj1
, "c");
51 static void make_obj2(int pretty
)
53 jw_object_begin(&obj2
, pretty
);
55 jw_object_intmax(&obj2
, "a", -1);
56 jw_object_intmax(&obj2
, "b", 0x7fffffff);
57 jw_object_intmax(&obj2
, "c", 0);
62 static void make_obj3(int pretty
)
64 jw_object_begin(&obj3
, pretty
);
66 jw_object_intmax(&obj3
, "a", 0);
67 jw_object_intmax(&obj3
, "b", 0xffffffff);
68 jw_object_intmax(&obj3
, "c", 0x7fffffffffffffffULL
);
73 static void make_obj4(int pretty
)
75 jw_object_begin(&obj4
, pretty
);
77 jw_object_true(&obj4
, "t");
78 jw_object_false(&obj4
, "f");
79 jw_object_null(&obj4
, "n");
84 static void make_obj5(int pretty
)
86 jw_object_begin(&obj5
, pretty
);
88 jw_object_string(&obj5
, "abc" "\x09" "def", "abc" "\\" "def");
93 static void make_obj6(int pretty
)
95 jw_object_begin(&obj6
, pretty
);
97 jw_object_double(&obj6
, "a", 2, 3.14159);
102 static const char *expect_arr1
= "[\"abc\",42,true]";
103 static const char *expect_arr2
= "[-1,2147483647,0]";
104 static const char *expect_arr3
= "[0,4294967295,9223372036854775807]";
105 static const char *expect_arr4
= "[true,false,null]";
107 static const char *pretty_arr1
= ("[\n"
112 static const char *pretty_arr2
= ("[\n"
117 static const char *pretty_arr3
= ("[\n"
120 " 9223372036854775807\n"
122 static const char *pretty_arr4
= ("[\n"
128 static struct json_writer arr1
= JSON_WRITER_INIT
;
129 static struct json_writer arr2
= JSON_WRITER_INIT
;
130 static struct json_writer arr3
= JSON_WRITER_INIT
;
131 static struct json_writer arr4
= JSON_WRITER_INIT
;
133 static void make_arr1(int pretty
)
135 jw_array_begin(&arr1
, pretty
);
137 jw_array_string(&arr1
, "abc");
138 jw_array_intmax(&arr1
, 42);
139 jw_array_true(&arr1
);
144 static void make_arr2(int pretty
)
146 jw_array_begin(&arr2
, pretty
);
148 jw_array_intmax(&arr2
, -1);
149 jw_array_intmax(&arr2
, 0x7fffffff);
150 jw_array_intmax(&arr2
, 0);
155 static void make_arr3(int pretty
)
157 jw_array_begin(&arr3
, pretty
);
159 jw_array_intmax(&arr3
, 0);
160 jw_array_intmax(&arr3
, 0xffffffff);
161 jw_array_intmax(&arr3
, 0x7fffffffffffffffULL
);
166 static void make_arr4(int pretty
)
168 jw_array_begin(&arr4
, pretty
);
170 jw_array_true(&arr4
);
171 jw_array_false(&arr4
);
172 jw_array_null(&arr4
);
177 static char *expect_nest1
=
178 "{\"obj1\":{\"a\":\"abc\",\"b\":42,\"c\":true},\"arr1\":[\"abc\",42,true]}";
180 static struct json_writer nest1
= JSON_WRITER_INIT
;
182 static void make_nest1(int pretty
)
187 jw_object_begin(&nest1
, pretty
);
189 jw_object_sub_jw(&nest1
, "obj1", &obj1
);
190 jw_object_sub_jw(&nest1
, "arr1", &arr1
);
198 static char *expect_inline1
=
199 "{\"obj1\":{\"a\":\"abc\",\"b\":42,\"c\":true},\"arr1\":[\"abc\",42,true]}";
201 static char *pretty_inline1
=
215 static struct json_writer inline1
= JSON_WRITER_INIT
;
217 static void make_inline1(int pretty
)
219 jw_object_begin(&inline1
, pretty
);
221 jw_object_inline_begin_object(&inline1
, "obj1");
223 jw_object_string(&inline1
, "a", "abc");
224 jw_object_intmax(&inline1
, "b", 42);
225 jw_object_true(&inline1
, "c");
228 jw_object_inline_begin_array(&inline1
, "arr1");
230 jw_array_string(&inline1
, "abc");
231 jw_array_intmax(&inline1
, 42);
232 jw_array_true(&inline1
);
239 static char *expect_inline2
=
240 "[[1,2],[3,4],{\"a\":\"abc\"}]";
242 static char *pretty_inline2
=
257 static struct json_writer inline2
= JSON_WRITER_INIT
;
259 static void make_inline2(int pretty
)
261 jw_array_begin(&inline2
, pretty
);
263 jw_array_inline_begin_array(&inline2
);
265 jw_array_intmax(&inline2
, 1);
266 jw_array_intmax(&inline2
, 2);
269 jw_array_inline_begin_array(&inline2
);
271 jw_array_intmax(&inline2
, 3);
272 jw_array_intmax(&inline2
, 4);
275 jw_array_inline_begin_object(&inline2
);
277 jw_object_string(&inline2
, "a", "abc");
285 * When super is compact, we expect subs to be compacted (even if originally
288 static const char *expect_mixed1
=
289 ("{\"obj1\":{\"a\":\"abc\",\"b\":42,\"c\":true},"
290 "\"arr1\":[\"abc\",42,true]}");
293 * When super is pretty, a compact sub (obj1) is kept compact and a pretty
294 * sub (arr1) is re-indented.
296 static const char *pretty_mixed1
=
298 " \"obj1\": {\"a\":\"abc\",\"b\":42,\"c\":true},\n"
306 static struct json_writer mixed1
= JSON_WRITER_INIT
;
308 static void make_mixed1(int pretty
)
313 make_obj1(0); /* obj1 is compact */
314 make_arr1(1); /* arr1 is pretty */
316 jw_object_begin(&mixed1
, pretty
);
318 jw_object_sub_jw(&mixed1
, "obj1", &obj1
);
319 jw_object_sub_jw(&mixed1
, "arr1", &arr1
);
327 static void cmp(const char *test
, const struct json_writer
*jw
, const char *exp
)
329 if (!strcmp(jw
->json
.buf
, exp
))
332 printf("error[%s]: observed '%s' expected '%s'\n",
333 test
, jw
->json
.buf
, exp
);
337 #define t(v) do { make_##v(0); cmp(#v, &v, expect_##v); jw_release(&v); } while (0)
338 #define p(v) do { make_##v(1); cmp(#v, &v, pretty_##v); jw_release(&v); } while (0)
341 * Run some basic regression tests with some known patterns.
342 * These tests also demonstrate how to use the jw_ API.
344 static int unit_tests(void)
346 /* comptact (canonical) forms */
398 static void get_s(int line_nr
, char **s_in
)
400 *s_in
= strtok(NULL
, " ");
402 die("line[%d]: expected: <s>", line_nr
);
405 static void get_i(int line_nr
, intmax_t *s_in
)
412 *s_in
= strtol(s
, &endptr
, 10);
413 if (*endptr
|| errno
== ERANGE
)
414 die("line[%d]: invalid integer value", line_nr
);
417 static void get_d(int line_nr
, double *s_in
)
424 *s_in
= strtod(s
, &endptr
);
425 if (*endptr
|| errno
== ERANGE
)
426 die("line[%d]: invalid float value", line_nr
);
431 #define MAX_LINE_LENGTH (64 * 1024)
433 static char *get_trimmed_line(char *buf
, int buf_size
)
437 if (!fgets(buf
, buf_size
, stdin
))
442 char c
= buf
[len
- 1];
443 if (c
== '\n' || c
== '\r' || c
== ' ' || c
== '\t')
449 while (*buf
== ' ' || *buf
== '\t')
455 static int scripted(void)
457 struct json_writer jw
= JSON_WRITER_INIT
;
458 char buf
[MAX_LINE_LENGTH
];
462 line
= get_trimmed_line(buf
, MAX_LINE_LENGTH
);
466 if (!strcmp(line
, "object"))
467 jw_object_begin(&jw
, pretty
);
468 else if (!strcmp(line
, "array"))
469 jw_array_begin(&jw
, pretty
);
471 die("expected first line to be 'object' or 'array'");
473 while ((line
= get_trimmed_line(buf
, MAX_LINE_LENGTH
)) != NULL
) {
482 verb
= strtok(line
, " ");
484 if (!strcmp(verb
, "end")) {
487 else if (!strcmp(verb
, "object-string")) {
488 get_s(line_nr
, &key
);
489 get_s(line_nr
, &s_value
);
490 jw_object_string(&jw
, key
, s_value
);
492 else if (!strcmp(verb
, "object-int")) {
493 get_s(line_nr
, &key
);
494 get_i(line_nr
, &i_value
);
495 jw_object_intmax(&jw
, key
, i_value
);
497 else if (!strcmp(verb
, "object-double")) {
498 get_s(line_nr
, &key
);
499 get_i(line_nr
, &i_value
);
500 get_d(line_nr
, &d_value
);
501 jw_object_double(&jw
, key
, i_value
, d_value
);
503 else if (!strcmp(verb
, "object-true")) {
504 get_s(line_nr
, &key
);
505 jw_object_true(&jw
, key
);
507 else if (!strcmp(verb
, "object-false")) {
508 get_s(line_nr
, &key
);
509 jw_object_false(&jw
, key
);
511 else if (!strcmp(verb
, "object-null")) {
512 get_s(line_nr
, &key
);
513 jw_object_null(&jw
, key
);
515 else if (!strcmp(verb
, "object-object")) {
516 get_s(line_nr
, &key
);
517 jw_object_inline_begin_object(&jw
, key
);
519 else if (!strcmp(verb
, "object-array")) {
520 get_s(line_nr
, &key
);
521 jw_object_inline_begin_array(&jw
, key
);
523 else if (!strcmp(verb
, "array-string")) {
524 get_s(line_nr
, &s_value
);
525 jw_array_string(&jw
, s_value
);
527 else if (!strcmp(verb
, "array-int")) {
528 get_i(line_nr
, &i_value
);
529 jw_array_intmax(&jw
, i_value
);
531 else if (!strcmp(verb
, "array-double")) {
532 get_i(line_nr
, &i_value
);
533 get_d(line_nr
, &d_value
);
534 jw_array_double(&jw
, i_value
, d_value
);
536 else if (!strcmp(verb
, "array-true"))
538 else if (!strcmp(verb
, "array-false"))
540 else if (!strcmp(verb
, "array-null"))
542 else if (!strcmp(verb
, "array-object"))
543 jw_array_inline_begin_object(&jw
);
544 else if (!strcmp(verb
, "array-array"))
545 jw_array_inline_begin_array(&jw
);
547 die("unrecognized token: '%s'", verb
);
550 if (!jw_is_terminated(&jw
))
551 die("json not terminated: '%s'", jw
.json
.buf
);
553 printf("%s\n", jw
.json
.buf
);
559 int cmd__json_writer(int argc
, const char **argv
)
561 argc
--; /* skip over "json-writer" arg */
564 if (argc
> 0 && argv
[0][0] == '-') {
565 if (!strcmp(argv
[0], "-u") || !strcmp(argv
[0], "--unit"))
568 if (!strcmp(argv
[0], "-p") || !strcmp(argv
[0], "--pretty"))