1
Fork 0

typescript(option): feat: added the 'oneOf' helper

Signed-off-by: prescientmoon <git@moonythm.dev>
This commit is contained in:
Matei Adriel 2019-12-25 16:09:18 +02:00 committed by prescientmoon
parent 6a8191cc34
commit 470574fdad
Signed by: prescientmoon
SSH key fingerprint: SHA256:UUF9JT2s8Xfyv76b8ZuVL7XrmimH4o49p4b+iexbVH4
4 changed files with 82 additions and 0 deletions

View file

@ -16,6 +16,7 @@ export * from './isSome'
export * from './iter'
export * from './map'
export * from './mapAsync'
export * from './oneOf'
export * from './optionify'
export * from './or'
export * from './orLazy'

View file

@ -0,0 +1,55 @@
import { constantly } from '@thi.ng/compose'
import { expect } from 'chai'
import { spy } from 'sinon'
import { x, alwaysSomeX } from '../../test/constants'
import { None, Some } from '../types'
import { oneOf } from './oneOf'
const alwaysSome = <T>(v: T) => constantly(Some(v))
describe('The oneOf helper', () => {
it('should return None on an empty array', () => {
// act
const result = oneOf(x, [])
// assert
expect(result).to.equal(None)
})
it('should return the result of the first function which evaluates to Some', () => {
// arrange
const alwaysNone = constantly(None)
// act
const head = oneOf(x, [alwaysSome('head'), alwaysNone])
const middle = oneOf(x, [alwaysNone, alwaysSome('middle'), alwaysNone])
const tail = oneOf(x, [alwaysNone, alwaysSome('tail')])
// assert
expect(head).to.equal(Some('head'))
expect(middle).to.equal(Some('middle'))
expect(tail).to.equal(Some('tail'))
})
it('should not evaluate any more functions after it found the result', () => {
// arrange
const func = spy(alwaysSomeX)
// act
oneOf(x, [alwaysSomeX, func])
// assert
expect(func.called).to.be.false
})
it('should pass the provided input to the functions', () => {
// arrange
const func = spy(alwaysSomeX)
// act
oneOf(x, [func])
// assert
expect(func.calledWith(x)).to.be.true
})
})

View file

@ -0,0 +1,23 @@
import { Binder } from '../internalTypes'
import { isSome } from './isSome'
import { None } from '../types'
/**
* Try a list of functions against a value.
* Return the value of the first call that succeeds (aka returns Some).
* If no function retursn Some this will default to None.
*
* @param input The input to pass to the functions.
* @param functions Iterable of functions to try against the input.
*/
export const oneOf = <T, U>(input: T, functions: Binder<T, U>[]) => {
for (const func of functions) {
const result = func(input)
if (isSome(result)) {
return result
}
}
return None
}

View file

@ -1,3 +1,4 @@
import { constantly } from '@thi.ng/compose'
import { Some } from '../src'
// general value to pass around
@ -5,3 +6,5 @@ export const x = Symbol('x')
// same as x but for some
export const someX = Some(x)
export const alwaysSomeX = constantly(someX)