]> git.proxmox.com Git - mirror_qemu.git/blob - tests/test-qobject-output-visitor.c
test-keyval: Cover use with qobject input visitor
[mirror_qemu.git] / tests / test-qobject-output-visitor.c
1 /*
2 * QObject Output Visitor unit-tests.
3 *
4 * Copyright (C) 2011-2016 Red Hat Inc.
5 *
6 * Authors:
7 * Luiz Capitulino <lcapitulino@redhat.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
11 */
12
13 #include "qemu/osdep.h"
14
15 #include "qemu-common.h"
16 #include "qapi/error.h"
17 #include "qapi/qobject-output-visitor.h"
18 #include "test-qapi-types.h"
19 #include "test-qapi-visit.h"
20 #include "qapi/qmp/types.h"
21 #include "qapi/qmp/qjson.h"
22
23 typedef struct TestOutputVisitorData {
24 Visitor *ov;
25 QObject *obj;
26 } TestOutputVisitorData;
27
28 static void visitor_output_setup(TestOutputVisitorData *data,
29 const void *unused)
30 {
31 data->ov = qobject_output_visitor_new(&data->obj);
32 g_assert(data->ov);
33 }
34
35 static void visitor_output_teardown(TestOutputVisitorData *data,
36 const void *unused)
37 {
38 visit_free(data->ov);
39 data->ov = NULL;
40 qobject_decref(data->obj);
41 data->obj = NULL;
42 }
43
44 static QObject *visitor_get(TestOutputVisitorData *data)
45 {
46 visit_complete(data->ov, &data->obj);
47 g_assert(data->obj);
48 return data->obj;
49 }
50
51 static void visitor_reset(TestOutputVisitorData *data)
52 {
53 visitor_output_teardown(data, NULL);
54 visitor_output_setup(data, NULL);
55 }
56
57 static void test_visitor_out_int(TestOutputVisitorData *data,
58 const void *unused)
59 {
60 int64_t value = -42;
61 QInt *qint;
62
63 visit_type_int(data->ov, NULL, &value, &error_abort);
64
65 qint = qobject_to_qint(visitor_get(data));
66 g_assert(qint);
67 g_assert_cmpint(qint_get_int(qint), ==, value);
68 }
69
70 static void test_visitor_out_bool(TestOutputVisitorData *data,
71 const void *unused)
72 {
73 bool value = true;
74 QBool *qbool;
75
76 visit_type_bool(data->ov, NULL, &value, &error_abort);
77
78 qbool = qobject_to_qbool(visitor_get(data));
79 g_assert(qbool);
80 g_assert(qbool_get_bool(qbool) == value);
81 }
82
83 static void test_visitor_out_number(TestOutputVisitorData *data,
84 const void *unused)
85 {
86 double value = 3.14;
87 QFloat *qfloat;
88
89 visit_type_number(data->ov, NULL, &value, &error_abort);
90
91 qfloat = qobject_to_qfloat(visitor_get(data));
92 g_assert(qfloat);
93 g_assert(qfloat_get_double(qfloat) == value);
94 }
95
96 static void test_visitor_out_string(TestOutputVisitorData *data,
97 const void *unused)
98 {
99 char *string = (char *) "Q E M U";
100 QString *qstr;
101
102 visit_type_str(data->ov, NULL, &string, &error_abort);
103
104 qstr = qobject_to_qstring(visitor_get(data));
105 g_assert(qstr);
106 g_assert_cmpstr(qstring_get_str(qstr), ==, string);
107 }
108
109 static void test_visitor_out_no_string(TestOutputVisitorData *data,
110 const void *unused)
111 {
112 char *string = NULL;
113 QString *qstr;
114
115 /* A null string should return "" */
116 visit_type_str(data->ov, NULL, &string, &error_abort);
117
118 qstr = qobject_to_qstring(visitor_get(data));
119 g_assert(qstr);
120 g_assert_cmpstr(qstring_get_str(qstr), ==, "");
121 }
122
123 static void test_visitor_out_enum(TestOutputVisitorData *data,
124 const void *unused)
125 {
126 EnumOne i;
127 QString *qstr;
128
129 for (i = 0; i < ENUM_ONE__MAX; i++) {
130 visit_type_EnumOne(data->ov, "unused", &i, &error_abort);
131
132 qstr = qobject_to_qstring(visitor_get(data));
133 g_assert(qstr);
134 g_assert_cmpstr(qstring_get_str(qstr), ==, EnumOne_lookup[i]);
135 visitor_reset(data);
136 }
137 }
138
139 static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
140 const void *unused)
141 {
142 EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 };
143 Error *err;
144
145 for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
146 err = NULL;
147 visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err);
148 g_assert(err);
149 error_free(err);
150 visitor_reset(data);
151 }
152 }
153
154
155 static void test_visitor_out_struct(TestOutputVisitorData *data,
156 const void *unused)
157 {
158 TestStruct test_struct = { .integer = 42,
159 .boolean = false,
160 .string = (char *) "foo"};
161 TestStruct *p = &test_struct;
162 QDict *qdict;
163
164 visit_type_TestStruct(data->ov, NULL, &p, &error_abort);
165
166 qdict = qobject_to_qdict(visitor_get(data));
167 g_assert(qdict);
168 g_assert_cmpint(qdict_size(qdict), ==, 3);
169 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 42);
170 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, false);
171 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "foo");
172 }
173
174 static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
175 const void *unused)
176 {
177 int64_t value = 42;
178 UserDefTwo *ud2;
179 QDict *qdict, *dict1, *dict2, *dict3, *userdef;
180 const char *string = "user def string";
181 const char *strings[] = { "forty two", "forty three", "forty four",
182 "forty five" };
183
184 ud2 = g_malloc0(sizeof(*ud2));
185 ud2->string0 = g_strdup(strings[0]);
186
187 ud2->dict1 = g_malloc0(sizeof(*ud2->dict1));
188 ud2->dict1->string1 = g_strdup(strings[1]);
189
190 ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2));
191 ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1);
192 ud2->dict1->dict2->userdef->string = g_strdup(string);
193 ud2->dict1->dict2->userdef->integer = value;
194 ud2->dict1->dict2->string = g_strdup(strings[2]);
195
196 ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3));
197 ud2->dict1->has_dict3 = true;
198 ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1);
199 ud2->dict1->dict3->userdef->string = g_strdup(string);
200 ud2->dict1->dict3->userdef->integer = value;
201 ud2->dict1->dict3->string = g_strdup(strings[3]);
202
203 visit_type_UserDefTwo(data->ov, "unused", &ud2, &error_abort);
204
205 qdict = qobject_to_qdict(visitor_get(data));
206 g_assert(qdict);
207 g_assert_cmpint(qdict_size(qdict), ==, 2);
208 g_assert_cmpstr(qdict_get_str(qdict, "string0"), ==, strings[0]);
209
210 dict1 = qdict_get_qdict(qdict, "dict1");
211 g_assert_cmpint(qdict_size(dict1), ==, 3);
212 g_assert_cmpstr(qdict_get_str(dict1, "string1"), ==, strings[1]);
213
214 dict2 = qdict_get_qdict(dict1, "dict2");
215 g_assert_cmpint(qdict_size(dict2), ==, 2);
216 g_assert_cmpstr(qdict_get_str(dict2, "string"), ==, strings[2]);
217 userdef = qdict_get_qdict(dict2, "userdef");
218 g_assert_cmpint(qdict_size(userdef), ==, 2);
219 g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
220 g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
221
222 dict3 = qdict_get_qdict(dict1, "dict3");
223 g_assert_cmpint(qdict_size(dict3), ==, 2);
224 g_assert_cmpstr(qdict_get_str(dict3, "string"), ==, strings[3]);
225 userdef = qdict_get_qdict(dict3, "userdef");
226 g_assert_cmpint(qdict_size(userdef), ==, 2);
227 g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
228 g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
229
230 qapi_free_UserDefTwo(ud2);
231 }
232
233 static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
234 const void *unused)
235 {
236 EnumOne bad_values[] = { ENUM_ONE__MAX, -1 };
237 UserDefOne u = {0};
238 UserDefOne *pu = &u;
239 Error *err;
240 int i;
241
242 for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
243 err = NULL;
244 u.has_enum1 = true;
245 u.enum1 = bad_values[i];
246 visit_type_UserDefOne(data->ov, "unused", &pu, &err);
247 g_assert(err);
248 error_free(err);
249 visitor_reset(data);
250 }
251 }
252
253
254 static void test_visitor_out_list(TestOutputVisitorData *data,
255 const void *unused)
256 {
257 const char *value_str = "list value";
258 TestStructList *p, *head = NULL;
259 const int max_items = 10;
260 bool value_bool = true;
261 int value_int = 10;
262 QListEntry *entry;
263 QList *qlist;
264 int i;
265
266 /* Build the list in reverse order... */
267 for (i = 0; i < max_items; i++) {
268 p = g_malloc0(sizeof(*p));
269 p->value = g_malloc0(sizeof(*p->value));
270 p->value->integer = value_int + (max_items - i - 1);
271 p->value->boolean = value_bool;
272 p->value->string = g_strdup(value_str);
273
274 p->next = head;
275 head = p;
276 }
277
278 visit_type_TestStructList(data->ov, NULL, &head, &error_abort);
279
280 qlist = qobject_to_qlist(visitor_get(data));
281 g_assert(qlist);
282 g_assert(!qlist_empty(qlist));
283
284 /* ...and ensure that the visitor sees it in order */
285 i = 0;
286 QLIST_FOREACH_ENTRY(qlist, entry) {
287 QDict *qdict;
288
289 qdict = qobject_to_qdict(entry->value);
290 g_assert(qdict);
291 g_assert_cmpint(qdict_size(qdict), ==, 3);
292 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, value_int + i);
293 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, value_bool);
294 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, value_str);
295 i++;
296 }
297 g_assert_cmpint(i, ==, max_items);
298
299 qapi_free_TestStructList(head);
300 }
301
302 static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
303 const void *unused)
304 {
305 UserDefTwoList *p, *head = NULL;
306 const char string[] = "foo bar";
307 int i, max_count = 1024;
308
309 for (i = 0; i < max_count; i++) {
310 p = g_malloc0(sizeof(*p));
311 p->value = g_malloc0(sizeof(*p->value));
312
313 p->value->string0 = g_strdup(string);
314 p->value->dict1 = g_new0(UserDefTwoDict, 1);
315 p->value->dict1->string1 = g_strdup(string);
316 p->value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
317 p->value->dict1->dict2->userdef = g_new0(UserDefOne, 1);
318 p->value->dict1->dict2->userdef->string = g_strdup(string);
319 p->value->dict1->dict2->userdef->integer = 42;
320 p->value->dict1->dict2->string = g_strdup(string);
321 p->value->dict1->has_dict3 = false;
322
323 p->next = head;
324 head = p;
325 }
326
327 qapi_free_UserDefTwoList(head);
328 }
329
330 static void test_visitor_out_any(TestOutputVisitorData *data,
331 const void *unused)
332 {
333 QObject *qobj;
334 QInt *qint;
335 QBool *qbool;
336 QString *qstring;
337 QDict *qdict;
338
339 qobj = QOBJECT(qint_from_int(-42));
340 visit_type_any(data->ov, NULL, &qobj, &error_abort);
341 qint = qobject_to_qint(visitor_get(data));
342 g_assert(qint);
343 g_assert_cmpint(qint_get_int(qint), ==, -42);
344 qobject_decref(qobj);
345
346 visitor_reset(data);
347 qdict = qdict_new();
348 qdict_put(qdict, "integer", qint_from_int(-42));
349 qdict_put(qdict, "boolean", qbool_from_bool(true));
350 qdict_put(qdict, "string", qstring_from_str("foo"));
351 qobj = QOBJECT(qdict);
352 visit_type_any(data->ov, NULL, &qobj, &error_abort);
353 qobject_decref(qobj);
354 qdict = qobject_to_qdict(visitor_get(data));
355 g_assert(qdict);
356 qint = qobject_to_qint(qdict_get(qdict, "integer"));
357 g_assert(qint);
358 g_assert_cmpint(qint_get_int(qint), ==, -42);
359 qbool = qobject_to_qbool(qdict_get(qdict, "boolean"));
360 g_assert(qbool);
361 g_assert(qbool_get_bool(qbool) == true);
362 qstring = qobject_to_qstring(qdict_get(qdict, "string"));
363 g_assert(qstring);
364 g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
365 }
366
367 static void test_visitor_out_union_flat(TestOutputVisitorData *data,
368 const void *unused)
369 {
370 QDict *qdict;
371
372 UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
373 tmp->enum1 = ENUM_ONE_VALUE1;
374 tmp->string = g_strdup("str");
375 tmp->integer = 41;
376 tmp->u.value1.boolean = true;
377
378 visit_type_UserDefFlatUnion(data->ov, NULL, &tmp, &error_abort);
379 qdict = qobject_to_qdict(visitor_get(data));
380 g_assert(qdict);
381 g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
382 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
383 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41);
384 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
385
386 qapi_free_UserDefFlatUnion(tmp);
387 }
388
389 static void test_visitor_out_alternate(TestOutputVisitorData *data,
390 const void *unused)
391 {
392 UserDefAlternate *tmp;
393 QInt *qint;
394 QString *qstr;
395 QDict *qdict;
396
397 tmp = g_new0(UserDefAlternate, 1);
398 tmp->type = QTYPE_QINT;
399 tmp->u.i = 42;
400
401 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
402 qint = qobject_to_qint(visitor_get(data));
403 g_assert(qint);
404 g_assert_cmpint(qint_get_int(qint), ==, 42);
405
406 qapi_free_UserDefAlternate(tmp);
407
408 visitor_reset(data);
409 tmp = g_new0(UserDefAlternate, 1);
410 tmp->type = QTYPE_QSTRING;
411 tmp->u.s = g_strdup("hello");
412
413 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
414 qstr = qobject_to_qstring(visitor_get(data));
415 g_assert(qstr);
416 g_assert_cmpstr(qstring_get_str(qstr), ==, "hello");
417
418 qapi_free_UserDefAlternate(tmp);
419
420 visitor_reset(data);
421 tmp = g_new0(UserDefAlternate, 1);
422 tmp->type = QTYPE_QDICT;
423 tmp->u.udfu.integer = 1;
424 tmp->u.udfu.string = g_strdup("str");
425 tmp->u.udfu.enum1 = ENUM_ONE_VALUE1;
426 tmp->u.udfu.u.value1.boolean = true;
427
428 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
429 qdict = qobject_to_qdict(visitor_get(data));
430 g_assert(qdict);
431 g_assert_cmpint(qdict_size(qdict), ==, 4);
432 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 1);
433 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
434 g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
435 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
436
437 qapi_free_UserDefAlternate(tmp);
438 }
439
440 static void test_visitor_out_null(TestOutputVisitorData *data,
441 const void *unused)
442 {
443 QDict *qdict;
444 QObject *nil;
445
446 visit_start_struct(data->ov, NULL, NULL, 0, &error_abort);
447 visit_type_null(data->ov, "a", &error_abort);
448 visit_check_struct(data->ov, &error_abort);
449 visit_end_struct(data->ov, NULL);
450 qdict = qobject_to_qdict(visitor_get(data));
451 g_assert(qdict);
452 g_assert_cmpint(qdict_size(qdict), ==, 1);
453 nil = qdict_get(qdict, "a");
454 g_assert(nil);
455 g_assert(qobject_type(nil) == QTYPE_QNULL);
456 }
457
458 static void init_native_list(UserDefNativeListUnion *cvalue)
459 {
460 int i;
461 switch (cvalue->type) {
462 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
463 intList **list = &cvalue->u.integer.data;
464 for (i = 0; i < 32; i++) {
465 *list = g_new0(intList, 1);
466 (*list)->value = i;
467 (*list)->next = NULL;
468 list = &(*list)->next;
469 }
470 break;
471 }
472 case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
473 int8List **list = &cvalue->u.s8.data;
474 for (i = 0; i < 32; i++) {
475 *list = g_new0(int8List, 1);
476 (*list)->value = i;
477 (*list)->next = NULL;
478 list = &(*list)->next;
479 }
480 break;
481 }
482 case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
483 int16List **list = &cvalue->u.s16.data;
484 for (i = 0; i < 32; i++) {
485 *list = g_new0(int16List, 1);
486 (*list)->value = i;
487 (*list)->next = NULL;
488 list = &(*list)->next;
489 }
490 break;
491 }
492 case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
493 int32List **list = &cvalue->u.s32.data;
494 for (i = 0; i < 32; i++) {
495 *list = g_new0(int32List, 1);
496 (*list)->value = i;
497 (*list)->next = NULL;
498 list = &(*list)->next;
499 }
500 break;
501 }
502 case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
503 int64List **list = &cvalue->u.s64.data;
504 for (i = 0; i < 32; i++) {
505 *list = g_new0(int64List, 1);
506 (*list)->value = i;
507 (*list)->next = NULL;
508 list = &(*list)->next;
509 }
510 break;
511 }
512 case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
513 uint8List **list = &cvalue->u.u8.data;
514 for (i = 0; i < 32; i++) {
515 *list = g_new0(uint8List, 1);
516 (*list)->value = i;
517 (*list)->next = NULL;
518 list = &(*list)->next;
519 }
520 break;
521 }
522 case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
523 uint16List **list = &cvalue->u.u16.data;
524 for (i = 0; i < 32; i++) {
525 *list = g_new0(uint16List, 1);
526 (*list)->value = i;
527 (*list)->next = NULL;
528 list = &(*list)->next;
529 }
530 break;
531 }
532 case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
533 uint32List **list = &cvalue->u.u32.data;
534 for (i = 0; i < 32; i++) {
535 *list = g_new0(uint32List, 1);
536 (*list)->value = i;
537 (*list)->next = NULL;
538 list = &(*list)->next;
539 }
540 break;
541 }
542 case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
543 uint64List **list = &cvalue->u.u64.data;
544 for (i = 0; i < 32; i++) {
545 *list = g_new0(uint64List, 1);
546 (*list)->value = i;
547 (*list)->next = NULL;
548 list = &(*list)->next;
549 }
550 break;
551 }
552 case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN: {
553 boolList **list = &cvalue->u.boolean.data;
554 for (i = 0; i < 32; i++) {
555 *list = g_new0(boolList, 1);
556 (*list)->value = (i % 3 == 0);
557 (*list)->next = NULL;
558 list = &(*list)->next;
559 }
560 break;
561 }
562 case USER_DEF_NATIVE_LIST_UNION_KIND_STRING: {
563 strList **list = &cvalue->u.string.data;
564 for (i = 0; i < 32; i++) {
565 *list = g_new0(strList, 1);
566 (*list)->value = g_strdup_printf("%d", i);
567 (*list)->next = NULL;
568 list = &(*list)->next;
569 }
570 break;
571 }
572 case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: {
573 numberList **list = &cvalue->u.number.data;
574 for (i = 0; i < 32; i++) {
575 *list = g_new0(numberList, 1);
576 (*list)->value = (double)i / 3;
577 (*list)->next = NULL;
578 list = &(*list)->next;
579 }
580 break;
581 }
582 default:
583 g_assert_not_reached();
584 }
585 }
586
587 static void check_native_list(QObject *qobj,
588 UserDefNativeListUnionKind kind)
589 {
590 QDict *qdict;
591 QList *qlist;
592 int i;
593
594 qdict = qobject_to_qdict(qobj);
595 g_assert(qdict);
596 g_assert(qdict_haskey(qdict, "data"));
597 qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
598
599 switch (kind) {
600 case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
601 case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
602 case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
603 case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
604 case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
605 case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
606 case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
607 case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
608 /* all integer elements in JSON arrays get stored into QInts when
609 * we convert to QObjects, so we can check them all in the same
610 * fashion, so simply fall through here
611 */
612 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
613 for (i = 0; i < 32; i++) {
614 QObject *tmp;
615 QInt *qvalue;
616 tmp = qlist_peek(qlist);
617 g_assert(tmp);
618 qvalue = qobject_to_qint(tmp);
619 g_assert_cmpint(qint_get_int(qvalue), ==, i);
620 qobject_decref(qlist_pop(qlist));
621 }
622 break;
623 case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN:
624 for (i = 0; i < 32; i++) {
625 QObject *tmp;
626 QBool *qvalue;
627 tmp = qlist_peek(qlist);
628 g_assert(tmp);
629 qvalue = qobject_to_qbool(tmp);
630 g_assert_cmpint(qbool_get_bool(qvalue), ==, i % 3 == 0);
631 qobject_decref(qlist_pop(qlist));
632 }
633 break;
634 case USER_DEF_NATIVE_LIST_UNION_KIND_STRING:
635 for (i = 0; i < 32; i++) {
636 QObject *tmp;
637 QString *qvalue;
638 gchar str[8];
639 tmp = qlist_peek(qlist);
640 g_assert(tmp);
641 qvalue = qobject_to_qstring(tmp);
642 sprintf(str, "%d", i);
643 g_assert_cmpstr(qstring_get_str(qvalue), ==, str);
644 qobject_decref(qlist_pop(qlist));
645 }
646 break;
647 case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER:
648 for (i = 0; i < 32; i++) {
649 QObject *tmp;
650 QFloat *qvalue;
651 GString *double_expected = g_string_new("");
652 GString *double_actual = g_string_new("");
653
654 tmp = qlist_peek(qlist);
655 g_assert(tmp);
656 qvalue = qobject_to_qfloat(tmp);
657 g_string_printf(double_expected, "%.6f", (double)i / 3);
658 g_string_printf(double_actual, "%.6f", qfloat_get_double(qvalue));
659 g_assert_cmpstr(double_actual->str, ==, double_expected->str);
660
661 qobject_decref(qlist_pop(qlist));
662 g_string_free(double_expected, true);
663 g_string_free(double_actual, true);
664 }
665 break;
666 default:
667 g_assert_not_reached();
668 }
669 QDECREF(qlist);
670 }
671
672 static void test_native_list(TestOutputVisitorData *data,
673 const void *unused,
674 UserDefNativeListUnionKind kind)
675 {
676 UserDefNativeListUnion *cvalue = g_new0(UserDefNativeListUnion, 1);
677 QObject *obj;
678
679 cvalue->type = kind;
680 init_native_list(cvalue);
681
682 visit_type_UserDefNativeListUnion(data->ov, NULL, &cvalue, &error_abort);
683
684 obj = visitor_get(data);
685 check_native_list(obj, cvalue->type);
686 qapi_free_UserDefNativeListUnion(cvalue);
687 }
688
689 static void test_visitor_out_native_list_int(TestOutputVisitorData *data,
690 const void *unused)
691 {
692 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
693 }
694
695 static void test_visitor_out_native_list_int8(TestOutputVisitorData *data,
696 const void *unused)
697 {
698 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S8);
699 }
700
701 static void test_visitor_out_native_list_int16(TestOutputVisitorData *data,
702 const void *unused)
703 {
704 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S16);
705 }
706
707 static void test_visitor_out_native_list_int32(TestOutputVisitorData *data,
708 const void *unused)
709 {
710 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S32);
711 }
712
713 static void test_visitor_out_native_list_int64(TestOutputVisitorData *data,
714 const void *unused)
715 {
716 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S64);
717 }
718
719 static void test_visitor_out_native_list_uint8(TestOutputVisitorData *data,
720 const void *unused)
721 {
722 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U8);
723 }
724
725 static void test_visitor_out_native_list_uint16(TestOutputVisitorData *data,
726 const void *unused)
727 {
728 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U16);
729 }
730
731 static void test_visitor_out_native_list_uint32(TestOutputVisitorData *data,
732 const void *unused)
733 {
734 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U32);
735 }
736
737 static void test_visitor_out_native_list_uint64(TestOutputVisitorData *data,
738 const void *unused)
739 {
740 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U64);
741 }
742
743 static void test_visitor_out_native_list_bool(TestOutputVisitorData *data,
744 const void *unused)
745 {
746 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
747 }
748
749 static void test_visitor_out_native_list_str(TestOutputVisitorData *data,
750 const void *unused)
751 {
752 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
753 }
754
755 static void test_visitor_out_native_list_number(TestOutputVisitorData *data,
756 const void *unused)
757 {
758 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
759 }
760
761 static void output_visitor_test_add(const char *testpath,
762 TestOutputVisitorData *data,
763 void (*test_func)(TestOutputVisitorData *data, const void *user_data))
764 {
765 g_test_add(testpath, TestOutputVisitorData, data, visitor_output_setup,
766 test_func, visitor_output_teardown);
767 }
768
769 int main(int argc, char **argv)
770 {
771 TestOutputVisitorData out_visitor_data;
772
773 g_test_init(&argc, &argv, NULL);
774
775 output_visitor_test_add("/visitor/output/int",
776 &out_visitor_data, test_visitor_out_int);
777 output_visitor_test_add("/visitor/output/bool",
778 &out_visitor_data, test_visitor_out_bool);
779 output_visitor_test_add("/visitor/output/number",
780 &out_visitor_data, test_visitor_out_number);
781 output_visitor_test_add("/visitor/output/string",
782 &out_visitor_data, test_visitor_out_string);
783 output_visitor_test_add("/visitor/output/no-string",
784 &out_visitor_data, test_visitor_out_no_string);
785 output_visitor_test_add("/visitor/output/enum",
786 &out_visitor_data, test_visitor_out_enum);
787 output_visitor_test_add("/visitor/output/enum-errors",
788 &out_visitor_data, test_visitor_out_enum_errors);
789 output_visitor_test_add("/visitor/output/struct",
790 &out_visitor_data, test_visitor_out_struct);
791 output_visitor_test_add("/visitor/output/struct-nested",
792 &out_visitor_data, test_visitor_out_struct_nested);
793 output_visitor_test_add("/visitor/output/struct-errors",
794 &out_visitor_data, test_visitor_out_struct_errors);
795 output_visitor_test_add("/visitor/output/list",
796 &out_visitor_data, test_visitor_out_list);
797 output_visitor_test_add("/visitor/output/any",
798 &out_visitor_data, test_visitor_out_any);
799 output_visitor_test_add("/visitor/output/list-qapi-free",
800 &out_visitor_data, test_visitor_out_list_qapi_free);
801 output_visitor_test_add("/visitor/output/union-flat",
802 &out_visitor_data, test_visitor_out_union_flat);
803 output_visitor_test_add("/visitor/output/alternate",
804 &out_visitor_data, test_visitor_out_alternate);
805 output_visitor_test_add("/visitor/output/null",
806 &out_visitor_data, test_visitor_out_null);
807 output_visitor_test_add("/visitor/output/native_list/int",
808 &out_visitor_data,
809 test_visitor_out_native_list_int);
810 output_visitor_test_add("/visitor/output/native_list/int8",
811 &out_visitor_data,
812 test_visitor_out_native_list_int8);
813 output_visitor_test_add("/visitor/output/native_list/int16",
814 &out_visitor_data,
815 test_visitor_out_native_list_int16);
816 output_visitor_test_add("/visitor/output/native_list/int32",
817 &out_visitor_data,
818 test_visitor_out_native_list_int32);
819 output_visitor_test_add("/visitor/output/native_list/int64",
820 &out_visitor_data,
821 test_visitor_out_native_list_int64);
822 output_visitor_test_add("/visitor/output/native_list/uint8",
823 &out_visitor_data,
824 test_visitor_out_native_list_uint8);
825 output_visitor_test_add("/visitor/output/native_list/uint16",
826 &out_visitor_data,
827 test_visitor_out_native_list_uint16);
828 output_visitor_test_add("/visitor/output/native_list/uint32",
829 &out_visitor_data,
830 test_visitor_out_native_list_uint32);
831 output_visitor_test_add("/visitor/output/native_list/uint64",
832 &out_visitor_data,
833 test_visitor_out_native_list_uint64);
834 output_visitor_test_add("/visitor/output/native_list/bool",
835 &out_visitor_data,
836 test_visitor_out_native_list_bool);
837 output_visitor_test_add("/visitor/output/native_list/string",
838 &out_visitor_data,
839 test_visitor_out_native_list_str);
840 output_visitor_test_add("/visitor/output/native_list/number",
841 &out_visitor_data,
842 test_visitor_out_native_list_number);
843
844 g_test_run();
845
846 return 0;
847 }