From 47e2a30fc401e656b476135f4a6f4dd663def89c Mon Sep 17 00:00:00 2001 From: Mauko Quiroga Date: Sat, 17 Aug 2024 22:09:27 +0200 Subject: [PATCH] test: add test for functor composability --- test/unit/utils/adt/maybe.test.ts | 64 +++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/test/unit/utils/adt/maybe.test.ts b/test/unit/utils/adt/maybe.test.ts index 96fa7a9..b268a26 100644 --- a/test/unit/utils/adt/maybe.test.ts +++ b/test/unit/utils/adt/maybe.test.ts @@ -4,6 +4,7 @@ import type { Matcher } from '~/utils/adt/maybe' import { describe, expect, expectTypeOf, test } from 'vitest' import { isJust, isNothing, just, map, match, nothing } from '~/utils/adt/maybe' +import { compose } from '~/utils/composition/compose' describe('Maybe', () => { describe('Given a value or the absence thereof', () => { @@ -104,17 +105,72 @@ describe('map/1', () => { type Inc = (a: A) => A const inc: Inc = (a) => a + 1 - type MaybeAdd = (a: Maybe) => Maybe - const maybeAdd: MaybeAdd = map(inc) + type MaybeInc = (a: Maybe) => Maybe + const maybeInc: MaybeInc = map(inc) test('When lifting it with "just"', () => { - const result = maybeAdd(just(1)) + const result = maybeInc(just(1)) expect(result).toStrictEqual(just(2)) }) test('When lifting it with "nothing"', () => { - const result = maybeAdd(nothing) + const result = maybeInc(nothing) expect(result).toBe(nothing) }) + + describe('Given another function', () => { + type Length = (a: A) => number + const length: Length = (a) => a.length + + type MaybeLength = (a: Maybe) => Maybe + const maybeLength: MaybeLength = map(length) + + const composed = compose([inc, length]) + + describe('Given the composed lifted functions', () => { + const composedMap = compose([maybeInc, maybeLength]) + + test('When evaluating with "just"', () => { + const result = composedMap(just('7')) + expect(result).toStrictEqual(just(2)) + }) + + test('When evaluating with "nothing"', () => { + const result = composedMap(nothing) + expect(result).toBe(nothing) + }) + }) + + describe('Given the lifted composed functions', () => { + const mappedCompose = map(composed) + + test('When evaluating with "just"', () => { + const result = mappedCompose(just('777')) + expect(result).toStrictEqual(just(4)) + }) + + test('When evaluating with "nothing"', () => { + const result = mappedCompose(nothing) + expect(result).toBe(nothing) + }) + }) + + describe('Given both composed-lifted and lifted-composed', () => { + const composedMap = compose([maybeInc, maybeLength]) + const mappedCompose = map(composed) + + test('When evaluating with "just"', () => { + const cm = composedMap(just('¡Hola!')) + const mc = mappedCompose(just('¡Hola!')) + expect(cm).toStrictEqual(mc) + }) + + test('When evaluating with "nothing"', () => { + const cm = composedMap(nothing) + const mc = composedMap(nothing) + expect(cm).toBe(mc) + }) + }) + }) }) })