]>
Commit | Line | Data |
---|---|---|
422c46a8 AL |
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 | */ | |
ef76dc59 | 11 | #include <glib.h> |
422c46a8 AL |
12 | |
13 | #include "qstring.h" | |
14 | #include "qint.h" | |
15 | #include "qdict.h" | |
16 | #include "qlist.h" | |
17 | #include "qfloat.h" | |
18 | #include "qbool.h" | |
19 | #include "qjson.h" | |
20 | ||
21 | #include "qemu-common.h" | |
22 | ||
ef76dc59 | 23 | static void escaped_string(void) |
422c46a8 AL |
24 | { |
25 | int i; | |
26 | struct { | |
27 | const char *encoded; | |
28 | const char *decoded; | |
6ee59202 | 29 | int skip; |
422c46a8 | 30 | } test_cases[] = { |
d22b0bd7 LC |
31 | { "\"\\b\"", "\b" }, |
32 | { "\"\\f\"", "\f" }, | |
33 | { "\"\\n\"", "\n" }, | |
34 | { "\"\\r\"", "\r" }, | |
35 | { "\"\\t\"", "\t" }, | |
69faeee1 JK |
36 | { "\"/\"", "/" }, |
37 | { "\"\\/\"", "/", .skip = 1 }, | |
d22b0bd7 | 38 | { "\"\\\\\"", "\\" }, |
422c46a8 AL |
39 | { "\"\\\"\"", "\"" }, |
40 | { "\"hello world \\\"embedded string\\\"\"", | |
41 | "hello world \"embedded string\"" }, | |
42 | { "\"hello world\\nwith new line\"", "hello world\nwith new line" }, | |
6ee59202 | 43 | { "\"single byte utf-8 \\u0020\"", "single byte utf-8 ", .skip = 1 }, |
422c46a8 AL |
44 | { "\"double byte utf-8 \\u00A2\"", "double byte utf-8 \xc2\xa2" }, |
45 | { "\"triple byte utf-8 \\u20AC\"", "triple byte utf-8 \xe2\x82\xac" }, | |
46 | {} | |
47 | }; | |
48 | ||
49 | for (i = 0; test_cases[i].encoded; i++) { | |
50 | QObject *obj; | |
51 | QString *str; | |
52 | ||
53 | obj = qobject_from_json(test_cases[i].encoded); | |
54 | ||
ef76dc59 AL |
55 | g_assert(obj != NULL); |
56 | g_assert(qobject_type(obj) == QTYPE_QSTRING); | |
422c46a8 AL |
57 | |
58 | str = qobject_to_qstring(obj); | |
ef76dc59 | 59 | g_assert_cmpstr(qstring_get_str(str), ==, test_cases[i].decoded); |
422c46a8 | 60 | |
6ee59202 AL |
61 | if (test_cases[i].skip == 0) { |
62 | str = qobject_to_json(obj); | |
ef76dc59 | 63 | g_assert_cmpstr(qstring_get_str(str), ==, test_cases[i].encoded); |
6ee59202 AL |
64 | qobject_decref(obj); |
65 | } | |
66 | ||
422c46a8 AL |
67 | QDECREF(str); |
68 | } | |
69 | } | |
422c46a8 | 70 | |
ef76dc59 | 71 | static void simple_string(void) |
422c46a8 AL |
72 | { |
73 | int i; | |
74 | struct { | |
75 | const char *encoded; | |
76 | const char *decoded; | |
77 | } test_cases[] = { | |
78 | { "\"hello world\"", "hello world" }, | |
79 | { "\"the quick brown fox jumped over the fence\"", | |
80 | "the quick brown fox jumped over the fence" }, | |
81 | {} | |
82 | }; | |
83 | ||
84 | for (i = 0; test_cases[i].encoded; i++) { | |
85 | QObject *obj; | |
86 | QString *str; | |
87 | ||
88 | obj = qobject_from_json(test_cases[i].encoded); | |
89 | ||
ef76dc59 AL |
90 | g_assert(obj != NULL); |
91 | g_assert(qobject_type(obj) == QTYPE_QSTRING); | |
422c46a8 AL |
92 | |
93 | str = qobject_to_qstring(obj); | |
ef76dc59 | 94 | g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0); |
422c46a8 | 95 | |
6ee59202 | 96 | str = qobject_to_json(obj); |
ef76dc59 | 97 | g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0); |
6ee59202 AL |
98 | |
99 | qobject_decref(obj); | |
100 | ||
422c46a8 AL |
101 | QDECREF(str); |
102 | } | |
103 | } | |
422c46a8 | 104 | |
ef76dc59 | 105 | static void single_quote_string(void) |
422c46a8 AL |
106 | { |
107 | int i; | |
108 | struct { | |
109 | const char *encoded; | |
110 | const char *decoded; | |
111 | } test_cases[] = { | |
112 | { "'hello world'", "hello world" }, | |
113 | { "'the quick brown fox \\' jumped over the fence'", | |
114 | "the quick brown fox ' jumped over the fence" }, | |
115 | {} | |
116 | }; | |
117 | ||
118 | for (i = 0; test_cases[i].encoded; i++) { | |
119 | QObject *obj; | |
120 | QString *str; | |
121 | ||
122 | obj = qobject_from_json(test_cases[i].encoded); | |
123 | ||
ef76dc59 AL |
124 | g_assert(obj != NULL); |
125 | g_assert(qobject_type(obj) == QTYPE_QSTRING); | |
422c46a8 AL |
126 | |
127 | str = qobject_to_qstring(obj); | |
ef76dc59 | 128 | g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0); |
422c46a8 AL |
129 | |
130 | QDECREF(str); | |
131 | } | |
132 | } | |
422c46a8 | 133 | |
ef76dc59 | 134 | static void vararg_string(void) |
422c46a8 AL |
135 | { |
136 | int i; | |
137 | struct { | |
138 | const char *decoded; | |
139 | } test_cases[] = { | |
140 | { "hello world" }, | |
141 | { "the quick brown fox jumped over the fence" }, | |
142 | {} | |
143 | }; | |
144 | ||
145 | for (i = 0; test_cases[i].decoded; i++) { | |
146 | QObject *obj; | |
147 | QString *str; | |
148 | ||
149 | obj = qobject_from_jsonf("%s", test_cases[i].decoded); | |
150 | ||
ef76dc59 AL |
151 | g_assert(obj != NULL); |
152 | g_assert(qobject_type(obj) == QTYPE_QSTRING); | |
422c46a8 AL |
153 | |
154 | str = qobject_to_qstring(obj); | |
ef76dc59 | 155 | g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0); |
422c46a8 AL |
156 | |
157 | QDECREF(str); | |
158 | } | |
159 | } | |
422c46a8 | 160 | |
ef76dc59 | 161 | static void simple_number(void) |
422c46a8 AL |
162 | { |
163 | int i; | |
164 | struct { | |
165 | const char *encoded; | |
166 | int64_t decoded; | |
6ee59202 | 167 | int skip; |
422c46a8 AL |
168 | } test_cases[] = { |
169 | { "0", 0 }, | |
170 | { "1234", 1234 }, | |
171 | { "1", 1 }, | |
172 | { "-32", -32 }, | |
6ee59202 | 173 | { "-0", 0, .skip = 1 }, |
422c46a8 AL |
174 | { }, |
175 | }; | |
176 | ||
177 | for (i = 0; test_cases[i].encoded; i++) { | |
178 | QObject *obj; | |
179 | QInt *qint; | |
180 | ||
181 | obj = qobject_from_json(test_cases[i].encoded); | |
ef76dc59 AL |
182 | g_assert(obj != NULL); |
183 | g_assert(qobject_type(obj) == QTYPE_QINT); | |
422c46a8 AL |
184 | |
185 | qint = qobject_to_qint(obj); | |
ef76dc59 | 186 | g_assert(qint_get_int(qint) == test_cases[i].decoded); |
6ee59202 AL |
187 | if (test_cases[i].skip == 0) { |
188 | QString *str; | |
189 | ||
190 | str = qobject_to_json(obj); | |
ef76dc59 | 191 | g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0); |
6ee59202 AL |
192 | QDECREF(str); |
193 | } | |
422c46a8 AL |
194 | |
195 | QDECREF(qint); | |
196 | } | |
197 | } | |
422c46a8 | 198 | |
ef76dc59 | 199 | static void float_number(void) |
422c46a8 AL |
200 | { |
201 | int i; | |
202 | struct { | |
203 | const char *encoded; | |
204 | double decoded; | |
6ee59202 | 205 | int skip; |
422c46a8 AL |
206 | } test_cases[] = { |
207 | { "32.43", 32.43 }, | |
208 | { "0.222", 0.222 }, | |
209 | { "-32.12313", -32.12313 }, | |
6ee59202 | 210 | { "-32.20e-10", -32.20e-10, .skip = 1 }, |
422c46a8 AL |
211 | { }, |
212 | }; | |
213 | ||
214 | for (i = 0; test_cases[i].encoded; i++) { | |
215 | QObject *obj; | |
216 | QFloat *qfloat; | |
217 | ||
218 | obj = qobject_from_json(test_cases[i].encoded); | |
ef76dc59 AL |
219 | g_assert(obj != NULL); |
220 | g_assert(qobject_type(obj) == QTYPE_QFLOAT); | |
422c46a8 AL |
221 | |
222 | qfloat = qobject_to_qfloat(obj); | |
ef76dc59 | 223 | g_assert(qfloat_get_double(qfloat) == test_cases[i].decoded); |
422c46a8 | 224 | |
6ee59202 AL |
225 | if (test_cases[i].skip == 0) { |
226 | QString *str; | |
227 | ||
228 | str = qobject_to_json(obj); | |
ef76dc59 | 229 | g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0); |
6ee59202 AL |
230 | QDECREF(str); |
231 | } | |
232 | ||
422c46a8 AL |
233 | QDECREF(qfloat); |
234 | } | |
235 | } | |
422c46a8 | 236 | |
ef76dc59 | 237 | static void vararg_number(void) |
422c46a8 AL |
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); | |
ef76dc59 AL |
247 | g_assert(obj != NULL); |
248 | g_assert(qobject_type(obj) == QTYPE_QINT); | |
422c46a8 AL |
249 | |
250 | qint = qobject_to_qint(obj); | |
ef76dc59 | 251 | g_assert(qint_get_int(qint) == value); |
422c46a8 AL |
252 | |
253 | QDECREF(qint); | |
254 | ||
255 | obj = qobject_from_jsonf("%" PRId64, value64); | |
ef76dc59 AL |
256 | g_assert(obj != NULL); |
257 | g_assert(qobject_type(obj) == QTYPE_QINT); | |
422c46a8 AL |
258 | |
259 | qint = qobject_to_qint(obj); | |
ef76dc59 | 260 | g_assert(qint_get_int(qint) == value64); |
422c46a8 AL |
261 | |
262 | QDECREF(qint); | |
263 | ||
264 | obj = qobject_from_jsonf("%f", valuef); | |
ef76dc59 AL |
265 | g_assert(obj != NULL); |
266 | g_assert(qobject_type(obj) == QTYPE_QFLOAT); | |
422c46a8 AL |
267 | |
268 | qfloat = qobject_to_qfloat(obj); | |
ef76dc59 | 269 | g_assert(qfloat_get_double(qfloat) == valuef); |
422c46a8 AL |
270 | |
271 | QDECREF(qfloat); | |
272 | } | |
422c46a8 | 273 | |
ef76dc59 | 274 | static void keyword_literal(void) |
422c46a8 AL |
275 | { |
276 | QObject *obj; | |
277 | QBool *qbool; | |
6ee59202 | 278 | QString *str; |
422c46a8 AL |
279 | |
280 | obj = qobject_from_json("true"); | |
ef76dc59 AL |
281 | g_assert(obj != NULL); |
282 | g_assert(qobject_type(obj) == QTYPE_QBOOL); | |
422c46a8 AL |
283 | |
284 | qbool = qobject_to_qbool(obj); | |
ef76dc59 | 285 | g_assert(qbool_get_int(qbool) != 0); |
422c46a8 | 286 | |
6ee59202 | 287 | str = qobject_to_json(obj); |
ef76dc59 | 288 | g_assert(strcmp(qstring_get_str(str), "true") == 0); |
6ee59202 AL |
289 | QDECREF(str); |
290 | ||
422c46a8 AL |
291 | QDECREF(qbool); |
292 | ||
293 | obj = qobject_from_json("false"); | |
ef76dc59 AL |
294 | g_assert(obj != NULL); |
295 | g_assert(qobject_type(obj) == QTYPE_QBOOL); | |
422c46a8 AL |
296 | |
297 | qbool = qobject_to_qbool(obj); | |
ef76dc59 | 298 | g_assert(qbool_get_int(qbool) == 0); |
422c46a8 | 299 | |
6ee59202 | 300 | str = qobject_to_json(obj); |
ef76dc59 | 301 | g_assert(strcmp(qstring_get_str(str), "false") == 0); |
6ee59202 AL |
302 | QDECREF(str); |
303 | ||
422c46a8 AL |
304 | QDECREF(qbool); |
305 | ||
306 | obj = qobject_from_jsonf("%i", false); | |
ef76dc59 AL |
307 | g_assert(obj != NULL); |
308 | g_assert(qobject_type(obj) == QTYPE_QBOOL); | |
422c46a8 AL |
309 | |
310 | qbool = qobject_to_qbool(obj); | |
ef76dc59 | 311 | g_assert(qbool_get_int(qbool) == 0); |
422c46a8 AL |
312 | |
313 | QDECREF(qbool); | |
314 | ||
315 | obj = qobject_from_jsonf("%i", true); | |
ef76dc59 AL |
316 | g_assert(obj != NULL); |
317 | g_assert(qobject_type(obj) == QTYPE_QBOOL); | |
422c46a8 AL |
318 | |
319 | qbool = qobject_to_qbool(obj); | |
ef76dc59 | 320 | g_assert(qbool_get_int(qbool) != 0); |
422c46a8 AL |
321 | |
322 | QDECREF(qbool); | |
323 | } | |
422c46a8 AL |
324 | |
325 | typedef struct LiteralQDictEntry LiteralQDictEntry; | |
326 | typedef struct LiteralQObject LiteralQObject; | |
327 | ||
328 | struct LiteralQObject | |
329 | { | |
330 | int type; | |
331 | union { | |
332 | int64_t qint; | |
333 | const char *qstr; | |
334 | LiteralQDictEntry *qdict; | |
335 | LiteralQObject *qlist; | |
336 | } value; | |
337 | }; | |
338 | ||
339 | struct LiteralQDictEntry | |
340 | { | |
341 | const char *key; | |
342 | LiteralQObject value; | |
343 | }; | |
344 | ||
345 | #define QLIT_QINT(val) (LiteralQObject){.type = QTYPE_QINT, .value.qint = (val)} | |
346 | #define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)} | |
347 | #define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)} | |
348 | #define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)} | |
349 | ||
350 | typedef struct QListCompareHelper | |
351 | { | |
352 | int index; | |
353 | LiteralQObject *objs; | |
354 | int result; | |
355 | } QListCompareHelper; | |
356 | ||
357 | static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs); | |
358 | ||
359 | static void compare_helper(QObject *obj, void *opaque) | |
360 | { | |
361 | QListCompareHelper *helper = opaque; | |
362 | ||
363 | if (helper->result == 0) { | |
364 | return; | |
365 | } | |
366 | ||
367 | if (helper->objs[helper->index].type == QTYPE_NONE) { | |
368 | helper->result = 0; | |
369 | return; | |
370 | } | |
371 | ||
372 | helper->result = compare_litqobj_to_qobj(&helper->objs[helper->index++], obj); | |
373 | } | |
374 | ||
375 | static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs) | |
376 | { | |
377 | if (lhs->type != qobject_type(rhs)) { | |
378 | return 0; | |
379 | } | |
380 | ||
381 | switch (lhs->type) { | |
382 | case QTYPE_QINT: | |
383 | return lhs->value.qint == qint_get_int(qobject_to_qint(rhs)); | |
384 | case QTYPE_QSTRING: | |
385 | return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0); | |
386 | case QTYPE_QDICT: { | |
387 | int i; | |
388 | ||
389 | for (i = 0; lhs->value.qdict[i].key; i++) { | |
390 | QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key); | |
391 | ||
392 | if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) { | |
393 | return 0; | |
394 | } | |
395 | } | |
396 | ||
397 | return 1; | |
398 | } | |
399 | case QTYPE_QLIST: { | |
400 | QListCompareHelper helper; | |
401 | ||
402 | helper.index = 0; | |
403 | helper.objs = lhs->value.qlist; | |
404 | helper.result = 1; | |
405 | ||
406 | qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper); | |
407 | ||
408 | return helper.result; | |
409 | } | |
410 | default: | |
411 | break; | |
412 | } | |
413 | ||
414 | return 0; | |
415 | } | |
416 | ||
ef76dc59 | 417 | static void simple_dict(void) |
422c46a8 AL |
418 | { |
419 | int i; | |
420 | struct { | |
421 | const char *encoded; | |
422 | LiteralQObject decoded; | |
423 | } test_cases[] = { | |
424 | { | |
6ee59202 | 425 | .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}", |
422c46a8 AL |
426 | .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ |
427 | { "foo", QLIT_QINT(42) }, | |
428 | { "bar", QLIT_QSTR("hello world") }, | |
429 | { } | |
430 | })), | |
431 | }, { | |
432 | .encoded = "{}", | |
433 | .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ | |
434 | { } | |
435 | })), | |
436 | }, { | |
6ee59202 | 437 | .encoded = "{\"foo\": 43}", |
422c46a8 AL |
438 | .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ |
439 | { "foo", QLIT_QINT(43) }, | |
440 | { } | |
441 | })), | |
442 | }, | |
443 | { } | |
444 | }; | |
445 | ||
446 | for (i = 0; test_cases[i].encoded; i++) { | |
447 | QObject *obj; | |
6ee59202 | 448 | QString *str; |
422c46a8 AL |
449 | |
450 | obj = qobject_from_json(test_cases[i].encoded); | |
ef76dc59 AL |
451 | g_assert(obj != NULL); |
452 | g_assert(qobject_type(obj) == QTYPE_QDICT); | |
422c46a8 | 453 | |
ef76dc59 | 454 | g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); |
422c46a8 | 455 | |
6ee59202 AL |
456 | str = qobject_to_json(obj); |
457 | qobject_decref(obj); | |
458 | ||
459 | obj = qobject_from_json(qstring_get_str(str)); | |
ef76dc59 AL |
460 | g_assert(obj != NULL); |
461 | g_assert(qobject_type(obj) == QTYPE_QDICT); | |
6ee59202 | 462 | |
ef76dc59 | 463 | g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); |
422c46a8 | 464 | qobject_decref(obj); |
6ee59202 | 465 | QDECREF(str); |
422c46a8 AL |
466 | } |
467 | } | |
422c46a8 | 468 | |
ef76dc59 | 469 | static void simple_list(void) |
422c46a8 AL |
470 | { |
471 | int i; | |
472 | struct { | |
473 | const char *encoded; | |
474 | LiteralQObject decoded; | |
475 | } test_cases[] = { | |
476 | { | |
477 | .encoded = "[43,42]", | |
478 | .decoded = QLIT_QLIST(((LiteralQObject[]){ | |
479 | QLIT_QINT(43), | |
480 | QLIT_QINT(42), | |
481 | { } | |
482 | })), | |
483 | }, | |
484 | { | |
485 | .encoded = "[43]", | |
486 | .decoded = QLIT_QLIST(((LiteralQObject[]){ | |
487 | QLIT_QINT(43), | |
488 | { } | |
489 | })), | |
490 | }, | |
491 | { | |
492 | .encoded = "[]", | |
493 | .decoded = QLIT_QLIST(((LiteralQObject[]){ | |
494 | { } | |
495 | })), | |
496 | }, | |
497 | { | |
498 | .encoded = "[{}]", | |
499 | .decoded = QLIT_QLIST(((LiteralQObject[]){ | |
500 | QLIT_QDICT(((LiteralQDictEntry[]){ | |
501 | {}, | |
502 | })), | |
503 | {}, | |
504 | })), | |
505 | }, | |
506 | { } | |
507 | }; | |
508 | ||
509 | for (i = 0; test_cases[i].encoded; i++) { | |
510 | QObject *obj; | |
6ee59202 | 511 | QString *str; |
422c46a8 AL |
512 | |
513 | obj = qobject_from_json(test_cases[i].encoded); | |
ef76dc59 AL |
514 | g_assert(obj != NULL); |
515 | g_assert(qobject_type(obj) == QTYPE_QLIST); | |
422c46a8 | 516 | |
ef76dc59 | 517 | g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); |
422c46a8 | 518 | |
6ee59202 AL |
519 | str = qobject_to_json(obj); |
520 | qobject_decref(obj); | |
521 | ||
522 | obj = qobject_from_json(qstring_get_str(str)); | |
ef76dc59 AL |
523 | g_assert(obj != NULL); |
524 | g_assert(qobject_type(obj) == QTYPE_QLIST); | |
6ee59202 | 525 | |
ef76dc59 | 526 | g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); |
422c46a8 | 527 | qobject_decref(obj); |
6ee59202 | 528 | QDECREF(str); |
422c46a8 AL |
529 | } |
530 | } | |
422c46a8 | 531 | |
ef76dc59 | 532 | static void simple_whitespace(void) |
422c46a8 AL |
533 | { |
534 | int i; | |
535 | struct { | |
536 | const char *encoded; | |
537 | LiteralQObject decoded; | |
538 | } test_cases[] = { | |
539 | { | |
540 | .encoded = " [ 43 , 42 ]", | |
541 | .decoded = QLIT_QLIST(((LiteralQObject[]){ | |
542 | QLIT_QINT(43), | |
543 | QLIT_QINT(42), | |
544 | { } | |
545 | })), | |
546 | }, | |
547 | { | |
548 | .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]", | |
549 | .decoded = QLIT_QLIST(((LiteralQObject[]){ | |
550 | QLIT_QINT(43), | |
551 | QLIT_QDICT(((LiteralQDictEntry[]){ | |
552 | { "h", QLIT_QSTR("b") }, | |
553 | { }})), | |
554 | QLIT_QLIST(((LiteralQObject[]){ | |
555 | { }})), | |
556 | QLIT_QINT(42), | |
557 | { } | |
558 | })), | |
559 | }, | |
560 | { | |
561 | .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]", | |
562 | .decoded = QLIT_QLIST(((LiteralQObject[]){ | |
563 | QLIT_QINT(43), | |
564 | QLIT_QDICT(((LiteralQDictEntry[]){ | |
565 | { "h", QLIT_QSTR("b") }, | |
566 | { "a", QLIT_QINT(32) }, | |
567 | { }})), | |
568 | QLIT_QLIST(((LiteralQObject[]){ | |
569 | { }})), | |
570 | QLIT_QINT(42), | |
571 | { } | |
572 | })), | |
573 | }, | |
574 | { } | |
575 | }; | |
576 | ||
577 | for (i = 0; test_cases[i].encoded; i++) { | |
578 | QObject *obj; | |
6ee59202 | 579 | QString *str; |
422c46a8 AL |
580 | |
581 | obj = qobject_from_json(test_cases[i].encoded); | |
ef76dc59 AL |
582 | g_assert(obj != NULL); |
583 | g_assert(qobject_type(obj) == QTYPE_QLIST); | |
422c46a8 | 584 | |
ef76dc59 | 585 | g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); |
422c46a8 | 586 | |
6ee59202 | 587 | str = qobject_to_json(obj); |
422c46a8 | 588 | qobject_decref(obj); |
6ee59202 AL |
589 | |
590 | obj = qobject_from_json(qstring_get_str(str)); | |
ef76dc59 AL |
591 | g_assert(obj != NULL); |
592 | g_assert(qobject_type(obj) == QTYPE_QLIST); | |
6ee59202 | 593 | |
ef76dc59 | 594 | g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); |
6ee59202 AL |
595 | |
596 | qobject_decref(obj); | |
597 | QDECREF(str); | |
422c46a8 AL |
598 | } |
599 | } | |
422c46a8 | 600 | |
ef76dc59 | 601 | static void simple_varargs(void) |
422c46a8 AL |
602 | { |
603 | QObject *embedded_obj; | |
604 | QObject *obj; | |
605 | LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){ | |
606 | QLIT_QINT(1), | |
607 | QLIT_QINT(2), | |
608 | QLIT_QLIST(((LiteralQObject[]){ | |
609 | QLIT_QINT(32), | |
610 | QLIT_QINT(42), | |
611 | {}})), | |
612 | {}})); | |
613 | ||
614 | embedded_obj = qobject_from_json("[32, 42]"); | |
ef76dc59 | 615 | g_assert(embedded_obj != NULL); |
422c46a8 AL |
616 | |
617 | obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj); | |
ef76dc59 | 618 | g_assert(obj != NULL); |
422c46a8 | 619 | |
ef76dc59 | 620 | g_assert(compare_litqobj_to_qobj(&decoded, obj) == 1); |
422c46a8 AL |
621 | |
622 | qobject_decref(obj); | |
623 | } | |
422c46a8 | 624 | |
ef76dc59 | 625 | static void empty_input(void) |
7f8fca7c | 626 | { |
e7a06af8 JK |
627 | const char *empty = ""; |
628 | ||
629 | QObject *obj = qobject_from_json(empty); | |
ef76dc59 | 630 | g_assert(obj == NULL); |
7f8fca7c | 631 | } |
7f8fca7c | 632 | |
ef76dc59 | 633 | static void unterminated_string(void) |
7f8fca7c PB |
634 | { |
635 | QObject *obj = qobject_from_json("\"abc"); | |
ef76dc59 | 636 | g_assert(obj == NULL); |
7f8fca7c | 637 | } |
7f8fca7c | 638 | |
ef76dc59 | 639 | static void unterminated_sq_string(void) |
7f8fca7c PB |
640 | { |
641 | QObject *obj = qobject_from_json("'abc"); | |
ef76dc59 | 642 | g_assert(obj == NULL); |
7f8fca7c | 643 | } |
7f8fca7c | 644 | |
ef76dc59 | 645 | static void unterminated_escape(void) |
7f8fca7c PB |
646 | { |
647 | QObject *obj = qobject_from_json("\"abc\\\""); | |
ef76dc59 | 648 | g_assert(obj == NULL); |
7f8fca7c | 649 | } |
7f8fca7c | 650 | |
ef76dc59 | 651 | static void unterminated_array(void) |
7f8fca7c PB |
652 | { |
653 | QObject *obj = qobject_from_json("[32"); | |
ef76dc59 | 654 | g_assert(obj == NULL); |
7f8fca7c | 655 | } |
7f8fca7c | 656 | |
ef76dc59 | 657 | static void unterminated_array_comma(void) |
7f8fca7c PB |
658 | { |
659 | QObject *obj = qobject_from_json("[32,"); | |
ef76dc59 | 660 | g_assert(obj == NULL); |
7f8fca7c | 661 | } |
7f8fca7c | 662 | |
ef76dc59 | 663 | static void invalid_array_comma(void) |
7f8fca7c PB |
664 | { |
665 | QObject *obj = qobject_from_json("[32,}"); | |
ef76dc59 | 666 | g_assert(obj == NULL); |
7f8fca7c | 667 | } |
7f8fca7c | 668 | |
ef76dc59 | 669 | static void unterminated_dict(void) |
7f8fca7c PB |
670 | { |
671 | QObject *obj = qobject_from_json("{'abc':32"); | |
ef76dc59 | 672 | g_assert(obj == NULL); |
7f8fca7c | 673 | } |
7f8fca7c | 674 | |
ef76dc59 | 675 | static void unterminated_dict_comma(void) |
7f8fca7c PB |
676 | { |
677 | QObject *obj = qobject_from_json("{'abc':32,"); | |
ef76dc59 | 678 | g_assert(obj == NULL); |
7f8fca7c | 679 | } |
7f8fca7c | 680 | |
ef76dc59 | 681 | static void invalid_dict_comma(void) |
7f8fca7c PB |
682 | { |
683 | QObject *obj = qobject_from_json("{'abc':32,}"); | |
ef76dc59 | 684 | g_assert(obj == NULL); |
7f8fca7c | 685 | } |
7f8fca7c | 686 | |
ef76dc59 | 687 | static void unterminated_literal(void) |
7f8fca7c PB |
688 | { |
689 | QObject *obj = qobject_from_json("nul"); | |
ef76dc59 | 690 | g_assert(obj == NULL); |
7f8fca7c | 691 | } |
7f8fca7c | 692 | |
ef76dc59 | 693 | int main(int argc, char **argv) |
422c46a8 | 694 | { |
ef76dc59 AL |
695 | g_test_init(&argc, &argv, NULL); |
696 | ||
697 | g_test_add_func("/literals/string/simple", simple_string); | |
698 | g_test_add_func("/literals/string/escaped", escaped_string); | |
699 | g_test_add_func("/literals/string/single_quote", single_quote_string); | |
700 | g_test_add_func("/literals/string/vararg", vararg_string); | |
701 | ||
702 | g_test_add_func("/literals/number/simple", simple_number); | |
703 | g_test_add_func("/literals/number/float", float_number); | |
704 | g_test_add_func("/literals/number/vararg", vararg_number); | |
705 | ||
706 | g_test_add_func("/literals/keyword", keyword_literal); | |
707 | ||
708 | g_test_add_func("/dicts/simple_dict", simple_dict); | |
709 | g_test_add_func("/lists/simple_list", simple_list); | |
710 | ||
711 | g_test_add_func("/whitespace/simple_whitespace", simple_whitespace); | |
712 | ||
713 | g_test_add_func("/varargs/simple_varargs", simple_varargs); | |
714 | ||
715 | g_test_add_func("/errors/empty_input", empty_input); | |
716 | g_test_add_func("/errors/unterminated/string", unterminated_string); | |
717 | g_test_add_func("/errors/unterminated/escape", unterminated_escape); | |
718 | g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string); | |
719 | g_test_add_func("/errors/unterminated/array", unterminated_array); | |
720 | g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma); | |
721 | g_test_add_func("/errors/unterminated/dict", unterminated_dict); | |
722 | g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma); | |
723 | g_test_add_func("/errors/invalid_array_comma", invalid_array_comma); | |
ef76dc59 AL |
724 | g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma); |
725 | g_test_add_func("/errors/unterminated/literal", unterminated_literal); | |
7f8fca7c | 726 | |
ef76dc59 | 727 | return g_test_run(); |
422c46a8 | 728 | } |