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>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Mon, 29 Jan 2024 22:26:59 -0500
parents 91a6a5244cce
children 3ededa985664
files tests/.hgignore tests/CMakeLists.txt tests/json-common/valid/array-3int.json tests/json-common/valid/array-3int.lisp tests/json-common/valid/array-empty.json tests/json-common/valid/array-empty.lisp tests/json-common/valid/array-nested.json tests/json-common/valid/array-nested.lisp tests/json-common/valid/bool-false.json tests/json-common/valid/bool-false.lisp tests/json-common/valid/bool-true.json tests/json-common/valid/bool-true.lisp tests/json-common/valid/int-limits-0.json tests/json-common/valid/int-limits-0.lisp tests/json-common/valid/int-limits-18446744073709551615.json tests/json-common/valid/int-limits-18446744073709551615.lisp tests/json-common/valid/str-ascii.json tests/json-common/valid/str-ascii.lisp tests/json-common/valid/str-empty.json tests/json-common/valid/str-empty.lisp tests/json-common/valid/str-quote-bslash.json tests/json-common/valid/str-quote-bslash.lisp tests/json-common/valid/str-unicode-escape-2byte.json tests/json-common/valid/str-unicode-escape-2byte.lisp tests/json-common/valid/str-unicode-escape-3byte.json tests/json-common/valid/str-unicode-escape-3byte.lisp tests/test_json_pack.c
diffstat 27 files changed, 200 insertions(+), 0 deletions(-) [+]
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);
+}