#include "../include/json.h" #include "../include/testing.h" #define JSON_parse_raw(a, s) JSON_parse(a, s, lengthof(s)); i32 test_json_integer() { Arena perm = Arena_new(128e3); JSON json_int = JSON_parse_raw(&perm, "123"); t_assert_equal(json_int.as.integer, 123); t_assert_equal(Arena_get_used(perm), 0); return 0; } i32 test_json_int_array() { Arena perm = Arena_new(128e3); JSON json_int_array = JSON_parse_raw(&perm, "[1,2,3]"); t_assert_equal(json_int_array.type, JSON_ARRAY); t_assert_equal(json_int_array.as.array.len, 3); int ints[3]; int sum = 0; for (int i = 0; i < json_int_array.as.array.len; i++) { JSON *item = Vec_get(json_int_array.as.array, JSON, i); ints[i] = item->as.integer; sum += item->as.integer; } t_assert_equal(ints[0], 1); t_assert_equal(ints[1], 2); t_assert_equal(ints[2], 3); t_assert_equal(sum, 6); t_assert_equal(Arena_get_used(perm), 576); return 0; } i32 test_json_empty_array() { Arena perm = Arena_new(128e3); JSON json_empty_array = JSON_parse_raw(&perm, "[]"); t_assert_equal(json_empty_array.as.array.len, 0); t_assert_equal(Arena_get_used(perm), 0); // TODO: weird return 0; } i32 test_json_nested_array() { Arena perm = Arena_new(128e3); JSON doc = JSON_parse_raw(&perm, "[[1,\"abc\"]]"); JSON sub_array = *Vec_get(doc.as.array, JSON, 0); JSON val_1 = *Vec_get(sub_array.as.array, JSON, 0); t_assert_equal(val_1.as.integer, 1); JSON val_2 = *Vec_get(sub_array.as.array, JSON, 1); t_assert_strequal(val_2.as.string, S("abc")); t_assert_equal(Arena_get_used(perm), 1152); return 0; } i32 test_json_string() { Arena perm = Arena_new(128e3); JSON js = JSON_parse_raw(&perm, "\"abc\""); t_assert_strequal(js.as.string, S("abc")); t_assert_equal(Arena_get_used(perm), 0); return 0; } i32 test_json_empty_object() { Arena perm = Arena_new(128e3); JSON doc = JSON_parse_raw(&perm, "{}"); t_assert_equal(doc.as.object.len, 0); t_assert_equal(Arena_get_used(perm), 672); return 0; } i32 test_json_object() { Arena perm = Arena_new(128e3); JSON doc = JSON_parse_raw(&perm, "{\"key\": \"value\"}"); t_assert_equal(doc.as.object.len, 1); StrView key = *Vec_get(doc.as.object.keys, StrView, 0); t_assert_strequal(key, S("key")); JSON value = *JSONObject_get(doc.as.object, S("key")); t_assert_strequal(value.as.string, S("value")); t_assert_equal(Arena_get_used(perm), 672); return 0; } i32 test_json_boolean() { Arena perm = Arena_new(128e3); JSON doc = JSON_parse_raw(&perm, "{\"a\": true, \"b\": false}"); JSON a = *JSONObject_get(doc.as.object, S("a")); t_assert_equal(a.as.boolean, true); JSON b = *JSONObject_get(doc.as.object, S("b")); t_assert_equal(b.as.boolean, false); t_assert_equal(Arena_get_used(perm), 672); return 0; } i32 test_json_float() { Arena perm = Arena_new(128e3); JSON doc = JSON_parse_raw(&perm, "[1.2, 2.3]"); t_assert_equal(doc.as.array.len, 2); JSON first = *Vec_get(doc.as.array, JSON, 0); t_assert_fequal(first.as.floating, 1.2); JSON second = *Vec_get(doc.as.array, JSON, 1); t_assert_fequal(second.as.floating, 2.3); t_assert_equal(Arena_get_used(perm), 576); return 0; } i32 test_json_null() { Arena perm = Arena_new(128e3); JSON doc = JSON_parse_raw(&perm, "[null]"); t_assert_equal(doc.as.array.len, 1); JSON first = *Vec_get(doc.as.array, JSON, 0); t_assert_equal(first.type, JSON_NULL); t_assert_equal(Arena_get_used(perm), 576); return 0; } i32 test_json_long_spaces() { Arena perm = Arena_new(128e3); JSON doc = JSON_parse_raw( &perm, "{\t \t \t \t \t }"); t_assert_equal(doc.as.object.len, 0); return 0; } i32 test_json_multiline() { Arena perm = Arena_new(128e3); MemoryFile file = load_file(&perm, "tests/test_json/test_json_multiline.json"); JSON doc = JSON_parse(&perm, file.content, file.size); JSON target_size_mb = *JSONObject_get(doc.as.object, S("target_size_mb")); t_assert_equal(target_size_mb.as.integer, 1); JSON generated_at = *JSONObject_get(doc.as.object, S("generated_at")); t_assert_strequal(generated_at.as.string, S("2025-07-22T10:36:30.974926")); return 0; } i32 test_json_nested_object() { Arena perm = Arena_new(128e3); JSON doc = JSON_parse_raw(&perm, "{\"1\":{\"2\":{}}}"); JSON lvl_1 = *JSONObject_get(doc.as.object, S("1")); t_assert_equal(lvl_1.type, JSON_OBJECT); JSON lvl_2 = *JSONObject_get(lvl_1.as.object, S("2")); t_assert_equal(lvl_2.type, JSON_OBJECT); return 0; } i32 test_json_array_in_object() { Arena perm = Arena_new(128e3); JSON doc = JSON_parse_raw(&perm, "{\"tags\": [\"TWvZi0\",\"pM0TPv9X\"]}"); JSON tags = *JSONObject_get(doc.as.object, S("tags")); t_assert_equal(tags.type, JSON_ARRAY); t_assert_equal(tags.as.array.len, 2); return 0; } i32 test_json_complex_multiline() { Arena perm = Arena_new(128e3); MemoryFile file = load_file(&perm, "tests/test_json/test_json_complex_multiline.json"); JSON doc = JSON_parse(&perm, file.content, file.size); JSON id = *JSONObject_get(doc.as.object, S("id")); t_assert_equal(id.as.integer, 819228); JSON metadata = *JSONObject_get(doc.as.object, S("metadata")); JSON preferences = *JSONObject_get(metadata.as.object, S("preferences")); JSON theme = *JSONObject_get(preferences.as.object, S("theme")); t_assert_strequal(theme.as.string, S("auto")); return 0; } i32 test_negative_numbers() { Arena perm = Arena_new(128e3); JSON doc = JSON_parse_raw(&perm, "[-1, -2.5]"); JSON integer = *Vec_get(doc.as.array, JSON, 0); t_assert_equal(integer.as.integer, -1); JSON floating = *Vec_get(doc.as.array, JSON, 1); t_assert_fequal(floating.as.floating, -2.5); return 0; } i32 test_json_backspaces() { Arena perm = Arena_new(128e3); MemoryFile file = load_file(&perm, "tests/test_json/test_json_backspaces.json"); JSON doc = JSON_parse(&perm, file.content, file.size); t_assert_strequal(doc.as.string, S("weird text\\")); return 0; }