summaryrefslogtreecommitdiff
path: root/tests/js/utils.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/js/utils.mjs')
-rw-r--r--tests/js/utils.mjs225
1 files changed, 225 insertions, 0 deletions
diff --git a/tests/js/utils.mjs b/tests/js/utils.mjs
new file mode 100644
index 0000000..1875ce5
--- /dev/null
+++ b/tests/js/utils.mjs
@@ -0,0 +1,225 @@
+import assert from "node:assert/strict";
+
+import { runTests } from "../runner.mjs";
+import {
+ eq,
+ keys,
+ assocIn,
+ getIn,
+ first,
+ log,
+} from "../../src/utils.mjs";
+
+const test_eq = t => {
+ t.start("eq()");
+ t.test("scalar values equality", () => {
+ assert(eq(0, 0));
+ assert(eq(100, 100));
+ assert(eq(1.5, 1.5));
+ assert(eq(-9, -9));
+
+ assert(!eq(0, 1));
+ assert(!eq(100, 99));
+ assert(!eq(1.5, 1.4));
+ assert(!eq(-9, 9));
+
+
+ assert(eq(null, null));
+ assert(eq(undefined, undefined));
+ assert(eq("", ""));
+ assert(eq("a string", "a string"));
+
+ assert(!eq(null, undefined));
+ assert(!eq(undefined, 0));
+ assert(!eq("", "0"));
+ assert(!eq("a string", "another string"));
+
+
+ assert(eq(true, true));
+ assert(eq(false, false));
+
+ assert(!eq(true, false));
+
+
+ assert(eq(1n, 1n));
+ assert(eq(99999999999999n, 99999999999999n));
+ });
+
+ t.test("array equality", () => {
+ assert(eq([], []));
+
+
+ assert(eq([0, 1, 2], [0, 1, 2]));
+ assert(eq([0, 1, 2], new Array(0, 1, 2)));
+
+ assert(!eq([0, 1, 2], [0, 1]));
+ assert(!eq([0, 1], new Array(0, 1, 2)));
+
+
+ assert(eq([undefined], [undefined]));
+ assert(eq([null, 0, "", true], [null, 0, "", true]));
+
+
+ assert(eq([[[[0]]]], [[[[0]]]]));
+
+ assert(!eq([[[[0]]]], [0]));
+ });
+
+ t.test("object equality", () => {
+ assert(eq({}, {}));
+ assert(eq({ a: 1 }, { a: 1 }));
+
+ assert(!eq({ a: 1, b: undefined }, { a: 1 }));
+
+
+ assert(eq(
+ { a: 1, b: { c: { d: "e" } } },
+ { a: 1, b: { c: { d: "e" } } },
+ ));
+ });
+
+ t.test("mixed values", () => {
+ assert(eq(
+ {a: ["", 1, 2, 3, [{ b: { c: [ "d", "e" ]}}]]},
+ {a: ["", 1, 2, 3, [{ b: { c: [ "d", "e" ]}}]]},
+ ));
+
+ assert(!eq(null, {}));
+
+ assert(!eq([], {}));
+ });
+};
+
+const test_keys = t => {
+ t.start("keys()");
+ t.test("happy paths", () => {
+ assert.deepEqual(
+ { a: 1, b: 2 },
+ keys(["a", "b"], { a: 1, b: 2, c: 3 }),
+ );
+ });
+
+ t.test("stress scenarios", () => {
+ assert.deepEqual(
+ {},
+ keys([], {}),
+ "empty selection of empty object",
+ );
+
+ assert.deepEqual(
+ {},
+ keys([], {a: 1}),
+ "empty selection of non-empty object",
+ );
+
+ assert.deepEqual(
+ {},
+ keys(["a"], {}),
+ "non-empty selection of empty object",
+ );
+
+ assert.deepEqual(
+ { a: undefined, b: null },
+ keys(["a", "b", "c"], { a: undefined, b: null }),
+ "falsy values",
+ );
+ });
+};
+
+const test_assocIn = t => {
+ t.start("assocIn()");
+
+ t.test("empty values", () => {
+ assert.deepEqual(assocIn({}, [], null), {});
+ assert.deepEqual(assocIn({ k: "v" }, [], null), { k: "v" });
+ });
+
+ t.test("adding values", () => {
+ assert.deepEqual(assocIn({}, ["k"], "v"), { k: "v" });
+ assert.deepEqual(assocIn({}, ["k1", "k2"], "v"), { k1: { k2: "v" }});
+ assert.deepEqual(assocIn({}, ["k1", "k2", "k3"], "v"), { k1: { k2: { k3: "v" }}});
+ assert.deepEqual(assocIn({ k: "v" }, ["k1", "k2"], "v"), { k: "v", k1: { k2: "v" }});
+ });
+
+ t.test("replacing values", () => {
+ assert.deepEqual(
+ assocIn(
+ { k1: { k2: { k3: "before" }}},
+ ["k1", "k2", "k3"],
+ "after"
+ ),
+ { k1: { k2: { k3: "after" }}}
+ );
+ });
+};
+
+const test_getIn = t => {
+ t.start("getIn()");
+
+ t.test("empty values", () => {
+ assert.deepEqual(getIn({}, []), {});
+ assert.deepEqual(getIn({ k: "v" }, []), { k: "v" });
+ });
+
+ t.test("missing values", () => {
+ assert.deepEqual(getIn({}, ["a", "b", "c"]), undefined);
+ assert.deepEqual(getIn({ a: {}}, ["a", "b", "c"]), undefined);
+ assert.deepEqual(getIn({ a: { b: {}}}, ["a", "b", "c"]), undefined);
+ assert.deepEqual(getIn({ a: { b: {}, c: {}}}, ["a", "b", "c"]), undefined);
+ });
+
+ t.test("nested valeues", () => {
+ assert.deepEqual(getIn({ a: { b: { c: { d: "e" }}}}, ["a", "b", "c", "d"]), "e");
+ });
+};
+
+const test_first = t => {
+ t.start("first()");
+
+ t.test("empty values", () => {
+ assert.equal(first([], () => {}), null);
+ });
+
+ t.test("when function doesn't transform, it behaves similarly to [].find()", () => {
+ const arr1 = [ 0, null, undefined, "", 1, 2 ];
+ assert.equal(first(arr1, x => x), 1);
+ assert.equal(arr1.find(x => x), 1);
+
+ const arr2 = [ 0, null, undefined, "", false ];
+ assert.equal(first(arr2, x => x), null);
+ assert.equal(arr2.find(x => x), undefined);
+ });
+
+ t.test("when it does transform, we return the transformed value", () => {
+ const arr = [ 1, 3, 5, 6 ];
+
+ assert.equal(
+ first(arr, x => x % 2 === 0 && "a brand new value"),
+ "a brand new value",
+ );
+ });
+};
+
+const test_log = t => {
+ t.start("log()");
+
+ t.test("we can log data", () => {
+ log({ a: 1, type: "log-test" });
+ });
+
+ t.test("we can't log unserializable things", () => {
+ const obj = { self: null };
+ obj.self = obj;
+ assert.throws(() => log(obj), TypeError);
+ });
+};
+
+
+await runTests([
+ test_eq,
+ test_keys,
+ test_assocIn,
+ test_getIn,
+ test_first,
+ test_log,
+]);