fast-check
Version:
Property based testing framework for JavaScript (like QuickCheck)
111 lines (110 loc) • 4.84 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultReportMessage = exports.reportRunDetails = void 0;
const stringify_1 = require("../../../utils/stringify");
const VerbosityLevel_1 = require("../configuration/VerbosityLevel");
const ExecutionStatus_1 = require("../reporter/ExecutionStatus");
function formatHints(hints) {
if (hints.length === 1) {
return `Hint: ${hints[0]}`;
}
return hints.map((h, idx) => `Hint (${idx + 1}): ${h}`).join('\n');
}
function formatFailures(failures) {
return `Encountered failures were:\n- ${failures.map(stringify_1.stringify).join('\n- ')}`;
}
function formatExecutionSummary(executionTrees) {
const summaryLines = [];
const remainingTreesAndDepth = [];
for (const tree of executionTrees.reverse()) {
remainingTreesAndDepth.push({ depth: 1, tree });
}
while (remainingTreesAndDepth.length !== 0) {
const currentTreeAndDepth = remainingTreesAndDepth.pop();
const currentTree = currentTreeAndDepth.tree;
const currentDepth = currentTreeAndDepth.depth;
const statusIcon = currentTree.status === ExecutionStatus_1.ExecutionStatus.Success
? '\x1b[32m\u221A\x1b[0m'
: currentTree.status === ExecutionStatus_1.ExecutionStatus.Failure
? '\x1b[31m\xD7\x1b[0m'
: '\x1b[33m!\x1b[0m';
const leftPadding = Array(currentDepth).join('. ');
summaryLines.push(`${leftPadding}${statusIcon} ${stringify_1.stringify(currentTree.value)}`);
for (const tree of currentTree.children.reverse()) {
remainingTreesAndDepth.push({ depth: currentDepth + 1, tree });
}
}
return `Execution summary:\n${summaryLines.join('\n')}`;
}
function preFormatTooManySkipped(out) {
const message = `Failed to run property, too many pre-condition failures encountered\n{ seed: ${out.seed} }\n\nRan ${out.numRuns} time(s)\nSkipped ${out.numSkips} time(s)`;
let details = null;
const hints = [
'Try to reduce the number of rejected values by combining map, flatMap and built-in arbitraries',
'Increase failure tolerance by setting maxSkipsPerRun to an higher value',
];
if (out.verbose >= VerbosityLevel_1.VerbosityLevel.VeryVerbose) {
details = formatExecutionSummary(out.executionSummary);
}
else {
hints.push('Enable verbose mode at level VeryVerbose in order to check all generated values and their associated status');
}
return { message, details, hints };
}
function preFormatFailure(out) {
const message = `Property failed after ${out.numRuns} tests\n{ seed: ${out.seed}, path: "${out.counterexamplePath}", endOnFailure: true }\nCounterexample: ${stringify_1.stringify(out.counterexample)}\nShrunk ${out.numShrinks} time(s)\nGot error: ${out.error}`;
let details = null;
const hints = [];
if (out.verbose >= VerbosityLevel_1.VerbosityLevel.VeryVerbose) {
details = formatExecutionSummary(out.executionSummary);
}
else if (out.verbose === VerbosityLevel_1.VerbosityLevel.Verbose) {
details = formatFailures(out.failures);
}
else {
hints.push('Enable verbose mode in order to have the list of all failing values encountered during the run');
}
return { message, details, hints };
}
function preFormatEarlyInterrupted(out) {
const message = `Property interrupted after ${out.numRuns} tests\n{ seed: ${out.seed} }`;
let details = null;
const hints = [];
if (out.verbose >= VerbosityLevel_1.VerbosityLevel.VeryVerbose) {
details = formatExecutionSummary(out.executionSummary);
}
else {
hints.push('Enable verbose mode at level VeryVerbose in order to check all generated values and their associated status');
}
return { message, details, hints };
}
function defaultReportMessage(out) {
if (!out.failed)
return;
const { message, details, hints } = out.counterexamplePath === null
? out.interrupted
? preFormatEarlyInterrupted(out)
: preFormatTooManySkipped(out)
: preFormatFailure(out);
let errorMessage = message;
if (details != null)
errorMessage += `\n\n${details}`;
if (hints.length > 0)
errorMessage += `\n\n${formatHints(hints)}`;
return errorMessage;
}
exports.defaultReportMessage = defaultReportMessage;
function throwIfFailed(out) {
if (!out.failed)
return;
throw new Error(defaultReportMessage(out));
}
function reportRunDetails(out) {
if (out.runConfiguration.asyncReporter)
return out.runConfiguration.asyncReporter(out);
else if (out.runConfiguration.reporter)
return out.runConfiguration.reporter(out);
else
return throwIfFailed(out);
}
exports.reportRunDetails = reportRunDetails;