File:  [Qemu by Fabrice Bellard] / qemu / check-qjson.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:34:08 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu0150, qemu0141, qemu0140, HEAD
qemu 0.14.0

    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[] = {
   31:         { "\"\\b\"", "\b" },
   32:         { "\"\\f\"", "\f" },
   33:         { "\"\\n\"", "\n" },
   34:         { "\"\\r\"", "\r" },
   35:         { "\"\\t\"", "\t" },
   36:         { "\"\\/\"", "\\/" },
   37:         { "\"\\\\\"", "\\" },
   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);
   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);
   60: 
   61:         if (test_cases[i].skip == 0) {
   62:             str = qobject_to_json(obj);
   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);
   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: 
  640: START_TEST(empty_input)
  641: {
  642:     const char *empty = "";
  643: 
  644:     QObject *obj = qobject_from_json(empty);
  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: 
  721: static Suite *qjson_suite(void)
  722: {
  723:     Suite *suite;
  724:     TCase *string_literals, *number_literals, *keyword_literals;
  725:     TCase *dicts, *lists, *whitespace, *varargs, *errors;
  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: 
  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: 
  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);
  775:     suite_add_tcase(suite, errors);
  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