| 115 |
115 |
| 116 cxJsonDestroy(&json); |
116 cxJsonDestroy(&json); |
| 117 } |
117 } |
| 118 } |
118 } |
| 119 |
119 |
| |
120 CX_TEST(test_json_large_object) { |
| |
121 CxJsonValue *obj = cxJsonCreateObj(NULL); |
| |
122 CX_TEST_DO { |
| |
123 cxJsonObjPutString(obj, "mystring", "test"); |
| |
124 char buf[10]; |
| |
125 for (unsigned i = 0 ; i < 300 ; i++) { |
| |
126 sprintf(buf, "key %d", i); |
| |
127 cxJsonObjPutInteger(obj, buf, i); |
| |
128 } |
| |
129 CX_TEST_ASSERT(301 == cxJsonObjSize(obj)); |
| |
130 // some samples |
| |
131 CxJsonValue *v; |
| |
132 v = cxJsonObjGet(obj, "key 64"); |
| |
133 CX_TEST_ASSERT(cxJsonIsInteger(v)); |
| |
134 CX_TEST_ASSERT(cxJsonAsInteger(v) == 64); |
| |
135 v = cxJsonObjGet(obj, "key 228"); |
| |
136 CX_TEST_ASSERT(cxJsonIsInteger(v)); |
| |
137 CX_TEST_ASSERT(cxJsonAsInteger(v) == 228); |
| |
138 |
| |
139 v = cxJsonObjGet(obj, "mystring"); |
| |
140 CX_TEST_ASSERT(cxJsonIsString(v)); |
| |
141 CX_TEST_ASSERT(0 == cx_strcmp(cxJsonAsCxMutStr(v), "test")); |
| |
142 } |
| |
143 cxJsonValueFree(obj); |
| |
144 } |
| |
145 |
| 120 CX_TEST(test_json_escaped_strings) { |
146 CX_TEST(test_json_escaped_strings) { |
| 121 cxstring text = cx_str( |
147 cxstring text = cx_str( |
| 122 "{\n" |
148 "{\n" |
| 123 "\t\"object\":\"{\\n\\t\\\"object\\\":null\\n}\",\n" |
149 "\t\"object\":\"{\\n\\t\\\"object\\\":null\\n}\",\n" |
| 124 "\t\"ctrl-chars\":\"\\\\foo\\r\\nbar\\f*ring\\/ring*\\b\"\n" |
150 "\t\"ctrl-chars\":\"\\\\foo\\r\\nbar\\f*ring\\/ring*\\b\"\n" |
| 135 CX_TEST_ASSERT(cxJsonIsObject(obj)); |
161 CX_TEST_ASSERT(cxJsonIsObject(obj)); |
| 136 CxJsonValue *object = cxJsonObjGet(obj, "object"); |
162 CxJsonValue *object = cxJsonObjGet(obj, "object"); |
| 137 CX_TEST_ASSERT(cxJsonIsString(object)); |
163 CX_TEST_ASSERT(cxJsonIsString(object)); |
| 138 CX_TEST_ASSERT(0 == cx_strcmp( |
164 CX_TEST_ASSERT(0 == cx_strcmp( |
| 139 cxJsonAsCxString(object), |
165 cxJsonAsCxString(object), |
| 140 CX_STR("{\n\t\"object\":null\n}")) |
166 "{\n\t\"object\":null\n}") |
| 141 ); |
167 ); |
| 142 CxJsonValue *ctrl = cxJsonObjGet(obj, "ctrl-chars"); |
168 CxJsonValue *ctrl = cxJsonObjGet(obj, "ctrl-chars"); |
| 143 CX_TEST_ASSERT(cxJsonIsString(ctrl)); |
169 CX_TEST_ASSERT(cxJsonIsString(ctrl)); |
| 144 CX_TEST_ASSERT(0 == cx_strcmp( |
170 CX_TEST_ASSERT(0 == cx_strcmp( |
| 145 cxJsonAsCxString(ctrl), |
171 cxJsonAsCxString(ctrl), |
| 146 CX_STR("\\foo\r\nbar\f*ring/ring*\b")) |
172 "\\foo\r\nbar\f*ring/ring*\b") |
| 147 ); |
173 ); |
| 148 cxJsonValueFree(obj); |
174 cxJsonValueFree(obj); |
| 149 } |
175 } |
| 150 cxJsonDestroy(&json); |
176 cxJsonDestroy(&json); |
| 151 } |
177 } |
| 174 |
200 |
| 175 CxJsonValue *ascii = cxJsonObjGet(obj, "ascii"); |
201 CxJsonValue *ascii = cxJsonObjGet(obj, "ascii"); |
| 176 CX_TEST_ASSERT(cxJsonIsString(ascii)); |
202 CX_TEST_ASSERT(cxJsonIsString(ascii)); |
| 177 CX_TEST_ASSERT(0 == cx_strcmp( |
203 CX_TEST_ASSERT(0 == cx_strcmp( |
| 178 cxJsonAsCxString(ascii), |
204 cxJsonAsCxString(ascii), |
| 179 CX_STR("ASCII")) |
205 "ASCII") |
| 180 ); |
206 ); |
| 181 |
207 |
| 182 CxJsonValue *unicode = cxJsonObjGet(obj, "unicode"); |
208 CxJsonValue *unicode = cxJsonObjGet(obj, "unicode"); |
| 183 CX_TEST_ASSERT(cxJsonIsString(unicode)); |
209 CX_TEST_ASSERT(cxJsonIsString(unicode)); |
| 184 CX_TEST_ASSERT(0 == cx_strcmp( |
210 CX_TEST_ASSERT(0 == cx_strcmp( |
| 185 cxJsonAsCxString(unicode), |
211 cxJsonAsCxString(unicode), |
| 186 CX_STR("ßß")) |
212 "ßß") |
| 187 ); |
213 ); |
| 188 |
214 |
| 189 CxJsonValue *mixed = cxJsonObjGet(obj, "mixed"); |
215 CxJsonValue *mixed = cxJsonObjGet(obj, "mixed"); |
| 190 CX_TEST_ASSERT(cxJsonIsString(mixed)); |
216 CX_TEST_ASSERT(cxJsonIsString(mixed)); |
| 191 CX_TEST_ASSERT(0 == cx_strcmp( |
217 CX_TEST_ASSERT(0 == cx_strcmp( |
| 192 cxJsonAsCxString(mixed), |
218 cxJsonAsCxString(mixed), |
| 193 CX_STR("mixed ä ö ä ö")) |
219 "mixed ä ö ä ö") |
| 194 ); |
220 ); |
| 195 |
221 |
| 196 CxJsonValue *wide = cxJsonObjGet(obj, "wide"); |
222 CxJsonValue *wide = cxJsonObjGet(obj, "wide"); |
| 197 CX_TEST_ASSERT(cxJsonIsString(wide)); |
223 CX_TEST_ASSERT(cxJsonIsString(wide)); |
| 198 CX_TEST_ASSERT(0 == cx_strcmp(cxJsonAsCxString(wide), CX_STR("Σ⦰"))); |
224 CX_TEST_ASSERT(0 == cx_strcmp(cxJsonAsCxString(wide), "Σ⦰")); |
| 199 |
225 |
| 200 CxJsonValue *surrogatepair1 = cxJsonObjGet(obj, "surrogatepair1"); |
226 CxJsonValue *surrogatepair1 = cxJsonObjGet(obj, "surrogatepair1"); |
| 201 CX_TEST_ASSERT(cxJsonIsString(surrogatepair1)); |
227 CX_TEST_ASSERT(cxJsonIsString(surrogatepair1)); |
| 202 CX_TEST_ASSERT(0 == cx_strcmp( |
228 CX_TEST_ASSERT(0 == cx_strcmp( |
| 203 cxJsonAsCxString(surrogatepair1), |
229 cxJsonAsCxString(surrogatepair1), |
| 204 CX_STR("\xf0\x9f\xaf\xb5")) |
230 "\xf0\x9f\xaf\xb5") |
| 205 ); |
231 ); |
| 206 |
232 |
| 207 CxJsonValue *surrogatepair2 = cxJsonObjGet(obj, "surrogatepair2"); |
233 CxJsonValue *surrogatepair2 = cxJsonObjGet(obj, "surrogatepair2"); |
| 208 CX_TEST_ASSERT(cxJsonIsString(surrogatepair2)); |
234 CX_TEST_ASSERT(cxJsonIsString(surrogatepair2)); |
| 209 CX_TEST_ASSERT(0 == cx_strcmp( |
235 CX_TEST_ASSERT(0 == cx_strcmp( |
| 210 cxJsonAsCxString(surrogatepair2), |
236 cxJsonAsCxString(surrogatepair2), |
| 211 CX_STR("test\xf0\x9f\xaf\xb1" "AA")) |
237 "test\xf0\x9f\xaf\xb1" "AA") |
| 212 ); |
238 ); |
| 213 |
239 |
| 214 CxJsonValue *mixed2 = cxJsonObjGet(obj, "mixed2"); |
240 CxJsonValue *mixed2 = cxJsonObjGet(obj, "mixed2"); |
| 215 char test[16]; |
241 char test[16]; |
| 216 strncpy(test, mixed2->value.string.ptr, 15); |
242 strncpy(test, mixed2->value.string.ptr, 15); |
| 217 CX_TEST_ASSERT(cxJsonIsString(mixed2)); |
243 CX_TEST_ASSERT(cxJsonIsString(mixed2)); |
| 218 CX_TEST_ASSERT(0 == cx_strcmp( |
244 CX_TEST_ASSERT(0 == cx_strcmp( |
| 219 cxJsonAsCxString(mixed2), |
245 cxJsonAsCxString(mixed2), |
| 220 CX_STR("123\xce\xa3\xf0\x9f\xaf\x85ß")) |
246 "123\xce\xa3\xf0\x9f\xaf\x85ß") |
| 221 ); |
247 ); |
| 222 |
248 |
| 223 cxJsonValueFree(obj); |
249 cxJsonValueFree(obj); |
| 224 } |
250 } |
| 225 cxJsonDestroy(&json); |
251 cxJsonDestroy(&json); |
| 229 CxJson json; |
255 CxJson json; |
| 230 cxJsonInit(&json, NULL); |
256 cxJsonInit(&json, NULL); |
| 231 CxJsonValue *obj; |
257 CxJsonValue *obj; |
| 232 CxJsonStatus result; |
258 CxJsonStatus result; |
| 233 CX_TEST_DO { |
259 CX_TEST_DO { |
| 234 cxJsonFill(&json, "\"too few \\u123 digits\""); |
260 cxJsonFill(&json, "\"too few digits \\u123\""); |
| 235 result = cxJsonNext(&json, &obj); |
261 result = cxJsonNext(&json, &obj); |
| 236 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
262 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
| 237 CX_TEST_ASSERT(cxJsonIsString(obj)); |
263 CX_TEST_ASSERT(cxJsonIsString(obj)); |
| 238 CX_TEST_ASSERT(0 == cx_strcmp( |
264 CX_TEST_ASSERT(0 == cx_strcmp( |
| 239 cxJsonAsCxString(obj), |
265 cxJsonAsCxString(obj), |
| 240 CX_STR("too few \\u123 digits") |
266 "too few digits \\u123" |
| 241 )); |
267 )); |
| 242 cxJsonValueFree(obj); |
268 cxJsonValueFree(obj); |
| 243 cxJsonFill(&json, "\"too many \\u00E456 digits\""); |
269 cxJsonFill(&json, "\"too many digits \\u00E456\""); |
| 244 result = cxJsonNext(&json, &obj); |
270 result = cxJsonNext(&json, &obj); |
| 245 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
271 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
| 246 CX_TEST_ASSERT(cxJsonIsString(obj)); |
272 CX_TEST_ASSERT(cxJsonIsString(obj)); |
| 247 CX_TEST_ASSERT(0 == cx_strcmp( |
273 CX_TEST_ASSERT(0 == cx_strcmp( |
| 248 cxJsonAsCxString(obj), |
274 cxJsonAsCxString(obj), |
| 249 CX_STR("too many ä56 digits") |
275 "too many digits ä56" |
| 250 )); |
276 )); |
| 251 cxJsonValueFree(obj); |
277 cxJsonValueFree(obj); |
| 252 cxJsonFill(&json, "\"only high \\uD800 surrogate\""); |
278 cxJsonFill(&json, "\"only high \\uD800 surrogate\""); |
| 253 result = cxJsonNext(&json, &obj); |
279 result = cxJsonNext(&json, &obj); |
| 254 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
280 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
| 255 CX_TEST_ASSERT(cxJsonIsString(obj)); |
281 CX_TEST_ASSERT(cxJsonIsString(obj)); |
| 256 CX_TEST_ASSERT(0 == cx_strcmp( |
282 CX_TEST_ASSERT(0 == cx_strcmp( |
| 257 cxJsonAsCxString(obj), |
283 cxJsonAsCxString(obj), |
| 258 CX_STR("only high \\uD800 surrogate") |
284 "only high \\uD800 surrogate" |
| 259 )); |
285 )); |
| 260 cxJsonValueFree(obj); |
286 cxJsonValueFree(obj); |
| 261 cxJsonFill(&json, "\"only low \\uDC00 surrogate\""); |
287 cxJsonFill(&json, "\"only low \\uDC00 surrogate\""); |
| 262 result = cxJsonNext(&json, &obj); |
288 result = cxJsonNext(&json, &obj); |
| 263 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
289 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
| 264 CX_TEST_ASSERT(cxJsonIsString(obj)); |
290 CX_TEST_ASSERT(cxJsonIsString(obj)); |
| 265 CX_TEST_ASSERT(0 == cx_strcmp( |
291 CX_TEST_ASSERT(0 == cx_strcmp( |
| 266 cxJsonAsCxString(obj), |
292 cxJsonAsCxString(obj), |
| 267 CX_STR("only low \\uDC00 surrogate") |
293 "only low \\uDC00 surrogate" |
| 268 )); |
294 )); |
| 269 cxJsonValueFree(obj); |
295 cxJsonValueFree(obj); |
| 270 cxJsonFill(&json, "\"two high \\uD800\\uD800 surrogates\""); |
296 cxJsonFill(&json, "\"two high \\uD800\\uD800 surrogates\""); |
| 271 result = cxJsonNext(&json, &obj); |
297 result = cxJsonNext(&json, &obj); |
| 272 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
298 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
| 273 CX_TEST_ASSERT(cxJsonIsString(obj)); |
299 CX_TEST_ASSERT(cxJsonIsString(obj)); |
| 274 CX_TEST_ASSERT(0 == cx_strcmp( |
300 CX_TEST_ASSERT(0 == cx_strcmp( |
| 275 cxJsonAsCxString(obj), |
301 cxJsonAsCxString(obj), |
| 276 CX_STR("two high \\uD800\\uD800 surrogates") |
302 "two high \\uD800\\uD800 surrogates" |
| 277 )); |
303 )); |
| 278 cxJsonValueFree(obj); |
304 cxJsonValueFree(obj); |
| 279 cxJsonFill(&json, "\"high plus bullshit \\uD800\\u567 foo\""); |
305 cxJsonFill(&json, "\"high plus bullshit \\uD800\\u567 foo\""); |
| 280 result = cxJsonNext(&json, &obj); |
306 result = cxJsonNext(&json, &obj); |
| 281 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
307 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
| 282 CX_TEST_ASSERT(cxJsonIsString(obj)); |
308 CX_TEST_ASSERT(cxJsonIsString(obj)); |
| 283 CX_TEST_ASSERT(0 == cx_strcmp( |
309 CX_TEST_ASSERT(0 == cx_strcmp( |
| 284 cxJsonAsCxString(obj), |
310 cxJsonAsCxString(obj), |
| 285 CX_STR("high plus bullshit \\uD800\\u567 foo") |
311 "high plus bullshit \\uD800\\u567 foo" |
| 286 )); |
312 )); |
| 287 cxJsonValueFree(obj); |
313 cxJsonValueFree(obj); |
| 288 } |
314 } |
| 289 cxJsonDestroy(&json); |
315 cxJsonDestroy(&json); |
| 290 } |
316 } |
| 400 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
426 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
| 401 } |
427 } |
| 402 cx_testing_allocator_destroy(&talloc); |
428 cx_testing_allocator_destroy(&talloc); |
| 403 } |
429 } |
| 404 |
430 |
| |
431 CX_TEST(test_json_parenthesis_mismatch) { |
| |
432 CxTestingAllocator talloc; |
| |
433 cx_testing_allocator_init(&talloc); |
| |
434 const CxAllocator *alloc = &talloc.base; |
| |
435 |
| |
436 CX_TEST_DO { |
| |
437 CxJson json; |
| |
438 cxJsonInit(&json, alloc); |
| |
439 |
| |
440 CxJsonStatus result; |
| |
441 CxJsonValue *obj; |
| |
442 |
| |
443 cxJsonFill(&json, "[0, 1, 2, 3}"); |
| |
444 result = cxJsonNext(&json, &obj); |
| |
445 CX_TEST_ASSERT(result == CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN); |
| |
446 |
| |
447 cxJsonReset(&json); |
| |
448 cxJsonFill(&json, "{\"test\": 42]"); |
| |
449 result = cxJsonNext(&json, &obj); |
| |
450 CX_TEST_ASSERT(result == CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN); |
| |
451 |
| |
452 cxJsonDestroy(&json); |
| |
453 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
| |
454 } |
| |
455 cx_testing_allocator_destroy(&talloc); |
| |
456 } |
| |
457 |
| |
458 CX_TEST(test_json_object_name_is_no_string) { |
| |
459 CxTestingAllocator talloc; |
| |
460 cx_testing_allocator_init(&talloc); |
| |
461 const CxAllocator *alloc = &talloc.base; |
| |
462 |
| |
463 CX_TEST_DO { |
| |
464 CxJson json; |
| |
465 cxJsonInit(&json, alloc); |
| |
466 |
| |
467 CxJsonStatus result; |
| |
468 CxJsonValue *obj; |
| |
469 |
| |
470 cxJsonFill(&json, "{42: \"test\"}"); |
| |
471 result = cxJsonNext(&json, &obj); |
| |
472 CX_TEST_ASSERT(result == CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN); |
| |
473 |
| |
474 cxJsonDestroy(&json); |
| |
475 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
| |
476 } |
| |
477 cx_testing_allocator_destroy(&talloc); |
| |
478 } |
| |
479 |
| 405 CX_TEST(test_json_subsequent_fill) { |
480 CX_TEST(test_json_subsequent_fill) { |
| 406 cxstring text = cx_str( |
481 cxstring text = cx_str( |
| 407 "{\"message\":\"success\" , \"__timestamp\":1729348561}"); |
482 "{\"message\":\"success\" , \"__timestamp\":1729348561}"); |
| 408 |
483 |
| 409 cxstring part1 = cx_strsubsl(text, 0, 25); |
484 cxstring part1 = cx_strsubsl(text, 0, 25); |
| 435 result = cxJsonNext(&json, &obj); |
510 result = cxJsonNext(&json, &obj); |
| 436 CX_TEST_ASSERT(result == CX_JSON_NO_DATA); |
511 CX_TEST_ASSERT(result == CX_JSON_NO_DATA); |
| 437 |
512 |
| 438 cxJsonDestroy(&json); |
513 cxJsonDestroy(&json); |
| 439 } |
514 } |
| |
515 } |
| |
516 |
| |
517 CX_TEST(test_json_no_fill) { |
| |
518 CxJson json; |
| |
519 cxJsonInit(&json, NULL); |
| |
520 CX_TEST_DO { |
| |
521 CxJsonValue *obj = NULL; |
| |
522 CxJsonStatus result = cxJsonNext(&json, &obj); |
| |
523 CX_TEST_ASSERT(result == CX_JSON_NULL_DATA); |
| |
524 CX_TEST_ASSERT(obj != NULL); |
| |
525 CX_TEST_ASSERT(obj->type == CX_JSON_NOTHING); |
| |
526 } |
| |
527 cxJsonDestroy(&json); |
| |
528 } |
| |
529 |
| |
530 CX_TEST(test_json_null_fill) { |
| |
531 CxJson json; |
| |
532 cxJsonInit(&json, NULL); |
| |
533 CX_TEST_DO { |
| |
534 CxJsonStatus result; |
| |
535 CxJsonValue *obj = NULL; |
| |
536 cxstring nullstr = cx_strn(NULL, 0); |
| |
537 cxJsonFill(&json, nullstr); |
| |
538 result = cxJsonNext(&json, &obj); |
| |
539 CX_TEST_ASSERT(result == CX_JSON_NO_DATA); |
| |
540 CX_TEST_ASSERT(obj != NULL); |
| |
541 CX_TEST_ASSERT(obj->type == CX_JSON_NOTHING); |
| |
542 obj = NULL; |
| |
543 |
| |
544 cxJsonFill(&json, "[0, 1"); |
| |
545 result = cxJsonNext(&json, &obj); |
| |
546 CX_TEST_ASSERT(result == CX_JSON_INCOMPLETE_DATA); |
| |
547 CX_TEST_ASSERT(obj != NULL); |
| |
548 CX_TEST_ASSERT(obj->type == CX_JSON_NOTHING); |
| |
549 obj = NULL; |
| |
550 |
| |
551 cxJsonFill(&json, nullstr); |
| |
552 result = cxJsonNext(&json, &obj); |
| |
553 CX_TEST_ASSERT(result == CX_JSON_INCOMPLETE_DATA); |
| |
554 CX_TEST_ASSERT(obj != NULL); |
| |
555 CX_TEST_ASSERT(obj->type == CX_JSON_NOTHING); |
| |
556 obj = NULL; |
| |
557 |
| |
558 cxJsonFill(&json, ", 2]"); |
| |
559 result = cxJsonNext(&json, &obj); |
| |
560 CX_TEST_ASSERT(result == CX_JSON_NO_ERROR); |
| |
561 CX_TEST_ASSERT(obj != NULL); |
| |
562 CX_TEST_ASSERT(cxJsonIsArray(obj)); |
| |
563 cxJsonValueFree(obj); |
| |
564 |
| |
565 cxJsonFill(&json, nullstr); |
| |
566 result = cxJsonNext(&json, &obj); |
| |
567 CX_TEST_ASSERT(result == CX_JSON_NO_DATA); |
| |
568 CX_TEST_ASSERT(obj != NULL); |
| |
569 CX_TEST_ASSERT(obj->type == CX_JSON_NOTHING); |
| |
570 } |
| |
571 cxJsonDestroy(&json); |
| 440 } |
572 } |
| 441 |
573 |
| 442 CX_TEST(test_json_object_error) { |
574 CX_TEST(test_json_object_error) { |
| 443 cxstring text0 = cx_str( |
575 cxstring text0 = cx_str( |
| 444 "{\n" |
576 "{\n" |
| 902 CX_TEST_ASSERT(cxJsonIsObject(obj)); |
1034 CX_TEST_ASSERT(cxJsonIsObject(obj)); |
| 903 CX_TEST_ASSERT(obj->allocator == allocator); |
1035 CX_TEST_ASSERT(obj->allocator == allocator); |
| 904 |
1036 |
| 905 // add the members |
1037 // add the members |
| 906 { |
1038 { |
| 907 cxJsonObjPutLiteral(obj, CX_STR("bool"), CX_JSON_FALSE); |
1039 cxJsonObjPutLiteral(obj, "bool", CX_JSON_FALSE); |
| 908 cxJsonObjPutInteger(obj, CX_STR("int"), 47); |
1040 cxJsonObjPutInteger(obj, "int", 47); |
| 909 CxJsonValue *strings = cxJsonObjPutArr(obj, CX_STR("strings")); |
1041 CxJsonValue *strings = cxJsonObjPutArr(obj, "strings"); |
| 910 CX_TEST_ASSERT(strings != NULL); |
1042 CX_TEST_ASSERT(strings != NULL); |
| 911 CX_TEST_ASSERT(cxJsonIsArray(strings)); |
1043 CX_TEST_ASSERT(cxJsonIsArray(strings)); |
| 912 const char* str[] = {"hello", "world"}; |
1044 const char* str[] = {"hello", "world"}; |
| 913 CX_TEST_ASSERT(0 == cxJsonArrAddStrings(strings, str, 2)); |
1045 CX_TEST_ASSERT(0 == cxJsonArrAddStrings(strings, str, 2)); |
| 914 |
1046 |
| 915 CxJsonValue *nested = cxJsonObjPutObj(obj, CX_STR("nested")); |
1047 CxJsonValue *nested = cxJsonObjPutObj(obj, "nested"); |
| 916 CX_TEST_ASSERT(nested != NULL); |
1048 CX_TEST_ASSERT(nested != NULL); |
| 917 CX_TEST_ASSERT(cxJsonIsObject(nested)); |
1049 CX_TEST_ASSERT(cxJsonIsObject(nested)); |
| 918 cxJsonObjPutCxString(nested, CX_STR("string"), CX_STR("test")); |
1050 cxJsonObjPutString(nested, "string", "test"); |
| 919 |
1051 |
| 920 cxJsonArrAddNumbers(cxJsonObjPutArr(nested, CX_STR("floats")), |
1052 cxJsonArrAddNumbers(cxJsonObjPutArr(nested, "floats"), |
| 921 (double[]){3.1415, 47.11, 8.15}, 3); |
1053 (double[]){3.1415, 47.11, 8.15}, 3); |
| 922 cxJsonArrAddIntegers(cxJsonObjPutArr(nested, CX_STR("ints")), |
1054 cxJsonArrAddIntegers(cxJsonObjPutArr(nested, "ints"), |
| 923 (int64_t[]){4, 8, 15, 16, 23, 42}, 6); |
1055 (int64_t[]){4, 8, 15, 16, 23, 42}, 6); |
| 924 cxJsonArrAddLiterals(cxJsonObjPutArr(nested, CX_STR("literals")), |
1056 cxJsonArrAddLiterals(cxJsonObjPutArr(nested, "literals"), |
| 925 (CxJsonLiteral[]){CX_JSON_TRUE, CX_JSON_NULL, CX_JSON_FALSE}, 3); |
1057 (CxJsonLiteral[]){CX_JSON_TRUE, CX_JSON_NULL, CX_JSON_FALSE}, 3); |
| 926 } |
1058 } |
| 927 |
1059 |
| 928 // verify the contents |
1060 // verify the contents |
| 929 { |
1061 { |
| 930 CX_TEST_ASSERT(cxJsonIsFalse(cxJsonObjGet(obj, "bool"))); |
1062 CX_TEST_ASSERT(cxJsonIsFalse(cxJsonObjGet(obj, "bool"))); |
| 931 CX_TEST_ASSERT(47 == cxJsonAsInteger(cxJsonObjGet(obj, "int"))); |
1063 CX_TEST_ASSERT(47 == cxJsonAsInteger(cxJsonObjGet(obj, "int"))); |
| 932 CxJsonValue *strings = cxJsonObjGet(obj, "strings"); |
1064 CxJsonValue *strings = cxJsonObjGet(obj, "strings"); |
| 933 CX_TEST_ASSERT(cxJsonIsArray(strings)); |
1065 CX_TEST_ASSERT(cxJsonIsArray(strings)); |
| 934 CX_TEST_ASSERT(2 == cxJsonArrSize(strings)); |
1066 CX_TEST_ASSERT(2 == cxJsonArrSize(strings)); |
| 935 CX_TEST_ASSERT(0 == cx_strcmp(CX_STR("hello"), cxJsonAsCxString(cxJsonArrGet(strings, 0)))); |
1067 CX_TEST_ASSERT(0 == cx_strcmp("hello", cxJsonAsString(cxJsonArrGet(strings, 0)))); |
| 936 CX_TEST_ASSERT(0 == cx_strcmp(CX_STR("world"), cxJsonAsCxString(cxJsonArrGet(strings, 1)))); |
1068 CX_TEST_ASSERT(0 == cx_strcmp("world", cxJsonAsString(cxJsonArrGet(strings, 1)))); |
| 937 |
1069 |
| 938 CxJsonValue *nested = cxJsonObjGet(obj, "nested"); |
1070 CxJsonValue *nested = cxJsonObjGet(obj, "nested"); |
| 939 CX_TEST_ASSERT(cxJsonIsObject(nested)); |
1071 CX_TEST_ASSERT(cxJsonIsObject(nested)); |
| 940 CX_TEST_ASSERT(0 == strcmp("test", cxJsonAsString(cxJsonObjGet(nested, "string")))); |
1072 CX_TEST_ASSERT(0 == strcmp("test", cxJsonAsString(cxJsonObjGet(nested, "string")))); |
| 941 CxJsonValue *floats = cxJsonObjGet(nested, "floats"); |
1073 CxJsonValue *floats = cxJsonObjGet(nested, "floats"); |
| 966 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
1098 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
| 967 } |
1099 } |
| 968 cx_testing_allocator_destroy(&talloc); |
1100 cx_testing_allocator_destroy(&talloc); |
| 969 } |
1101 } |
| 970 |
1102 |
| |
1103 CX_TEST(test_json_overwrite_value) { |
| |
1104 CxTestingAllocator talloc; |
| |
1105 cx_testing_allocator_init(&talloc); |
| |
1106 CxAllocator *allocator = &talloc.base; |
| |
1107 CX_TEST_DO { |
| |
1108 CxJsonValue *obj = cxJsonCreateObj(allocator); |
| |
1109 |
| |
1110 // put some values |
| |
1111 cxJsonObjPutInteger(obj, "test1", 1); |
| |
1112 cxJsonObjPutInteger(obj, "test2", 2); |
| |
1113 cxJsonObjPutInteger(obj, "test3", 3); |
| |
1114 |
| |
1115 // overwrite test2 |
| |
1116 cxJsonObjPutInteger(obj, "test2", 0); |
| |
1117 |
| |
1118 // verify the values |
| |
1119 CxIterator iter = cxJsonObjIter(obj); |
| |
1120 bool found[5] = {0}; |
| |
1121 cx_foreach(CxJsonObjValue *, ov, iter) { |
| |
1122 CxJsonValue *v = ov->value; |
| |
1123 CX_TEST_ASSERT(cxJsonIsInteger(v)); |
| |
1124 int64_t i = cxJsonAsInteger(v); |
| |
1125 CX_TEST_ASSERT(i >= 0 && i <= 4); |
| |
1126 found[i] = true; |
| |
1127 } |
| |
1128 CX_TEST_ASSERT(found[0]); |
| |
1129 CX_TEST_ASSERT(found[1]); |
| |
1130 CX_TEST_ASSERT(!found[2]); |
| |
1131 CX_TEST_ASSERT(found[3]); |
| |
1132 CX_TEST_ASSERT(!found[4]); |
| |
1133 |
| |
1134 // destroy the value and verify the allocations |
| |
1135 cxJsonValueFree(obj); |
| |
1136 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
| |
1137 } |
| |
1138 cx_testing_allocator_destroy(&talloc); |
| |
1139 } |
| 971 |
1140 |
| 972 CX_TEST_SUBROUTINE(test_json_write_sub, |
1141 CX_TEST_SUBROUTINE(test_json_write_sub, |
| 973 const CxAllocator *allocator, |
1142 const CxAllocator *allocator, |
| 974 cxstring expected, |
1143 cxstring expected, |
| 975 const CxJsonWriter *writer |
1144 const CxJsonWriter *writer |
| 976 ) { |
1145 ) { |
| 977 // create the value |
1146 // create the value |
| 978 CxJsonValue *obj = cxJsonCreateObj(allocator); |
1147 CxJsonValue *obj = cxJsonCreateObj(allocator); |
| 979 cxJsonObjPutLiteral(obj, CX_STR("bool"), CX_JSON_FALSE); |
1148 cxJsonObjPutLiteral(obj, "bool", CX_JSON_FALSE); |
| 980 cxJsonObjPutNumber(obj, CX_STR("int"), 47); // purposely use PutNumber to put an int |
1149 cxJsonObjPutNumber(obj, "int", 47); // purposely use PutNumber to put an int |
| 981 CxJsonValue *strings = cxJsonObjPutArr(obj, CX_STR("strings")); |
1150 CxJsonValue *strings = cxJsonObjPutArr(obj, "strings"); |
| 982 cxJsonArrAddCxStrings(strings, (cxstring[]) {CX_STR("hello"), CX_STR("world")}, 2); |
1151 cxJsonArrAddCxStrings(strings, (cxstring[]) {CX_STR("hello"), CX_STR("world")}, 2); |
| 983 CxJsonValue *nested = cxJsonObjPutObj(obj, CX_STR("nested")); |
1152 CxJsonValue *nested = cxJsonObjPutObj(obj, "nested"); |
| 984 CxJsonValue *objects = cxJsonObjPutArr(nested, CX_STR("objects")); |
1153 CxJsonValue *objects = cxJsonObjPutArr(nested, "objects"); |
| 985 CxJsonValue *obj_in_arr[2] = {cxJsonCreateObj(allocator), cxJsonCreateObj(allocator)}; |
1154 CxJsonValue *obj_in_arr[2] = {cxJsonCreateObj(allocator), cxJsonCreateObj(allocator)}; |
| 986 cxJsonObjPutInteger(obj_in_arr[0], CX_STR("name1"), 1); |
1155 cxJsonObjPutInteger(obj_in_arr[0], "name1", 1); |
| 987 cxJsonObjPutInteger(obj_in_arr[0], CX_STR("name2"), 3); |
1156 cxJsonObjPutInteger(obj_in_arr[0], "name2", 3); |
| 988 cxJsonObjPutInteger(obj_in_arr[1], CX_STR("name2"), 7); |
1157 cxJsonObjPutInteger(obj_in_arr[1], "name2", 7); |
| 989 cxJsonObjPutInteger(obj_in_arr[1], CX_STR("name1"), 3); |
1158 cxJsonObjPutInteger(obj_in_arr[1], "name1", 3); |
| 990 cxJsonArrAddValues(objects, obj_in_arr, 2); |
1159 cxJsonArrAddValues(objects, obj_in_arr, 2); |
| 991 cxJsonArrAddNumbers(cxJsonObjPutArr(nested, CX_STR("floats")), |
1160 cxJsonArrAddNumbers(cxJsonObjPutArr(nested, "floats"), |
| 992 (double[]){3.1415, 47.11, 8.15}, 3); |
1161 (double[]){3.1415, 47.11, 8.15}, 3); |
| 993 cxJsonArrAddLiterals(cxJsonObjPutArr(nested, CX_STR("literals")), |
1162 cxJsonArrAddLiterals(cxJsonObjPutArr(nested, "literals"), |
| 994 (CxJsonLiteral[]){CX_JSON_TRUE, CX_JSON_NULL, CX_JSON_FALSE}, 3); |
1163 (CxJsonLiteral[]){CX_JSON_TRUE, CX_JSON_NULL, CX_JSON_FALSE}, 3); |
| 995 CxJsonValue *ints = cxJsonObjPutArr(nested, CX_STR("ints")); |
1164 CxJsonValue *ints = cxJsonObjPutArr(nested, "ints"); |
| 996 cxJsonArrAddIntegers(ints, (int64_t[]){4, 8, 15}, 3); |
1165 cxJsonArrAddIntegers(ints, (int64_t[]){4, 8, 15}, 3); |
| 997 CxJsonValue *nested_array = cxJsonCreateArr(allocator); |
1166 CxJsonValue *nested_array = cxJsonCreateArr(allocator); |
| 998 cxJsonArrAddValues(ints, &nested_array, 1); |
1167 cxJsonArrAddValues(ints, &nested_array, 1); |
| 999 cxJsonArrAddIntegers(nested_array, (int64_t[]){16, 23}, 2); |
1168 cxJsonArrAddIntegers(nested_array, (int64_t[]){16, 23}, 2); |
| 1000 cxJsonArrAddIntegers(ints, (int64_t[]){42}, 1); |
1169 cxJsonArrAddIntegers(ints, (int64_t[]){42}, 1); |
| 1039 "}" |
1208 "}" |
| 1040 ); |
1209 ); |
| 1041 |
1210 |
| 1042 CxJsonWriter writer = cxJsonWriterCompact(); |
1211 CxJsonWriter writer = cxJsonWriterCompact(); |
| 1043 CX_TEST_CALL_SUBROUTINE(test_json_write_sub, allocator, expected, &writer); |
1212 CX_TEST_CALL_SUBROUTINE(test_json_write_sub, allocator, expected, &writer); |
| |
1213 // try again, but this time with implicitly defaulted writer |
| |
1214 CX_TEST_CALL_SUBROUTINE(test_json_write_sub, allocator, expected, NULL); |
| 1044 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
1215 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
| 1045 } |
1216 } |
| 1046 cx_testing_allocator_destroy(&talloc); |
1217 cx_testing_allocator_destroy(&talloc); |
| 1047 } |
1218 } |
| 1048 |
1219 |
| 1049 CX_TEST(test_json_write_pretty_default_spaces) { |
1220 CX_TEST(test_json_write_pretty_default_spaces) { |
| 1050 CxTestingAllocator talloc; |
1221 CxTestingAllocator talloc; |
| 1051 cx_testing_allocator_init(&talloc); |
1222 cx_testing_allocator_init(&talloc); |
| 1052 CxAllocator *allocator = &talloc.base; |
1223 CxAllocator *allocator = &talloc.base; |
| 1053 CX_TEST_DO { |
1224 CX_TEST_DO { |
| 1054 cxstring expected = CX_STR( |
1225 cxstring expected = cx_str( |
| 1055 "{\n" |
1226 "{\n" |
| 1056 " \"bool\": false,\n" |
1227 " \"bool\": false,\n" |
| 1057 " \"int\": 47,\n" |
1228 " \"int\": 47,\n" |
| 1058 " \"nested\": {\n" |
1229 " \"nested\": {\n" |
| 1059 " \"floats\": [3.1415, 47.11, 8.15],\n" |
1230 " \"floats\": [3.1415, 47.11, 8.15],\n" |
| 1140 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
1311 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
| 1141 } |
1312 } |
| 1142 cx_testing_allocator_destroy(&talloc); |
1313 cx_testing_allocator_destroy(&talloc); |
| 1143 } |
1314 } |
| 1144 |
1315 |
| |
1316 CX_TEST(test_json_write_pretty_deep_nesting) { |
| |
1317 CxTestingAllocator talloc; |
| |
1318 cx_testing_allocator_init(&talloc); |
| |
1319 CxAllocator *allocator = &talloc.base; |
| |
1320 CX_TEST_DO { |
| |
1321 cxstring expected = cx_str( |
| |
1322 "{\n" |
| |
1323 " \"test\": {\n" |
| |
1324 " \"test\": {\n" |
| |
1325 " \"test\": {\n" |
| |
1326 " \"test\": {\n" |
| |
1327 " \"test\": {\n" |
| |
1328 " \"test\": 47\n" |
| |
1329 " }\n" |
| |
1330 " }\n" |
| |
1331 " }\n" |
| |
1332 " }\n" |
| |
1333 " }\n" |
| |
1334 "}" |
| |
1335 ); |
| |
1336 |
| |
1337 CxJsonValue *obj = cxJsonCreateObj(allocator); |
| |
1338 CxJsonValue *test = obj; |
| |
1339 for (unsigned i = 0 ; i < 5 ; i++) { |
| |
1340 test = cxJsonObjPutObj(test, "test"); |
| |
1341 } |
| |
1342 cxJsonObjPutInteger(test, "test", 47); |
| |
1343 |
| |
1344 CxJsonWriter writer = cxJsonWriterPretty(true); |
| |
1345 writer.indent = 8; |
| |
1346 CxBuffer buf; |
| |
1347 cxBufferInit(&buf, NULL, 512, NULL, CX_BUFFER_DEFAULT); |
| |
1348 int result = cxJsonWrite(&buf, obj, cxBufferWriteFunc, &writer); |
| |
1349 cxBufferTerminate(&buf); // makes debugging easier |
| |
1350 CX_TEST_ASSERT(result == 0); |
| |
1351 |
| |
1352 // compare the string |
| |
1353 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), expected)); |
| |
1354 |
| |
1355 // destroy everything |
| |
1356 cxBufferDestroy(&buf); |
| |
1357 cxJsonValueFree(obj); |
| |
1358 |
| |
1359 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); |
| |
1360 } |
| |
1361 cx_testing_allocator_destroy(&talloc); |
| |
1362 } |
| |
1363 |
| 1145 CX_TEST(test_json_write_frac_max_digits) { |
1364 CX_TEST(test_json_write_frac_max_digits) { |
| 1146 CxJsonValue* num = cxJsonCreateNumber(NULL, 3.141592653589793); |
1365 CxJsonValue* num = cxJsonCreateNumber(NULL, 3.141592653589793); |
| 1147 CxJsonWriter writer = cxJsonWriterCompact(); |
1366 CxJsonWriter writer = cxJsonWriterCompact(); |
| 1148 CxBuffer buf; |
1367 CxBuffer buf; |
| 1149 cxBufferInit(&buf, NULL, 32, NULL, 0); |
1368 cxBufferInit(&buf, NULL, 32, NULL, 0); |
| 1150 CX_TEST_DO { |
1369 CX_TEST_DO { |
| 1151 // test default settings (6 digits) |
1370 // test default settings (6 digits) |
| 1152 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
1371 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
| 1153 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), CX_STR("3.141592"))); |
1372 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), "3.141592")); |
| 1154 |
1373 |
| 1155 // test too many digits |
1374 // test too many digits |
| 1156 cxBufferReset(&buf); |
1375 cxBufferReset(&buf); |
| 1157 writer.frac_max_digits = 200; |
1376 writer.frac_max_digits = 200; |
| 1158 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
1377 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
| 1159 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), CX_STR("3.141592653589793"))); |
1378 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), "3.141592653589793")); |
| 1160 |
1379 |
| 1161 // test 0 digits |
1380 // test 0 digits |
| 1162 cxBufferReset(&buf); |
1381 cxBufferReset(&buf); |
| 1163 writer.frac_max_digits = 0; |
1382 writer.frac_max_digits = 0; |
| 1164 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
1383 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
| 1165 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), CX_STR("3"))); |
1384 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), "3")); |
| 1166 |
1385 |
| 1167 // test 2 digits |
1386 // test 2 digits |
| 1168 cxBufferReset(&buf); |
1387 cxBufferReset(&buf); |
| 1169 writer.frac_max_digits = 2; |
1388 writer.frac_max_digits = 2; |
| 1170 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
1389 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
| 1171 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), CX_STR("3.14"))); |
1390 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), "3.14")); |
| 1172 |
1391 |
| 1173 // test 3 digits |
1392 // test 3 digits |
| 1174 cxBufferReset(&buf); |
1393 cxBufferReset(&buf); |
| 1175 writer.frac_max_digits = 3; |
1394 writer.frac_max_digits = 3; |
| 1176 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
1395 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
| 1177 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), CX_STR("3.141"))); |
1396 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), "3.141")); |
| 1178 |
1397 |
| 1179 // test 6 digits, but two are left of the decimal point |
1398 // test 6 digits, but two are left of the decimal point |
| 1180 num->value.number = 47.110815; |
1399 num->value.number = 47.110815; |
| 1181 cxBufferReset(&buf); |
1400 cxBufferReset(&buf); |
| 1182 writer.frac_max_digits = 6; |
1401 writer.frac_max_digits = 6; |
| 1183 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
1402 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
| 1184 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), CX_STR("47.110815"))); |
1403 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), "47.110815")); |
| 1185 |
1404 |
| 1186 // test 4 digits with exponent |
1405 // test 4 digits with exponent |
| 1187 num->value.number = 5.11223344e23; |
1406 num->value.number = 5.11223344e23; |
| 1188 cxBufferReset(&buf); |
1407 cxBufferReset(&buf); |
| 1189 writer.frac_max_digits = 4; |
1408 writer.frac_max_digits = 4; |
| 1190 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
1409 cxJsonWrite(&buf, num, cxBufferWriteFunc, &writer); |
| 1191 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), CX_STR("5.1122e+23"))); |
1410 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), "5.1122e+23")); |
| 1192 } |
1411 } |
| 1193 cxBufferDestroy(&buf); |
1412 cxBufferDestroy(&buf); |
| 1194 cxJsonValueFree(num); |
1413 cxJsonValueFree(num); |
| 1195 } |
1414 } |
| 1196 |
1415 |
| 1214 CxBuffer buf; |
1433 CxBuffer buf; |
| 1215 cxBufferInit(&buf, NULL, 128, NULL, 0); |
1434 cxBufferInit(&buf, NULL, 128, NULL, 0); |
| 1216 CX_TEST_DO { |
1435 CX_TEST_DO { |
| 1217 cxJsonWrite(&buf, str, cxBufferWriteFunc, &writer); |
1436 cxJsonWrite(&buf, str, cxBufferWriteFunc, &writer); |
| 1218 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), |
1437 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), |
| 1219 CX_STR("\"hello\\twörld\\r\\nthis is\\\\a \\\"string\\\"\\b in \\u0007 string\\f\""))); |
1438 "\"hello\\twörld\\r\\nthis is\\\\a \\\"string\\\"\\b in \\u0007 string\\f\"")); |
| 1220 } |
1439 } |
| 1221 cxBufferDestroy(&buf); |
1440 cxBufferDestroy(&buf); |
| 1222 cxJsonValueFree(str); |
1441 cxJsonValueFree(str); |
| 1223 } |
1442 } |
| 1224 |
1443 |
| 1225 CX_TEST(test_json_write_name_escape) { |
1444 CX_TEST(test_json_write_name_escape) { |
| 1226 CxJsonValue* obj = cxJsonCreateObj(NULL); |
1445 CxJsonValue* obj = cxJsonCreateObj(NULL); |
| 1227 cxJsonObjPutLiteral(obj, |
1446 cxJsonObjPutLiteral(obj, |
| 1228 CX_STR("hello\twörld\r\nthis is\\a \"string\"\b in \a string\f"), CX_JSON_TRUE); |
1447 "hello\twörld\r\nthis is\\a \"string\"\b in \a string\f", CX_JSON_TRUE); |
| 1229 CxJsonWriter writer = cxJsonWriterCompact(); |
1448 CxJsonWriter writer = cxJsonWriterCompact(); |
| 1230 CxBuffer buf; |
1449 CxBuffer buf; |
| 1231 cxBufferInit(&buf, NULL, 128, NULL, 0); |
1450 cxBufferInit(&buf, NULL, 128, NULL, 0); |
| 1232 CX_TEST_DO { |
1451 CX_TEST_DO { |
| 1233 cxJsonWrite(&buf, obj, cxBufferWriteFunc, &writer); |
1452 cxJsonWrite(&buf, obj, cxBufferWriteFunc, &writer); |
| 1234 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), |
1453 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), |
| 1235 CX_STR("{\"hello\\twörld\\r\\nthis is\\\\a \\\"string\\\"\\b in \\u0007 string\\f\":true}"))); |
1454 "{\"hello\\twörld\\r\\nthis is\\\\a \\\"string\\\"\\b in \\u0007 string\\f\":true}")); |
| 1236 } |
1455 } |
| 1237 cxBufferDestroy(&buf); |
1456 cxBufferDestroy(&buf); |
| 1238 cxJsonValueFree(obj); |
1457 cxJsonValueFree(obj); |
| 1239 } |
1458 } |
| 1240 |
1459 |
| 1244 CxBuffer buf; |
1463 CxBuffer buf; |
| 1245 cxBufferInit(&buf, NULL, 16, NULL, 0); |
1464 cxBufferInit(&buf, NULL, 16, NULL, 0); |
| 1246 CX_TEST_DO { |
1465 CX_TEST_DO { |
| 1247 // default: do not escape |
1466 // default: do not escape |
| 1248 cxJsonWrite(&buf, str, cxBufferWriteFunc, &writer); |
1467 cxJsonWrite(&buf, str, cxBufferWriteFunc, &writer); |
| 1249 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), CX_STR("\"test/solidus\""))); |
1468 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), "\"test/solidus\"")); |
| 1250 |
1469 |
| 1251 // enable escaping |
1470 // enable escaping |
| 1252 writer.escape_slash = true; |
1471 writer.escape_slash = true; |
| 1253 cxBufferReset(&buf); |
1472 cxBufferReset(&buf); |
| 1254 cxJsonWrite(&buf, str, cxBufferWriteFunc, &writer); |
1473 cxJsonWrite(&buf, str, cxBufferWriteFunc, &writer); |
| 1255 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), CX_STR("\"test\\/solidus\""))); |
1474 CX_TEST_ASSERT(0 == cx_strcmp(cx_strn(buf.space, buf.size), "\"test\\/solidus\"")); |
| 1256 } |
1475 } |
| 1257 cxBufferDestroy(&buf); |
1476 cxBufferDestroy(&buf); |
| 1258 cxJsonValueFree(str); |
1477 cxJsonValueFree(str); |
| 1259 } |
1478 } |
| 1260 |
1479 |
| |
1480 CX_TEST(test_json_write_nothing) { |
| |
1481 CxBuffer buf; |
| |
1482 cxBufferInit(&buf, NULL, 16, NULL, 0); |
| |
1483 CX_TEST_DO { |
| |
1484 CxJsonValue nothing; |
| |
1485 nothing.type = CX_JSON_NOTHING; |
| |
1486 cxJsonWrite(&buf, ¬hing, cxBufferWriteFunc, NULL); |
| |
1487 CX_TEST_ASSERT(buf.size == 0); |
| |
1488 } |
| |
1489 cxBufferDestroy(&buf); |
| |
1490 } |
| |
1491 |
| 1261 CxTestSuite *cx_test_suite_json(void) { |
1492 CxTestSuite *cx_test_suite_json(void) { |
| 1262 CxTestSuite *suite = cx_test_suite_new("json"); |
1493 CxTestSuite *suite = cx_test_suite_new("json"); |
| 1263 |
1494 |
| 1264 cx_test_register(suite, test_json_init_default); |
1495 cx_test_register(suite, test_json_init_default); |
| 1265 cx_test_register(suite, test_json_simple_object); |
1496 cx_test_register(suite, test_json_simple_object); |
| |
1497 cx_test_register(suite, test_json_large_object); |
| 1266 cx_test_register(suite, test_json_escaped_strings); |
1498 cx_test_register(suite, test_json_escaped_strings); |
| 1267 cx_test_register(suite, test_json_escaped_unicode_strings); |
1499 cx_test_register(suite, test_json_escaped_unicode_strings); |
| 1268 cx_test_register(suite, test_json_escaped_unicode_malformed); |
1500 cx_test_register(suite, test_json_escaped_unicode_malformed); |
| 1269 cx_test_register(suite, test_json_escaped_end_of_string); |
1501 cx_test_register(suite, test_json_escaped_end_of_string); |
| 1270 cx_test_register(suite, test_json_object_incomplete_token); |
1502 cx_test_register(suite, test_json_object_incomplete_token); |
| |
1503 cx_test_register(suite, test_json_parenthesis_mismatch); |
| |
1504 cx_test_register(suite, test_json_object_name_is_no_string); |
| 1271 cx_test_register(suite, test_json_token_wrongly_completed); |
1505 cx_test_register(suite, test_json_token_wrongly_completed); |
| 1272 cx_test_register(suite, test_json_object_error); |
1506 cx_test_register(suite, test_json_object_error); |
| 1273 cx_test_register(suite, test_json_object_remove_member); |
1507 cx_test_register(suite, test_json_object_remove_member); |
| 1274 cx_test_register(suite, test_json_subsequent_fill); |
1508 cx_test_register(suite, test_json_subsequent_fill); |
| |
1509 cx_test_register(suite, test_json_no_fill); |
| |
1510 cx_test_register(suite, test_json_null_fill); |
| 1275 cx_test_register(suite, test_json_large_nesting_depth); |
1511 cx_test_register(suite, test_json_large_nesting_depth); |
| 1276 cx_test_register(suite, test_json_number); |
1512 cx_test_register(suite, test_json_number); |
| 1277 cx_test_register(suite, test_json_number_format_errors); |
1513 cx_test_register(suite, test_json_number_format_errors); |
| 1278 cx_test_register(suite, test_json_multiple_values); |
1514 cx_test_register(suite, test_json_multiple_values); |
| 1279 cx_test_register(suite, test_json_array); |
1515 cx_test_register(suite, test_json_array); |
| 1280 cx_test_register(suite, test_json_array_iterator); |
1516 cx_test_register(suite, test_json_array_iterator); |
| 1281 cx_test_register(suite, test_json_allocator); |
1517 cx_test_register(suite, test_json_allocator); |
| 1282 cx_test_register(suite, test_json_allocator_parse_error); |
1518 cx_test_register(suite, test_json_allocator_parse_error); |
| 1283 cx_test_register(suite, test_json_create_value); |
1519 cx_test_register(suite, test_json_create_value); |
| |
1520 cx_test_register(suite, test_json_overwrite_value); |
| 1284 cx_test_register(suite, test_json_write_default_format); |
1521 cx_test_register(suite, test_json_write_default_format); |
| 1285 cx_test_register(suite, test_json_write_pretty_default_spaces); |
1522 cx_test_register(suite, test_json_write_pretty_default_spaces); |
| 1286 cx_test_register(suite, test_json_write_pretty_default_tabs); |
1523 cx_test_register(suite, test_json_write_pretty_default_tabs); |
| 1287 cx_test_register(suite, test_json_write_pretty_preserve_order); |
1524 cx_test_register(suite, test_json_write_pretty_preserve_order); |
| |
1525 cx_test_register(suite, test_json_write_pretty_deep_nesting); |
| 1288 cx_test_register(suite, test_json_write_frac_max_digits); |
1526 cx_test_register(suite, test_json_write_frac_max_digits); |
| 1289 cx_test_register(suite, test_json_write_string_escape); |
1527 cx_test_register(suite, test_json_write_string_escape); |
| 1290 cx_test_register(suite, test_json_write_name_escape); |
1528 cx_test_register(suite, test_json_write_name_escape); |
| 1291 cx_test_register(suite, test_json_write_solidus); |
1529 cx_test_register(suite, test_json_write_solidus); |
| |
1530 cx_test_register(suite, test_json_write_nothing); |
| 1292 |
1531 |
| 1293 return suite; |
1532 return suite; |
| 1294 } |
1533 } |
| 1295 |
1534 |