2 * Copyright IBM, Corp. 2009
7 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
8 * See the COPYING.LIB file in the top-level directory.
22 #include "qemu-common.h"
24 START_TEST(escaped_string)
33 { "\"hello world \\\"embedded string\\\"\"",
34 "hello world \"embedded string\"" },
35 { "\"hello world\\nwith new line\"", "hello world\nwith new line" },
36 { "\"single byte utf-8 \\u0020\"", "single byte utf-8 ", .skip = 1 },
37 { "\"double byte utf-8 \\u00A2\"", "double byte utf-8 \xc2\xa2" },
38 { "\"triple byte utf-8 \\u20AC\"", "triple byte utf-8 \xe2\x82\xac" },
42 for (i = 0; test_cases[i].encoded; i++) {
46 obj = qobject_from_json(test_cases[i].encoded);
48 fail_unless(obj != NULL);
49 fail_unless(qobject_type(obj) == QTYPE_QSTRING);
51 str = qobject_to_qstring(obj);
52 fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
54 if (test_cases[i].skip == 0) {
55 str = qobject_to_json(obj);
56 fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
66 START_TEST(simple_string)
73 { "\"hello world\"", "hello world" },
74 { "\"the quick brown fox jumped over the fence\"",
75 "the quick brown fox jumped over the fence" },
79 for (i = 0; test_cases[i].encoded; i++) {
83 obj = qobject_from_json(test_cases[i].encoded);
85 fail_unless(obj != NULL);
86 fail_unless(qobject_type(obj) == QTYPE_QSTRING);
88 str = qobject_to_qstring(obj);
89 fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
91 str = qobject_to_json(obj);
92 fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
101 START_TEST(single_quote_string)
108 { "'hello world'", "hello world" },
109 { "'the quick brown fox \\' jumped over the fence'",
110 "the quick brown fox ' jumped over the fence" },
114 for (i = 0; test_cases[i].encoded; i++) {
118 obj = qobject_from_json(test_cases[i].encoded);
120 fail_unless(obj != NULL);
121 fail_unless(qobject_type(obj) == QTYPE_QSTRING);
123 str = qobject_to_qstring(obj);
124 fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
131 START_TEST(vararg_string)
138 { "the quick brown fox jumped over the fence" },
142 for (i = 0; test_cases[i].decoded; i++) {
146 obj = qobject_from_jsonf("%s", test_cases[i].decoded);
148 fail_unless(obj != NULL);
149 fail_unless(qobject_type(obj) == QTYPE_QSTRING);
151 str = qobject_to_qstring(obj);
152 fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
159 START_TEST(simple_number)
171 { "-0", 0, .skip = 1 },
175 for (i = 0; test_cases[i].encoded; i++) {
179 obj = qobject_from_json(test_cases[i].encoded);
180 fail_unless(obj != NULL);
181 fail_unless(qobject_type(obj) == QTYPE_QINT);
183 qint = qobject_to_qint(obj);
184 fail_unless(qint_get_int(qint) == test_cases[i].decoded);
185 if (test_cases[i].skip == 0) {
188 str = qobject_to_json(obj);
189 fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
198 START_TEST(float_number)
208 { "-32.12313", -32.12313 },
209 { "-32.20e-10", -32.20e-10, .skip = 1 },
213 for (i = 0; test_cases[i].encoded; i++) {
217 obj = qobject_from_json(test_cases[i].encoded);
218 fail_unless(obj != NULL);
219 fail_unless(qobject_type(obj) == QTYPE_QFLOAT);
221 qfloat = qobject_to_qfloat(obj);
222 fail_unless(qfloat_get_double(qfloat) == test_cases[i].decoded);
224 if (test_cases[i].skip == 0) {
227 str = qobject_to_json(obj);
228 fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
237 START_TEST(vararg_number)
243 int64_t value64 = 0x2342342343LL;
244 double valuef = 2.323423423;
246 obj = qobject_from_jsonf("%d", value);
247 fail_unless(obj != NULL);
248 fail_unless(qobject_type(obj) == QTYPE_QINT);
250 qint = qobject_to_qint(obj);
251 fail_unless(qint_get_int(qint) == value);
255 obj = qobject_from_jsonf("%" PRId64, value64);
256 fail_unless(obj != NULL);
257 fail_unless(qobject_type(obj) == QTYPE_QINT);
259 qint = qobject_to_qint(obj);
260 fail_unless(qint_get_int(qint) == value64);
264 obj = qobject_from_jsonf("%f", valuef);
265 fail_unless(obj != NULL);
266 fail_unless(qobject_type(obj) == QTYPE_QFLOAT);
268 qfloat = qobject_to_qfloat(obj);
269 fail_unless(qfloat_get_double(qfloat) == valuef);
275 START_TEST(keyword_literal)
281 obj = qobject_from_json("true");
282 fail_unless(obj != NULL);
283 fail_unless(qobject_type(obj) == QTYPE_QBOOL);
285 qbool = qobject_to_qbool(obj);
286 fail_unless(qbool_get_int(qbool) != 0);
288 str = qobject_to_json(obj);
289 fail_unless(strcmp(qstring_get_str(str), "true") == 0);
294 obj = qobject_from_json("false");
295 fail_unless(obj != NULL);
296 fail_unless(qobject_type(obj) == QTYPE_QBOOL);
298 qbool = qobject_to_qbool(obj);
299 fail_unless(qbool_get_int(qbool) == 0);
301 str = qobject_to_json(obj);
302 fail_unless(strcmp(qstring_get_str(str), "false") == 0);
307 obj = qobject_from_jsonf("%i", false);
308 fail_unless(obj != NULL);
309 fail_unless(qobject_type(obj) == QTYPE_QBOOL);
311 qbool = qobject_to_qbool(obj);
312 fail_unless(qbool_get_int(qbool) == 0);
316 obj = qobject_from_jsonf("%i", true);
317 fail_unless(obj != NULL);
318 fail_unless(qobject_type(obj) == QTYPE_QBOOL);
320 qbool = qobject_to_qbool(obj);
321 fail_unless(qbool_get_int(qbool) != 0);
327 typedef struct LiteralQDictEntry LiteralQDictEntry;
328 typedef struct LiteralQObject LiteralQObject;
330 struct LiteralQObject
336 LiteralQDictEntry *qdict;
337 LiteralQObject *qlist;
341 struct LiteralQDictEntry
344 LiteralQObject value;
347 #define QLIT_QINT(val) (LiteralQObject){.type = QTYPE_QINT, .value.qint = (val)}
348 #define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
349 #define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
350 #define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
352 typedef struct QListCompareHelper
355 LiteralQObject *objs;
357 } QListCompareHelper;
359 static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs);
361 static void compare_helper(QObject *obj, void *opaque)
363 QListCompareHelper *helper = opaque;
365 if (helper->result == 0) {
369 if (helper->objs[helper->index].type == QTYPE_NONE) {
374 helper->result = compare_litqobj_to_qobj(&helper->objs[helper->index++], obj);
377 static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs)
379 if (lhs->type != qobject_type(rhs)) {
385 return lhs->value.qint == qint_get_int(qobject_to_qint(rhs));
387 return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0);
391 for (i = 0; lhs->value.qdict[i].key; i++) {
392 QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key);
394 if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) {
402 QListCompareHelper helper;
405 helper.objs = lhs->value.qlist;
408 qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper);
410 return helper.result;
419 START_TEST(simple_dict)
424 LiteralQObject decoded;
427 .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
428 .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
429 { "foo", QLIT_QINT(42) },
430 { "bar", QLIT_QSTR("hello world") },
435 .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
439 .encoded = "{\"foo\": 43}",
440 .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
441 { "foo", QLIT_QINT(43) },
448 for (i = 0; test_cases[i].encoded; i++) {
452 obj = qobject_from_json(test_cases[i].encoded);
453 fail_unless(obj != NULL);
454 fail_unless(qobject_type(obj) == QTYPE_QDICT);
456 fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
458 str = qobject_to_json(obj);
461 obj = qobject_from_json(qstring_get_str(str));
462 fail_unless(obj != NULL);
463 fail_unless(qobject_type(obj) == QTYPE_QDICT);
465 fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
472 START_TEST(simple_list)
477 LiteralQObject decoded;
480 .encoded = "[43,42]",
481 .decoded = QLIT_QLIST(((LiteralQObject[]){
489 .decoded = QLIT_QLIST(((LiteralQObject[]){
496 .decoded = QLIT_QLIST(((LiteralQObject[]){
502 .decoded = QLIT_QLIST(((LiteralQObject[]){
503 QLIT_QDICT(((LiteralQDictEntry[]){
512 for (i = 0; test_cases[i].encoded; i++) {
516 obj = qobject_from_json(test_cases[i].encoded);
517 fail_unless(obj != NULL);
518 fail_unless(qobject_type(obj) == QTYPE_QLIST);
520 fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
522 str = qobject_to_json(obj);
525 obj = qobject_from_json(qstring_get_str(str));
526 fail_unless(obj != NULL);
527 fail_unless(qobject_type(obj) == QTYPE_QLIST);
529 fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
536 START_TEST(simple_whitespace)
541 LiteralQObject decoded;
544 .encoded = " [ 43 , 42 ]",
545 .decoded = QLIT_QLIST(((LiteralQObject[]){
552 .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
553 .decoded = QLIT_QLIST(((LiteralQObject[]){
555 QLIT_QDICT(((LiteralQDictEntry[]){
556 { "h", QLIT_QSTR("b") },
558 QLIT_QLIST(((LiteralQObject[]){
565 .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
566 .decoded = QLIT_QLIST(((LiteralQObject[]){
568 QLIT_QDICT(((LiteralQDictEntry[]){
569 { "h", QLIT_QSTR("b") },
570 { "a", QLIT_QINT(32) },
572 QLIT_QLIST(((LiteralQObject[]){
581 for (i = 0; test_cases[i].encoded; i++) {
585 obj = qobject_from_json(test_cases[i].encoded);
586 fail_unless(obj != NULL);
587 fail_unless(qobject_type(obj) == QTYPE_QLIST);
589 fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
591 str = qobject_to_json(obj);
594 obj = qobject_from_json(qstring_get_str(str));
595 fail_unless(obj != NULL);
596 fail_unless(qobject_type(obj) == QTYPE_QLIST);
598 fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
606 START_TEST(simple_varargs)
608 QObject *embedded_obj;
610 LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){
613 QLIT_QLIST(((LiteralQObject[]){
619 embedded_obj = qobject_from_json("[32, 42]");
620 fail_unless(embedded_obj != NULL);
622 obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj);
623 fail_unless(obj != NULL);
625 fail_unless(compare_litqobj_to_qobj(&decoded, obj) == 1);
631 static Suite *qjson_suite(void)
634 TCase *string_literals, *number_literals, *keyword_literals;
635 TCase *dicts, *lists, *whitespace, *varargs;
637 string_literals = tcase_create("String Literals");
638 tcase_add_test(string_literals, simple_string);
639 tcase_add_test(string_literals, escaped_string);
640 tcase_add_test(string_literals, single_quote_string);
641 tcase_add_test(string_literals, vararg_string);
643 number_literals = tcase_create("Number Literals");
644 tcase_add_test(number_literals, simple_number);
645 tcase_add_test(number_literals, float_number);
646 tcase_add_test(number_literals, vararg_number);
648 keyword_literals = tcase_create("Keywords");
649 tcase_add_test(keyword_literals, keyword_literal);
650 dicts = tcase_create("Objects");
651 tcase_add_test(dicts, simple_dict);
652 lists = tcase_create("Lists");
653 tcase_add_test(lists, simple_list);
655 whitespace = tcase_create("Whitespace");
656 tcase_add_test(whitespace, simple_whitespace);
658 varargs = tcase_create("Varargs");
659 tcase_add_test(varargs, simple_varargs);
661 suite = suite_create("QJSON test-suite");
662 suite_add_tcase(suite, string_literals);
663 suite_add_tcase(suite, number_literals);
664 suite_add_tcase(suite, keyword_literals);
665 suite_add_tcase(suite, dicts);
666 suite_add_tcase(suite, lists);
667 suite_add_tcase(suite, whitespace);
668 suite_add_tcase(suite, varargs);
680 sr = srunner_create(s);
682 srunner_run_all(sr, CK_NORMAL);
683 nf = srunner_ntests_failed(sr);
686 return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;