tests/test_json.c

changeset 1015
a0922b925d2a
parent 1007
81b2986d2b04
equal deleted inserted replaced
1014:56eb7da4f3e1 1015:a0922b925d2a
114 114
115 cxJsonDestroy(&json); 115 cxJsonDestroy(&json);
116 } 116 }
117 } 117 }
118 118
119 CX_TEST(test_json_escaped_strings) {
120 cxstring text = cx_str(
121 "{\n"
122 "\t\"object\":\"{\\n\\t\\\"object\\\":null\\n}\"}\"\n"
123 "}"
124 );
125
126 CxJson json;
127 cxJsonInit(&json, NULL);
128 CX_TEST_DO {
129 cxJsonFill(&json, text);
130 CxJsonValue *obj;
131 CxJsonStatus result = cxJsonNext(&json, &obj);
132 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR);
133 CX_TEST_ASSERT(cxJsonIsObject(obj));
134 CxJsonValue *object = cxJsonObjGet(obj, "object");
135 CX_TEST_ASSERT(cxJsonIsString(object));
136 CX_TEST_ASSERT(0 == cx_strcmp(
137 cxJsonAsCxString(object),
138 CX_STR("{\n\t\"object\":null\n}"))
139 );
140 }
141 cxJsonDestroy(&json);
142 }
143
119 CX_TEST(test_json_object_incomplete_token) { 144 CX_TEST(test_json_object_incomplete_token) {
120 cxstring text = cx_str( 145 cxstring text = cx_str(
121 "{\"message\":\"success\" , \"__timestamp\":1729348561}"); 146 "{\"message\":\"success\" , \"__timestamp\":1729348561}");
122 cxstring parts[16]; 147 cxstring parts[16];
123 size_t nparts = 0; // split the json text into mulple parts 148 size_t nparts = 0; // split the json text into mulple parts
162 result = cxJsonNext(&json, &obj); 187 result = cxJsonNext(&json, &obj);
163 CX_TEST_ASSERT(result == CX_JSON_NO_DATA); 188 CX_TEST_ASSERT(result == CX_JSON_NO_DATA);
164 189
165 cxJsonDestroy(&json); 190 cxJsonDestroy(&json);
166 } 191 }
192 }
193
194 CX_TEST(test_json_token_wrongly_completed) {
195 cxstring text = cx_str("{\"number\": 47110815!}");
196 cxstring part1 = cx_strsubsl(text, 0, 16);
197 cxstring part2 = cx_strsubs(text, 16);
198
199 CxJson json;
200 cxJsonInit(&json, NULL);
201 CX_TEST_DO {
202 CxJsonStatus result;
203 CxJsonValue *obj;
204
205 cxJsonFill(&json, part1);
206 result = cxJsonNext(&json, &obj);
207 CX_TEST_ASSERT(result == CX_JSON_INCOMPLETE_DATA);
208 cxJsonFill(&json, part2);
209 result = cxJsonNext(&json, &obj);
210 CX_TEST_ASSERT(result == CX_JSON_FORMAT_ERROR_NUMBER);
211 CX_TEST_ASSERT(obj->type == CX_JSON_NOTHING);
212 }
213 cxJsonDestroy(&json);
167 } 214 }
168 215
169 CX_TEST(test_json_subsequent_fill) { 216 CX_TEST(test_json_subsequent_fill) {
170 cxstring text = cx_str( 217 cxstring text = cx_str(
171 "{\"message\":\"success\" , \"__timestamp\":1729348561}"); 218 "{\"message\":\"success\" , \"__timestamp\":1729348561}");
294 341
295 CX_TEST(test_json_number) { 342 CX_TEST(test_json_number) {
296 CxJson json; 343 CxJson json;
297 cxJsonInit(&json, NULL); 344 cxJsonInit(&json, NULL);
298 CX_TEST_DO { 345 CX_TEST_DO {
299 // TODO: find a better way to terminate values that are not arrays/objects
300 CxJsonValue *v; 346 CxJsonValue *v;
301 CxJsonStatus result; 347 CxJsonStatus result;
348
302 cxJsonFill(&json, "3.1415 "); 349 cxJsonFill(&json, "3.1415 ");
303 result = cxJsonNext(&json, &v); 350 result = cxJsonNext(&json, &v);
304 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); 351 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR);
305 CX_TEST_ASSERT(cxJsonIsNumber(v)); 352 CX_TEST_ASSERT(cxJsonIsNumber(v));
306 CX_TEST_ASSERT(cxJsonAsDouble(v) == 3.1415); 353 CX_TEST_ASSERT(cxJsonAsDouble(v) == 3.1415);
307 cxJsonValueFree(v); 354 cxJsonValueFree(v);
355
308 cxJsonFill(&json, "-47.11e2 "); 356 cxJsonFill(&json, "-47.11e2 ");
309 result = cxJsonNext(&json, &v); 357 result = cxJsonNext(&json, &v);
310 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); 358 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR);
311 CX_TEST_ASSERT(cxJsonIsNumber(v)); 359 CX_TEST_ASSERT(cxJsonIsNumber(v));
312 CX_TEST_ASSERT(cxJsonAsDouble(v) == -4711.0); 360 CX_TEST_ASSERT(cxJsonAsDouble(v) == -4711.0);
313 cxJsonValueFree(v); 361 cxJsonValueFree(v);
362
363 cxJsonFill(&json, "0.815e-3 ");
364 result = cxJsonNext(&json, &v);
365 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR);
366 CX_TEST_ASSERT(cxJsonIsNumber(v));
367 CX_TEST_ASSERT(cxJsonAsDouble(v) == 0.000815);
368
369 cxJsonFill(&json, "1.23E4 ");
370 result = cxJsonNext(&json, &v);
371 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR);
372 CX_TEST_ASSERT(cxJsonIsNumber(v));
373 CX_TEST_ASSERT(cxJsonAsInteger(v) == 12300);
374 CX_TEST_ASSERT(cxJsonAsDouble(v) == 12300.0);
375
376 cxJsonValueFree(v);
377 }
378 cxJsonDestroy(&json);
379 }
380
381 CX_TEST(test_json_number_format_errors) {
382 CxJson json;
383 cxJsonInit(&json, NULL);
384 CX_TEST_DO {
385 CxJsonValue *v;
386 CxJsonStatus result;
387
388 cxJsonFill(&json, "+3.1415 ");
389 result = cxJsonNext(&json, &v);
390 CX_TEST_ASSERTM(result == CX_JSON_FORMAT_ERROR_NUMBER,
391 "leading plus is not RFC-8259 compliant");
392 CX_TEST_ASSERT(v->type == CX_JSON_NOTHING);
393 cxJsonReset(&json);
394
395 #if 0 // TODO: discuss if it is intended that this produces -47 as valid value
396 cxJsonFill(&json, "-47,11e2 ");
397 result = cxJsonNext(&json, &v);
398 CX_TEST_ASSERTM(result == CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN,
399 "decimal separator cannot be a comma");
400 CX_TEST_ASSERT(v->type == CX_JSON_NOTHING);
401 cxJsonReset(&json);
402 #endif
403
404 cxJsonFill(&json, "0.815e-3.0 ");
405 result = cxJsonNext(&json, &v);
406 CX_TEST_ASSERTM(result == CX_JSON_FORMAT_ERROR_NUMBER,
407 "exponent must be an integer");
408 CX_TEST_ASSERT(v->type == CX_JSON_NOTHING);
409 cxJsonReset(&json);
410
411 cxJsonFill(&json, "3.14e ");
412 result = cxJsonNext(&json, &v);
413 CX_TEST_ASSERTM(result == CX_JSON_FORMAT_ERROR_NUMBER,
414 "exponent cannot be empty");
415 CX_TEST_ASSERT(v->type == CX_JSON_NOTHING);
416 cxJsonReset(&json);
417
418 cxJsonFill(&json, "3.14e~7 ");
419 result = cxJsonNext(&json, &v);
420 CX_TEST_ASSERTM(result == CX_JSON_FORMAT_ERROR_NUMBER,
421 "exponent cannot start with bullshit");
422 CX_TEST_ASSERT(v->type == CX_JSON_NOTHING);
423 cxJsonReset(&json);
424
425 cxJsonFill(&json, "1.23e4f ");
426 result = cxJsonNext(&json, &v);
427 CX_TEST_ASSERTM(result == CX_JSON_FORMAT_ERROR_NUMBER,
428 "non-digits in exponent");
429 CX_TEST_ASSERT(v->type == CX_JSON_NOTHING);
430 cxJsonReset(&json);
431
432 cxJsonFill(&json, "1.23f ");
433 result = cxJsonNext(&json, &v);
434 CX_TEST_ASSERTM(result == CX_JSON_FORMAT_ERROR_NUMBER,
435 "non-digits in value");
436 CX_TEST_ASSERT(v->type == CX_JSON_NOTHING);
437 cxJsonReset(&json);
438
439 cxJsonFill(&json, "1.23.45 ");
440 result = cxJsonNext(&json, &v);
441 CX_TEST_ASSERTM(result == CX_JSON_FORMAT_ERROR_NUMBER,
442 "multiple decimal separators");
443 CX_TEST_ASSERT(v->type == CX_JSON_NOTHING);
444 cxJsonReset(&json);
445
446 cxJsonFill(&json, "184467440737095516150123456789 ");
447 result = cxJsonNext(&json, &v);
448 CX_TEST_ASSERTM(result == CX_JSON_FORMAT_ERROR_NUMBER,
449 "30 digit int does not fit into 64-bit int");
450 CX_TEST_ASSERT(v->type == CX_JSON_NOTHING);
451 cxJsonReset(&json);
452
453 cxJsonFill(&json, "18446744073709551615.0123456789 ");
454 result = cxJsonNext(&json, &v);
455 CX_TEST_ASSERTM(result == CX_JSON_FORMAT_ERROR_NUMBER,
456 "numbers with more than 30 characters are unsupported in general");
457 CX_TEST_ASSERT(v->type == CX_JSON_NOTHING);
458 cxJsonReset(&json);
314 } 459 }
315 cxJsonDestroy(&json); 460 cxJsonDestroy(&json);
316 } 461 }
317 462
318 CX_TEST(test_json_multiple_values) { 463 CX_TEST(test_json_multiple_values) {
363 // read literal 508 // read literal
364 cxJsonFill(&json, "true\n"); 509 cxJsonFill(&json, "true\n");
365 result = cxJsonNext(&json, &v); 510 result = cxJsonNext(&json, &v);
366 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); 511 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR);
367 CX_TEST_ASSERT(cxJsonIsLiteral(v)); 512 CX_TEST_ASSERT(cxJsonIsLiteral(v));
513 CX_TEST_ASSERT(cxJsonIsBool(v));
514 CX_TEST_ASSERT(cxJsonIsTrue(v));
368 CX_TEST_ASSERT(cxJsonAsBool(v)); 515 CX_TEST_ASSERT(cxJsonAsBool(v));
369 cxJsonValueFree(v); 516 cxJsonValueFree(v);
370 // read null 517 cxJsonFill(&json, "false\n");
518 result = cxJsonNext(&json, &v);
519 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR);
520 CX_TEST_ASSERT(cxJsonIsLiteral(v));
521 CX_TEST_ASSERT(cxJsonIsBool(v));
522 CX_TEST_ASSERT(cxJsonIsFalse(v));
523 CX_TEST_ASSERT(!cxJsonAsBool(v));
524 cxJsonValueFree(v);
371 cxJsonFill(&json, "null\n"); 525 cxJsonFill(&json, "null\n");
372 result = cxJsonNext(&json, &v); 526 result = cxJsonNext(&json, &v);
373 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); 527 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR);
528 CX_TEST_ASSERT(cxJsonIsLiteral(v));
529 CX_TEST_ASSERT(!cxJsonIsBool(v));
374 CX_TEST_ASSERT(cxJsonIsNull(v)); 530 CX_TEST_ASSERT(cxJsonIsNull(v));
375 cxJsonValueFree(v); 531 cxJsonValueFree(v);
376 } 532 }
377 cxJsonDestroy(&json); 533 cxJsonDestroy(&json);
378 } 534 }
441 CxTestSuite *cx_test_suite_json(void) { 597 CxTestSuite *cx_test_suite_json(void) {
442 CxTestSuite *suite = cx_test_suite_new("json"); 598 CxTestSuite *suite = cx_test_suite_new("json");
443 599
444 cx_test_register(suite, test_json_init_default); 600 cx_test_register(suite, test_json_init_default);
445 cx_test_register(suite, test_json_simple_object); 601 cx_test_register(suite, test_json_simple_object);
602 cx_test_register(suite, test_json_escaped_strings);
446 cx_test_register(suite, test_json_object_incomplete_token); 603 cx_test_register(suite, test_json_object_incomplete_token);
604 cx_test_register(suite, test_json_token_wrongly_completed);
447 cx_test_register(suite, test_json_object_error); 605 cx_test_register(suite, test_json_object_error);
448 cx_test_register(suite, test_json_subsequent_fill); 606 cx_test_register(suite, test_json_subsequent_fill);
449 cx_test_register(suite, test_json_large_nesting_depth); 607 cx_test_register(suite, test_json_large_nesting_depth);
450 cx_test_register(suite, test_json_number); 608 cx_test_register(suite, test_json_number);
609 cx_test_register(suite, test_json_number_format_errors);
451 cx_test_register(suite, test_json_multiple_values); 610 cx_test_register(suite, test_json_multiple_values);
452 cx_test_register(suite, test_json_allocator); 611 cx_test_register(suite, test_json_allocator);
453 cx_test_register(suite, test_json_allocator_parse_error); 612 cx_test_register(suite, test_json_allocator_parse_error);
454 613
455 return suite; 614 return suite;

mercurial