diff options
Diffstat (limited to 'test/json.c')
| -rw-r--r-- | test/json.c | 124 |
1 files changed, 116 insertions, 8 deletions
diff --git a/test/json.c b/test/json.c index c67fc75..0243ee3 100644 --- a/test/json.c +++ b/test/json.c @@ -3,16 +3,64 @@ #include "dged/json.h" +#include <stdlib.h> #include <string.h> +#include <sys/stat.h> + +struct parsed_json { + struct json_result result; + uint8_t *buf; +}; + +static struct parsed_json json_parse_error(const char *msg) { + return (struct parsed_json){ + .result = + (struct json_result){ + .ok = false, + .result.error = msg, + }, + .buf = NULL, + }; +} + +static struct parsed_json parse_json_file(const char *path) { + struct stat sb; + if (stat(path, &sb) != 0) { + return json_parse_error("file not found"); + } + + FILE *file = fopen(path, "r"); + if (fseek(file, 0, SEEK_END) != 0) { + return json_parse_error("fseek to end failed"); + } + + long sz = ftell(file); + if (sz == -1) { + return json_parse_error("ftell failed"); + } + + rewind(file); + + uint8_t *buff = malloc(sz); + int bytes = fread(buff, 1, sz, file); + if (bytes != sz) { + return json_parse_error("did not read whole file"); + } + + return (struct parsed_json){ + .result = json_parse(buff, sz), + .buf = buff, + }; +} -void test_empty_parse(void) { +static void test_empty_parse(void) { struct json_result res = json_parse((uint8_t *)"", 0); ASSERT(res.ok, "Expected empty parse to work"); json_destroy(&res.result.document); } -void test_empty_array(void) { +static void test_empty_array(void) { struct json_result res = json_parse((uint8_t *)"[]", 2); ASSERT(res.ok, "Expected parse of empty array to work"); @@ -23,7 +71,7 @@ void test_empty_array(void) { json_destroy(&root); } -void test_array(void) { +static void test_array(void) { struct json_result res = json_parse((uint8_t *)"[ 1, 2, 4 ]", 11); ASSERT(res.ok, "Expected parse of number array to work"); @@ -33,7 +81,7 @@ void test_array(void) { json_destroy(&root); - const char *jsn = "[ \"hello\", \"world\" ]"; + const char *jsn = "[ \"hello\", \"world\", \"\\\"\" ]"; res = json_parse((uint8_t *)jsn, strlen(jsn)); ASSERT(res.ok, "Expected parse of string array to work"); root = res.result.document; @@ -46,7 +94,7 @@ void test_array(void) { json_destroy(&root); } -void test_object(void) { +static void test_object(void) { struct json_result res = json_parse((uint8_t *)"{ }", 3); ASSERT(res.ok, "Expected parse of empty object to work"); struct json_value root = res.result.document; @@ -55,7 +103,8 @@ void test_object(void) { json_destroy(&root); - const char *jsn = "{ \"name\": \"Kalle Kula\", \"age\": 33, }"; + const char *jsn = "{ \"name\": \"Kalle Kula\", \"age\": 33, \"ball\": true, " + "\"square\": false }"; res = json_parse((uint8_t *)jsn, strlen(jsn)); ASSERT(res.ok, "Expected parse of simple object to work"); root = res.result.document; @@ -67,13 +116,17 @@ void test_object(void) { ASSERT(age->type == Json_Number, "Expected age to (just?) be a number"); ASSERT(age->value.number == 33, "Expected age to be 33"); + struct json_value *ball = json_get(root.value.object, s8("ball")); + ASSERT(ball->type == Json_Bool, "Expected ball to be a boolean."); + ASSERT(ball->value.boolean, "Expected Kalle Kulla to be a ball."); + json_destroy(&root); jsn = "{ \"name\": \"Kalle Kula\", \"age\": 33, \"kids\": " "[ " "{ \"name\": \"Sune Kula\", \"age\": 10, }, " - "{ \"name\": \"Suna Kula\", \"age\": 7 } " - "] }"; + "{ \"name\": \"Suna Kula\", \"age\": 7 }, " + "], \"pet_names\": [ \"fido\", \"fado\" ], \"ball\": true }"; res = json_parse((uint8_t *)jsn, strlen(jsn)); ASSERT(res.ok, "Expected parse of nested object to work"); root = res.result.document; @@ -84,12 +137,67 @@ void test_object(void) { struct json_value *kids = json_get(root.value.object, s8("kids")); ASSERT(kids->type == Json_Array, "Expected kids to be array"); + ball = json_get(root.value.object, s8("ball")); + ASSERT(ball->type == Json_Bool, "Expected ball to be a boolean."); + ASSERT(ball->value.boolean, "Expected Kalle Kulla to be a ball."); + json_destroy(&root); } +#define xstr(s) str(s) +#define str(s) #s + +#define test_parse_file(path) \ + { \ + struct parsed_json parsed = parse_json_file(xstr(TEST_ROOT) "/" path); \ + ASSERT(parsed.result.ok, "Expected parsing of " #path " to work: %s", \ + parsed.result.result.error); \ + json_destroy(&parsed.result.result.document); \ + free(parsed.buf); \ + } + +static void test_files(void) { test_parse_file("json/diag.json"); } + +static void test_brackets_in_strings(void) { + struct parsed_json parsed = + parse_json_file(xstr(TEST_ROOT) "/json/diag2.json"); + ASSERT(parsed.result.ok, "Expected parsing of diag2.json to work"); + + struct json_value *params = + json_get(parsed.result.result.document.value.object, s8("params")); + ASSERT(params != NULL, "Expected JSON object to contain params"); + ASSERT(params->type == Json_Object, "Expected params to be a JSON object"); + + struct json_value *diagnostics = + json_get(params->value.object, s8("diagnostics")); + ASSERT(diagnostics != NULL, "Expected params to contain diagnostics"); + ASSERT(diagnostics->type == Json_Array, "Expected params to be a JSON array"); + + struct json_array *diags = diagnostics->value.array; + ASSERT(json_array_len(diags) == 5, + "Expected diagnostics array to contain five items"); + + json_destroy(&parsed.result.result.document); + free(parsed.buf); +} + +static void test_str_escape(void) { + struct s8 res = unescape_json_string(s8("a\n\\n\r\\rb")); + ASSERT(s8eq(res, s8("a\n\n\r\rb")), "Expected \\n and \\r to not be removed"); + + s8delete(res); + + struct s8 res2 = unescape_json_string(s8(" \\\\\\n")); + ASSERT(s8eq(res2, s8(" \\\n")), "Expected \\ and \\n to not be removed"); + s8delete(res2); +} + void run_json_tests(void) { run_test(test_empty_parse); run_test(test_empty_array); run_test(test_array); run_test(test_object); + run_test(test_files); + run_test(test_brackets_in_strings); + run_test(test_str_escape); } |
