Mercurial > libjeffpc
changeset 866:1c4c64f0ef21
json: add packing tests
It is far from exhaustive, but it is a start.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
line wrap: on
line diff
--- a/tests/.hgignore Sun Mar 15 15:49:39 2020 +0200 +++ b/tests/.hgignore Mon Jan 29 22:26:59 2024 -0500 @@ -16,6 +16,7 @@ test_hexdump test_hostname test_is_p2 +test_json_pack test_list test_mutex-destroy-held test_mutex-destroy-memcpy
--- a/tests/CMakeLists.txt Sun Mar 15 15:49:39 2020 +0200 +++ b/tests/CMakeLists.txt Mon Jan 29 22:26:59 2024 -0500 @@ -27,6 +27,7 @@ build_test_bin_and_run_files(cbor_pack lisp cbor cbor-common/valid) build_test_bin_and_run_files(cbor_unpack cbor lisp "cbor-common/valid;cbor-common/valid-unpack") +build_test_bin_and_run_files(json_pack lisp json json-common/valid) build_test_bin_and_run_files(nvl_pack lisp "cbor;json" nvl-pack) build_test_bin_and_run_files(qstring qs lisp qstring-basic) build_test_bin_and_run_files(sexpr_parser lisp "raw;txt" sexpr-parser)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/array-3int.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +[1,2,3] \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/array-3int.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +(1 2 3)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/array-empty.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +[] \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/array-empty.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/array-nested.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +[1,[2,3],[4,5]] \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/array-nested.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +(1 (2 3) (4 5))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/bool-false.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +false \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/bool-false.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +#f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/bool-true.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +true \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/bool-true.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +#t
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/int-limits-0.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +0 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/int-limits-0.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/int-limits-18446744073709551615.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +18446744073709551615 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/int-limits-18446744073709551615.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +18446744073709551615
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/str-ascii.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +"abcdef" \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/str-ascii.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +"abcdef"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/str-empty.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +"" \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/str-empty.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/str-quote-bslash.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +"\"\\" \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/str-quote-bslash.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +"\"\\"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/str-unicode-escape-2byte.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +"ü" \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/str-unicode-escape-2byte.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +"\u00fc"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/str-unicode-escape-3byte.json Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +"水" \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/json-common/valid/str-unicode-escape-3byte.lisp Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,1 @@ +"\u6c34"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test_json_pack.c Mon Jan 29 22:26:59 2024 -0500 @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2017-2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <jeffpc/hexdump.h> +#include <jeffpc/sexpr.h> +#include <jeffpc/json.h> +#include <jeffpc/io.h> +#include <jeffpc/mem.h> + +#include "test.c" + +static void cmp_buffers(const char *exp, struct buffer *_got) +{ + const char *got = buffer_data(_got); + + fprintf(stderr, " expected: %s\n", exp); + fprintf(stderr, " got: %s\n", got); + + if (strcmp(got, exp)) + fail("json packing failed: content mismatch"); +} + +#define TEST_ONE(pack, got, exp, input) \ + do { \ + int ret; \ + \ + buffer_truncate((got), 0); \ + \ + fprintf(stderr, "pack via: %s\n", #pack); \ + ret = pack; \ + if (ret) \ + fail("failed to pack value directly: %s", \ + xstrerror(ret)); \ + \ + cmp_buffers((exp), (got)); \ + \ + buffer_truncate((got), 0); \ + \ + fprintf(stderr, "pack via: %s\n", \ + "json_pack_val(got, input)"); \ + ret = json_pack_val((got), (input)); \ + if (ret) \ + fail("failed to pack value indirectly: %s", \ + xstrerror(ret)); \ + \ + cmp_buffers((exp), (got)); \ + } while (0) + +static struct val *convert_input(struct val *input) +{ + struct val **arr; + size_t len; + size_t i; + int ret; + + if (input->type != VT_CONS) + return input; + + /* + * We are dealing with either a list or an assoc, we need to figure + * out which it is... + * FIXME + */ + + if (0) { + /* it is an assoc; turn it into a VT_NVL */ + fail("not yet implemented"); + } else { + /* it is a list; turn it into a VT_ARRAY */ + len = sexpr_length(val_getref(input)); + if (len < 0) + fail("failed to get length of array"); + + arr = mem_reallocarray(NULL, len, sizeof(struct val *)); + if (!arr) + fail("failed to allocate val array"); + + ret = sexpr_list_to_array(input, arr, len); + if (ret < 0) + fail("failed to construct an array"); + + for (i = 0; i < len; i++) + arr[i] = convert_input(arr[i]); + + val_putref(input); + + return VAL_ALLOC_ARRAY(arr, len); + } +} + +static void onefile(struct val *input, const char *expected) +{ + struct buffer *got; + + fprintf(stderr, "input: "); + val_dump_file(stderr, input, 0); + + got = buffer_alloc(1000); + if (IS_ERR(got)) + fail("failed to allocate output buffer"); + + /* possibly an VT_ARRAY or VT_NVL in sexpr list form */ + if (input->type == VT_CONS) + input = convert_input(input); + + fprintf(stderr, "modified input: "); + val_dump_file(stderr, input, 0); + + switch (input->type) { + case VT_NULL: + TEST_ONE(json_pack_null(got), got, expected, input); + break; + case VT_INT: + TEST_ONE(json_pack_uint(got, input->i), got, expected, + input); + break; + case VT_BOOL: + TEST_ONE(json_pack_bool(got, input->b), got, expected, + input); + break; + case VT_STR: + TEST_ONE(json_pack_str(got, val_cast_to_str(input)), + got, expected, input); + break; + case VT_ARRAY: + TEST_ONE(json_pack_array_vals(got, input->array.vals, + input->array.nelem), + got, expected, input); + break; + case VT_NVL: + TEST_ONE(json_pack_map_val(got, input), got, + expected, input); + break; + case VT_SYM: + case VT_CONS: + case VT_CHAR: + case VT_BLOB: + fail("Unsupported val type"); + break; + } + + val_putref(input); +} + +void test(const char *ifname, void *in, size_t ilen, const char *iext, + const char *ofname, void *out, size_t olen, const char *oext) +{ + struct val *lv; + + lv = sexpr_parse(in, ilen); + if (IS_ERR(lv)) + fail("failed to parse input: %s", xstrerror(PTR_ERR(lv))); + + onefile(lv, out); +}