xref: /openbmc/qemu/tests/unit/test-qobject-input-visitor.c (revision da668aa15b99150a8595c491aee00d5d2426aaf9)
1*da668aa1SThomas Huth /*
2*da668aa1SThomas Huth  * QObject Input Visitor unit-tests.
3*da668aa1SThomas Huth  *
4*da668aa1SThomas Huth  * Copyright (C) 2011-2016 Red Hat Inc.
5*da668aa1SThomas Huth  *
6*da668aa1SThomas Huth  * Authors:
7*da668aa1SThomas Huth  *  Luiz Capitulino <lcapitulino@redhat.com>
8*da668aa1SThomas Huth  *  Paolo Bonzini <pbonzini@redhat.com>
9*da668aa1SThomas Huth  *
10*da668aa1SThomas Huth  * This work is licensed under the terms of the GNU GPL, version 2 or later.
11*da668aa1SThomas Huth  * See the COPYING file in the top-level directory.
12*da668aa1SThomas Huth  */
13*da668aa1SThomas Huth 
14*da668aa1SThomas Huth #include "qemu/osdep.h"
15*da668aa1SThomas Huth 
16*da668aa1SThomas Huth #include "qemu-common.h"
17*da668aa1SThomas Huth #include "qapi/error.h"
18*da668aa1SThomas Huth #include "qapi/qapi-visit-introspect.h"
19*da668aa1SThomas Huth #include "qapi/qobject-input-visitor.h"
20*da668aa1SThomas Huth #include "test-qapi-visit.h"
21*da668aa1SThomas Huth #include "qapi/qmp/qbool.h"
22*da668aa1SThomas Huth #include "qapi/qmp/qdict.h"
23*da668aa1SThomas Huth #include "qapi/qmp/qnull.h"
24*da668aa1SThomas Huth #include "qapi/qmp/qnum.h"
25*da668aa1SThomas Huth #include "qapi/qmp/qstring.h"
26*da668aa1SThomas Huth #include "qapi/qmp/qjson.h"
27*da668aa1SThomas Huth #include "test-qapi-introspect.h"
28*da668aa1SThomas Huth #include "qapi/qapi-introspect.h"
29*da668aa1SThomas Huth 
30*da668aa1SThomas Huth typedef struct TestInputVisitorData {
31*da668aa1SThomas Huth     QObject *obj;
32*da668aa1SThomas Huth     Visitor *qiv;
33*da668aa1SThomas Huth } TestInputVisitorData;
34*da668aa1SThomas Huth 
35*da668aa1SThomas Huth static void visitor_input_teardown(TestInputVisitorData *data,
36*da668aa1SThomas Huth                                    const void *unused)
37*da668aa1SThomas Huth {
38*da668aa1SThomas Huth     qobject_unref(data->obj);
39*da668aa1SThomas Huth     data->obj = NULL;
40*da668aa1SThomas Huth 
41*da668aa1SThomas Huth     if (data->qiv) {
42*da668aa1SThomas Huth         visit_free(data->qiv);
43*da668aa1SThomas Huth         data->qiv = NULL;
44*da668aa1SThomas Huth     }
45*da668aa1SThomas Huth }
46*da668aa1SThomas Huth 
47*da668aa1SThomas Huth /* The various test_init functions are provided instead of a test setup
48*da668aa1SThomas Huth    function so that the JSON string used by the tests are kept in the test
49*da668aa1SThomas Huth    functions (and not in main()). */
50*da668aa1SThomas Huth 
51*da668aa1SThomas Huth static Visitor *test_init_internal(TestInputVisitorData *data, bool keyval,
52*da668aa1SThomas Huth                                    QObject *obj)
53*da668aa1SThomas Huth {
54*da668aa1SThomas Huth     visitor_input_teardown(data, NULL);
55*da668aa1SThomas Huth 
56*da668aa1SThomas Huth     data->obj = obj;
57*da668aa1SThomas Huth 
58*da668aa1SThomas Huth     if (keyval) {
59*da668aa1SThomas Huth         data->qiv = qobject_input_visitor_new_keyval(data->obj);
60*da668aa1SThomas Huth     } else {
61*da668aa1SThomas Huth         data->qiv = qobject_input_visitor_new(data->obj);
62*da668aa1SThomas Huth     }
63*da668aa1SThomas Huth     g_assert(data->qiv);
64*da668aa1SThomas Huth     return data->qiv;
65*da668aa1SThomas Huth }
66*da668aa1SThomas Huth 
67*da668aa1SThomas Huth static GCC_FMT_ATTR(3, 4)
68*da668aa1SThomas Huth Visitor *visitor_input_test_init_full(TestInputVisitorData *data,
69*da668aa1SThomas Huth                                       bool keyval,
70*da668aa1SThomas Huth                                       const char *json_string, ...)
71*da668aa1SThomas Huth {
72*da668aa1SThomas Huth     Visitor *v;
73*da668aa1SThomas Huth     va_list ap;
74*da668aa1SThomas Huth 
75*da668aa1SThomas Huth     va_start(ap, json_string);
76*da668aa1SThomas Huth     v = test_init_internal(data, keyval,
77*da668aa1SThomas Huth                            qobject_from_vjsonf_nofail(json_string, ap));
78*da668aa1SThomas Huth     va_end(ap);
79*da668aa1SThomas Huth     return v;
80*da668aa1SThomas Huth }
81*da668aa1SThomas Huth 
82*da668aa1SThomas Huth static GCC_FMT_ATTR(2, 3)
83*da668aa1SThomas Huth Visitor *visitor_input_test_init(TestInputVisitorData *data,
84*da668aa1SThomas Huth                                  const char *json_string, ...)
85*da668aa1SThomas Huth {
86*da668aa1SThomas Huth     Visitor *v;
87*da668aa1SThomas Huth     va_list ap;
88*da668aa1SThomas Huth 
89*da668aa1SThomas Huth     va_start(ap, json_string);
90*da668aa1SThomas Huth     v = test_init_internal(data, false,
91*da668aa1SThomas Huth                            qobject_from_vjsonf_nofail(json_string, ap));
92*da668aa1SThomas Huth     va_end(ap);
93*da668aa1SThomas Huth     return v;
94*da668aa1SThomas Huth }
95*da668aa1SThomas Huth 
96*da668aa1SThomas Huth /* similar to visitor_input_test_init(), but does not expect a string
97*da668aa1SThomas Huth  * literal/format json_string argument and so can be used for
98*da668aa1SThomas Huth  * programatically generated strings (and we can't pass in programatically
99*da668aa1SThomas Huth  * generated strings via %s format parameters since qobject_from_jsonv()
100*da668aa1SThomas Huth  * will wrap those in double-quotes and treat the entire object as a
101*da668aa1SThomas Huth  * string)
102*da668aa1SThomas Huth  */
103*da668aa1SThomas Huth static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
104*da668aa1SThomas Huth                                             const char *json_string)
105*da668aa1SThomas Huth {
106*da668aa1SThomas Huth     return test_init_internal(data, false,
107*da668aa1SThomas Huth                               qobject_from_json(json_string, &error_abort));
108*da668aa1SThomas Huth }
109*da668aa1SThomas Huth 
110*da668aa1SThomas Huth static void test_visitor_in_int(TestInputVisitorData *data,
111*da668aa1SThomas Huth                                 const void *unused)
112*da668aa1SThomas Huth {
113*da668aa1SThomas Huth     int64_t res = 0;
114*da668aa1SThomas Huth     double dbl;
115*da668aa1SThomas Huth     int value = -42;
116*da668aa1SThomas Huth     Visitor *v;
117*da668aa1SThomas Huth 
118*da668aa1SThomas Huth     v = visitor_input_test_init(data, "%d", value);
119*da668aa1SThomas Huth 
120*da668aa1SThomas Huth     visit_type_int(v, NULL, &res, &error_abort);
121*da668aa1SThomas Huth     g_assert_cmpint(res, ==, value);
122*da668aa1SThomas Huth 
123*da668aa1SThomas Huth     visit_type_number(v, NULL, &dbl, &error_abort);
124*da668aa1SThomas Huth     g_assert_cmpfloat(dbl, ==, -42.0);
125*da668aa1SThomas Huth }
126*da668aa1SThomas Huth 
127*da668aa1SThomas Huth static void test_visitor_in_uint(TestInputVisitorData *data,
128*da668aa1SThomas Huth                                 const void *unused)
129*da668aa1SThomas Huth {
130*da668aa1SThomas Huth     uint64_t res = 0;
131*da668aa1SThomas Huth     int64_t i64;
132*da668aa1SThomas Huth     double dbl;
133*da668aa1SThomas Huth     int value = 42;
134*da668aa1SThomas Huth     Visitor *v;
135*da668aa1SThomas Huth 
136*da668aa1SThomas Huth     v = visitor_input_test_init(data, "%d", value);
137*da668aa1SThomas Huth 
138*da668aa1SThomas Huth     visit_type_uint64(v, NULL, &res, &error_abort);
139*da668aa1SThomas Huth     g_assert_cmpuint(res, ==, (uint64_t)value);
140*da668aa1SThomas Huth 
141*da668aa1SThomas Huth     visit_type_int(v, NULL, &i64, &error_abort);
142*da668aa1SThomas Huth     g_assert_cmpint(i64, ==, value);
143*da668aa1SThomas Huth 
144*da668aa1SThomas Huth     visit_type_number(v, NULL, &dbl, &error_abort);
145*da668aa1SThomas Huth     g_assert_cmpfloat(dbl, ==, value);
146*da668aa1SThomas Huth 
147*da668aa1SThomas Huth     /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */
148*da668aa1SThomas Huth     v = visitor_input_test_init(data, "%d", -value);
149*da668aa1SThomas Huth 
150*da668aa1SThomas Huth     visit_type_uint64(v, NULL, &res, &error_abort);
151*da668aa1SThomas Huth     g_assert_cmpuint(res, ==, (uint64_t)-value);
152*da668aa1SThomas Huth 
153*da668aa1SThomas Huth     v = visitor_input_test_init(data, "18446744073709551574");
154*da668aa1SThomas Huth 
155*da668aa1SThomas Huth     visit_type_uint64(v, NULL, &res, &error_abort);
156*da668aa1SThomas Huth     g_assert_cmpuint(res, ==, 18446744073709551574U);
157*da668aa1SThomas Huth 
158*da668aa1SThomas Huth     visit_type_number(v, NULL, &dbl, &error_abort);
159*da668aa1SThomas Huth     g_assert_cmpfloat(dbl, ==, 18446744073709552000.0);
160*da668aa1SThomas Huth }
161*da668aa1SThomas Huth 
162*da668aa1SThomas Huth static void test_visitor_in_int_overflow(TestInputVisitorData *data,
163*da668aa1SThomas Huth                                          const void *unused)
164*da668aa1SThomas Huth {
165*da668aa1SThomas Huth     int64_t res = 0;
166*da668aa1SThomas Huth     Error *err = NULL;
167*da668aa1SThomas Huth     Visitor *v;
168*da668aa1SThomas Huth 
169*da668aa1SThomas Huth     /*
170*da668aa1SThomas Huth      * This will overflow a QNUM_I64, so should be deserialized into a
171*da668aa1SThomas Huth      * QNUM_DOUBLE field instead, leading to an error if we pass it to
172*da668aa1SThomas Huth      * visit_type_int().  Confirm this.
173*da668aa1SThomas Huth      */
174*da668aa1SThomas Huth     v = visitor_input_test_init(data, "%f", DBL_MAX);
175*da668aa1SThomas Huth 
176*da668aa1SThomas Huth     visit_type_int(v, NULL, &res, &err);
177*da668aa1SThomas Huth     error_free_or_abort(&err);
178*da668aa1SThomas Huth }
179*da668aa1SThomas Huth 
180*da668aa1SThomas Huth static void test_visitor_in_int_keyval(TestInputVisitorData *data,
181*da668aa1SThomas Huth                                        const void *unused)
182*da668aa1SThomas Huth {
183*da668aa1SThomas Huth     int64_t res = 0, value = -42;
184*da668aa1SThomas Huth     Error *err = NULL;
185*da668aa1SThomas Huth     Visitor *v;
186*da668aa1SThomas Huth 
187*da668aa1SThomas Huth     v = visitor_input_test_init_full(data, true, "%" PRId64, value);
188*da668aa1SThomas Huth     visit_type_int(v, NULL, &res, &err);
189*da668aa1SThomas Huth     error_free_or_abort(&err);
190*da668aa1SThomas Huth }
191*da668aa1SThomas Huth 
192*da668aa1SThomas Huth static void test_visitor_in_int_str_keyval(TestInputVisitorData *data,
193*da668aa1SThomas Huth                                            const void *unused)
194*da668aa1SThomas Huth {
195*da668aa1SThomas Huth     int64_t res = 0, value = -42;
196*da668aa1SThomas Huth     Visitor *v;
197*da668aa1SThomas Huth 
198*da668aa1SThomas Huth     v = visitor_input_test_init_full(data, true, "\"-42\"");
199*da668aa1SThomas Huth 
200*da668aa1SThomas Huth     visit_type_int(v, NULL, &res, &error_abort);
201*da668aa1SThomas Huth     g_assert_cmpint(res, ==, value);
202*da668aa1SThomas Huth }
203*da668aa1SThomas Huth 
204*da668aa1SThomas Huth static void test_visitor_in_int_str_fail(TestInputVisitorData *data,
205*da668aa1SThomas Huth                                          const void *unused)
206*da668aa1SThomas Huth {
207*da668aa1SThomas Huth     int64_t res = 0;
208*da668aa1SThomas Huth     Visitor *v;
209*da668aa1SThomas Huth     Error *err = NULL;
210*da668aa1SThomas Huth 
211*da668aa1SThomas Huth     v = visitor_input_test_init(data, "\"-42\"");
212*da668aa1SThomas Huth 
213*da668aa1SThomas Huth     visit_type_int(v, NULL, &res, &err);
214*da668aa1SThomas Huth     error_free_or_abort(&err);
215*da668aa1SThomas Huth }
216*da668aa1SThomas Huth 
217*da668aa1SThomas Huth static void test_visitor_in_bool(TestInputVisitorData *data,
218*da668aa1SThomas Huth                                  const void *unused)
219*da668aa1SThomas Huth {
220*da668aa1SThomas Huth     bool res = false;
221*da668aa1SThomas Huth     Visitor *v;
222*da668aa1SThomas Huth 
223*da668aa1SThomas Huth     v = visitor_input_test_init(data, "true");
224*da668aa1SThomas Huth 
225*da668aa1SThomas Huth     visit_type_bool(v, NULL, &res, &error_abort);
226*da668aa1SThomas Huth     g_assert_cmpint(res, ==, true);
227*da668aa1SThomas Huth }
228*da668aa1SThomas Huth 
229*da668aa1SThomas Huth static void test_visitor_in_bool_keyval(TestInputVisitorData *data,
230*da668aa1SThomas Huth                                         const void *unused)
231*da668aa1SThomas Huth {
232*da668aa1SThomas Huth     bool res = false;
233*da668aa1SThomas Huth     Error *err = NULL;
234*da668aa1SThomas Huth     Visitor *v;
235*da668aa1SThomas Huth 
236*da668aa1SThomas Huth     v = visitor_input_test_init_full(data, true, "true");
237*da668aa1SThomas Huth 
238*da668aa1SThomas Huth     visit_type_bool(v, NULL, &res, &err);
239*da668aa1SThomas Huth     error_free_or_abort(&err);
240*da668aa1SThomas Huth }
241*da668aa1SThomas Huth 
242*da668aa1SThomas Huth static void test_visitor_in_bool_str_keyval(TestInputVisitorData *data,
243*da668aa1SThomas Huth                                             const void *unused)
244*da668aa1SThomas Huth {
245*da668aa1SThomas Huth     bool res = false;
246*da668aa1SThomas Huth     Visitor *v;
247*da668aa1SThomas Huth 
248*da668aa1SThomas Huth     v = visitor_input_test_init_full(data, true, "\"on\"");
249*da668aa1SThomas Huth 
250*da668aa1SThomas Huth     visit_type_bool(v, NULL, &res, &error_abort);
251*da668aa1SThomas Huth     g_assert_cmpint(res, ==, true);
252*da668aa1SThomas Huth }
253*da668aa1SThomas Huth 
254*da668aa1SThomas Huth static void test_visitor_in_bool_str_fail(TestInputVisitorData *data,
255*da668aa1SThomas Huth                                           const void *unused)
256*da668aa1SThomas Huth {
257*da668aa1SThomas Huth     bool res = false;
258*da668aa1SThomas Huth     Visitor *v;
259*da668aa1SThomas Huth     Error *err = NULL;
260*da668aa1SThomas Huth 
261*da668aa1SThomas Huth     v = visitor_input_test_init(data, "\"true\"");
262*da668aa1SThomas Huth 
263*da668aa1SThomas Huth     visit_type_bool(v, NULL, &res, &err);
264*da668aa1SThomas Huth     error_free_or_abort(&err);
265*da668aa1SThomas Huth }
266*da668aa1SThomas Huth 
267*da668aa1SThomas Huth static void test_visitor_in_number(TestInputVisitorData *data,
268*da668aa1SThomas Huth                                    const void *unused)
269*da668aa1SThomas Huth {
270*da668aa1SThomas Huth     double res = 0, value = 3.14;
271*da668aa1SThomas Huth     Visitor *v;
272*da668aa1SThomas Huth 
273*da668aa1SThomas Huth     v = visitor_input_test_init(data, "%f", value);
274*da668aa1SThomas Huth 
275*da668aa1SThomas Huth     visit_type_number(v, NULL, &res, &error_abort);
276*da668aa1SThomas Huth     g_assert_cmpfloat(res, ==, value);
277*da668aa1SThomas Huth }
278*da668aa1SThomas Huth 
279*da668aa1SThomas Huth static void test_visitor_in_large_number(TestInputVisitorData *data,
280*da668aa1SThomas Huth                                          const void *unused)
281*da668aa1SThomas Huth {
282*da668aa1SThomas Huth     Error *err = NULL;
283*da668aa1SThomas Huth     double res = 0;
284*da668aa1SThomas Huth     int64_t i64;
285*da668aa1SThomas Huth     uint64_t u64;
286*da668aa1SThomas Huth     Visitor *v;
287*da668aa1SThomas Huth 
288*da668aa1SThomas Huth     v = visitor_input_test_init(data, "-18446744073709551616"); /* -2^64 */
289*da668aa1SThomas Huth 
290*da668aa1SThomas Huth     visit_type_number(v, NULL, &res, &error_abort);
291*da668aa1SThomas Huth     g_assert_cmpfloat(res, ==, -18446744073709552e3);
292*da668aa1SThomas Huth 
293*da668aa1SThomas Huth     visit_type_int(v, NULL, &i64, &err);
294*da668aa1SThomas Huth     error_free_or_abort(&err);
295*da668aa1SThomas Huth 
296*da668aa1SThomas Huth     visit_type_uint64(v, NULL, &u64, &err);
297*da668aa1SThomas Huth     error_free_or_abort(&err);
298*da668aa1SThomas Huth }
299*da668aa1SThomas Huth 
300*da668aa1SThomas Huth static void test_visitor_in_number_keyval(TestInputVisitorData *data,
301*da668aa1SThomas Huth                                           const void *unused)
302*da668aa1SThomas Huth {
303*da668aa1SThomas Huth     double res = 0, value = 3.14;
304*da668aa1SThomas Huth     Error *err = NULL;
305*da668aa1SThomas Huth     Visitor *v;
306*da668aa1SThomas Huth 
307*da668aa1SThomas Huth     v = visitor_input_test_init_full(data, true, "%f", value);
308*da668aa1SThomas Huth 
309*da668aa1SThomas Huth     visit_type_number(v, NULL, &res, &err);
310*da668aa1SThomas Huth     error_free_or_abort(&err);
311*da668aa1SThomas Huth }
312*da668aa1SThomas Huth 
313*da668aa1SThomas Huth static void test_visitor_in_number_str_keyval(TestInputVisitorData *data,
314*da668aa1SThomas Huth                                               const void *unused)
315*da668aa1SThomas Huth {
316*da668aa1SThomas Huth     double res = 0, value = 3.14;
317*da668aa1SThomas Huth     Visitor *v;
318*da668aa1SThomas Huth     Error *err = NULL;
319*da668aa1SThomas Huth 
320*da668aa1SThomas Huth     v = visitor_input_test_init_full(data, true, "\"3.14\"");
321*da668aa1SThomas Huth 
322*da668aa1SThomas Huth     visit_type_number(v, NULL, &res, &error_abort);
323*da668aa1SThomas Huth     g_assert_cmpfloat(res, ==, value);
324*da668aa1SThomas Huth 
325*da668aa1SThomas Huth     v = visitor_input_test_init_full(data, true, "\"inf\"");
326*da668aa1SThomas Huth 
327*da668aa1SThomas Huth     visit_type_number(v, NULL, &res, &err);
328*da668aa1SThomas Huth     error_free_or_abort(&err);
329*da668aa1SThomas Huth }
330*da668aa1SThomas Huth 
331*da668aa1SThomas Huth static void test_visitor_in_number_str_fail(TestInputVisitorData *data,
332*da668aa1SThomas Huth                                             const void *unused)
333*da668aa1SThomas Huth {
334*da668aa1SThomas Huth     double res = 0;
335*da668aa1SThomas Huth     Visitor *v;
336*da668aa1SThomas Huth     Error *err = NULL;
337*da668aa1SThomas Huth 
338*da668aa1SThomas Huth     v = visitor_input_test_init(data, "\"3.14\"");
339*da668aa1SThomas Huth 
340*da668aa1SThomas Huth     visit_type_number(v, NULL, &res, &err);
341*da668aa1SThomas Huth     error_free_or_abort(&err);
342*da668aa1SThomas Huth }
343*da668aa1SThomas Huth 
344*da668aa1SThomas Huth static void test_visitor_in_size_str_keyval(TestInputVisitorData *data,
345*da668aa1SThomas Huth                                             const void *unused)
346*da668aa1SThomas Huth {
347*da668aa1SThomas Huth     uint64_t res, value = 500 * 1024 * 1024;
348*da668aa1SThomas Huth     Visitor *v;
349*da668aa1SThomas Huth 
350*da668aa1SThomas Huth     v = visitor_input_test_init_full(data, true, "\"500M\"");
351*da668aa1SThomas Huth 
352*da668aa1SThomas Huth     visit_type_size(v, NULL, &res, &error_abort);
353*da668aa1SThomas Huth     g_assert_cmpfloat(res, ==, value);
354*da668aa1SThomas Huth }
355*da668aa1SThomas Huth 
356*da668aa1SThomas Huth static void test_visitor_in_size_str_fail(TestInputVisitorData *data,
357*da668aa1SThomas Huth                                           const void *unused)
358*da668aa1SThomas Huth {
359*da668aa1SThomas Huth     uint64_t res = 0;
360*da668aa1SThomas Huth     Visitor *v;
361*da668aa1SThomas Huth     Error *err = NULL;
362*da668aa1SThomas Huth 
363*da668aa1SThomas Huth     v = visitor_input_test_init(data, "\"500M\"");
364*da668aa1SThomas Huth 
365*da668aa1SThomas Huth     visit_type_size(v, NULL, &res, &err);
366*da668aa1SThomas Huth     error_free_or_abort(&err);
367*da668aa1SThomas Huth }
368*da668aa1SThomas Huth 
369*da668aa1SThomas Huth static void test_visitor_in_string(TestInputVisitorData *data,
370*da668aa1SThomas Huth                                    const void *unused)
371*da668aa1SThomas Huth {
372*da668aa1SThomas Huth     char *res = NULL, *value = (char *) "Q E M U";
373*da668aa1SThomas Huth     Visitor *v;
374*da668aa1SThomas Huth 
375*da668aa1SThomas Huth     v = visitor_input_test_init(data, "%s", value);
376*da668aa1SThomas Huth 
377*da668aa1SThomas Huth     visit_type_str(v, NULL, &res, &error_abort);
378*da668aa1SThomas Huth     g_assert_cmpstr(res, ==, value);
379*da668aa1SThomas Huth 
380*da668aa1SThomas Huth     g_free(res);
381*da668aa1SThomas Huth }
382*da668aa1SThomas Huth 
383*da668aa1SThomas Huth static void test_visitor_in_enum(TestInputVisitorData *data,
384*da668aa1SThomas Huth                                  const void *unused)
385*da668aa1SThomas Huth {
386*da668aa1SThomas Huth     Visitor *v;
387*da668aa1SThomas Huth     EnumOne i;
388*da668aa1SThomas Huth 
389*da668aa1SThomas Huth     for (i = 0; i < ENUM_ONE__MAX; i++) {
390*da668aa1SThomas Huth         EnumOne res = -1;
391*da668aa1SThomas Huth 
392*da668aa1SThomas Huth         v = visitor_input_test_init(data, "%s", EnumOne_str(i));
393*da668aa1SThomas Huth 
394*da668aa1SThomas Huth         visit_type_EnumOne(v, NULL, &res, &error_abort);
395*da668aa1SThomas Huth         g_assert_cmpint(i, ==, res);
396*da668aa1SThomas Huth     }
397*da668aa1SThomas Huth }
398*da668aa1SThomas Huth 
399*da668aa1SThomas Huth 
400*da668aa1SThomas Huth static void test_visitor_in_struct(TestInputVisitorData *data,
401*da668aa1SThomas Huth                                    const void *unused)
402*da668aa1SThomas Huth {
403*da668aa1SThomas Huth     TestStruct *p = NULL;
404*da668aa1SThomas Huth     Visitor *v;
405*da668aa1SThomas Huth 
406*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
407*da668aa1SThomas Huth 
408*da668aa1SThomas Huth     visit_type_TestStruct(v, NULL, &p, &error_abort);
409*da668aa1SThomas Huth     g_assert_cmpint(p->integer, ==, -42);
410*da668aa1SThomas Huth     g_assert(p->boolean == true);
411*da668aa1SThomas Huth     g_assert_cmpstr(p->string, ==, "foo");
412*da668aa1SThomas Huth 
413*da668aa1SThomas Huth     g_free(p->string);
414*da668aa1SThomas Huth     g_free(p);
415*da668aa1SThomas Huth }
416*da668aa1SThomas Huth 
417*da668aa1SThomas Huth static void test_visitor_in_struct_nested(TestInputVisitorData *data,
418*da668aa1SThomas Huth                                           const void *unused)
419*da668aa1SThomas Huth {
420*da668aa1SThomas Huth     g_autoptr(UserDefTwo) udp = NULL;
421*da668aa1SThomas Huth     Visitor *v;
422*da668aa1SThomas Huth 
423*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'string0': 'string0', "
424*da668aa1SThomas Huth                                 "'dict1': { 'string1': 'string1', "
425*da668aa1SThomas Huth                                 "'dict2': { 'userdef': { 'integer': 42, "
426*da668aa1SThomas Huth                                 "'string': 'string' }, 'string': 'string2'}}}");
427*da668aa1SThomas Huth 
428*da668aa1SThomas Huth     visit_type_UserDefTwo(v, NULL, &udp, &error_abort);
429*da668aa1SThomas Huth 
430*da668aa1SThomas Huth     g_assert_cmpstr(udp->string0, ==, "string0");
431*da668aa1SThomas Huth     g_assert_cmpstr(udp->dict1->string1, ==, "string1");
432*da668aa1SThomas Huth     g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
433*da668aa1SThomas Huth     g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
434*da668aa1SThomas Huth     g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
435*da668aa1SThomas Huth     g_assert(udp->dict1->has_dict3 == false);
436*da668aa1SThomas Huth }
437*da668aa1SThomas Huth 
438*da668aa1SThomas Huth static void test_visitor_in_list(TestInputVisitorData *data,
439*da668aa1SThomas Huth                                  const void *unused)
440*da668aa1SThomas Huth {
441*da668aa1SThomas Huth     UserDefOneList *item, *head = NULL;
442*da668aa1SThomas Huth     Visitor *v;
443*da668aa1SThomas Huth     int i;
444*da668aa1SThomas Huth 
445*da668aa1SThomas Huth     v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
446*da668aa1SThomas Huth 
447*da668aa1SThomas Huth     visit_type_UserDefOneList(v, NULL, &head, &error_abort);
448*da668aa1SThomas Huth     g_assert(head != NULL);
449*da668aa1SThomas Huth 
450*da668aa1SThomas Huth     for (i = 0, item = head; item; item = item->next, i++) {
451*da668aa1SThomas Huth         char string[12];
452*da668aa1SThomas Huth 
453*da668aa1SThomas Huth         snprintf(string, sizeof(string), "string%d", i);
454*da668aa1SThomas Huth         g_assert_cmpstr(item->value->string, ==, string);
455*da668aa1SThomas Huth         g_assert_cmpint(item->value->integer, ==, 42 + i);
456*da668aa1SThomas Huth     }
457*da668aa1SThomas Huth 
458*da668aa1SThomas Huth     qapi_free_UserDefOneList(head);
459*da668aa1SThomas Huth     head = NULL;
460*da668aa1SThomas Huth 
461*da668aa1SThomas Huth     /* An empty list is valid */
462*da668aa1SThomas Huth     v = visitor_input_test_init(data, "[]");
463*da668aa1SThomas Huth     visit_type_UserDefOneList(v, NULL, &head, &error_abort);
464*da668aa1SThomas Huth     g_assert(!head);
465*da668aa1SThomas Huth }
466*da668aa1SThomas Huth 
467*da668aa1SThomas Huth static void test_visitor_in_any(TestInputVisitorData *data,
468*da668aa1SThomas Huth                                 const void *unused)
469*da668aa1SThomas Huth {
470*da668aa1SThomas Huth     QObject *res = NULL;
471*da668aa1SThomas Huth     Visitor *v;
472*da668aa1SThomas Huth     QNum *qnum;
473*da668aa1SThomas Huth     QBool *qbool;
474*da668aa1SThomas Huth     QString *qstring;
475*da668aa1SThomas Huth     QDict *qdict;
476*da668aa1SThomas Huth     QObject *qobj;
477*da668aa1SThomas Huth     int64_t val;
478*da668aa1SThomas Huth 
479*da668aa1SThomas Huth     v = visitor_input_test_init(data, "-42");
480*da668aa1SThomas Huth     visit_type_any(v, NULL, &res, &error_abort);
481*da668aa1SThomas Huth     qnum = qobject_to(QNum, res);
482*da668aa1SThomas Huth     g_assert(qnum);
483*da668aa1SThomas Huth     g_assert(qnum_get_try_int(qnum, &val));
484*da668aa1SThomas Huth     g_assert_cmpint(val, ==, -42);
485*da668aa1SThomas Huth     qobject_unref(res);
486*da668aa1SThomas Huth 
487*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
488*da668aa1SThomas Huth     visit_type_any(v, NULL, &res, &error_abort);
489*da668aa1SThomas Huth     qdict = qobject_to(QDict, res);
490*da668aa1SThomas Huth     g_assert(qdict && qdict_size(qdict) == 3);
491*da668aa1SThomas Huth     qobj = qdict_get(qdict, "integer");
492*da668aa1SThomas Huth     g_assert(qobj);
493*da668aa1SThomas Huth     qnum = qobject_to(QNum, qobj);
494*da668aa1SThomas Huth     g_assert(qnum);
495*da668aa1SThomas Huth     g_assert(qnum_get_try_int(qnum, &val));
496*da668aa1SThomas Huth     g_assert_cmpint(val, ==, -42);
497*da668aa1SThomas Huth     qobj = qdict_get(qdict, "boolean");
498*da668aa1SThomas Huth     g_assert(qobj);
499*da668aa1SThomas Huth     qbool = qobject_to(QBool, qobj);
500*da668aa1SThomas Huth     g_assert(qbool);
501*da668aa1SThomas Huth     g_assert(qbool_get_bool(qbool) == true);
502*da668aa1SThomas Huth     qobj = qdict_get(qdict, "string");
503*da668aa1SThomas Huth     g_assert(qobj);
504*da668aa1SThomas Huth     qstring = qobject_to(QString, qobj);
505*da668aa1SThomas Huth     g_assert(qstring);
506*da668aa1SThomas Huth     g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
507*da668aa1SThomas Huth     qobject_unref(res);
508*da668aa1SThomas Huth }
509*da668aa1SThomas Huth 
510*da668aa1SThomas Huth static void test_visitor_in_null(TestInputVisitorData *data,
511*da668aa1SThomas Huth                                  const void *unused)
512*da668aa1SThomas Huth {
513*da668aa1SThomas Huth     Visitor *v;
514*da668aa1SThomas Huth     Error *err = NULL;
515*da668aa1SThomas Huth     QNull *null;
516*da668aa1SThomas Huth     char *tmp;
517*da668aa1SThomas Huth 
518*da668aa1SThomas Huth     /*
519*da668aa1SThomas Huth      * FIXME: Since QAPI doesn't know the 'null' type yet, we can't
520*da668aa1SThomas Huth      * test visit_type_null() by reading into a QAPI struct then
521*da668aa1SThomas Huth      * checking that it was populated correctly.  The best we can do
522*da668aa1SThomas Huth      * for now is ensure that we consumed null from the input, proven
523*da668aa1SThomas Huth      * by the fact that we can't re-read the key; and that we detect
524*da668aa1SThomas Huth      * when input is not null.
525*da668aa1SThomas Huth      */
526*da668aa1SThomas Huth 
527*da668aa1SThomas Huth     v = visitor_input_test_init_full(data, false,
528*da668aa1SThomas Huth                                      "{ 'a': null, 'b': '' }");
529*da668aa1SThomas Huth     visit_start_struct(v, NULL, NULL, 0, &error_abort);
530*da668aa1SThomas Huth     visit_type_null(v, "a", &null, &error_abort);
531*da668aa1SThomas Huth     g_assert(qobject_type(QOBJECT(null)) == QTYPE_QNULL);
532*da668aa1SThomas Huth     qobject_unref(null);
533*da668aa1SThomas Huth     visit_type_null(v, "b", &null, &err);
534*da668aa1SThomas Huth     error_free_or_abort(&err);
535*da668aa1SThomas Huth     g_assert(!null);
536*da668aa1SThomas Huth     visit_type_str(v, "c", &tmp, &err);
537*da668aa1SThomas Huth     error_free_or_abort(&err);
538*da668aa1SThomas Huth     g_assert(!tmp);
539*da668aa1SThomas Huth     visit_check_struct(v, &error_abort);
540*da668aa1SThomas Huth     visit_end_struct(v, NULL);
541*da668aa1SThomas Huth }
542*da668aa1SThomas Huth 
543*da668aa1SThomas Huth static void test_visitor_in_union_flat(TestInputVisitorData *data,
544*da668aa1SThomas Huth                                        const void *unused)
545*da668aa1SThomas Huth {
546*da668aa1SThomas Huth     Visitor *v;
547*da668aa1SThomas Huth     g_autoptr(UserDefFlatUnion) tmp = NULL;
548*da668aa1SThomas Huth     UserDefUnionBase *base;
549*da668aa1SThomas Huth 
550*da668aa1SThomas Huth     v = visitor_input_test_init(data,
551*da668aa1SThomas Huth                                 "{ 'enum1': 'value1', "
552*da668aa1SThomas Huth                                 "'integer': 41, "
553*da668aa1SThomas Huth                                 "'string': 'str', "
554*da668aa1SThomas Huth                                 "'boolean': true }");
555*da668aa1SThomas Huth 
556*da668aa1SThomas Huth     visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort);
557*da668aa1SThomas Huth     g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
558*da668aa1SThomas Huth     g_assert_cmpstr(tmp->string, ==, "str");
559*da668aa1SThomas Huth     g_assert_cmpint(tmp->integer, ==, 41);
560*da668aa1SThomas Huth     g_assert_cmpint(tmp->u.value1.boolean, ==, true);
561*da668aa1SThomas Huth 
562*da668aa1SThomas Huth     base = qapi_UserDefFlatUnion_base(tmp);
563*da668aa1SThomas Huth     g_assert(&base->enum1 == &tmp->enum1);
564*da668aa1SThomas Huth }
565*da668aa1SThomas Huth 
566*da668aa1SThomas Huth static void test_visitor_in_alternate(TestInputVisitorData *data,
567*da668aa1SThomas Huth                                       const void *unused)
568*da668aa1SThomas Huth {
569*da668aa1SThomas Huth     Visitor *v;
570*da668aa1SThomas Huth     UserDefAlternate *tmp;
571*da668aa1SThomas Huth     WrapAlternate *wrap;
572*da668aa1SThomas Huth 
573*da668aa1SThomas Huth     v = visitor_input_test_init(data, "42");
574*da668aa1SThomas Huth     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
575*da668aa1SThomas Huth     g_assert_cmpint(tmp->type, ==, QTYPE_QNUM);
576*da668aa1SThomas Huth     g_assert_cmpint(tmp->u.i, ==, 42);
577*da668aa1SThomas Huth     qapi_free_UserDefAlternate(tmp);
578*da668aa1SThomas Huth 
579*da668aa1SThomas Huth     v = visitor_input_test_init(data, "'value1'");
580*da668aa1SThomas Huth     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
581*da668aa1SThomas Huth     g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
582*da668aa1SThomas Huth     g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1);
583*da668aa1SThomas Huth     qapi_free_UserDefAlternate(tmp);
584*da668aa1SThomas Huth 
585*da668aa1SThomas Huth     v = visitor_input_test_init(data, "null");
586*da668aa1SThomas Huth     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
587*da668aa1SThomas Huth     g_assert_cmpint(tmp->type, ==, QTYPE_QNULL);
588*da668aa1SThomas Huth     qapi_free_UserDefAlternate(tmp);
589*da668aa1SThomas Huth 
590*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
591*da668aa1SThomas Huth                                 "'enum1':'value1', 'boolean':true}");
592*da668aa1SThomas Huth     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
593*da668aa1SThomas Huth     g_assert_cmpint(tmp->type, ==, QTYPE_QDICT);
594*da668aa1SThomas Huth     g_assert_cmpint(tmp->u.udfu.integer, ==, 1);
595*da668aa1SThomas Huth     g_assert_cmpstr(tmp->u.udfu.string, ==, "str");
596*da668aa1SThomas Huth     g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
597*da668aa1SThomas Huth     g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true);
598*da668aa1SThomas Huth     g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false);
599*da668aa1SThomas Huth     qapi_free_UserDefAlternate(tmp);
600*da668aa1SThomas Huth 
601*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'alt': 42 }");
602*da668aa1SThomas Huth     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
603*da668aa1SThomas Huth     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QNUM);
604*da668aa1SThomas Huth     g_assert_cmpint(wrap->alt->u.i, ==, 42);
605*da668aa1SThomas Huth     qapi_free_WrapAlternate(wrap);
606*da668aa1SThomas Huth 
607*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'alt': 'value1' }");
608*da668aa1SThomas Huth     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
609*da668aa1SThomas Huth     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING);
610*da668aa1SThomas Huth     g_assert_cmpint(wrap->alt->u.e, ==, ENUM_ONE_VALUE1);
611*da668aa1SThomas Huth     qapi_free_WrapAlternate(wrap);
612*da668aa1SThomas Huth 
613*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
614*da668aa1SThomas Huth                                 "'enum1':'value1', 'boolean':true} }");
615*da668aa1SThomas Huth     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
616*da668aa1SThomas Huth     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT);
617*da668aa1SThomas Huth     g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1);
618*da668aa1SThomas Huth     g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str");
619*da668aa1SThomas Huth     g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
620*da668aa1SThomas Huth     g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true);
621*da668aa1SThomas Huth     g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false);
622*da668aa1SThomas Huth     qapi_free_WrapAlternate(wrap);
623*da668aa1SThomas Huth }
624*da668aa1SThomas Huth 
625*da668aa1SThomas Huth static void test_visitor_in_alternate_number(TestInputVisitorData *data,
626*da668aa1SThomas Huth                                              const void *unused)
627*da668aa1SThomas Huth {
628*da668aa1SThomas Huth     Visitor *v;
629*da668aa1SThomas Huth     Error *err = NULL;
630*da668aa1SThomas Huth     AltEnumBool *aeb;
631*da668aa1SThomas Huth     AltEnumNum *aen;
632*da668aa1SThomas Huth     AltNumEnum *ans;
633*da668aa1SThomas Huth     AltEnumInt *asi;
634*da668aa1SThomas Huth 
635*da668aa1SThomas Huth     /* Parsing an int */
636*da668aa1SThomas Huth 
637*da668aa1SThomas Huth     v = visitor_input_test_init(data, "42");
638*da668aa1SThomas Huth     visit_type_AltEnumBool(v, NULL, &aeb, &err);
639*da668aa1SThomas Huth     error_free_or_abort(&err);
640*da668aa1SThomas Huth     qapi_free_AltEnumBool(aeb);
641*da668aa1SThomas Huth 
642*da668aa1SThomas Huth     v = visitor_input_test_init(data, "42");
643*da668aa1SThomas Huth     visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
644*da668aa1SThomas Huth     g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
645*da668aa1SThomas Huth     g_assert_cmpfloat(aen->u.n, ==, 42);
646*da668aa1SThomas Huth     qapi_free_AltEnumNum(aen);
647*da668aa1SThomas Huth 
648*da668aa1SThomas Huth     v = visitor_input_test_init(data, "42");
649*da668aa1SThomas Huth     visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
650*da668aa1SThomas Huth     g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
651*da668aa1SThomas Huth     g_assert_cmpfloat(ans->u.n, ==, 42);
652*da668aa1SThomas Huth     qapi_free_AltNumEnum(ans);
653*da668aa1SThomas Huth 
654*da668aa1SThomas Huth     v = visitor_input_test_init(data, "42");
655*da668aa1SThomas Huth     visit_type_AltEnumInt(v, NULL, &asi, &error_abort);
656*da668aa1SThomas Huth     g_assert_cmpint(asi->type, ==, QTYPE_QNUM);
657*da668aa1SThomas Huth     g_assert_cmpint(asi->u.i, ==, 42);
658*da668aa1SThomas Huth     qapi_free_AltEnumInt(asi);
659*da668aa1SThomas Huth 
660*da668aa1SThomas Huth     /* Parsing a double */
661*da668aa1SThomas Huth 
662*da668aa1SThomas Huth     v = visitor_input_test_init(data, "42.5");
663*da668aa1SThomas Huth     visit_type_AltEnumBool(v, NULL, &aeb, &err);
664*da668aa1SThomas Huth     error_free_or_abort(&err);
665*da668aa1SThomas Huth     qapi_free_AltEnumBool(aeb);
666*da668aa1SThomas Huth 
667*da668aa1SThomas Huth     v = visitor_input_test_init(data, "42.5");
668*da668aa1SThomas Huth     visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
669*da668aa1SThomas Huth     g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
670*da668aa1SThomas Huth     g_assert_cmpfloat(aen->u.n, ==, 42.5);
671*da668aa1SThomas Huth     qapi_free_AltEnumNum(aen);
672*da668aa1SThomas Huth 
673*da668aa1SThomas Huth     v = visitor_input_test_init(data, "42.5");
674*da668aa1SThomas Huth     visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
675*da668aa1SThomas Huth     g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
676*da668aa1SThomas Huth     g_assert_cmpfloat(ans->u.n, ==, 42.5);
677*da668aa1SThomas Huth     qapi_free_AltNumEnum(ans);
678*da668aa1SThomas Huth 
679*da668aa1SThomas Huth     v = visitor_input_test_init(data, "42.5");
680*da668aa1SThomas Huth     visit_type_AltEnumInt(v, NULL, &asi, &err);
681*da668aa1SThomas Huth     error_free_or_abort(&err);
682*da668aa1SThomas Huth     qapi_free_AltEnumInt(asi);
683*da668aa1SThomas Huth }
684*da668aa1SThomas Huth 
685*da668aa1SThomas Huth static void test_list_union_integer_helper(TestInputVisitorData *data,
686*da668aa1SThomas Huth                                            const void *unused,
687*da668aa1SThomas Huth                                            UserDefListUnionKind kind)
688*da668aa1SThomas Huth {
689*da668aa1SThomas Huth     g_autoptr(UserDefListUnion) cvalue = NULL;
690*da668aa1SThomas Huth     Visitor *v;
691*da668aa1SThomas Huth     GString *gstr_list = g_string_new("");
692*da668aa1SThomas Huth     GString *gstr_union = g_string_new("");
693*da668aa1SThomas Huth     int i;
694*da668aa1SThomas Huth 
695*da668aa1SThomas Huth     for (i = 0; i < 32; i++) {
696*da668aa1SThomas Huth         g_string_append_printf(gstr_list, "%d", i);
697*da668aa1SThomas Huth         if (i != 31) {
698*da668aa1SThomas Huth             g_string_append(gstr_list, ", ");
699*da668aa1SThomas Huth         }
700*da668aa1SThomas Huth     }
701*da668aa1SThomas Huth     g_string_append_printf(gstr_union,  "{ 'type': '%s', 'data': [ %s ] }",
702*da668aa1SThomas Huth                            UserDefListUnionKind_str(kind),
703*da668aa1SThomas Huth                            gstr_list->str);
704*da668aa1SThomas Huth     v = visitor_input_test_init_raw(data,  gstr_union->str);
705*da668aa1SThomas Huth 
706*da668aa1SThomas Huth     visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
707*da668aa1SThomas Huth     g_assert(cvalue != NULL);
708*da668aa1SThomas Huth     g_assert_cmpint(cvalue->type, ==, kind);
709*da668aa1SThomas Huth 
710*da668aa1SThomas Huth     switch (kind) {
711*da668aa1SThomas Huth     case USER_DEF_LIST_UNION_KIND_INTEGER: {
712*da668aa1SThomas Huth         intList *elem = NULL;
713*da668aa1SThomas Huth         for (i = 0, elem = cvalue->u.integer.data;
714*da668aa1SThomas Huth              elem; elem = elem->next, i++) {
715*da668aa1SThomas Huth             g_assert_cmpint(elem->value, ==, i);
716*da668aa1SThomas Huth         }
717*da668aa1SThomas Huth         break;
718*da668aa1SThomas Huth     }
719*da668aa1SThomas Huth     case USER_DEF_LIST_UNION_KIND_S8: {
720*da668aa1SThomas Huth         int8List *elem = NULL;
721*da668aa1SThomas Huth         for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) {
722*da668aa1SThomas Huth             g_assert_cmpint(elem->value, ==, i);
723*da668aa1SThomas Huth         }
724*da668aa1SThomas Huth         break;
725*da668aa1SThomas Huth     }
726*da668aa1SThomas Huth     case USER_DEF_LIST_UNION_KIND_S16: {
727*da668aa1SThomas Huth         int16List *elem = NULL;
728*da668aa1SThomas Huth         for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) {
729*da668aa1SThomas Huth             g_assert_cmpint(elem->value, ==, i);
730*da668aa1SThomas Huth         }
731*da668aa1SThomas Huth         break;
732*da668aa1SThomas Huth     }
733*da668aa1SThomas Huth     case USER_DEF_LIST_UNION_KIND_S32: {
734*da668aa1SThomas Huth         int32List *elem = NULL;
735*da668aa1SThomas Huth         for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) {
736*da668aa1SThomas Huth             g_assert_cmpint(elem->value, ==, i);
737*da668aa1SThomas Huth         }
738*da668aa1SThomas Huth         break;
739*da668aa1SThomas Huth     }
740*da668aa1SThomas Huth     case USER_DEF_LIST_UNION_KIND_S64: {
741*da668aa1SThomas Huth         int64List *elem = NULL;
742*da668aa1SThomas Huth         for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) {
743*da668aa1SThomas Huth             g_assert_cmpint(elem->value, ==, i);
744*da668aa1SThomas Huth         }
745*da668aa1SThomas Huth         break;
746*da668aa1SThomas Huth     }
747*da668aa1SThomas Huth     case USER_DEF_LIST_UNION_KIND_U8: {
748*da668aa1SThomas Huth         uint8List *elem = NULL;
749*da668aa1SThomas Huth         for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) {
750*da668aa1SThomas Huth             g_assert_cmpint(elem->value, ==, i);
751*da668aa1SThomas Huth         }
752*da668aa1SThomas Huth         break;
753*da668aa1SThomas Huth     }
754*da668aa1SThomas Huth     case USER_DEF_LIST_UNION_KIND_U16: {
755*da668aa1SThomas Huth         uint16List *elem = NULL;
756*da668aa1SThomas Huth         for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) {
757*da668aa1SThomas Huth             g_assert_cmpint(elem->value, ==, i);
758*da668aa1SThomas Huth         }
759*da668aa1SThomas Huth         break;
760*da668aa1SThomas Huth     }
761*da668aa1SThomas Huth     case USER_DEF_LIST_UNION_KIND_U32: {
762*da668aa1SThomas Huth         uint32List *elem = NULL;
763*da668aa1SThomas Huth         for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) {
764*da668aa1SThomas Huth             g_assert_cmpint(elem->value, ==, i);
765*da668aa1SThomas Huth         }
766*da668aa1SThomas Huth         break;
767*da668aa1SThomas Huth     }
768*da668aa1SThomas Huth     case USER_DEF_LIST_UNION_KIND_U64: {
769*da668aa1SThomas Huth         uint64List *elem = NULL;
770*da668aa1SThomas Huth         for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) {
771*da668aa1SThomas Huth             g_assert_cmpint(elem->value, ==, i);
772*da668aa1SThomas Huth         }
773*da668aa1SThomas Huth         break;
774*da668aa1SThomas Huth     }
775*da668aa1SThomas Huth     default:
776*da668aa1SThomas Huth         g_assert_not_reached();
777*da668aa1SThomas Huth     }
778*da668aa1SThomas Huth 
779*da668aa1SThomas Huth     g_string_free(gstr_union, true);
780*da668aa1SThomas Huth     g_string_free(gstr_list, true);
781*da668aa1SThomas Huth }
782*da668aa1SThomas Huth 
783*da668aa1SThomas Huth static void test_visitor_in_list_union_int(TestInputVisitorData *data,
784*da668aa1SThomas Huth                                            const void *unused)
785*da668aa1SThomas Huth {
786*da668aa1SThomas Huth     test_list_union_integer_helper(data, unused,
787*da668aa1SThomas Huth                                    USER_DEF_LIST_UNION_KIND_INTEGER);
788*da668aa1SThomas Huth }
789*da668aa1SThomas Huth 
790*da668aa1SThomas Huth static void test_visitor_in_list_union_int8(TestInputVisitorData *data,
791*da668aa1SThomas Huth                                             const void *unused)
792*da668aa1SThomas Huth {
793*da668aa1SThomas Huth     test_list_union_integer_helper(data, unused,
794*da668aa1SThomas Huth                                    USER_DEF_LIST_UNION_KIND_S8);
795*da668aa1SThomas Huth }
796*da668aa1SThomas Huth 
797*da668aa1SThomas Huth static void test_visitor_in_list_union_int16(TestInputVisitorData *data,
798*da668aa1SThomas Huth                                              const void *unused)
799*da668aa1SThomas Huth {
800*da668aa1SThomas Huth     test_list_union_integer_helper(data, unused,
801*da668aa1SThomas Huth                                    USER_DEF_LIST_UNION_KIND_S16);
802*da668aa1SThomas Huth }
803*da668aa1SThomas Huth 
804*da668aa1SThomas Huth static void test_visitor_in_list_union_int32(TestInputVisitorData *data,
805*da668aa1SThomas Huth                                              const void *unused)
806*da668aa1SThomas Huth {
807*da668aa1SThomas Huth     test_list_union_integer_helper(data, unused,
808*da668aa1SThomas Huth                                    USER_DEF_LIST_UNION_KIND_S32);
809*da668aa1SThomas Huth }
810*da668aa1SThomas Huth 
811*da668aa1SThomas Huth static void test_visitor_in_list_union_int64(TestInputVisitorData *data,
812*da668aa1SThomas Huth                                              const void *unused)
813*da668aa1SThomas Huth {
814*da668aa1SThomas Huth     test_list_union_integer_helper(data, unused,
815*da668aa1SThomas Huth                                    USER_DEF_LIST_UNION_KIND_S64);
816*da668aa1SThomas Huth }
817*da668aa1SThomas Huth 
818*da668aa1SThomas Huth static void test_visitor_in_list_union_uint8(TestInputVisitorData *data,
819*da668aa1SThomas Huth                                              const void *unused)
820*da668aa1SThomas Huth {
821*da668aa1SThomas Huth     test_list_union_integer_helper(data, unused,
822*da668aa1SThomas Huth                                    USER_DEF_LIST_UNION_KIND_U8);
823*da668aa1SThomas Huth }
824*da668aa1SThomas Huth 
825*da668aa1SThomas Huth static void test_visitor_in_list_union_uint16(TestInputVisitorData *data,
826*da668aa1SThomas Huth                                               const void *unused)
827*da668aa1SThomas Huth {
828*da668aa1SThomas Huth     test_list_union_integer_helper(data, unused,
829*da668aa1SThomas Huth                                    USER_DEF_LIST_UNION_KIND_U16);
830*da668aa1SThomas Huth }
831*da668aa1SThomas Huth 
832*da668aa1SThomas Huth static void test_visitor_in_list_union_uint32(TestInputVisitorData *data,
833*da668aa1SThomas Huth                                               const void *unused)
834*da668aa1SThomas Huth {
835*da668aa1SThomas Huth     test_list_union_integer_helper(data, unused,
836*da668aa1SThomas Huth                                    USER_DEF_LIST_UNION_KIND_U32);
837*da668aa1SThomas Huth }
838*da668aa1SThomas Huth 
839*da668aa1SThomas Huth static void test_visitor_in_list_union_uint64(TestInputVisitorData *data,
840*da668aa1SThomas Huth                                               const void *unused)
841*da668aa1SThomas Huth {
842*da668aa1SThomas Huth     test_list_union_integer_helper(data, unused,
843*da668aa1SThomas Huth                                    USER_DEF_LIST_UNION_KIND_U64);
844*da668aa1SThomas Huth }
845*da668aa1SThomas Huth 
846*da668aa1SThomas Huth static void test_visitor_in_list_union_bool(TestInputVisitorData *data,
847*da668aa1SThomas Huth                                             const void *unused)
848*da668aa1SThomas Huth {
849*da668aa1SThomas Huth     g_autoptr(UserDefListUnion) cvalue = NULL;
850*da668aa1SThomas Huth     boolList *elem = NULL;
851*da668aa1SThomas Huth     Visitor *v;
852*da668aa1SThomas Huth     GString *gstr_list = g_string_new("");
853*da668aa1SThomas Huth     GString *gstr_union = g_string_new("");
854*da668aa1SThomas Huth     int i;
855*da668aa1SThomas Huth 
856*da668aa1SThomas Huth     for (i = 0; i < 32; i++) {
857*da668aa1SThomas Huth         g_string_append_printf(gstr_list, "%s",
858*da668aa1SThomas Huth                                (i % 3 == 0) ? "true" : "false");
859*da668aa1SThomas Huth         if (i != 31) {
860*da668aa1SThomas Huth             g_string_append(gstr_list, ", ");
861*da668aa1SThomas Huth         }
862*da668aa1SThomas Huth     }
863*da668aa1SThomas Huth     g_string_append_printf(gstr_union,  "{ 'type': 'boolean', 'data': [ %s ] }",
864*da668aa1SThomas Huth                            gstr_list->str);
865*da668aa1SThomas Huth     v = visitor_input_test_init_raw(data,  gstr_union->str);
866*da668aa1SThomas Huth 
867*da668aa1SThomas Huth     visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
868*da668aa1SThomas Huth     g_assert(cvalue != NULL);
869*da668aa1SThomas Huth     g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_BOOLEAN);
870*da668aa1SThomas Huth 
871*da668aa1SThomas Huth     for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) {
872*da668aa1SThomas Huth         g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
873*da668aa1SThomas Huth     }
874*da668aa1SThomas Huth 
875*da668aa1SThomas Huth     g_string_free(gstr_union, true);
876*da668aa1SThomas Huth     g_string_free(gstr_list, true);
877*da668aa1SThomas Huth }
878*da668aa1SThomas Huth 
879*da668aa1SThomas Huth static void test_visitor_in_list_union_string(TestInputVisitorData *data,
880*da668aa1SThomas Huth                                               const void *unused)
881*da668aa1SThomas Huth {
882*da668aa1SThomas Huth     g_autoptr(UserDefListUnion) cvalue = NULL;
883*da668aa1SThomas Huth     strList *elem = NULL;
884*da668aa1SThomas Huth     Visitor *v;
885*da668aa1SThomas Huth     GString *gstr_list = g_string_new("");
886*da668aa1SThomas Huth     GString *gstr_union = g_string_new("");
887*da668aa1SThomas Huth     int i;
888*da668aa1SThomas Huth 
889*da668aa1SThomas Huth     for (i = 0; i < 32; i++) {
890*da668aa1SThomas Huth         g_string_append_printf(gstr_list, "'%d'", i);
891*da668aa1SThomas Huth         if (i != 31) {
892*da668aa1SThomas Huth             g_string_append(gstr_list, ", ");
893*da668aa1SThomas Huth         }
894*da668aa1SThomas Huth     }
895*da668aa1SThomas Huth     g_string_append_printf(gstr_union,  "{ 'type': 'string', 'data': [ %s ] }",
896*da668aa1SThomas Huth                            gstr_list->str);
897*da668aa1SThomas Huth     v = visitor_input_test_init_raw(data,  gstr_union->str);
898*da668aa1SThomas Huth 
899*da668aa1SThomas Huth     visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
900*da668aa1SThomas Huth     g_assert(cvalue != NULL);
901*da668aa1SThomas Huth     g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_STRING);
902*da668aa1SThomas Huth 
903*da668aa1SThomas Huth     for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) {
904*da668aa1SThomas Huth         gchar str[8];
905*da668aa1SThomas Huth         sprintf(str, "%d", i);
906*da668aa1SThomas Huth         g_assert_cmpstr(elem->value, ==, str);
907*da668aa1SThomas Huth     }
908*da668aa1SThomas Huth 
909*da668aa1SThomas Huth     g_string_free(gstr_union, true);
910*da668aa1SThomas Huth     g_string_free(gstr_list, true);
911*da668aa1SThomas Huth }
912*da668aa1SThomas Huth 
913*da668aa1SThomas Huth #define DOUBLE_STR_MAX 16
914*da668aa1SThomas Huth 
915*da668aa1SThomas Huth static void test_visitor_in_list_union_number(TestInputVisitorData *data,
916*da668aa1SThomas Huth                                               const void *unused)
917*da668aa1SThomas Huth {
918*da668aa1SThomas Huth     g_autoptr(UserDefListUnion) cvalue = NULL;
919*da668aa1SThomas Huth     numberList *elem = NULL;
920*da668aa1SThomas Huth     Visitor *v;
921*da668aa1SThomas Huth     GString *gstr_list = g_string_new("");
922*da668aa1SThomas Huth     GString *gstr_union = g_string_new("");
923*da668aa1SThomas Huth     int i;
924*da668aa1SThomas Huth 
925*da668aa1SThomas Huth     for (i = 0; i < 32; i++) {
926*da668aa1SThomas Huth         g_string_append_printf(gstr_list, "%f", (double)i / 3);
927*da668aa1SThomas Huth         if (i != 31) {
928*da668aa1SThomas Huth             g_string_append(gstr_list, ", ");
929*da668aa1SThomas Huth         }
930*da668aa1SThomas Huth     }
931*da668aa1SThomas Huth     g_string_append_printf(gstr_union,  "{ 'type': 'number', 'data': [ %s ] }",
932*da668aa1SThomas Huth                            gstr_list->str);
933*da668aa1SThomas Huth     v = visitor_input_test_init_raw(data,  gstr_union->str);
934*da668aa1SThomas Huth 
935*da668aa1SThomas Huth     visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
936*da668aa1SThomas Huth     g_assert(cvalue != NULL);
937*da668aa1SThomas Huth     g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_NUMBER);
938*da668aa1SThomas Huth 
939*da668aa1SThomas Huth     for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) {
940*da668aa1SThomas Huth         GString *double_expected = g_string_new("");
941*da668aa1SThomas Huth         GString *double_actual = g_string_new("");
942*da668aa1SThomas Huth 
943*da668aa1SThomas Huth         g_string_printf(double_expected, "%.6f", (double)i / 3);
944*da668aa1SThomas Huth         g_string_printf(double_actual, "%.6f", elem->value);
945*da668aa1SThomas Huth         g_assert_cmpstr(double_expected->str, ==, double_actual->str);
946*da668aa1SThomas Huth 
947*da668aa1SThomas Huth         g_string_free(double_expected, true);
948*da668aa1SThomas Huth         g_string_free(double_actual, true);
949*da668aa1SThomas Huth     }
950*da668aa1SThomas Huth 
951*da668aa1SThomas Huth     g_string_free(gstr_union, true);
952*da668aa1SThomas Huth     g_string_free(gstr_list, true);
953*da668aa1SThomas Huth }
954*da668aa1SThomas Huth 
955*da668aa1SThomas Huth static void input_visitor_test_add(const char *testpath,
956*da668aa1SThomas Huth                                    const void *user_data,
957*da668aa1SThomas Huth                                    void (*test_func)(TestInputVisitorData *data,
958*da668aa1SThomas Huth                                                      const void *user_data))
959*da668aa1SThomas Huth {
960*da668aa1SThomas Huth     g_test_add(testpath, TestInputVisitorData, user_data, NULL, test_func,
961*da668aa1SThomas Huth                visitor_input_teardown);
962*da668aa1SThomas Huth }
963*da668aa1SThomas Huth 
964*da668aa1SThomas Huth static void test_visitor_in_errors(TestInputVisitorData *data,
965*da668aa1SThomas Huth                                    const void *unused)
966*da668aa1SThomas Huth {
967*da668aa1SThomas Huth     TestStruct *p = NULL;
968*da668aa1SThomas Huth     Error *err = NULL;
969*da668aa1SThomas Huth     Visitor *v;
970*da668aa1SThomas Huth     strList *q = NULL;
971*da668aa1SThomas Huth     UserDefTwo *r = NULL;
972*da668aa1SThomas Huth     WrapAlternate *s = NULL;
973*da668aa1SThomas Huth 
974*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', "
975*da668aa1SThomas Huth                                 "'string': -42 }");
976*da668aa1SThomas Huth 
977*da668aa1SThomas Huth     visit_type_TestStruct(v, NULL, &p, &err);
978*da668aa1SThomas Huth     error_free_or_abort(&err);
979*da668aa1SThomas Huth     g_assert(!p);
980*da668aa1SThomas Huth 
981*da668aa1SThomas Huth     v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
982*da668aa1SThomas Huth     visit_type_strList(v, NULL, &q, &err);
983*da668aa1SThomas Huth     error_free_or_abort(&err);
984*da668aa1SThomas Huth     assert(!q);
985*da668aa1SThomas Huth 
986*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'str':'hi' }");
987*da668aa1SThomas Huth     visit_type_UserDefTwo(v, NULL, &r, &err);
988*da668aa1SThomas Huth     error_free_or_abort(&err);
989*da668aa1SThomas Huth     assert(!r);
990*da668aa1SThomas Huth 
991*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ }");
992*da668aa1SThomas Huth     visit_type_WrapAlternate(v, NULL, &s, &err);
993*da668aa1SThomas Huth     error_free_or_abort(&err);
994*da668aa1SThomas Huth     assert(!s);
995*da668aa1SThomas Huth }
996*da668aa1SThomas Huth 
997*da668aa1SThomas Huth static void test_visitor_in_wrong_type(TestInputVisitorData *data,
998*da668aa1SThomas Huth                                        const void *unused)
999*da668aa1SThomas Huth {
1000*da668aa1SThomas Huth     TestStruct *p = NULL;
1001*da668aa1SThomas Huth     Visitor *v;
1002*da668aa1SThomas Huth     strList *q = NULL;
1003*da668aa1SThomas Huth     int64_t i;
1004*da668aa1SThomas Huth     Error *err = NULL;
1005*da668aa1SThomas Huth 
1006*da668aa1SThomas Huth     /* Make sure arrays and structs cannot be confused */
1007*da668aa1SThomas Huth 
1008*da668aa1SThomas Huth     v = visitor_input_test_init(data, "[]");
1009*da668aa1SThomas Huth     visit_type_TestStruct(v, NULL, &p, &err);
1010*da668aa1SThomas Huth     error_free_or_abort(&err);
1011*da668aa1SThomas Huth     g_assert(!p);
1012*da668aa1SThomas Huth 
1013*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{}");
1014*da668aa1SThomas Huth     visit_type_strList(v, NULL, &q, &err);
1015*da668aa1SThomas Huth     error_free_or_abort(&err);
1016*da668aa1SThomas Huth     assert(!q);
1017*da668aa1SThomas Huth 
1018*da668aa1SThomas Huth     /* Make sure primitives and struct cannot be confused */
1019*da668aa1SThomas Huth 
1020*da668aa1SThomas Huth     v = visitor_input_test_init(data, "1");
1021*da668aa1SThomas Huth     visit_type_TestStruct(v, NULL, &p, &err);
1022*da668aa1SThomas Huth     error_free_or_abort(&err);
1023*da668aa1SThomas Huth     g_assert(!p);
1024*da668aa1SThomas Huth 
1025*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{}");
1026*da668aa1SThomas Huth     visit_type_int(v, NULL, &i, &err);
1027*da668aa1SThomas Huth     error_free_or_abort(&err);
1028*da668aa1SThomas Huth 
1029*da668aa1SThomas Huth     /* Make sure primitives and arrays cannot be confused */
1030*da668aa1SThomas Huth 
1031*da668aa1SThomas Huth     v = visitor_input_test_init(data, "1");
1032*da668aa1SThomas Huth     visit_type_strList(v, NULL, &q, &err);
1033*da668aa1SThomas Huth     error_free_or_abort(&err);
1034*da668aa1SThomas Huth     assert(!q);
1035*da668aa1SThomas Huth 
1036*da668aa1SThomas Huth     v = visitor_input_test_init(data, "[]");
1037*da668aa1SThomas Huth     visit_type_int(v, NULL, &i, &err);
1038*da668aa1SThomas Huth     error_free_or_abort(&err);
1039*da668aa1SThomas Huth }
1040*da668aa1SThomas Huth 
1041*da668aa1SThomas Huth static void test_visitor_in_fail_struct(TestInputVisitorData *data,
1042*da668aa1SThomas Huth                                         const void *unused)
1043*da668aa1SThomas Huth {
1044*da668aa1SThomas Huth     TestStruct *p = NULL;
1045*da668aa1SThomas Huth     Error *err = NULL;
1046*da668aa1SThomas Huth     Visitor *v;
1047*da668aa1SThomas Huth 
1048*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
1049*da668aa1SThomas Huth 
1050*da668aa1SThomas Huth     visit_type_TestStruct(v, NULL, &p, &err);
1051*da668aa1SThomas Huth     error_free_or_abort(&err);
1052*da668aa1SThomas Huth     g_assert(!p);
1053*da668aa1SThomas Huth }
1054*da668aa1SThomas Huth 
1055*da668aa1SThomas Huth static void test_visitor_in_fail_struct_nested(TestInputVisitorData *data,
1056*da668aa1SThomas Huth                                                const void *unused)
1057*da668aa1SThomas Huth {
1058*da668aa1SThomas Huth     UserDefTwo *udp = NULL;
1059*da668aa1SThomas Huth     Error *err = NULL;
1060*da668aa1SThomas Huth     Visitor *v;
1061*da668aa1SThomas Huth 
1062*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
1063*da668aa1SThomas Huth 
1064*da668aa1SThomas Huth     visit_type_UserDefTwo(v, NULL, &udp, &err);
1065*da668aa1SThomas Huth     error_free_or_abort(&err);
1066*da668aa1SThomas Huth     g_assert(!udp);
1067*da668aa1SThomas Huth }
1068*da668aa1SThomas Huth 
1069*da668aa1SThomas Huth static void test_visitor_in_fail_struct_in_list(TestInputVisitorData *data,
1070*da668aa1SThomas Huth                                                 const void *unused)
1071*da668aa1SThomas Huth {
1072*da668aa1SThomas Huth     UserDefOneList *head = NULL;
1073*da668aa1SThomas Huth     Error *err = NULL;
1074*da668aa1SThomas Huth     Visitor *v;
1075*da668aa1SThomas Huth 
1076*da668aa1SThomas Huth     v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
1077*da668aa1SThomas Huth 
1078*da668aa1SThomas Huth     visit_type_UserDefOneList(v, NULL, &head, &err);
1079*da668aa1SThomas Huth     error_free_or_abort(&err);
1080*da668aa1SThomas Huth     g_assert(!head);
1081*da668aa1SThomas Huth }
1082*da668aa1SThomas Huth 
1083*da668aa1SThomas Huth static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data,
1084*da668aa1SThomas Huth                                                 const void *unused)
1085*da668aa1SThomas Huth {
1086*da668aa1SThomas Huth     Error *err = NULL;
1087*da668aa1SThomas Huth     Visitor *v;
1088*da668aa1SThomas Huth     QObject *any;
1089*da668aa1SThomas Huth     QNull *null;
1090*da668aa1SThomas Huth     GenericAlternate *alt;
1091*da668aa1SThomas Huth     bool present;
1092*da668aa1SThomas Huth     int en;
1093*da668aa1SThomas Huth     int64_t i64;
1094*da668aa1SThomas Huth     uint32_t u32;
1095*da668aa1SThomas Huth     int8_t i8;
1096*da668aa1SThomas Huth     char *str;
1097*da668aa1SThomas Huth     double dbl;
1098*da668aa1SThomas Huth 
1099*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'sub': [ {} ] }");
1100*da668aa1SThomas Huth     visit_start_struct(v, NULL, NULL, 0, &error_abort);
1101*da668aa1SThomas Huth     visit_start_struct(v, "struct", NULL, 0, &err);
1102*da668aa1SThomas Huth     error_free_or_abort(&err);
1103*da668aa1SThomas Huth     visit_start_list(v, "list", NULL, 0, &err);
1104*da668aa1SThomas Huth     error_free_or_abort(&err);
1105*da668aa1SThomas Huth     visit_start_alternate(v, "alternate", &alt, sizeof(*alt), &err);
1106*da668aa1SThomas Huth     error_free_or_abort(&err);
1107*da668aa1SThomas Huth     visit_optional(v, "optional", &present);
1108*da668aa1SThomas Huth     g_assert(!present);
1109*da668aa1SThomas Huth     visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err);
1110*da668aa1SThomas Huth     error_free_or_abort(&err);
1111*da668aa1SThomas Huth     visit_type_int(v, "i64", &i64, &err);
1112*da668aa1SThomas Huth     error_free_or_abort(&err);
1113*da668aa1SThomas Huth     visit_type_uint32(v, "u32", &u32, &err);
1114*da668aa1SThomas Huth     error_free_or_abort(&err);
1115*da668aa1SThomas Huth     visit_type_int8(v, "i8", &i8, &err);
1116*da668aa1SThomas Huth     error_free_or_abort(&err);
1117*da668aa1SThomas Huth     visit_type_str(v, "i8", &str, &err);
1118*da668aa1SThomas Huth     error_free_or_abort(&err);
1119*da668aa1SThomas Huth     visit_type_number(v, "dbl", &dbl, &err);
1120*da668aa1SThomas Huth     error_free_or_abort(&err);
1121*da668aa1SThomas Huth     visit_type_any(v, "any", &any, &err);
1122*da668aa1SThomas Huth     error_free_or_abort(&err);
1123*da668aa1SThomas Huth     visit_type_null(v, "null", &null, &err);
1124*da668aa1SThomas Huth     error_free_or_abort(&err);
1125*da668aa1SThomas Huth     visit_start_list(v, "sub", NULL, 0, &error_abort);
1126*da668aa1SThomas Huth     visit_start_struct(v, NULL, NULL, 0, &error_abort);
1127*da668aa1SThomas Huth     visit_type_int(v, "i64", &i64, &err);
1128*da668aa1SThomas Huth     error_free_or_abort(&err);
1129*da668aa1SThomas Huth     visit_end_struct(v, NULL);
1130*da668aa1SThomas Huth     visit_end_list(v, NULL);
1131*da668aa1SThomas Huth     visit_end_struct(v, NULL);
1132*da668aa1SThomas Huth }
1133*da668aa1SThomas Huth 
1134*da668aa1SThomas Huth static void test_visitor_in_fail_list(TestInputVisitorData *data,
1135*da668aa1SThomas Huth                                       const void *unused)
1136*da668aa1SThomas Huth {
1137*da668aa1SThomas Huth     int64_t i64 = -1;
1138*da668aa1SThomas Huth     Error *err = NULL;
1139*da668aa1SThomas Huth     Visitor *v;
1140*da668aa1SThomas Huth 
1141*da668aa1SThomas Huth     /* Unvisited list tail */
1142*da668aa1SThomas Huth 
1143*da668aa1SThomas Huth     v = visitor_input_test_init(data, "[ 1, 2, 3 ]");
1144*da668aa1SThomas Huth 
1145*da668aa1SThomas Huth     visit_start_list(v, NULL, NULL, 0, &error_abort);
1146*da668aa1SThomas Huth     visit_type_int(v, NULL, &i64, &error_abort);
1147*da668aa1SThomas Huth     g_assert_cmpint(i64, ==, 1);
1148*da668aa1SThomas Huth     visit_type_int(v, NULL, &i64, &error_abort);
1149*da668aa1SThomas Huth     g_assert_cmpint(i64, ==, 2);
1150*da668aa1SThomas Huth     visit_check_list(v, &err);
1151*da668aa1SThomas Huth     error_free_or_abort(&err);
1152*da668aa1SThomas Huth     visit_end_list(v, NULL);
1153*da668aa1SThomas Huth 
1154*da668aa1SThomas Huth     /* Visit beyond end of list */
1155*da668aa1SThomas Huth     v = visitor_input_test_init(data, "[]");
1156*da668aa1SThomas Huth 
1157*da668aa1SThomas Huth     visit_start_list(v, NULL, NULL, 0, &error_abort);
1158*da668aa1SThomas Huth     visit_type_int(v, NULL, &i64, &err);
1159*da668aa1SThomas Huth     error_free_or_abort(&err);
1160*da668aa1SThomas Huth     visit_end_list(v, NULL);
1161*da668aa1SThomas Huth }
1162*da668aa1SThomas Huth 
1163*da668aa1SThomas Huth static void test_visitor_in_fail_list_nested(TestInputVisitorData *data,
1164*da668aa1SThomas Huth                                              const void *unused)
1165*da668aa1SThomas Huth {
1166*da668aa1SThomas Huth     int64_t i64 = -1;
1167*da668aa1SThomas Huth     Error *err = NULL;
1168*da668aa1SThomas Huth     Visitor *v;
1169*da668aa1SThomas Huth 
1170*da668aa1SThomas Huth     /* Unvisited nested list tail */
1171*da668aa1SThomas Huth 
1172*da668aa1SThomas Huth     v = visitor_input_test_init(data, "[ 0, [ 1, 2, 3 ] ]");
1173*da668aa1SThomas Huth 
1174*da668aa1SThomas Huth     visit_start_list(v, NULL, NULL, 0, &error_abort);
1175*da668aa1SThomas Huth     visit_type_int(v, NULL, &i64, &error_abort);
1176*da668aa1SThomas Huth     g_assert_cmpint(i64, ==, 0);
1177*da668aa1SThomas Huth     visit_start_list(v, NULL, NULL, 0, &error_abort);
1178*da668aa1SThomas Huth     visit_type_int(v, NULL, &i64, &error_abort);
1179*da668aa1SThomas Huth     g_assert_cmpint(i64, ==, 1);
1180*da668aa1SThomas Huth     visit_check_list(v, &err);
1181*da668aa1SThomas Huth     error_free_or_abort(&err);
1182*da668aa1SThomas Huth     visit_end_list(v, NULL);
1183*da668aa1SThomas Huth     visit_check_list(v, &error_abort);
1184*da668aa1SThomas Huth     visit_end_list(v, NULL);
1185*da668aa1SThomas Huth }
1186*da668aa1SThomas Huth 
1187*da668aa1SThomas Huth static void test_visitor_in_fail_union_list(TestInputVisitorData *data,
1188*da668aa1SThomas Huth                                             const void *unused)
1189*da668aa1SThomas Huth {
1190*da668aa1SThomas Huth     UserDefListUnion *tmp = NULL;
1191*da668aa1SThomas Huth     Error *err = NULL;
1192*da668aa1SThomas Huth     Visitor *v;
1193*da668aa1SThomas Huth 
1194*da668aa1SThomas Huth     v = visitor_input_test_init(data,
1195*da668aa1SThomas Huth                                 "{ 'type': 'integer', 'data' : [ 'string' ] }");
1196*da668aa1SThomas Huth 
1197*da668aa1SThomas Huth     visit_type_UserDefListUnion(v, NULL, &tmp, &err);
1198*da668aa1SThomas Huth     error_free_or_abort(&err);
1199*da668aa1SThomas Huth     g_assert(!tmp);
1200*da668aa1SThomas Huth }
1201*da668aa1SThomas Huth 
1202*da668aa1SThomas Huth static void test_visitor_in_fail_union_flat(TestInputVisitorData *data,
1203*da668aa1SThomas Huth                                             const void *unused)
1204*da668aa1SThomas Huth {
1205*da668aa1SThomas Huth     UserDefFlatUnion *tmp = NULL;
1206*da668aa1SThomas Huth     Error *err = NULL;
1207*da668aa1SThomas Huth     Visitor *v;
1208*da668aa1SThomas Huth 
1209*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }");
1210*da668aa1SThomas Huth 
1211*da668aa1SThomas Huth     visit_type_UserDefFlatUnion(v, NULL, &tmp, &err);
1212*da668aa1SThomas Huth     error_free_or_abort(&err);
1213*da668aa1SThomas Huth     g_assert(!tmp);
1214*da668aa1SThomas Huth }
1215*da668aa1SThomas Huth 
1216*da668aa1SThomas Huth static void test_visitor_in_fail_union_flat_no_discrim(TestInputVisitorData *data,
1217*da668aa1SThomas Huth                                                        const void *unused)
1218*da668aa1SThomas Huth {
1219*da668aa1SThomas Huth     UserDefFlatUnion2 *tmp = NULL;
1220*da668aa1SThomas Huth     Error *err = NULL;
1221*da668aa1SThomas Huth     Visitor *v;
1222*da668aa1SThomas Huth 
1223*da668aa1SThomas Huth     /* test situation where discriminator field ('enum1' here) is missing */
1224*da668aa1SThomas Huth     v = visitor_input_test_init(data, "{ 'integer': 42, 'string': 'c', 'string1': 'd', 'string2': 'e' }");
1225*da668aa1SThomas Huth 
1226*da668aa1SThomas Huth     visit_type_UserDefFlatUnion2(v, NULL, &tmp, &err);
1227*da668aa1SThomas Huth     error_free_or_abort(&err);
1228*da668aa1SThomas Huth     g_assert(!tmp);
1229*da668aa1SThomas Huth }
1230*da668aa1SThomas Huth 
1231*da668aa1SThomas Huth static void test_visitor_in_fail_alternate(TestInputVisitorData *data,
1232*da668aa1SThomas Huth                                            const void *unused)
1233*da668aa1SThomas Huth {
1234*da668aa1SThomas Huth     UserDefAlternate *tmp;
1235*da668aa1SThomas Huth     Visitor *v;
1236*da668aa1SThomas Huth     Error *err = NULL;
1237*da668aa1SThomas Huth 
1238*da668aa1SThomas Huth     v = visitor_input_test_init(data, "3.14");
1239*da668aa1SThomas Huth 
1240*da668aa1SThomas Huth     visit_type_UserDefAlternate(v, NULL, &tmp, &err);
1241*da668aa1SThomas Huth     error_free_or_abort(&err);
1242*da668aa1SThomas Huth     g_assert(!tmp);
1243*da668aa1SThomas Huth }
1244*da668aa1SThomas Huth 
1245*da668aa1SThomas Huth static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data,
1246*da668aa1SThomas Huth                                               const QLitObject *qlit)
1247*da668aa1SThomas Huth {
1248*da668aa1SThomas Huth     g_autoptr(SchemaInfoList) schema = NULL;
1249*da668aa1SThomas Huth     QObject *obj = qobject_from_qlit(qlit);
1250*da668aa1SThomas Huth     Visitor *v;
1251*da668aa1SThomas Huth 
1252*da668aa1SThomas Huth     v = qobject_input_visitor_new(obj);
1253*da668aa1SThomas Huth 
1254*da668aa1SThomas Huth     visit_type_SchemaInfoList(v, NULL, &schema, &error_abort);
1255*da668aa1SThomas Huth     g_assert(schema);
1256*da668aa1SThomas Huth 
1257*da668aa1SThomas Huth     qobject_unref(obj);
1258*da668aa1SThomas Huth     visit_free(v);
1259*da668aa1SThomas Huth }
1260*da668aa1SThomas Huth 
1261*da668aa1SThomas Huth static void test_visitor_in_qmp_introspect(TestInputVisitorData *data,
1262*da668aa1SThomas Huth                                            const void *unused)
1263*da668aa1SThomas Huth {
1264*da668aa1SThomas Huth     do_test_visitor_in_qmp_introspect(data, &test_qmp_schema_qlit);
1265*da668aa1SThomas Huth }
1266*da668aa1SThomas Huth 
1267*da668aa1SThomas Huth int main(int argc, char **argv)
1268*da668aa1SThomas Huth {
1269*da668aa1SThomas Huth     g_test_init(&argc, &argv, NULL);
1270*da668aa1SThomas Huth 
1271*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/int",
1272*da668aa1SThomas Huth                            NULL, test_visitor_in_int);
1273*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/uint",
1274*da668aa1SThomas Huth                            NULL, test_visitor_in_uint);
1275*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/int_overflow",
1276*da668aa1SThomas Huth                            NULL, test_visitor_in_int_overflow);
1277*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/int_keyval",
1278*da668aa1SThomas Huth                            NULL, test_visitor_in_int_keyval);
1279*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/int_str_keyval",
1280*da668aa1SThomas Huth                            NULL, test_visitor_in_int_str_keyval);
1281*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/int_str_fail",
1282*da668aa1SThomas Huth                            NULL, test_visitor_in_int_str_fail);
1283*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/bool",
1284*da668aa1SThomas Huth                            NULL, test_visitor_in_bool);
1285*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/bool_keyval",
1286*da668aa1SThomas Huth                            NULL, test_visitor_in_bool_keyval);
1287*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/bool_str_keyval",
1288*da668aa1SThomas Huth                            NULL, test_visitor_in_bool_str_keyval);
1289*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/bool_str_fail",
1290*da668aa1SThomas Huth                            NULL, test_visitor_in_bool_str_fail);
1291*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/number",
1292*da668aa1SThomas Huth                            NULL, test_visitor_in_number);
1293*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/large_number",
1294*da668aa1SThomas Huth                            NULL, test_visitor_in_large_number);
1295*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/number_keyval",
1296*da668aa1SThomas Huth                            NULL, test_visitor_in_number_keyval);
1297*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/number_str_keyval",
1298*da668aa1SThomas Huth                            NULL, test_visitor_in_number_str_keyval);
1299*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/number_str_fail",
1300*da668aa1SThomas Huth                            NULL, test_visitor_in_number_str_fail);
1301*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/size_str_keyval",
1302*da668aa1SThomas Huth                            NULL, test_visitor_in_size_str_keyval);
1303*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/size_str_fail",
1304*da668aa1SThomas Huth                            NULL, test_visitor_in_size_str_fail);
1305*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/string",
1306*da668aa1SThomas Huth                            NULL, test_visitor_in_string);
1307*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/enum",
1308*da668aa1SThomas Huth                            NULL, test_visitor_in_enum);
1309*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/struct",
1310*da668aa1SThomas Huth                            NULL, test_visitor_in_struct);
1311*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/struct-nested",
1312*da668aa1SThomas Huth                            NULL, test_visitor_in_struct_nested);
1313*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list",
1314*da668aa1SThomas Huth                            NULL, test_visitor_in_list);
1315*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/any",
1316*da668aa1SThomas Huth                            NULL, test_visitor_in_any);
1317*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/null",
1318*da668aa1SThomas Huth                            NULL, test_visitor_in_null);
1319*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/union-flat",
1320*da668aa1SThomas Huth                            NULL, test_visitor_in_union_flat);
1321*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/alternate",
1322*da668aa1SThomas Huth                            NULL, test_visitor_in_alternate);
1323*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/errors",
1324*da668aa1SThomas Huth                            NULL, test_visitor_in_errors);
1325*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/wrong-type",
1326*da668aa1SThomas Huth                            NULL, test_visitor_in_wrong_type);
1327*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/alternate-number",
1328*da668aa1SThomas Huth                            NULL, test_visitor_in_alternate_number);
1329*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/int",
1330*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_int);
1331*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/int8",
1332*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_int8);
1333*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/int16",
1334*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_int16);
1335*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/int32",
1336*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_int32);
1337*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/int64",
1338*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_int64);
1339*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/uint8",
1340*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_uint8);
1341*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/uint16",
1342*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_uint16);
1343*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/uint32",
1344*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_uint32);
1345*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/uint64",
1346*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_uint64);
1347*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/bool",
1348*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_bool);
1349*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/str",
1350*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_string);
1351*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/list_union/number",
1352*da668aa1SThomas Huth                            NULL, test_visitor_in_list_union_number);
1353*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/fail/struct",
1354*da668aa1SThomas Huth                            NULL, test_visitor_in_fail_struct);
1355*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/fail/struct-nested",
1356*da668aa1SThomas Huth                            NULL, test_visitor_in_fail_struct_nested);
1357*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/fail/struct-in-list",
1358*da668aa1SThomas Huth                            NULL, test_visitor_in_fail_struct_in_list);
1359*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/fail/struct-missing",
1360*da668aa1SThomas Huth                            NULL, test_visitor_in_fail_struct_missing);
1361*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/fail/list",
1362*da668aa1SThomas Huth                            NULL, test_visitor_in_fail_list);
1363*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/fail/list-nested",
1364*da668aa1SThomas Huth                            NULL, test_visitor_in_fail_list_nested);
1365*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/fail/union-flat",
1366*da668aa1SThomas Huth                            NULL, test_visitor_in_fail_union_flat);
1367*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/fail/union-flat-no-discriminator",
1368*da668aa1SThomas Huth                            NULL, test_visitor_in_fail_union_flat_no_discrim);
1369*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/fail/alternate",
1370*da668aa1SThomas Huth                            NULL, test_visitor_in_fail_alternate);
1371*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/fail/union-list",
1372*da668aa1SThomas Huth                            NULL, test_visitor_in_fail_union_list);
1373*da668aa1SThomas Huth     input_visitor_test_add("/visitor/input/qapi-introspect",
1374*da668aa1SThomas Huth                            NULL, test_visitor_in_qmp_introspect);
1375*da668aa1SThomas Huth 
1376*da668aa1SThomas Huth     g_test_run();
1377*da668aa1SThomas Huth 
1378*da668aa1SThomas Huth     return 0;
1379*da668aa1SThomas Huth }
1380