diff options
Diffstat (limited to 'pbt/ts/src/property.ts')
| -rw-r--r-- | pbt/ts/src/property.ts | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/pbt/ts/src/property.ts b/pbt/ts/src/property.ts index 500c423..04f2a62 100644 --- a/pbt/ts/src/property.ts +++ b/pbt/ts/src/property.ts @@ -1,3 +1,5 @@ +import {Option, getOrElse, isSome, none, some} from 'fp-ts/lib/Option'; +import {LazyArg, pipe} from 'fp-ts/lib/function'; import Prando from 'prando'; type Result = 'OK' | 'Falsified' | 'Exception'; @@ -125,6 +127,31 @@ export function elements<A>(arr: A[]): Gen<A> { }; } +export function frequency<A>(distribution: [number, Gen<A>][]): Gen<A> { + const total: number = distribution.reduce((acc, [freq, _]) => acc + freq, 0); + + return (rng: Prando) => (size: number) => { + const idx = rng.next(0, total); + let selectedGen: Option<Gen<A>> = none; + selectedGen = distribution.reduce((found, [freq, gen]) => { + if (isSome(found)) { + return found; + } else if (idx <= freq) { + return some(gen); + } else { + return none; + } + }, selectedGen); + const generator: Gen<A> = pipe( + selectedGen, + getOrElse((() => { + throw new Error(`invalid frequency distribution ${distribution}`); + }) as LazyArg<Gen<A>>), + ); + return generator(rng)(size); + }; +} + /// Select one key-value pair from given map export function keyValueOf<K, V>(map: Map<K, V>): Gen<[K, V]> { let keys = Array.from(map.keys()); |
