diff --git a/src/index.ts b/src/index.ts index 10a7fab..43907a2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,6 +10,20 @@ export interface ErrorParameters extends Parameters { errorReporter?: ErrorReporter; } +/** + * Run a suite of test scenarios with the same arbitrary `strategy`. Each test in the `suite` will be run separately + * with its own set of values, generated by the fast-check runner. + * + * This is a wrapper for Mocha's `describe`, and the `it` function passed to `suite` is a wrapper for Mocha's `it`. + * Most Mocha features, like `beforeEach` hooks, should work normally and will operate at the `over` level. + * + * @param name the suite name, as you would pass to `describe(name, suite)` + * @param strategy a fast-check `Arbitrary` used to produce semi-random values + * @param suite the test suite, as you would pass to `describe(name, suite)` + * @param parameters additional parameters to the fast-check `Runner` + * @throws Error when the property check fails + * @public + */ export function over(name: string, strategy: Arbitrary, suite: Suite, parameters: ErrorParameters = {}): void { describe(name, () => { suite((name, test) => { @@ -42,6 +56,13 @@ export function over(name: string, strategy: Arbitrary, suite: Suite, p }); } +/** + * Format the details of a fast-check run. This always returns a string and will not throw or print to the console, + * whether the run was successful or failed. This is compatible with fast-check's `defaultReportMessage` function, + * but produces a shorter message. + * + * @public + */ export function briefReporter(details: RunDetails<[T]>): string { const prefix = formatPrefix(details); const counts = `${prefix} after ${details.numRuns} runs and ${details.numShrinks} shrinks`; @@ -54,6 +75,11 @@ export function briefReporter(details: RunDetails<[T]>): string { } } +/** + * Format the counterexamples in a run's details. + * + * @private + */ export function formatExamples(details: RunDetails<[T]>): string { if (details.counterexample !== null) { const examples = details.counterexample.map((val) => { @@ -69,6 +95,11 @@ export function formatExamples(details: RunDetails<[T]>): string { } } +/** + * Format the friendly prefix for the run details, indicating whether it returned false or threw an error. + * + * @private + */ export function formatPrefix(details: RunDetails<[T]>): string { if (isErrorRun(details)) { return 'Property failed by throwing an error'; @@ -81,13 +112,22 @@ export function formatPrefix(details: RunDetails<[T]>): string { return 'Property failed without a reason'; } -export function isString(val: unknown): val is string { - return typeof val === 'string'; -} - +/** + * Guess whether the run threw an error. + * + * @private + */ export function isErrorRun(details: RunDetails): boolean { if (isString(details.error)) { return /^([A-Z][a-z]*)*Error:/.test(details.error); } + return false; -} \ No newline at end of file +} + +/** + * Typeguard for string primitives. + */ +export function isString(val: unknown): val is string { + return typeof val === 'string'; +}