2 * Copyright IBM, Corp. 2009
5 * Anthony Liguori <aliguori@us.ibm.com>
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
)
32 { "\"hello world \\\"embedded string\\\"\"",
33 "hello world \"embedded string\"" },
34 { "\"hello world\\nwith new line\"", "hello world\nwith new line" },
35 { "\"single byte utf-8 \\u0020\"", "single byte utf-8 " },
36 { "\"double byte utf-8 \\u00A2\"", "double byte utf-8 \xc2\xa2" },
37 { "\"triple byte utf-8 \\u20AC\"", "triple byte utf-8 \xe2\x82\xac" },
41 for (i
= 0; test_cases
[i
].encoded
; i
++) {
45 obj
= qobject_from_json(test_cases
[i
].encoded
);
47 fail_unless(obj
!= NULL
);
48 fail_unless(qobject_type(obj
) == QTYPE_QSTRING
);
50 str
= qobject_to_qstring(obj
);
51 fail_unless(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
58 START_TEST(simple_string
)
65 { "\"hello world\"", "hello world" },
66 { "\"the quick brown fox jumped over the fence\"",
67 "the quick brown fox jumped over the fence" },
71 for (i
= 0; test_cases
[i
].encoded
; i
++) {
75 obj
= qobject_from_json(test_cases
[i
].encoded
);
77 fail_unless(obj
!= NULL
);
78 fail_unless(qobject_type(obj
) == QTYPE_QSTRING
);
80 str
= qobject_to_qstring(obj
);
81 fail_unless(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
88 START_TEST(single_quote_string
)
95 { "'hello world'", "hello world" },
96 { "'the quick brown fox \\' jumped over the fence'",
97 "the quick brown fox ' jumped over the fence" },
101 for (i
= 0; test_cases
[i
].encoded
; i
++) {
105 obj
= qobject_from_json(test_cases
[i
].encoded
);
107 fail_unless(obj
!= NULL
);
108 fail_unless(qobject_type(obj
) == QTYPE_QSTRING
);
110 str
= qobject_to_qstring(obj
);
111 fail_unless(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
118 START_TEST(vararg_string
)
125 { "the quick brown fox jumped over the fence" },
129 for (i
= 0; test_cases
[i
].decoded
; i
++) {
133 obj
= qobject_from_jsonf("%s", test_cases
[i
].decoded
);
135 fail_unless(obj
!= NULL
);
136 fail_unless(qobject_type(obj
) == QTYPE_QSTRING
);
138 str
= qobject_to_qstring(obj
);
139 fail_unless(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
146 START_TEST(simple_number
)
161 for (i
= 0; test_cases
[i
].encoded
; i
++) {
165 obj
= qobject_from_json(test_cases
[i
].encoded
);
166 fail_unless(obj
!= NULL
);
167 fail_unless(qobject_type(obj
) == QTYPE_QINT
);
169 qint
= qobject_to_qint(obj
);
170 fail_unless(qint_get_int(qint
) == test_cases
[i
].decoded
);
177 START_TEST(float_number
)
186 { "-32.12313", -32.12313 },
187 { "-32.20e-10", -32.20e-10 },
191 for (i
= 0; test_cases
[i
].encoded
; i
++) {
195 obj
= qobject_from_json(test_cases
[i
].encoded
);
196 fail_unless(obj
!= NULL
);
197 fail_unless(qobject_type(obj
) == QTYPE_QFLOAT
);
199 qfloat
= qobject_to_qfloat(obj
);
200 fail_unless(qfloat_get_double(qfloat
) == test_cases
[i
].decoded
);
207 START_TEST(vararg_number
)
213 int64_t value64
= 0x2342342343LL
;
214 double valuef
= 2.323423423;
216 obj
= qobject_from_jsonf("%d", value
);
217 fail_unless(obj
!= NULL
);
218 fail_unless(qobject_type(obj
) == QTYPE_QINT
);
220 qint
= qobject_to_qint(obj
);
221 fail_unless(qint_get_int(qint
) == value
);
225 obj
= qobject_from_jsonf("%" PRId64
, value64
);
226 fail_unless(obj
!= NULL
);
227 fail_unless(qobject_type(obj
) == QTYPE_QINT
);
229 qint
= qobject_to_qint(obj
);
230 fail_unless(qint_get_int(qint
) == value64
);
234 obj
= qobject_from_jsonf("%f", valuef
);
235 fail_unless(obj
!= NULL
);
236 fail_unless(qobject_type(obj
) == QTYPE_QFLOAT
);
238 qfloat
= qobject_to_qfloat(obj
);
239 fail_unless(qfloat_get_double(qfloat
) == valuef
);
245 START_TEST(keyword_literal
)
250 obj
= qobject_from_json("true");
251 fail_unless(obj
!= NULL
);
252 fail_unless(qobject_type(obj
) == QTYPE_QBOOL
);
254 qbool
= qobject_to_qbool(obj
);
255 fail_unless(qbool_get_int(qbool
) != 0);
259 obj
= qobject_from_json("false");
260 fail_unless(obj
!= NULL
);
261 fail_unless(qobject_type(obj
) == QTYPE_QBOOL
);
263 qbool
= qobject_to_qbool(obj
);
264 fail_unless(qbool_get_int(qbool
) == 0);
268 obj
= qobject_from_jsonf("%i", false);
269 fail_unless(obj
!= NULL
);
270 fail_unless(qobject_type(obj
) == QTYPE_QBOOL
);
272 qbool
= qobject_to_qbool(obj
);
273 fail_unless(qbool_get_int(qbool
) == 0);
277 obj
= qobject_from_jsonf("%i", true);
278 fail_unless(obj
!= NULL
);
279 fail_unless(qobject_type(obj
) == QTYPE_QBOOL
);
281 qbool
= qobject_to_qbool(obj
);
282 fail_unless(qbool_get_int(qbool
) != 0);
288 typedef struct LiteralQDictEntry LiteralQDictEntry
;
289 typedef struct LiteralQObject LiteralQObject
;
291 struct LiteralQObject
297 LiteralQDictEntry
*qdict
;
298 LiteralQObject
*qlist
;
302 struct LiteralQDictEntry
305 LiteralQObject value
;
308 #define QLIT_QINT(val) (LiteralQObject){.type = QTYPE_QINT, .value.qint = (val)}
309 #define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
310 #define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
311 #define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
313 typedef struct QListCompareHelper
316 LiteralQObject
*objs
;
318 } QListCompareHelper
;
320 static int compare_litqobj_to_qobj(LiteralQObject
*lhs
, QObject
*rhs
);
322 static void compare_helper(QObject
*obj
, void *opaque
)
324 QListCompareHelper
*helper
= opaque
;
326 if (helper
->result
== 0) {
330 if (helper
->objs
[helper
->index
].type
== QTYPE_NONE
) {
335 helper
->result
= compare_litqobj_to_qobj(&helper
->objs
[helper
->index
++], obj
);
338 static int compare_litqobj_to_qobj(LiteralQObject
*lhs
, QObject
*rhs
)
340 if (lhs
->type
!= qobject_type(rhs
)) {
346 return lhs
->value
.qint
== qint_get_int(qobject_to_qint(rhs
));
348 return (strcmp(lhs
->value
.qstr
, qstring_get_str(qobject_to_qstring(rhs
))) == 0);
352 for (i
= 0; lhs
->value
.qdict
[i
].key
; i
++) {
353 QObject
*obj
= qdict_get(qobject_to_qdict(rhs
), lhs
->value
.qdict
[i
].key
);
355 if (!compare_litqobj_to_qobj(&lhs
->value
.qdict
[i
].value
, obj
)) {
363 QListCompareHelper helper
;
366 helper
.objs
= lhs
->value
.qlist
;
369 qlist_iter(qobject_to_qlist(rhs
), compare_helper
, &helper
);
371 return helper
.result
;
380 START_TEST(simple_dict
)
385 LiteralQObject decoded
;
388 .encoded
= "{\"foo\":42,\"bar\":\"hello world\"}",
389 .decoded
= QLIT_QDICT(((LiteralQDictEntry
[]){
390 { "foo", QLIT_QINT(42) },
391 { "bar", QLIT_QSTR("hello world") },
396 .decoded
= QLIT_QDICT(((LiteralQDictEntry
[]){
400 .encoded
= "{\"foo\":43}",
401 .decoded
= QLIT_QDICT(((LiteralQDictEntry
[]){
402 { "foo", QLIT_QINT(43) },
409 for (i
= 0; test_cases
[i
].encoded
; i
++) {
412 obj
= qobject_from_json(test_cases
[i
].encoded
);
413 fail_unless(obj
!= NULL
);
414 fail_unless(qobject_type(obj
) == QTYPE_QDICT
);
416 fail_unless(compare_litqobj_to_qobj(&test_cases
[i
].decoded
, obj
) == 1);
423 START_TEST(simple_list
)
428 LiteralQObject decoded
;
431 .encoded
= "[43,42]",
432 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
440 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
447 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
453 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
454 QLIT_QDICT(((LiteralQDictEntry
[]){
463 for (i
= 0; test_cases
[i
].encoded
; i
++) {
466 obj
= qobject_from_json(test_cases
[i
].encoded
);
467 fail_unless(obj
!= NULL
);
468 fail_unless(qobject_type(obj
) == QTYPE_QLIST
);
470 fail_unless(compare_litqobj_to_qobj(&test_cases
[i
].decoded
, obj
) == 1);
477 START_TEST(simple_whitespace
)
482 LiteralQObject decoded
;
485 .encoded
= " [ 43 , 42 ]",
486 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
493 .encoded
= " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
494 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
496 QLIT_QDICT(((LiteralQDictEntry
[]){
497 { "h", QLIT_QSTR("b") },
499 QLIT_QLIST(((LiteralQObject
[]){
506 .encoded
= " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
507 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
509 QLIT_QDICT(((LiteralQDictEntry
[]){
510 { "h", QLIT_QSTR("b") },
511 { "a", QLIT_QINT(32) },
513 QLIT_QLIST(((LiteralQObject
[]){
522 for (i
= 0; test_cases
[i
].encoded
; i
++) {
525 obj
= qobject_from_json(test_cases
[i
].encoded
);
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_varargs
)
538 QObject
*embedded_obj
;
540 LiteralQObject decoded
= QLIT_QLIST(((LiteralQObject
[]){
543 QLIT_QLIST(((LiteralQObject
[]){
549 embedded_obj
= qobject_from_json("[32, 42]");
550 fail_unless(embedded_obj
!= NULL
);
552 obj
= qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj
);
553 fail_unless(obj
!= NULL
);
555 fail_unless(compare_litqobj_to_qobj(&decoded
, obj
) == 1);
561 static Suite
*qjson_suite(void)
564 TCase
*string_literals
, *number_literals
, *keyword_literals
;
565 TCase
*dicts
, *lists
, *whitespace
, *varargs
;
567 string_literals
= tcase_create("String Literals");
568 tcase_add_test(string_literals
, simple_string
);
569 tcase_add_test(string_literals
, escaped_string
);
570 tcase_add_test(string_literals
, single_quote_string
);
571 tcase_add_test(string_literals
, vararg_string
);
573 number_literals
= tcase_create("Number Literals");
574 tcase_add_test(number_literals
, simple_number
);
575 tcase_add_test(number_literals
, float_number
);
576 tcase_add_test(number_literals
, vararg_number
);
578 keyword_literals
= tcase_create("Keywords");
579 tcase_add_test(keyword_literals
, keyword_literal
);
580 dicts
= tcase_create("Objects");
581 tcase_add_test(dicts
, simple_dict
);
582 lists
= tcase_create("Lists");
583 tcase_add_test(lists
, simple_list
);
585 whitespace
= tcase_create("Whitespace");
586 tcase_add_test(whitespace
, simple_whitespace
);
588 varargs
= tcase_create("Varargs");
589 tcase_add_test(varargs
, simple_varargs
);
591 suite
= suite_create("QJSON test-suite");
592 suite_add_tcase(suite
, string_literals
);
593 suite_add_tcase(suite
, number_literals
);
594 suite_add_tcase(suite
, keyword_literals
);
595 suite_add_tcase(suite
, dicts
);
596 suite_add_tcase(suite
, lists
);
597 suite_add_tcase(suite
, whitespace
);
598 suite_add_tcase(suite
, varargs
);
610 sr
= srunner_create(s
);
612 srunner_run_all(sr
, CK_NORMAL
);
613 nf
= srunner_ntests_failed(sr
);
616 return (nf
== 0) ? EXIT_SUCCESS
: EXIT_FAILURE
;