UNPKG

monads-co

Version:

An implementation of Haskell's type classes in TS

286 lines (196 loc) 6.87 kB
import { describe } from 'mocha' import { Err, Ok, Result, ResultHKT } from './Result' import { expect } from 'chai' describe('Result', () => { describe('#map', () => { it('Should replace transform the result\'s value if it exists', () => { const a = Ok<number, unknown>(4) const b = a.map((value) => value + 1) expect(b._value).to.eq(5) }) it('Should propagate the error otherwise', () => { const a = Err<number, string>('failure occurred') const b = a.map((value) => value + 1) expect(b._value).to.eq('failure occurred') }) }) describe('#amap', () => { it('Should perform mapping if all Ok', () => { const a = Ok<number, string>(4) const fn = Ok<(value: number) => number, string>((value) => value + 1) const b = a.amap(fn) expect(b._value).to.eq(5) }) it('Should return value error if Err', () => { const a = Err<number, string>('a') const fn = Ok<(value: number) => number, string>((value) => value + 1) const b = a.amap(fn) expect(b._value).to.eq('a') }) it('Should return fn error if Err', () => { const a = Ok<number, string>(4) const fn = Err<(value: number) => number, string>('b') const b = a.amap(fn) expect(b._value).to.eq('b') }) it('Should return mapping error if both are Err', () => { const a = Err<number, string>('a') const fn = Err<(value: number) => number, string>('b') const b = a.amap(fn) expect(b._value).to.eq('b') }) }) describe('#pure', () => { it('Should create a new result with new value', () => { const a = Ok(3) const b = a.pure(4) expect(b._value).to.eq(4) }) it('Should replace an error', () => { const a = Err<number, string>('a') const b = a.pure(4) expect(b._value).to.eq(4) }) }) describe('#then', () => { it('Should transform the result\'s value if it exists', () => { const a = Ok(4) const b = a.then((value) => Ok(value + 1)) expect(b._value).to.eq(5) }) it('Should propagate error if value Err', () => { const a = Err<number, string>('a') const b = a.then((value) => Ok(value + 1)) expect(b._value).to.eq('a') }) it('Should return mapping error if its an Err', () => { const a = Ok(4) const b = a.then(() => Err('b')) expect(b._value).to.eq('b') }) it('Should prefer original Err', () => { const a = Err('a') const b = a.then(() => Err('b')) expect(b._value).to.eq('a') }) }) describe('#and', () => { it('Should form Ok([a, b]) from Ok(a) and Ok(b)', () => { const a = Ok(2) const b = Ok(3) const c = a.and<number, ResultHKT<unknown>>(b) expect(c._value).to.deep.eq([2, 3]) }) it('Should Err if Left is Err', () => { const a = Err('a') const b = Ok<number, string>(3) const c = a.and<number, ResultHKT<string>>(b) expect(c._value).to.eq('a') }) it('Should Err if Right is Err', () => { const a = Ok(2) const b = Err<number, string>('b') const c = a.and<number, ResultHKT<string>>(b) expect(c._value).to.eq('b') }) it('Should Err if Left if both are Err', () => { const a = Err('a') const b = Err('b') const c = a.and<unknown, ResultHKT<string>>(b) expect(c._value).to.eq('a') }) }) describe('#andIgnoreRight', () => { it('Should form Ok(a) from Ok(a) and Ok(b)', () => { const a = Ok(2) const b = Ok(3) const c = a.andIgnoreRight<number, ResultHKT<unknown>>(b) expect(c._value).to.eq(2) }) it('Should Err if Left is Err', () => { const a = Err('a') const b = Ok<number, string>(3) const c = a.andIgnoreRight<number, ResultHKT<string>>(b) expect(c._value).to.eq('a') }) it('Should Err if Right is Err', () => { const a = Ok(2) const b = Err<number, string>('b') const c = a.andIgnoreRight<number, ResultHKT<string>>(b) expect(c._value).to.eq('b') }) it('Should Err if Left if both are Err', () => { const a = Err('a') const b = Err('b') const c = a.andIgnoreRight<unknown, ResultHKT<string>>(b) expect(c._value).to.eq('a') }) }) describe('#andIgnoreLeft', () => { it('Should form Ok(b) from Ok(a) and Ok(b)', () => { const a = Ok(2) const b = Ok(3) const c = a.andIgnoreLeft<number, ResultHKT<unknown>>(b) expect(c._value).to.eq(3) }) it('Should Err if Left is Err', () => { const a = Err('a') const b = Ok<number, string>(3) const c = a.andIgnoreLeft<number, ResultHKT<string>>(b) expect(c._value).to.eq('a') }) it('Should Err if Right is Err', () => { const a = Ok(2) const b = Err<number, string>('b') const c = a.andIgnoreLeft<number, ResultHKT<string>>(b) expect(c._value).to.eq('b') }) it('Should Err if Left if both are Err', () => { const a = Err('a') const b = Err('b') const c = a.andIgnoreLeft<unknown, ResultHKT<string>>(b) expect(c._value).to.eq('a') }) }) describe('#catch', () => { it('Should do nothing if LHS Ok', () => { const a = Ok<number, string>(2) const b = a.catch(() => 3) expect(b._value).to.eq(2) }) it('Should map error if LHS Err', () => { const a = Err<number, string>('a') const b = a.catch((error) => error === 'a' ? 1 : 2) expect(b._value).to.eq(1) }) }) describe('#catchThen', () => { it('Should do nothing if LHS Ok', () => { const a = Ok<number, string>(2) const b = a.catchThen(() => Ok(3)) expect(b._value).to.eq(2) }) it('Should return Ok if mapping Ok if LHS Err', () => { const a = Err<number, string>('a') const b = a.catchThen((error) => Ok(error === 'a' ? 1 : 2)) expect(b._value).to.eq(1) }) it('Should return Err if mapping Err if LHS Err', () => { const a = Err<number, string>('a') const b = a.catchThen((error) => Err('b')) expect(b._value).to.eq('b') }) }) describe('#toOptional', () => { it('Should return Some(T) for Ok(T)', () => { const a = Ok<number, string>(2) const b = a.toOptional() expect(b._value).to.eq(2) }) it('Should return None for Err', () => { const a = Err<number, string>('b') const b = a.toOptional() expect(b._value).to.eq(null) }) }) })