57 "\t\"alive\":true\n" |
57 "\t\"alive\":true\n" |
58 "}" |
58 "}" |
59 ); |
59 ); |
60 |
60 |
61 CX_TEST_DO { |
61 CX_TEST_DO { |
62 int result; |
62 CxJsonStatus result; |
63 |
63 |
64 CxJson json; |
64 CxJson json; |
65 cxJsonInit(&json, NULL); |
65 cxJsonInit(&json, NULL); |
66 cxJsonFill(&json, text); |
66 cxJsonFill(&json, text); |
67 |
67 |
68 // parse the big fat object |
68 // parse the big fat object |
69 CxJsonValue *obj; |
69 CxJsonValue *obj; |
70 result = cxJsonNext(&json, &obj); |
70 result = cxJsonNext(&json, &obj); |
71 CX_TEST_ASSERT(result == 1); |
71 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
72 |
72 |
73 // check the contents |
73 // check the contents |
74 CX_TEST_ASSERT(cxJsonIsObject(obj)); |
74 CX_TEST_ASSERT(cxJsonIsObject(obj)); |
75 |
75 |
76 CxJsonValue *message = cxJsonObjGet(obj, "message"); |
76 CxJsonValue *message = cxJsonObjGet(obj, "message"); |
124 for(size_t i=0;i<text.length;i+=4) { |
124 for(size_t i=0;i<text.length;i+=4) { |
125 parts[nparts++] = cx_strsubsl(text, i, 4); |
125 parts[nparts++] = cx_strsubsl(text, i, 4); |
126 } |
126 } |
127 |
127 |
128 CX_TEST_DO { |
128 CX_TEST_DO { |
129 int result; |
129 CxJsonStatus result; |
130 |
130 |
131 CxJson json; |
131 CxJson json; |
132 cxJsonInit(&json, NULL); |
132 cxJsonInit(&json, NULL); |
133 CxJsonValue *obj; |
133 CxJsonValue *obj; |
134 |
134 |
135 size_t part = 0; |
135 size_t part = 0; |
136 while(part < nparts) { |
136 while(part < nparts - 1) { |
137 cxJsonFill(&json, parts[part]); |
137 cxJsonFill(&json, parts[part]); |
138 part++; |
138 part++; |
139 result = cxJsonNext(&json, &obj); |
139 result = cxJsonNext(&json, &obj); |
140 |
140 CX_TEST_ASSERT(result == CX_JSON_INCOMPLETE_DATA); |
141 if(result != 0) { |
|
142 break; |
|
143 } |
|
144 } |
141 } |
145 |
142 cxJsonFill(&json, parts[nparts - 1]); |
146 CX_TEST_ASSERT(result == 1); |
143 result = cxJsonNext(&json, &obj); |
147 CX_TEST_ASSERT(part == nparts); |
144 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
148 CX_TEST_ASSERT(obj); |
145 CX_TEST_ASSERT(obj); |
149 |
146 |
150 CxJsonValue *message = cxJsonObjGet(obj, "message"); |
147 CxJsonValue *message = cxJsonObjGet(obj, "message"); |
151 CX_TEST_ASSERT(cxJsonIsString(message)); |
148 CX_TEST_ASSERT(cxJsonIsString(message)); |
152 CX_TEST_ASSERT(0 == cx_strcmp( |
149 CX_TEST_ASSERT(0 == cx_strcmp( |
185 cxstring text2 = cx_str("{ \"a\" : }"); |
182 cxstring text2 = cx_str("{ \"a\" : }"); |
186 cxstring text3 = cx_str("{ \"a\" : \"b\" ]"); |
183 cxstring text3 = cx_str("{ \"a\" : \"b\" ]"); |
187 cxstring text4 = cx_str("{ \"name\": \"value\" ]"); |
184 cxstring text4 = cx_str("{ \"name\": \"value\" ]"); |
188 |
185 |
189 cxstring tests[] = { text0, text1, text2, text3, text4 }; |
186 cxstring tests[] = { text0, text1, text2, text3, text4 }; |
|
187 CxJsonStatus errors[] = { |
|
188 CX_JSON_FORMAT_ERROR_NUMBER, |
|
189 CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN, |
|
190 CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN, |
|
191 CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN, |
|
192 CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN |
|
193 }; |
190 |
194 |
191 CX_TEST_DO { |
195 CX_TEST_DO { |
192 int result; |
196 CxJsonStatus result; |
193 CxJson json; |
197 CxJson json; |
194 CxJsonValue *obj = NULL; |
198 CxJsonValue *obj = NULL; |
195 |
199 |
196 for(int i=0;i<5;i++) { |
200 for(int i=0;i<5;i++) { |
197 cxJsonInit(&json, NULL); |
201 cxJsonInit(&json, NULL); |
198 cxJsonFill(&json, tests[i]); |
202 cxJsonFill(&json, tests[i]); |
199 result = cxJsonNext(&json, &obj); |
203 result = cxJsonNext(&json, &obj); |
200 |
204 |
201 CX_TEST_ASSERT(result == -1); |
205 CX_TEST_ASSERT(result == errors[i]); |
202 CX_TEST_ASSERT(obj != NULL && obj->type == CX_JSON_NOTHING); |
206 CX_TEST_ASSERT(obj != NULL && obj->type == CX_JSON_NOTHING); |
203 cxJsonDestroy(&json); |
207 cxJsonDestroy(&json); |
204 } |
208 } |
205 } |
209 } |
206 } |
210 } |
255 CxJson json; |
259 CxJson json; |
256 cxJsonInit(&json, NULL); |
260 cxJsonInit(&json, NULL); |
257 CX_TEST_DO { |
261 CX_TEST_DO { |
258 // TODO: find a better way to terminate values that are not arrays/objects |
262 // TODO: find a better way to terminate values that are not arrays/objects |
259 CxJsonValue *v; |
263 CxJsonValue *v; |
260 int result; |
264 CxJsonStatus result; |
261 cxJsonFill(&json, "3.1415 "); |
265 cxJsonFill(&json, "3.1415 "); |
262 result = cxJsonNext(&json, &v); |
266 result = cxJsonNext(&json, &v); |
263 CX_TEST_ASSERT(result == 1); |
267 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
264 CX_TEST_ASSERT(cxJsonIsNumber(v)); |
268 CX_TEST_ASSERT(cxJsonIsNumber(v)); |
265 CX_TEST_ASSERT(cxJsonAsDouble(v) == 3.1415); |
269 CX_TEST_ASSERT(cxJsonAsDouble(v) == 3.1415); |
266 cxJsonValueFree(v); |
270 cxJsonValueFree(v); |
267 cxJsonFill(&json, "-47.11e2 "); |
271 cxJsonFill(&json, "-47.11e2 "); |
268 result = cxJsonNext(&json, &v); |
272 result = cxJsonNext(&json, &v); |
269 CX_TEST_ASSERT(result == 1); |
273 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
270 CX_TEST_ASSERT(cxJsonIsNumber(v)); |
274 CX_TEST_ASSERT(cxJsonIsNumber(v)); |
271 CX_TEST_ASSERT(cxJsonAsDouble(v) == -4711.0); |
275 CX_TEST_ASSERT(cxJsonAsDouble(v) == -4711.0); |
272 cxJsonValueFree(v); |
276 cxJsonValueFree(v); |
273 } |
277 } |
274 cxJsonDestroy(&json); |
278 cxJsonDestroy(&json); |
277 CX_TEST(test_json_multiple_values) { |
281 CX_TEST(test_json_multiple_values) { |
278 CxJson json; |
282 CxJson json; |
279 cxJsonInit(&json, NULL); |
283 cxJsonInit(&json, NULL); |
280 CX_TEST_DO { |
284 CX_TEST_DO { |
281 CxJsonValue *v; |
285 CxJsonValue *v; |
282 int result; |
286 CxJsonStatus result; |
283 |
287 |
284 // read number |
288 // read number |
285 cxJsonFill(&json, "10\n"); |
289 cxJsonFill(&json, "10\n"); |
286 result = cxJsonNext(&json, &v); |
290 result = cxJsonNext(&json, &v); |
287 CX_TEST_ASSERT(result == 1); |
291 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
288 CX_TEST_ASSERT(cxJsonIsNumber(v)); |
292 CX_TEST_ASSERT(cxJsonIsNumber(v)); |
289 CX_TEST_ASSERT(cxJsonAsInteger(v) == 10); |
293 CX_TEST_ASSERT(cxJsonAsInteger(v) == 10); |
290 cxJsonValueFree(v); |
294 cxJsonValueFree(v); |
291 // read remaining '\n' |
295 // read remaining '\n' |
292 result = cxJsonNext(&json, &v); |
296 result = cxJsonNext(&json, &v); |
293 CX_TEST_ASSERT(result == 0); |
297 CX_TEST_ASSERT(result == CX_JSON_INCOMPLETE_DATA); |
294 // read string |
298 // read string |
295 cxJsonFill(&json, "\"hello world\"\n"); |
299 cxJsonFill(&json, "\"hello world\"\n"); |
296 result = cxJsonNext(&json, &v); |
300 result = cxJsonNext(&json, &v); |
297 CX_TEST_ASSERT(result == 1); |
301 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
298 CX_TEST_ASSERT(cxJsonIsString(v)); |
302 CX_TEST_ASSERT(cxJsonIsString(v)); |
299 CX_TEST_ASSERT(!cx_strcmp(cxJsonAsCxString(v), CX_STR("hello world"))); |
303 CX_TEST_ASSERT(!cx_strcmp(cxJsonAsCxString(v), CX_STR("hello world"))); |
300 cxJsonValueFree(v); |
304 cxJsonValueFree(v); |
301 // don't process the remaining newline this time |
305 // don't process the remaining newline this time |
302 // read obj |
306 // read obj |
303 cxJsonFill(&json, "{ \"value\": \"test\" }\n"); |
307 cxJsonFill(&json, "{ \"value\": \"test\" }\n"); |
304 result = cxJsonNext(&json, &v); |
308 result = cxJsonNext(&json, &v); |
305 CX_TEST_ASSERT(result == 1); |
309 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
306 CX_TEST_ASSERT(cxJsonIsObject(v)); |
310 CX_TEST_ASSERT(cxJsonIsObject(v)); |
307 CxJsonValue *value = cxJsonObjGet(v, "value"); |
311 CxJsonValue *value = cxJsonObjGet(v, "value"); |
308 CX_TEST_ASSERT(cxJsonAsString(value)); |
312 CX_TEST_ASSERT(cxJsonAsString(value)); |
309 cxJsonValueFree(v); |
313 cxJsonValueFree(v); |
310 // read array |
314 // read array |
311 cxJsonFill(&json, "[ 0, 1, 2, 3, 4, 5 ]\n"); |
315 cxJsonFill(&json, "[ 0, 1, 2, 3, 4, 5 ]\n"); |
312 result = cxJsonNext(&json, &v); |
316 result = cxJsonNext(&json, &v); |
313 CX_TEST_ASSERT(result == 1); |
317 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
314 CX_TEST_ASSERT(cxJsonIsArray(v)); |
318 CX_TEST_ASSERT(cxJsonIsArray(v)); |
315 CxJsonValue *a0 = cxJsonArrGet(v, 0); |
319 CxJsonValue *a0 = cxJsonArrGet(v, 0); |
316 CxJsonValue *a3 = cxJsonArrGet(v, 3); |
320 CxJsonValue *a3 = cxJsonArrGet(v, 3); |
317 CX_TEST_ASSERT(cxJsonIsNumber(a0)); |
321 CX_TEST_ASSERT(cxJsonIsNumber(a0)); |
318 CX_TEST_ASSERT(cxJsonAsInteger(a0) == 0); |
322 CX_TEST_ASSERT(cxJsonAsInteger(a0) == 0); |
320 CX_TEST_ASSERT(cxJsonAsInteger(a3) == 3); |
324 CX_TEST_ASSERT(cxJsonAsInteger(a3) == 3); |
321 cxJsonValueFree(v); |
325 cxJsonValueFree(v); |
322 // read literal |
326 // read literal |
323 cxJsonFill(&json, "true\n"); |
327 cxJsonFill(&json, "true\n"); |
324 result = cxJsonNext(&json, &v); |
328 result = cxJsonNext(&json, &v); |
325 CX_TEST_ASSERT(result == 1); |
329 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
326 CX_TEST_ASSERT(cxJsonIsLiteral(v)); |
330 CX_TEST_ASSERT(cxJsonIsLiteral(v)); |
327 CX_TEST_ASSERT(cxJsonAsBool(v)); |
331 CX_TEST_ASSERT(cxJsonAsBool(v)); |
328 cxJsonValueFree(v); |
332 cxJsonValueFree(v); |
329 // read null |
333 // read null |
330 cxJsonFill(&json, "null\n"); |
334 cxJsonFill(&json, "null\n"); |
331 result = cxJsonNext(&json, &v); |
335 result = cxJsonNext(&json, &v); |
332 CX_TEST_ASSERT(result == 1); |
336 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
333 CX_TEST_ASSERT(cxJsonIsNull(v)); |
337 CX_TEST_ASSERT(cxJsonIsNull(v)); |
334 cxJsonValueFree(v); |
338 cxJsonValueFree(v); |
335 } |
339 } |
336 cxJsonDestroy(&json); |
340 cxJsonDestroy(&json); |
337 } |
341 } |
352 CxJson json; |
356 CxJson json; |
353 cxJsonInit(&json, allocator); |
357 cxJsonInit(&json, allocator); |
354 cxJsonFill(&json, text); |
358 cxJsonFill(&json, text); |
355 |
359 |
356 CxJsonValue *obj; |
360 CxJsonValue *obj; |
357 int result = cxJsonNext(&json, &obj); |
361 CxJsonStatus result = cxJsonNext(&json, &obj); |
358 CX_TEST_ASSERT(result == 1); |
362 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
359 CX_TEST_ASSERT(obj->allocator == allocator); |
363 CX_TEST_ASSERT(obj->allocator == allocator); |
360 |
364 |
361 // this recursively frees everything |
365 // this recursively frees everything |
362 cxJsonValueFree(obj); |
366 cxJsonValueFree(obj); |
363 cxJsonDestroy(&json); |
367 cxJsonDestroy(&json); |
383 CxJson json; |
387 CxJson json; |
384 cxJsonInit(&json, allocator); |
388 cxJsonInit(&json, allocator); |
385 cxJsonFill(&json, text); |
389 cxJsonFill(&json, text); |
386 |
390 |
387 CxJsonValue *obj = NULL; |
391 CxJsonValue *obj = NULL; |
388 int result = cxJsonNext(&json, &obj); |
392 CxJsonStatus result = cxJsonNext(&json, &obj); |
389 CX_TEST_ASSERT(result == -1); |
393 CX_TEST_ASSERT(result == CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN); |
390 CX_TEST_ASSERT(obj != NULL && obj->type == CX_JSON_NOTHING); |
394 CX_TEST_ASSERT(obj != NULL && obj->type == CX_JSON_NOTHING); |
391 |
395 |
392 // clean-up any left-over memory |
396 // clean-up any left-over memory |
393 cxJsonDestroy(&json); |
397 cxJsonDestroy(&json); |
394 |
398 |