Sun, 14 Dec 2025 11:05:03 +0100
add json clone tests, obj tests still dysfunctional - relates to #785
| src/json.c | file | annotate | diff | comparison | revisions | |
| tests/test_json.c | file | annotate | diff | comparison | revisions |
--- a/src/json.c Sat Dec 13 20:47:07 2025 +0100 +++ b/src/json.c Sun Dec 14 11:05:03 2025 +0100 @@ -1543,7 +1543,7 @@ case CX_JSON_STRING: return_value(cxJsonCreateString(allocator, source->string)); case CX_JSON_INTEGER: - return_value(cxJsonCreateNumber(allocator, source->integer)); + return_value(cxJsonCreateInteger(allocator, source->integer)); case CX_JSON_NUMBER: return_value(cxJsonCreateNumber(allocator, source->number)); case CX_JSON_LITERAL:
--- a/tests/test_json.c Sat Dec 13 20:47:07 2025 +0100 +++ b/tests/test_json.c Sun Dec 14 11:05:03 2025 +0100 @@ -1444,6 +1444,145 @@ } } +CX_TEST(test_json_clone_primitives) { + CxJsonValue *a[14]; + a[0] = cxJsonCreateLiteral(NULL, CX_JSON_NULL); + a[1] = cxJsonCreateLiteral(NULL, CX_JSON_TRUE); + a[2] = cxJsonCreateLiteral(NULL, CX_JSON_FALSE); + a[3] = cxJsonCreateInteger(NULL, 1234); + a[4] = cxJsonCreateInteger(NULL, 5432); + a[5] = cxJsonCreateInteger(NULL, -10); + a[6] = cxJsonCreateInteger(NULL, 0); + a[7] = cxJsonCreateNumber(NULL, 0.0f); + a[8] = cxJsonCreateNumber(NULL, 13.37f); + a[9] = cxJsonCreateNumber(NULL, -123.456f); + a[10] = cxJsonCreateNumber(NULL, 1234.0f); + a[11] = cxJsonCreateNumber(NULL, -10.3f); + a[12] = cxJsonCreateString(NULL, ""); + a[13] = cxJsonCreateString(NULL, "test"); + + CX_TEST_DO { + CxJsonValue *n = cxJsonClone(NULL, NULL); + CX_TEST_ASSERT(n != NULL); + CX_TEST_ASSERT(n->type == CX_JSON_NOTHING); + + for(int i=0;i<14;i++) { + // make sure the test setup is not broken + CX_TEST_ASSERT(a[i]->type != CX_JSON_NOTHING); + + CxJsonValue *b = cxJsonClone(a[i], NULL); + CX_TEST_ASSERT(b != NULL); + CX_TEST_ASSERT(a[i]->type == b->type); + CX_TEST_ASSERT(cxJsonCompare(a[i], b) == 0); + + // alternative comparison using cxJsonToString + cxmutstr aStr = cxJsonToString(a[i], NULL); + cxmutstr bStr = cxJsonToString(b, NULL); + CX_TEST_ASSERT(cx_strcmp(aStr, bStr) == 0); + cxFree(cxDefaultAllocator, aStr.ptr); + cxFree(cxDefaultAllocator, bStr.ptr); + + cxJsonValueFree(b); + } + + CxJsonValue *nan1 = cxJsonCreateNumber(NULL, NAN); + CxJsonValue *nan2 = cxJsonClone(nan1, NULL); + CX_TEST_ASSERT(nan2 != NULL); + CX_TEST_ASSERT(nan2->type == CX_JSON_NUMBER); + CX_TEST_ASSERT(isnan(nan2->number)); + + cxJsonValueFree(nan1); + cxJsonValueFree(nan2); + } + + for(int i=0;i<14;i++) { + cxJsonValueFree(a[i]); + } +} + +#ifndef TEST_CLONE_OBJECTS_LARGE_OBJ +#define TEST_CLONE_OBJECTS_LARGE_OBJ 100 +#endif +#ifndef TEST_CLONE_OBJECTS_LARGE_ARR +#define TEST_CLONE_OBJECTS_LARGE_ARR 200 +#endif +CX_TEST(test_json_clone_objects) { + CxJsonValue *a[10]; + + cxJsonFromString(NULL, "{}", &a[0]); + cxJsonFromString(NULL, "{ \"key\":\"value\" }", &a[1]); + cxJsonFromString(NULL, "{ \"abc\": {} }", &a[2]); + cxJsonFromString(NULL, "{ \"abc\": [ false ] }", &a[3]); + cxJsonFromString(NULL, "{ \"a4\": { \"x1\": 123, \"x2\": 456 } }", &a[4]); + cxJsonFromString(NULL, "{ \"a5\": [ true, false, null ] }", &a[5]); + cxJsonFromString(NULL, "{ \"a5\": [ true, false, null, {} ] }", &a[6]); + cxJsonFromString(NULL, "{ \"string\": \"hello\", \"int\": 12, \"literal\":true }", &a[7]); + cxJsonFromString(NULL, + "{ \"x0\": {\n" + " \"x1\": {\n" + " \"x2\": {\n" + " \"x3\": {\n" + " \"x4\": [\n" + " 1, 2, [3, [4, [[[{\"x5\":6}]]]]]\n" + " ]\n" + " }\n" + " }\n" + " }\n" + " }\n" + "}", + &a[8]); + a[9] = cxJsonCreateObj(NULL); + + // fill the very large object (a[9]) + for(int i=0;i<TEST_CLONE_OBJECTS_LARGE_OBJ;i++) { + char buf[32]; + snprintf(buf, 32, "int%d", i); + cxJsonObjPutInteger(a[9], buf, i); + + + CxJsonValue *arr = cxJsonCreateArr(NULL); + int64_t *ints = calloc(TEST_CLONE_OBJECTS_LARGE_ARR, sizeof(int64_t)); + for(int n=0;n<TEST_CLONE_OBJECTS_LARGE_ARR;n++) { + ints[i] = n; + } + cxJsonArrAddIntegers(arr, ints, TEST_CLONE_OBJECTS_LARGE_ARR); + free(ints); + cxJsonObjPut(a[9], "array", arr); + } + + CX_TEST_DO { + // TODO: only the first test works yet, change i<1 to i<10 for all tests + for(int i=0;i<1;i++) { + CX_TEST_ASSERT(cxJsonIsObject(a[i])); + + CxJsonValue *b = cxJsonClone(a[i], NULL); + + CX_TEST_ASSERT(b != NULL); + CX_TEST_ASSERT(b->type == a[i]->type); + CX_TEST_ASSERT(cxJsonCompare(a[i], b) == 0); + + // TODO: cxJsonToString(b, NULL) segfaults + //cxmutstr a_str = cxJsonToString(a[i], NULL); + //cxmutstr b_str = cxJsonToString(b, NULL); + //CX_TEST_ASSERT(cx_strcmp(a_str, b_str) == 0); + + cxJsonValueFree(b); + } + } + + for(int i=0;i<10;i++) { + cxJsonValueFree(a[i]); + } +} + +CX_TEST(test_json_clone_arrays) { + + CX_TEST_DO { + + } +} + + static CxJsonValue *test_json_write_create_test_object(const CxAllocator *allocator) { CxJsonValue *obj = cxJsonCreateObj(allocator); @@ -1880,6 +2019,9 @@ cx_test_register(suite, test_json_compare_primitives); cx_test_register(suite, test_json_compare_objects); cx_test_register(suite, test_json_compare_arrays); + cx_test_register(suite, test_json_clone_primitives); + cx_test_register(suite, test_json_clone_objects); + cx_test_register(suite, test_json_clone_arrays); cx_test_register(suite, test_json_write_default_format); cx_test_register(suite, test_json_write_pretty_default_spaces); cx_test_register(suite, test_json_write_pretty_default_tabs);