UNPKG

pragmatic-fp-ts

Version:

Opinionated functional programming library with easy use in mind

163 lines (141 loc) 4.72 kB
import * as l from "../main.ts"; import { Chain, chain, either, identity, Just, just, Left, left, maybe, Nothing, nothing, Right, right, M, } from "../main.ts"; describe("monads", () => { describe("Maybe", () => { expect(maybe(1)).toBeInstanceOf(Just); expect(maybe(null)).toBeInstanceOf(Nothing); expect(maybe(undefined)).toBeInstanceOf(Nothing); expect(just(4).bind(() => null)).toBeInstanceOf(Nothing); expect(nothing().bind(() => 1)).toBeInstanceOf(Nothing); expect( just("just") .match({ just: identity, nothing: () => "nothing" }) .getValue() ).toBe("just"); expect( nothing() .match({ just: identity, nothing: () => "nothing" }) .getValue() ).toBe("nothing"); expect(just(1).filter(() => true)).toBeInstanceOf(Just); expect(just(1).filter(() => false)).toBeInstanceOf(Nothing); expect(nothing().filter(() => true)).toBeInstanceOf(Nothing); const x = maybe([1, 2, 3]) ._(l.find(l.eq(4))) ._(l.add(3)); expect(x).toBeInstanceOf(Nothing); }); describe("Either", () => { expect(either(1)).toBeInstanceOf(Right); expect(either(null)).toBeInstanceOf(Left); expect(either(undefined)).toBeInstanceOf(Left); expect(right(4).bind(() => null)).toBeInstanceOf(Left); expect(left("Error").bind(() => 1)).toBeInstanceOf(Left); expect( right("right") .match({ right: identity, left: () => "left" }) .getValue() ).toBe("right"); expect( left("Error") .match({ right: identity, left: () => "left" }) .getValue() ).toBe("left"); expect(right(1).filter(() => true)).toBeInstanceOf(Right); expect(right(1).filter(() => false)).toBeInstanceOf(Left); expect(left("Error").filter(() => true)).toBeInstanceOf(Left); }); describe("transformers", () => { it("transforms Maybe to Chain", () => { expect(just(5).to(chain)).toBeInstanceOf(Chain); expect(nothing().to(chain)).toBeInstanceOf(Chain); expect(nothing().to(chain).getValue()).toBe(null); }); it("transforms Maybe to Either", () => { expect(just(5).to(either)).toBeInstanceOf(Right); expect(just(null).to(either)).toBeInstanceOf(Left); }); it("transforms Chain to Maybe", () => { expect(chain(1).to(maybe)).toBeInstanceOf(Just); expect(chain(null).to(maybe)).toBeInstanceOf(Nothing); }); it("transforms Chain to Either", () => { expect(chain(1).to(either)).toBeInstanceOf(Right); expect(chain(null).to(either)).toBeInstanceOf(Left); }); it("transforms Either to Chain", () => { expect(left(1).to(chain)).toBeInstanceOf(Chain); expect(right(1).to(chain)).toBeInstanceOf(Chain); }); it("transforms Either to Maybe", () => { expect(left(1).to(maybe)).toBeInstanceOf(Nothing); expect(right(1).to(maybe)).toBeInstanceOf(Just); }); }); }); describe("generic monad functions", () => { describe("bind()", () => { it("should map just", () => { const j = M.bind((x: number) => x + 1)(just(1)); expect(j.isJust()).toBe(true); expect(j.getValue()).toBe(2); }); it("should map nothing", () => { const j = M.bind((x: number) => x + 1)(nothing<number>()); expect(j.isNothing()).toBe(true); }); it("should map right", () => { const j = M.bind((x: number) => x + 1)(right<number, any>(1)); expect(j.isRight()).toBe(true); expect(j.getValue()).toBe(2); }); it("should map left", () => { const j = M.bind((x: number) => x + 1)(left<any, any>(1)); expect(j.isLeft()).toBe(true); }); it("should map chain", () => { const j = M.bind((x: number) => x + 1)(chain(1)); expect(j.getValue()).toBe(2); }); }); describe("bindM()", () => { it("should map just", () => { const j = M.bindM((x: number) => just(x + 1))(just(1)); console.log({ j }); expect(j.isJust()).toBe(true); expect(j.getValue()).toBe(2); }); it("should map nothing", () => { const j = M.bindM((x: number) => just(x + 1))(nothing<number>()); expect(j.isNothing()).toBe(true); }); it("should map right", () => { const j = M.bindM((x: number) => right(x + 1))(right<number, any>(1)); expect(j.isRight()).toBe(true); expect(j.getValue()).toBe(2); }); it("should map left", () => { const j = M.bindM((x: number) => left(x + 1))(right<any, any>(1)); expect(j.isLeft()).toBe(true); }); it("should map chain", () => { const j = M.bindM((x: number) => chain(x + 1))(chain(1)); expect(j.getValue()).toBe(2); }); }); });