From 56b93642b10c13d8c6ddc846143831316b2dce85 Mon Sep 17 00:00:00 2001 From: Lukas Obermann Date: Tue, 31 Oct 2023 14:41:00 +0100 Subject: [PATCH] test: add tests for maybe and type safety modules --- src/shared/utils/maybe.test.ts | 102 ++++++++++++++++++++++++++++ src/shared/utils/typeSafety.test.ts | 13 ++++ 2 files changed, 115 insertions(+) create mode 100644 src/shared/utils/maybe.test.ts create mode 100644 src/shared/utils/typeSafety.test.ts diff --git a/src/shared/utils/maybe.test.ts b/src/shared/utils/maybe.test.ts new file mode 100644 index 00000000..a0286446 --- /dev/null +++ b/src/shared/utils/maybe.test.ts @@ -0,0 +1,102 @@ +import assert from "node:assert/strict" +import { describe, it } from "node:test" +import { Just, Nothing, combine, fromNullable, isJust, isNothing, map, reduce } from "./maybe.ts" + +describe(Just.name, () => { + it("creates a maybe that contains a value", () => { + const maybe = Just("hello") + assert.deepEqual(maybe, { tag: "Just", value: "hello" }) + }) +}) + +describe("Nothing", () => { + it("creates a maybe that contains nothing", () => { + const maybe = Nothing + assert.deepEqual(maybe, { tag: "Nothing" }) + }) +}) + +describe(isJust.name, () => { + it("returns true if the maybe contains a value", () => { + const maybe = Just("hello") + assert.equal(isJust(maybe), true) + }) + + it("returns false if the maybe contains nothing", () => { + const maybe = Nothing + assert.equal(isJust(maybe), false) + }) +}) + +describe(isNothing.name, () => { + it("returns true if the maybe contains nothing", () => { + const maybe = Nothing + assert.equal(isNothing(maybe), true) + }) + + it("returns false if the maybe contains a value", () => { + const maybe = Just("hello") + assert.equal(isNothing(maybe), false) + }) +}) + +describe(fromNullable.name, () => { + it("creates a maybe that contains a value if the input is not null or undefined", () => { + const maybe = fromNullable("hello") + assert.deepEqual(maybe, { tag: "Just", value: "hello" }) + }) + + it("creates a maybe that contains nothing if the input is null", () => { + const maybe = fromNullable(null) + assert.deepEqual(maybe, { tag: "Nothing" }) + }) + + it("creates a maybe that contains nothing if the input is undefined", () => { + const maybe = fromNullable(undefined) + assert.deepEqual(maybe, { tag: "Nothing" }) + }) +}) + +describe(reduce.name, () => { + it("returns the default value if the maybe contains nothing", () => { + const maybe = Nothing + const result = reduce(maybe, "default", value => value.toUpperCase()) + assert.equal(result, "default") + }) + + it("applies the function to the value if the maybe contains a value", () => { + const maybe = Just("hello") + const result = reduce(maybe, "default", value => value.toUpperCase()) + assert.equal(result, "HELLO") + }) +}) + +describe(map.name, () => { + it("returns a maybe that contains nothing if the input maybe contains nothing", () => { + const maybe = Nothing + const result = map(maybe, value => value.toUpperCase()) + assert.deepEqual(result, { tag: "Nothing" }) + }) + + it("applies the function to the value if the input maybe contains a value", () => { + const maybe = Just("hello") + const result = map(maybe, value => value.toUpperCase()) + assert.deepEqual(result, { tag: "Just", value: "HELLO" }) + }) +}) + +describe(combine.name, () => { + it("returns a maybe that contains nothing if either input maybe contains nothing", () => { + const maybe1 = Just("hello") + const maybe2 = Nothing + const result = combine(maybe1, maybe2, (value1, value2) => value1 + value2) + assert.deepEqual(result, { tag: "Nothing" }) + }) + + it("applies the function to the values if both input maybes contain a value", () => { + const maybe1 = Just("hello") + const maybe2 = Just("world") + const result = combine(maybe1, maybe2, (value1, value2) => `${value1} ${value2}`) + assert.deepEqual(result, { tag: "Just", value: "hello world" }) + }) +}) diff --git a/src/shared/utils/typeSafety.test.ts b/src/shared/utils/typeSafety.test.ts new file mode 100644 index 00000000..98459077 --- /dev/null +++ b/src/shared/utils/typeSafety.test.ts @@ -0,0 +1,13 @@ +import assert from "node:assert/strict" +import { describe, it } from "node:test" +import { assertExhaustive } from "./typeSafety.ts" + +describe("assertExhaustive", () => { + it("should throw an error with the message 'The switch is not exhaustive.'", () => { + assert.throws( + // @ts-expect-error The function should never receive a value. + () => assertExhaustive(""), + err => err instanceof Error && err.message === "The switch is not exhaustive.", + ) + }) +})