effect-ts-laws
Version:
effect-ts law testing using fast-check.
131 lines • 4.33 kB
JavaScript
/**
* Arbitraries for basic effect-ts datatypes.
* @module
*/
import { Array as AR, Cause as CA, Either as EI, flow, List as LI, Option as OP, pipe, String as STR, } from 'effect';
import fc from 'fast-check';
import { Monad as arbitraryMonad } from './instances.js';
const { map, flatMap } = arbitraryMonad;
/**
* Returns an `Either` arbitrary given a pair of arbitraries for the underlying
* left and right values.
* @category arbitraries
*/
export const either = (e, a) => fc.oneof(a.map(EI.right), e.map(EI.left));
/**
* Returns an `Option` arbitrary given an arbitrary for the underlying value.
* @category arbitraries
*/
export const option = (a) => fc.oneof(pipe(a, map(OP.some)), fc.constant(OP.none()));
/**
* An integer arbitrary small enough so that we can avoid having to think about
* numeric overflows in generated functions.
* @category arbitraries
*/
export const tinyInteger = fc.integer({
min: -100,
max: 100,
});
/**
* A non-negative integer arbitrary small enough so that we can avoid having to
* think about numeric overflows in generated functions.
* @category arbitraries
*/
export const tinyNonNegative = fc.integer({
min: 0,
max: 100,
});
/**
* A arbitrary for a tiny, possibly empty, string.
* @category arbitraries
*/
export const tinyString = fc.string({
minLength: 0,
maxLength: 3,
});
/**
* An integer in the range 1…100.
* @category arbitraries
*/
export const tinyPositive = fc.integer({
min: 1,
max: 100,
});
/**
* An array of tiny integers with max size fixed at 4.
* @category arbitraries
*/
export const tinyArray = (a) => fc.array(a, { maxLength: 4 });
/**
* An array of tiny integers with max size fixed at 4.
* @category arbitraries
*/
export const tinyIntegerArray = tinyArray(tinyInteger);
/**
* Given a {@link LiftArbitrary} function, and 1..n `Arbitrary`s for
* different types `A₁, A₂, ...Aₙ`, returns the given list except every
* arbitrary for type `Aᵢ` has been replaced by an arbitrary for type
* `Kind<F, R, O, E, Aᵢ>`. For example:
* @example
* import {option, liftArbitraries, tinyPositive, tinyIntegerArray} from 'effect-ts-laws'
* import {OptionTypeLambda} from 'effect/Option'
* import fc from 'fast-check'
*
* const [positive, integerArray] = liftArbitraries<OptionTypeLambda>(
* option,
* )(
* tinyPositive,
* tinyIntegerArray,
* )
* // typeof positive ≡ fc.Arbitrary<Option<number>>
* // typeof integerArray ≡ fc.Arbitrary<Option<readonly number[]>>
*
* console.log(fc.sample(positive, {numRuns: 1}))
* console.table(fc.sample(integerArray, {numRuns: 1}))
* @category lifting
*/
export const liftArbitraries = (liftArbitrary) => {
return (...arbs) => AR.map(arbs, (arb) => liftArbitrary(arb));
};
/**
* Build an arbitrary error from an arbitrary of a message.
* @param message Arbitrary for the error message string.
* @returns Arbitrary error.
* @category arbitraries
*/
export const error = map(s => new Error(s));
/**
* Build an arbitrary record with arbitrary string keys and
* values built from the given arbitrary.
* @param value Arbitrary for the record values.
* @returns Arbitrary record.
* @category arbitraries
*/
export const stringKeyRecord = (value) => pipe(uniqueStrings, flatMap(flow(AR.map(key => [key, value]), Object.fromEntries, fc.record)));
const uniqueStrings = fc.uniqueArray(fc.string({
minLength: 1,
maxLength: 5,
}), {
minLength: 1,
maxLength: 5,
comparator: STR.Equivalence,
});
/**
* Lift an arbitrary into an arbitrary for the effect-ts linked-list `List`
* type.
* @category arbitraries
*/
export const list = (a) => tinyArray(a).map(LI.fromIterable);
/**
* Arbitrary [Cause](https://effect-ts.github.io/effect/effect/Cause.ts.html).
* @category arbitraries
*/
export const cause = (a, defect = tinyInteger) => {
const depthIdentifier = fc.createDepthIdentifier();
return fc.letrec(tie => ({
cause: fc.oneof({ maxDepth: 3, depthIdentifier }, tie('atomic'), tie('composed')),
composed: map(fc.tuple(fc.oneof(fc.constant('sequential'), fc.constant('parallel')), fc.tuple(tie('cause'), tie('cause'))), ([op, pair]) => CA[op](...pair)),
atomic: fc.oneof(fc.constant(CA.empty), map(defect, CA.die), map(a, CA.fail)),
})).cause;
};
//# sourceMappingURL=data.js.map