UNPKG

fast-check

Version:

Property based testing framework for JavaScript (like QuickCheck)

111 lines (110 loc) 4.84 kB
"use strict"; 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;