pragmatic-fp-ts
Version:
Opinionated functional programming library with easy use in mind
57 lines (46 loc) • 1.99 kB
text/typescript
import { defmulti, defmethod } from "../multimethod.ts";
describe("multimethods", () => {
describe("unary", () => {
it("should dispatch on the dispatchFn", () => {
const dispatch = (str?: string) =>
(str?.length || 0) > 5 ? "long" : (str?.length || 0) > 0 ? "short" : "empty";
const strLen = defmulti(dispatch);
defmethod(strLen, "long", (_input: unknown) => "It was a long string");
defmethod(strLen, "short", (str) => "It was a short string: " + str?.toUpperCase());
defmethod(strLen, "default", () => "No implementation found");
expect(strLen("foo")).toEqual("It was a short string: FOO");
expect(strLen()).toEqual("No implementation found");
});
it("should throw on missing implementations", () => {
const fn = defmulti((_i: any) => "foo");
defmethod(fn, "bar", (_i: any) => "??");
expect(() => fn(123)).toThrow();
});
});
describe("multi-ary", () => {
it("should dispatch on the dispatchFn", () => {
const dispatch = (a: number, b: number) => Math.sign(a * b);
const tellRange = defmulti(dispatch);
const rngInt = "Integers";
const natZero = "Natural numbers, Zero";
const natural = "Natural numbers";
defmethod(tellRange, -1, () => rngInt);
defmethod(tellRange, 0, () => natZero);
defmethod(tellRange, 1, () => natural);
expect(tellRange(1, 1)).toEqual(natural);
expect(tellRange(1, 0)).toEqual(natZero);
expect(tellRange(12, -2)).toEqual(rngInt);
});
});
describe("errors", () => {
it("should throw on missing implementations", () => {
const fn = defmulti((_i: any, _u: any) => "foo");
defmethod(fn, "bar", (_i: any, _u: any) => "??");
expect(() => fn(123, 456)).toThrow();
});
it("should throw when extending non-multimethods", () => {
const fn = function (_: string) {};
expect(() => defmethod(fn, "someKey", (_: any) => null)).toThrow();
});
});
});