diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/js/compat.js | 17 | ||||
| -rw-r--r-- | tests/js/server/web.js | 12 | ||||
| -rw-r--r-- | tests/js/utils.js | 135 | ||||
| -rw-r--r-- | tests/lib.sh | 33 | ||||
| -rw-r--r-- | tests/runner.js | 56 |
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); + } +}); |
