]> Git Repo - qemu.git/blob - check-qjson.c
use new cursor struct + functions for vmware vga and sdl.
[qemu.git] / check-qjson.c
1 /*
2  * Copyright IBM, Corp. 2009
3  *
4  * Authors:
5  *  Anthony Liguori   <[email protected]>
6  *
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.
9  *
10  */
11 #include <check.h>
12 #include <stdbool.h>
13
14 #include "qstring.h"
15 #include "qint.h"
16 #include "qdict.h"
17 #include "qlist.h"
18 #include "qfloat.h"
19 #include "qbool.h"
20 #include "qjson.h"
21
22 #include "qemu-common.h"
23
24 START_TEST(escaped_string)
25 {
26     int i;
27     struct {
28         const char *encoded;
29         const char *decoded;
30         int skip;
31     } test_cases[] = {
32         { "\"\\\"\"", "\"" },
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" },
39         {}
40     };
41
42     for (i = 0; test_cases[i].encoded; i++) {
43         QObject *obj;
44         QString *str;
45
46         obj = qobject_from_json(test_cases[i].encoded);
47
48         fail_unless(obj != NULL);
49         fail_unless(qobject_type(obj) == QTYPE_QSTRING);
50         
51         str = qobject_to_qstring(obj);
52         fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
53
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);
57
58             qobject_decref(obj);
59         }
60
61         QDECREF(str);
62     }
63 }
64 END_TEST
65
66 START_TEST(simple_string)
67 {
68     int i;
69     struct {
70         const char *encoded;
71         const char *decoded;
72     } test_cases[] = {
73         { "\"hello world\"", "hello world" },
74         { "\"the quick brown fox jumped over the fence\"",
75           "the quick brown fox jumped over the fence" },
76         {}
77     };
78
79     for (i = 0; test_cases[i].encoded; i++) {
80         QObject *obj;
81         QString *str;
82
83         obj = qobject_from_json(test_cases[i].encoded);
84
85         fail_unless(obj != NULL);
86         fail_unless(qobject_type(obj) == QTYPE_QSTRING);
87         
88         str = qobject_to_qstring(obj);
89         fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
90
91         str = qobject_to_json(obj);
92         fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
93
94         qobject_decref(obj);
95         
96         QDECREF(str);
97     }
98 }
99 END_TEST
100
101 START_TEST(single_quote_string)
102 {
103     int i;
104     struct {
105         const char *encoded;
106         const char *decoded;
107     } test_cases[] = {
108         { "'hello world'", "hello world" },
109         { "'the quick brown fox \\' jumped over the fence'",
110           "the quick brown fox ' jumped over the fence" },
111         {}
112     };
113
114     for (i = 0; test_cases[i].encoded; i++) {
115         QObject *obj;
116         QString *str;
117
118         obj = qobject_from_json(test_cases[i].encoded);
119
120         fail_unless(obj != NULL);
121         fail_unless(qobject_type(obj) == QTYPE_QSTRING);
122         
123         str = qobject_to_qstring(obj);
124         fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
125
126         QDECREF(str);
127     }
128 }
129 END_TEST
130
131 START_TEST(vararg_string)
132 {
133     int i;
134     struct {
135         const char *decoded;
136     } test_cases[] = {
137         { "hello world" },
138         { "the quick brown fox jumped over the fence" },
139         {}
140     };
141
142     for (i = 0; test_cases[i].decoded; i++) {
143         QObject *obj;
144         QString *str;
145
146         obj = qobject_from_jsonf("%s", test_cases[i].decoded);
147
148         fail_unless(obj != NULL);
149         fail_unless(qobject_type(obj) == QTYPE_QSTRING);
150         
151         str = qobject_to_qstring(obj);
152         fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
153
154         QDECREF(str);
155     }
156 }
157 END_TEST
158
159 START_TEST(simple_number)
160 {
161     int i;
162     struct {
163         const char *encoded;
164         int64_t decoded;
165         int skip;
166     } test_cases[] = {
167         { "0", 0 },
168         { "1234", 1234 },
169         { "1", 1 },
170         { "-32", -32 },
171         { "-0", 0, .skip = 1 },
172         { },
173     };
174
175     for (i = 0; test_cases[i].encoded; i++) {
176         QObject *obj;
177         QInt *qint;
178
179         obj = qobject_from_json(test_cases[i].encoded);
180         fail_unless(obj != NULL);
181         fail_unless(qobject_type(obj) == QTYPE_QINT);
182
183         qint = qobject_to_qint(obj);
184         fail_unless(qint_get_int(qint) == test_cases[i].decoded);
185         if (test_cases[i].skip == 0) {
186             QString *str;
187
188             str = qobject_to_json(obj);
189             fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
190             QDECREF(str);
191         }
192
193         QDECREF(qint);
194     }
195 }
196 END_TEST
197
198 START_TEST(float_number)
199 {
200     int i;
201     struct {
202         const char *encoded;
203         double decoded;
204         int skip;
205     } test_cases[] = {
206         { "32.43", 32.43 },
207         { "0.222", 0.222 },
208         { "-32.12313", -32.12313 },
209         { "-32.20e-10", -32.20e-10, .skip = 1 },
210         { },
211     };
212
213     for (i = 0; test_cases[i].encoded; i++) {
214         QObject *obj;
215         QFloat *qfloat;
216
217         obj = qobject_from_json(test_cases[i].encoded);
218         fail_unless(obj != NULL);
219         fail_unless(qobject_type(obj) == QTYPE_QFLOAT);
220
221         qfloat = qobject_to_qfloat(obj);
222         fail_unless(qfloat_get_double(qfloat) == test_cases[i].decoded);
223
224         if (test_cases[i].skip == 0) {
225             QString *str;
226
227             str = qobject_to_json(obj);
228             fail_unless(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
229             QDECREF(str);
230         }
231
232         QDECREF(qfloat);
233     }
234 }
235 END_TEST
236
237 START_TEST(vararg_number)
238 {
239     QObject *obj;
240     QInt *qint;
241     QFloat *qfloat;
242     int value = 0x2342;
243     int64_t value64 = 0x2342342343LL;
244     double valuef = 2.323423423;
245
246     obj = qobject_from_jsonf("%d", value);
247     fail_unless(obj != NULL);
248     fail_unless(qobject_type(obj) == QTYPE_QINT);
249
250     qint = qobject_to_qint(obj);
251     fail_unless(qint_get_int(qint) == value);
252
253     QDECREF(qint);
254
255     obj = qobject_from_jsonf("%" PRId64, value64);
256     fail_unless(obj != NULL);
257     fail_unless(qobject_type(obj) == QTYPE_QINT);
258
259     qint = qobject_to_qint(obj);
260     fail_unless(qint_get_int(qint) == value64);
261
262     QDECREF(qint);
263
264     obj = qobject_from_jsonf("%f", valuef);
265     fail_unless(obj != NULL);
266     fail_unless(qobject_type(obj) == QTYPE_QFLOAT);
267
268     qfloat = qobject_to_qfloat(obj);
269     fail_unless(qfloat_get_double(qfloat) == valuef);
270
271     QDECREF(qfloat);
272 }
273 END_TEST
274
275 START_TEST(keyword_literal)
276 {
277     QObject *obj;
278     QBool *qbool;
279     QString *str;
280
281     obj = qobject_from_json("true");
282     fail_unless(obj != NULL);
283     fail_unless(qobject_type(obj) == QTYPE_QBOOL);
284
285     qbool = qobject_to_qbool(obj);
286     fail_unless(qbool_get_int(qbool) != 0);
287
288     str = qobject_to_json(obj);
289     fail_unless(strcmp(qstring_get_str(str), "true") == 0);
290     QDECREF(str);
291
292     QDECREF(qbool);
293
294     obj = qobject_from_json("false");
295     fail_unless(obj != NULL);
296     fail_unless(qobject_type(obj) == QTYPE_QBOOL);
297
298     qbool = qobject_to_qbool(obj);
299     fail_unless(qbool_get_int(qbool) == 0);
300
301     str = qobject_to_json(obj);
302     fail_unless(strcmp(qstring_get_str(str), "false") == 0);
303     QDECREF(str);
304
305     QDECREF(qbool);
306
307     obj = qobject_from_jsonf("%i", false);
308     fail_unless(obj != NULL);
309     fail_unless(qobject_type(obj) == QTYPE_QBOOL);
310
311     qbool = qobject_to_qbool(obj);
312     fail_unless(qbool_get_int(qbool) == 0);
313
314     QDECREF(qbool);
315     
316     obj = qobject_from_jsonf("%i", true);
317     fail_unless(obj != NULL);
318     fail_unless(qobject_type(obj) == QTYPE_QBOOL);
319
320     qbool = qobject_to_qbool(obj);
321     fail_unless(qbool_get_int(qbool) != 0);
322
323     QDECREF(qbool);
324 }
325 END_TEST
326
327 typedef struct LiteralQDictEntry LiteralQDictEntry;
328 typedef struct LiteralQObject LiteralQObject;
329
330 struct LiteralQObject
331 {
332     int type;
333     union {
334         int64_t qint;
335         const char *qstr;
336         LiteralQDictEntry *qdict;
337         LiteralQObject *qlist;
338     } value;
339 };
340
341 struct LiteralQDictEntry
342 {
343     const char *key;
344     LiteralQObject value;
345 };
346
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)}
351
352 typedef struct QListCompareHelper
353 {
354     int index;
355     LiteralQObject *objs;
356     int result;
357 } QListCompareHelper;
358
359 static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs);
360
361 static void compare_helper(QObject *obj, void *opaque)
362 {
363     QListCompareHelper *helper = opaque;
364
365     if (helper->result == 0) {
366         return;
367     }
368
369     if (helper->objs[helper->index].type == QTYPE_NONE) {
370         helper->result = 0;
371         return;
372     }
373
374     helper->result = compare_litqobj_to_qobj(&helper->objs[helper->index++], obj);
375 }
376
377 static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs)
378 {
379     if (lhs->type != qobject_type(rhs)) {
380         return 0;
381     }
382
383     switch (lhs->type) {
384     case QTYPE_QINT:
385         return lhs->value.qint == qint_get_int(qobject_to_qint(rhs));
386     case QTYPE_QSTRING:
387         return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0);
388     case QTYPE_QDICT: {
389         int i;
390
391         for (i = 0; lhs->value.qdict[i].key; i++) {
392             QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key);
393
394             if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) {
395                 return 0;
396             }
397         }
398
399         return 1;
400     }
401     case QTYPE_QLIST: {
402         QListCompareHelper helper;
403
404         helper.index = 0;
405         helper.objs = lhs->value.qlist;
406         helper.result = 1;
407         
408         qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper);
409
410         return helper.result;
411     }
412     default:
413         break;
414     }
415
416     return 0;
417 }
418
419 START_TEST(simple_dict)
420 {
421     int i;
422     struct {
423         const char *encoded;
424         LiteralQObject decoded;
425     } test_cases[] = {
426         {
427             .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
428             .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
429                         { "foo", QLIT_QINT(42) },
430                         { "bar", QLIT_QSTR("hello world") },
431                         { }
432                     })),
433         }, {
434             .encoded = "{}",
435             .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
436                         { }
437                     })),
438         }, {
439             .encoded = "{\"foo\": 43}",
440             .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
441                         { "foo", QLIT_QINT(43) },
442                         { }
443                     })),
444         },
445         { }
446     };
447
448     for (i = 0; test_cases[i].encoded; i++) {
449         QObject *obj;
450         QString *str;
451
452         obj = qobject_from_json(test_cases[i].encoded);
453         fail_unless(obj != NULL);
454         fail_unless(qobject_type(obj) == QTYPE_QDICT);
455
456         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
457
458         str = qobject_to_json(obj);
459         qobject_decref(obj);
460
461         obj = qobject_from_json(qstring_get_str(str));
462         fail_unless(obj != NULL);
463         fail_unless(qobject_type(obj) == QTYPE_QDICT);
464
465         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
466         qobject_decref(obj);
467         QDECREF(str);
468     }
469 }
470 END_TEST
471
472 START_TEST(simple_list)
473 {
474     int i;
475     struct {
476         const char *encoded;
477         LiteralQObject decoded;
478     } test_cases[] = {
479         {
480             .encoded = "[43,42]",
481             .decoded = QLIT_QLIST(((LiteralQObject[]){
482                         QLIT_QINT(43),
483                         QLIT_QINT(42),
484                         { }
485                     })),
486         },
487         {
488             .encoded = "[43]",
489             .decoded = QLIT_QLIST(((LiteralQObject[]){
490                         QLIT_QINT(43),
491                         { }
492                     })),
493         },
494         {
495             .encoded = "[]",
496             .decoded = QLIT_QLIST(((LiteralQObject[]){
497                         { }
498                     })),
499         },
500         {
501             .encoded = "[{}]",
502             .decoded = QLIT_QLIST(((LiteralQObject[]){
503                         QLIT_QDICT(((LiteralQDictEntry[]){
504                                     {},
505                                         })),
506                         {},
507                             })),
508         },
509         { }
510     };
511
512     for (i = 0; test_cases[i].encoded; i++) {
513         QObject *obj;
514         QString *str;
515
516         obj = qobject_from_json(test_cases[i].encoded);
517         fail_unless(obj != NULL);
518         fail_unless(qobject_type(obj) == QTYPE_QLIST);
519
520         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
521
522         str = qobject_to_json(obj);
523         qobject_decref(obj);
524
525         obj = qobject_from_json(qstring_get_str(str));
526         fail_unless(obj != NULL);
527         fail_unless(qobject_type(obj) == QTYPE_QLIST);
528
529         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
530         qobject_decref(obj);
531         QDECREF(str);
532     }
533 }
534 END_TEST
535
536 START_TEST(simple_whitespace)
537 {
538     int i;
539     struct {
540         const char *encoded;
541         LiteralQObject decoded;
542     } test_cases[] = {
543         {
544             .encoded = " [ 43 , 42 ]",
545             .decoded = QLIT_QLIST(((LiteralQObject[]){
546                         QLIT_QINT(43),
547                         QLIT_QINT(42),
548                         { }
549                     })),
550         },
551         {
552             .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
553             .decoded = QLIT_QLIST(((LiteralQObject[]){
554                         QLIT_QINT(43),
555                         QLIT_QDICT(((LiteralQDictEntry[]){
556                                     { "h", QLIT_QSTR("b") },
557                                     { }})),
558                         QLIT_QLIST(((LiteralQObject[]){
559                                     { }})),
560                         QLIT_QINT(42),
561                         { }
562                     })),
563         },
564         {
565             .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
566             .decoded = QLIT_QLIST(((LiteralQObject[]){
567                         QLIT_QINT(43),
568                         QLIT_QDICT(((LiteralQDictEntry[]){
569                                     { "h", QLIT_QSTR("b") },
570                                     { "a", QLIT_QINT(32) },
571                                     { }})),
572                         QLIT_QLIST(((LiteralQObject[]){
573                                     { }})),
574                         QLIT_QINT(42),
575                         { }
576                     })),
577         },
578         { }
579     };
580
581     for (i = 0; test_cases[i].encoded; i++) {
582         QObject *obj;
583         QString *str;
584
585         obj = qobject_from_json(test_cases[i].encoded);
586         fail_unless(obj != NULL);
587         fail_unless(qobject_type(obj) == QTYPE_QLIST);
588
589         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
590
591         str = qobject_to_json(obj);
592         qobject_decref(obj);
593
594         obj = qobject_from_json(qstring_get_str(str));
595         fail_unless(obj != NULL);
596         fail_unless(qobject_type(obj) == QTYPE_QLIST);
597
598         fail_unless(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
599
600         qobject_decref(obj);
601         QDECREF(str);
602     }
603 }
604 END_TEST
605
606 START_TEST(simple_varargs)
607 {
608     QObject *embedded_obj;
609     QObject *obj;
610     LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){
611             QLIT_QINT(1),
612             QLIT_QINT(2),
613             QLIT_QLIST(((LiteralQObject[]){
614                         QLIT_QINT(32),
615                         QLIT_QINT(42),
616                         {}})),
617             {}}));
618
619     embedded_obj = qobject_from_json("[32, 42]");
620     fail_unless(embedded_obj != NULL);
621
622     obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj);
623     fail_unless(obj != NULL);
624
625     fail_unless(compare_litqobj_to_qobj(&decoded, obj) == 1);
626
627     qobject_decref(obj);
628 }
629 END_TEST
630
631 static Suite *qjson_suite(void)
632 {
633     Suite *suite;
634     TCase *string_literals, *number_literals, *keyword_literals;
635     TCase *dicts, *lists, *whitespace, *varargs;
636
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);
642
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);
647
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);
654
655     whitespace = tcase_create("Whitespace");
656     tcase_add_test(whitespace, simple_whitespace);
657
658     varargs = tcase_create("Varargs");
659     tcase_add_test(varargs, simple_varargs);
660
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);
669
670     return suite;
671 }
672
673 int main(void)
674 {
675     int nf;
676     Suite *s;
677     SRunner *sr;
678
679     s = qjson_suite();
680     sr = srunner_create(s);
681         
682     srunner_run_all(sr, CK_NORMAL);
683     nf = srunner_ntests_failed(sr);
684     srunner_free(sr);
685     
686     return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
687 }
This page took 0.06112 seconds and 4 git commands to generate.