Statistics
| Branch: | Revision:

root / check-qjson.c @ 4f690853

History | View | Annotate | Download (17.5 kB)

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