effect-ts-laws
Version:
effect-ts law testing using fast-check.
87 lines • 3.43 kB
JavaScript
/**
* Predicates for statistical testing of equality between functions.
* @module
*/
import { Boolean as BO, Option as OP, pipe } from 'effect';
import { constFalse, constTrue } from 'effect/Function';
import fc from 'fast-check';
/**
* Attempt to find an example input where the pair of given unary functions
* is not equal. Given an arbitrary of `A`, an equivalence for `B` and a
* pair of functions, check the functions compute the same `B` given the
* same `A`, for `numRuns` values. Returns none or some value found.
* @param a - An arbitrary for the function argument type `A`.
* @param equalsB - Equivalence for the function return value type `B`.
* @param parameters - Optional [fast-check parameters](https://fast-check.dev/api-reference/interfaces/Parameters.html).
* @returns `none` if no counterexample to the equivalence was found, else
* `some` of the `A` that was found to produce different values.
* @category equivalence
*/
export const findCounterexample = (a, equalsB, parameters) => (
/**
* First function to sample.
*/
self,
/**
* Second function to sample.
*/
that) => {
const samples = fc.sample(a, parameters);
/* v8 ignore next 1 */
if (samples.length === 0)
throw new Error('Empty sample.');
for (const a of samples)
if (!equalsB(self(a), that(a)))
return OP.some(a);
return OP.none();
};
/**
* Attempt to find an example input where the pair of given unary functions
* is not equal. Given an arbitrary of `A`, an equivalence for `B` and a
* pair of functions, check the functions compute the same `B` given the
* same `A`, for `numRuns` values. Returns a boolean flag indicating
* equivalence.
* @param a - An arbitrary for the function argument type `A`.
* @param equalsB - Equivalence for the function return value type `B`.
* @param parameters - Optional [fast-check parameters](https://fast-check.dev/api-reference/interfaces/Parameters.html).
* @returns True if no counterexample found, else false.
* @category equivalence
*/
export const testUnaryEquivalence = (a, equalsB, parameters) => (
/**
* First function to sample.
*/
self,
/**
* Second function to sample.
*/
that) => pipe(findCounterexample(a, equalsB, parameters)(self, that), OP.match({
onNone: constTrue,
onSome: constFalse,
}));
/**
* Same as `testUnaryEquivalence` but for functions of type `Endo<A>`.
* @param a - An arbitrary for the function argument type `A`.
* @param equalsA - Equivalence for the type `A`.
* @param parameters - Optional [fast-check parameters](https://fast-check.dev/api-reference/interfaces/Parameters.html).
* @returns True if no counterexample found, else false.
* @category equivalence
*/
export const testEndoEquivalence = (a, equalsA, parameters) => (
/**
* First function to sample.
*/
self,
/**
* Second function to sample.
*/
that) => testUnaryEquivalence(a, equalsA, parameters)(self, that);
/**
* Same as `testUnaryEquivalence` but for functions of type `Predicate<A>`.
* @param a - An arbitrary for the function argument type `A`.
* @param parameters - Optional [fast-check parameters](https://fast-check.dev/api-reference/interfaces/Parameters.html).
* @returns True if no counterexample found, else false.
* @category equivalence
*/
export const testPredicateEquivalence = (a, parameters) => testUnaryEquivalence(a, BO.Equivalence, parameters);
//# sourceMappingURL=equivalence.js.map