--- a/tests/test_json.c Thu Dec 11 22:43:13 2025 +0100 +++ b/tests/test_json.c Thu Dec 11 22:59:55 2025 +0100 @@ -1249,12 +1249,7 @@ cx_testing_allocator_destroy(&talloc); } -CX_TEST_SUBROUTINE(test_json_write_sub, - const CxAllocator *allocator, - cxstring expected, - const CxJsonWriter *writer -) { - // create the value +static CxJsonValue *test_json_write_create_test_object(const CxAllocator *allocator) { CxJsonValue *obj = cxJsonCreateObj(allocator); cxJsonObjPutLiteral(obj, "bool", CX_JSON_FALSE); cxJsonObjPutNumber(obj, "int", 47); // purposely use PutNumber to put an int @@ -1278,6 +1273,16 @@ cxJsonArrAddValues(ints, &nested_array, 1); cxJsonArrAddIntegers(nested_array, (int64_t[]){16, 23}, 2); cxJsonArrAddIntegers(ints, (int64_t[]){42}, 1); + return obj; +} + +CX_TEST_SUBROUTINE(test_json_write_sub, + const CxAllocator *allocator, + cxstring expected, + const CxJsonWriter *writer +) { + // create the value + CxJsonValue *obj = test_json_write_create_test_object(allocator); // write it to a buffer CxBuffer buf; @@ -1567,6 +1572,82 @@ cxBufferDestroy(&buf); } +CX_TEST(test_json_to_string) { + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); + CxAllocator *allocator = &talloc.base; + CX_TEST_DO { + // expected value + cxstring expected = cx_str( +"{\"bool\":false," +"\"int\":47," +"\"strings\":[\"hello\",\"world\"]," +"\"nested\":{" +"\"objects\":[{" +"\"name1\":1," +"\"name2\":3" +"},{" +"\"name2\":7," +"\"name1\":3" +"}]," +"\"floats\":[3.1415,47.11,8.15]," +"\"literals\":[true,null,false]," +"\"ints\":[4,8,15,[16,23],42]" +"}" +"}" + ); + + CxJsonValue *obj = test_json_write_create_test_object(allocator); + cxmutstr result = cxJsonToString(obj, allocator); + CX_TEST_ASSERT(0 == cx_strcmp(result, expected)); + CX_TEST_ASSERT(result.ptr[result.length] == '\0'); + + cx_strfree_a(allocator, &result); + cxJsonValueFree(obj); + + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); + } + cx_testing_allocator_destroy(&talloc); +} + +CX_TEST(test_json_to_pretty_string) { + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); + CxAllocator *allocator = &talloc.base; + CX_TEST_DO { + cxstring expected = cx_str( +"{\n" +" \"bool\": false,\n" +" \"int\": 47,\n" +" \"strings\": [\"hello\", \"world\"],\n" +" \"nested\": {\n" +" \"objects\": [{\n" +" \"name1\": 1,\n" +" \"name2\": 3\n" +" }, {\n" +" \"name2\": 7,\n" +" \"name1\": 3\n" +" }],\n" +" \"floats\": [3.1415, 47.11, 8.15],\n" +" \"literals\": [true, null, false],\n" +" \"ints\": [4, 8, 15, [16, 23], 42]\n" +" }\n" +"}" + ); + + CxJsonValue *obj = test_json_write_create_test_object(allocator); + cxmutstr result = cxJsonToPrettyString(obj, allocator); + CX_TEST_ASSERT(0 == cx_strcmp(result, expected)); + CX_TEST_ASSERT(result.ptr[result.length] == '\0'); + + cx_strfree_a(allocator, &result); + cxJsonValueFree(obj); + + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); + } + cx_testing_allocator_destroy(&talloc); +} + CxTestSuite *cx_test_suite_json(void) { CxTestSuite *suite = cx_test_suite_new("json"); @@ -1609,6 +1690,8 @@ cx_test_register(suite, test_json_write_name_escape); cx_test_register(suite, test_json_write_solidus); cx_test_register(suite, test_json_write_nothing); + cx_test_register(suite, test_json_to_string); + cx_test_register(suite, test_json_to_pretty_string); return suite; }