Annotation of qemu/check-qjson.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com