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