@fast-check/ava
Version:
Property based testing for AVA based on fast-check
56 lines (55 loc) • 2.11 kB
JavaScript
import test from 'ava';
import * as fc from 'fast-check';
export { fc, test };
function wrapProp(arbitraries, prop, params) {
return async (t, ..._args) => {
let failingTry;
try {
await fc.assert(fc.asyncProperty(...arbitraries, async (...args) => {
const tryResult = await t.try((tt) => prop(tt, ...args));
if (tryResult.passed) {
tryResult.commit();
return true;
}
const encounteredPreconditionFailure = tryResult.errors.some((error) => fc.PreconditionFailure.isFailure(error.savedError) || fc.PreconditionFailure.isFailure(error.cause));
if (encounteredPreconditionFailure) {
tryResult.discard();
fc.pre(false);
}
failingTry = tryResult;
return false;
}), params);
}
catch (error) {
t.log(error.message);
(failingTry?.commit ?? t.fail)();
}
t.pass();
};
}
function internalTestProp(testFn, label, arbitraries, prop, params) {
const customParams = { ...params };
if (customParams.seed === undefined) {
const seedFromGlobals = fc.readConfigureGlobal().seed;
if (seedFromGlobals !== undefined) {
customParams.seed = seedFromGlobals;
}
else {
customParams.seed = Date.now() ^ (Math.random() * 0x100000000);
}
}
testFn(`${label} (with seed=${customParams.seed})`, wrapProp(arbitraries, prop, customParams));
}
function exposeModifier(modifier) {
return (label, arbitraries, prop, params) => internalTestProp(test[modifier], label, arbitraries, prop, params);
}
export const testProp = Object.assign(function testProp(label, arbitraries, prop, params) {
internalTestProp(test, label, arbitraries, prop, params);
}, {
only: exposeModifier('only'),
failing: exposeModifier('failing'),
skip: exposeModifier('skip'),
serial: exposeModifier('serial'),
before: test.before,
after: test.after,
});