@fast-check/ava
Version:
Property based testing for AVA based on fast-check
52 lines (51 loc) • 1.74 kB
JavaScript
import test from "ava";
import * as fc from "fast-check";
//#region src/ava-fast-check.ts
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;
}
if (tryResult.errors.some((error) => fc.PreconditionFailure.isFailure(error.savedError) || fc.PreconditionFailure.isFailure(error.cause))) {
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 === void 0) {
const seedFromGlobals = fc.readConfigureGlobal().seed;
if (seedFromGlobals !== void 0) customParams.seed = seedFromGlobals;
else customParams.seed = Date.now() ^ Math.random() * 4294967296;
}
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);
}
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
});
//#endregion
export { fc, test, testProp };