@fast-check/jest
Version:
Property based testing for Jest based on fast-check
129 lines (128 loc) • 5.85 kB
JavaScript
//#region \0rolldown/runtime.js
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
let fast_check = require("fast-check");
//#region src/internals/TestWithPropRunnerBuilder.ts
function wrapProp(prop) {
return (...args) => Promise.resolve(prop(...args));
}
function buildTestWithPropRunner(testFn, label, arbitraries, prop, params, timeout, jest, fc) {
const customParams = { ...params };
if (customParams.seed === void 0) {
const seedFromGlobals = (0, fast_check.readConfigureGlobal)().seed;
if (seedFromGlobals !== void 0) customParams.seed = seedFromGlobals;
else {
const seedFromJest = typeof jest.getSeed === "function" ? jest.getSeed() : void 0;
if (seedFromJest !== void 0) customParams.seed = seedFromJest;
else customParams.seed = Date.now() ^ Math.random() * 4294967296;
}
}
if (customParams.interruptAfterTimeLimit === void 0) customParams.interruptAfterTimeLimit = fc.readConfigureGlobal().interruptAfterTimeLimit;
const jestTimeout = timeout !== void 0 ? timeout : extractJestGlobalTimeout();
if (jestTimeout !== void 0) if (customParams.interruptAfterTimeLimit === void 0) customParams.interruptAfterTimeLimit = jestTimeout;
else customParams.interruptAfterTimeLimit = Math.min(customParams.interruptAfterTimeLimit, jestTimeout);
else console.warn("Unable to get back timeout of Jest, falling back onto Jest for global timeout handling");
const promiseProp = wrapProp(prop);
const propertyInstance = fc.asyncProperty(...arbitraries, promiseProp);
testFn(`${label} (with seed=${customParams.seed})`, async () => {
await fc.assert(propertyInstance, customParams);
}, jestTimeout !== void 0 ? 2147483647 : void 0);
}
function extractJestGlobalTimeout() {
const jestTimeout = globalThis[Symbol.for("TEST_TIMEOUT_SYMBOL")];
if (typeof jestTimeout === "number") return jestTimeout;
const stateSymbolStringValue = String(Symbol("JEST_STATE_SYMBOL"));
for (const key of Object.getOwnPropertySymbols(globalThis)) if (String(key) === stateSymbolStringValue) {
const jestState = globalThis[key];
if (jestState !== null && typeof jestState === "object" && typeof jestState.testTimeout === "number") return jestState.testTimeout;
}
if (typeof jasmine !== "undefined") return jasmine.DEFAULT_TIMEOUT_INTERVAL;
}
//#endregion
//#region src/internals/TestBuilder.ts
function adaptParametersForRecord(parameters, originalParamaters) {
return {
...parameters,
examples: parameters.examples !== void 0 ? parameters.examples.map((example) => example[0]) : void 0,
reporter: originalParamaters.reporter,
asyncReporter: originalParamaters.asyncReporter
};
}
function adaptExecutionTreeForRecord(executionSummary) {
return executionSummary.map((summary) => ({
...summary,
value: summary.value[0],
children: adaptExecutionTreeForRecord(summary.children)
}));
}
function adaptRunDetailsForRecord(runDetails, originalParamaters) {
return {
...runDetails,
counterexample: runDetails.counterexample !== null ? runDetails.counterexample[0] : null,
failures: runDetails.failures.map((failure) => failure[0]),
executionSummary: adaptExecutionTreeForRecord(runDetails.executionSummary),
runConfiguration: adaptParametersForRecord(runDetails.runConfiguration, originalParamaters)
};
}
function buildTestProp(testFn, jest, fc) {
return (arbitraries, params) => {
if (Array.isArray(arbitraries)) return (testName, prop, timeout) => buildTestWithPropRunner(testFn, testName, arbitraries, prop, params, timeout, jest, fc);
return (testName, prop, timeout) => {
const recordArb = (0, fast_check.record)(arbitraries);
const recordParams = params !== void 0 ? {
...params,
examples: params.examples !== void 0 ? params.examples.map((example) => [example]) : void 0,
reporter: params.reporter !== void 0 ? (runDetails) => params.reporter(adaptRunDetailsForRecord(runDetails, params)) : void 0,
asyncReporter: params.asyncReporter !== void 0 ? (runDetails) => params.asyncReporter(adaptRunDetailsForRecord(runDetails, params)) : void 0
} : void 0;
buildTestWithPropRunner(testFn, testName, [recordArb], (value) => prop(value), recordParams, timeout, jest, fc);
};
};
}
/**
* Build the enriched version of {it,test}, the one with added `.prop`
*/
function buildTest(testFn, jest, fc) {
let atLeastOneExtra = false;
const extraKeys = {};
for (const key in testFn) if (typeof testFn[key] === "function") {
atLeastOneExtra = true;
extraKeys[key] = key !== "each" ? buildTest(testFn[key], jest, fc) : testFn[key];
}
if (!atLeastOneExtra) return testFn;
const enrichedTestFn = (...args) => testFn(...args);
if ("each" in testFn) extraKeys["prop"] = buildTestProp(testFn, jest, fc);
return Object.assign(enrichedTestFn, extraKeys);
}
//#endregion
Object.defineProperty(exports, "__toESM", {
enumerable: true,
get: function() {
return __toESM;
}
});
Object.defineProperty(exports, "buildTest", {
enumerable: true,
get: function() {
return buildTest;
}
});