summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/js/compat.js17
-rw-r--r--tests/js/server/web.js12
-rw-r--r--tests/js/utils.js135
-rw-r--r--tests/lib.sh33
-rw-r--r--tests/runner.js56
5 files changed, 253 insertions, 0 deletions
diff --git a/tests/js/compat.js b/tests/js/compat.js
new file mode 100644
index 0000000..8eaf4f3
--- /dev/null
+++ b/tests/js/compat.js
@@ -0,0 +1,17 @@
+import { getJSImpl } from "../../src/compat.js";
+
+const test_getJSImpl = t => {
+ t.start("getJSImpl()");
+ // FIXME
+};
+
+const test_mappings = t => {
+ t.start("mappings");
+ // FIXME
+};
+
+
+export const tests = [
+ test_getJSImpl,
+ test_mappings,
+];
diff --git a/tests/js/server/web.js b/tests/js/server/web.js
new file mode 100644
index 0000000..ecc6b2e
--- /dev/null
+++ b/tests/js/server/web.js
@@ -0,0 +1,12 @@
+import { f } from "../../../src/server/web.js";
+
+const test_f = t => {
+ t.start("f()");
+ t.test("it returns the correct answer", () => {
+ t.assertEq(42, f());
+ });
+};
+
+export const tests = [
+ test_f,
+];
diff --git a/tests/js/utils.js b/tests/js/utils.js
new file mode 100644
index 0000000..1ecc0a4
--- /dev/null
+++ b/tests/js/utils.js
@@ -0,0 +1,135 @@
+import { eq, keys } from "../../src/utils.js";
+
+const test_eq = t => {
+ t.start("eq()");
+ t.test("scalar values equality", () => {
+ t.assert(eq(0, 0));
+ t.assert(eq(100, 100));
+ t.assert(eq(1.5, 1.5));
+ t.assert(eq(-9, -9));
+
+ t.assert(!eq(0, 1));
+ t.assert(!eq(100, 99));
+ t.assert(!eq(1.5, 1.4));
+ t.assert(!eq(-9, 9));
+
+
+ t.assert(eq(null, null));
+ t.assert(eq(undefined, undefined));
+ t.assert(eq("", ""));
+ t.assert(eq("a string", "a string"));
+
+ t.assert(!eq(null, undefined));
+ t.assert(!eq(undefined, 0));
+ t.assert(!eq("", "0"));
+ t.assert(!eq("a string", "another string"));
+
+
+ t.assert(eq(true, true));
+ t.assert(eq(false, false));
+
+ t.assert(!eq(true, false));
+
+
+ t.assert(eq(1n, 1n));
+ t.assert(eq(99999999999999n, 99999999999999n));
+
+ // t.assert(eq(1, 1n));
+ });
+
+ t.test("array equality", () => {
+ t.assert(eq([], []));
+
+
+ t.assert(eq([0, 1, 2], [0, 1, 2]));
+ t.assert(eq([0, 1, 2], new Array(0, 1, 2)));
+
+ t.assert(!eq([0, 1, 2], [0, 1]));
+ t.assert(!eq([0, 1], new Array(0, 1, 2)));
+
+
+ t.assert(eq([undefined], [undefined]));
+ t.assert(eq([null, 0, "", true], [null, 0, "", true]));
+
+
+ t.assert(eq([[[[0]]]], [[[[0]]]]));
+
+ t.assert(!eq([[[[0]]]], [0]));
+ });
+
+ t.test("object equality", () => {
+ t.assert(eq({}, {}));
+ t.assert(eq({ a: 1 }, { a: 1 }));
+
+ t.assert(!eq({ a: 1, b: undefined }, { a: 1 }));
+
+
+ t.assert(eq(
+ { a: 1, b: { c: { d: "e" } } },
+ { a: 1, b: { c: { d: "e" } } },
+ ));
+
+ class C {}
+ // ...
+ });
+
+ t.test("mixed values", () => {
+ t.assert(eq(
+ {a: ["", 1, 2, 3, [{ b: { c: [ "d", "e" ]}}]]},
+ {a: ["", 1, 2, 3, [{ b: { c: [ "d", "e" ]}}]]},
+ ));
+
+ t.assert(!eq(null, {}));
+
+ t.assert(!eq([], {}));
+
+
+ t.assert(eq(new Date(123), new Date(123)));
+ t.assert(eq({ d: new Date(123) }, { d: new Date(123) }));
+
+ // FIXME
+ // t.assert(!eq(new Date(123), new Date(321)));
+ // t.assert(!eq({ d: new Date(123) }, { d: new Date(321) }));
+ });
+};
+
+const test_keys = t => {
+ t.start("keys()");
+ t.test("happy paths", () => {
+ t.assertEq(
+ { a: 1, b: 2 },
+ keys(["a", "b"], { a: 1, b: 2, c: 3 }),
+ );
+ });
+
+ t.test("stress scenarios", () => {
+ t.assertEq(
+ {},
+ keys([], {}),
+ "empty selection of empty object",
+ );
+
+ t.assertEq(
+ {},
+ keys([], {a: 1}),
+ "empty selection of non-empty object",
+ );
+
+ t.assertEq(
+ {},
+ keys(["a"], {}),
+ "non-empty selection of empty object",
+ );
+
+ t.assertEq(
+ { a: undefined, b: null },
+ keys(["a", "b", "c"], { a: undefined, b: null }),
+ "falsy values",
+ );
+ });
+};
+
+export const tests = [
+ test_eq,
+ test_keys,
+];
diff --git a/tests/lib.sh b/tests/lib.sh
new file mode 100644
index 0000000..9d183f9
--- /dev/null
+++ b/tests/lib.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+assert_arg() {
+ if [ -z "$1" ]; then
+ printf 'Missing %s.\n\n' "$2" >&2
+ cat <<-'EOF'
+ usage >&2
+ exit 2
+ EOF
+ fi
+}
+
+uuid() {
+ od -xN20 /dev/urandom |
+ head -n1 |
+ awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}'
+}
+
+tmpname() {
+ echo "${TMPDIR:-/tmp}/uuid-tmpname with spaces.$(uuid)"
+}
+
+mkstemp() {
+ name="$(tmpname)"
+ touch "$name"
+ echo "$name"
+}
+
+mkdtemp() {
+ name="$(tmpname)"
+ mkdir "$name"
+ echo "$name"
+}
diff --git a/tests/runner.js b/tests/runner.js
new file mode 100644
index 0000000..2e4e2ce
--- /dev/null
+++ b/tests/runner.js
@@ -0,0 +1,56 @@
+import { getExit, ARGV } from "../src/compat.js";
+import { eq } from "../src/utils.js";
+
+class AssertionError extends Error {}
+
+const red = s => `\x1b[31m${s}\x1b[0m`;
+const green = s => `\x1b[32m${s}\x1b[0m`;
+const yellow = s => `\x1b[33m${s}\x1b[0m`;
+
+const t = {
+ tap: x => {
+ console.error("tap:", x);
+ return x;
+ },
+ start: msg => {
+ console.error(`${msg}:`);
+ },
+ test: (msg, fn) => {
+ try {
+ fn();
+ console.error(`${yellow("testing")}: ${msg}... ${green("OK")}`);
+ } catch (e) {
+ console.error(`${yellow("testing")}: ${msg}... ${red("FAIL")}`);
+ throw e;
+ }
+ },
+ assertEq: (expected, given, msg = "") => {
+ if (!eq(expected, given)) {
+ console.error("expected:", expected, "\ngiven: ", given);
+ throw new AssertionError(`${red(msg)}`);
+ }
+ },
+ assert: (x, msg = "") => {
+ if (!x) {
+ throw new AssertionError(`${red(msg)}`);
+ }
+ },
+};
+
+const main = async () => {
+ const { tests } = await import(`../${ARGV[1]}`);
+ for (const testFn of tests) {
+ await testFn(t);
+ }
+};
+
+
+getExit().then(async exit => {
+ try {
+ await main();
+ exit(0);
+ } catch (e) {
+ console.error(e);
+ exit(1);
+ }
+});