UNPKG

@augment-vir/assert

Version:

A collection of assertions for test and production code alike.

183 lines (182 loc) 14.3 kB
import { type AnyFunction } from '@augment-vir/core'; import { type IsAny } from 'type-fest'; import { type WaitUntilOptions } from '../guard-types/wait-until-function.js'; /** * A custom asserter for `.output` guards (`assert.output`, `check.output`, etc.). This is typically * not necessary, as the `.output` guards already perform deep equality checks by default. * * @category Assert : Util * @category Package : @augment-vir/assert * @example * * ```ts * import {assert, AssertionError, CustomOutputAsserter} from '@augment-vir/assert'; * * function myFunctionToTest(name: string) { * return `Hello there ${name}`; * } * * const myCustomAsserter: CustomOutputAsserter<typeof myFunctionToTest> = ( * actual, * expected, * failureMessage, * ) => { * // Write your assertion in an `if`. * if (!actual.startsWith('hello there') || actual.endsWith(expected)) { * // Throw an `AssertionError` if the `if` fails. * throw new AssertionError('', failureMessage); * } * }; * // Use your custom asserter as the first input to any `.output` guard. * assert.output(myCustomAsserter, myFunctionToTest, ['John'], 'John', 'Name insertion failed'); * ``` * * @param FunctionToCall The function type that your custom asserter will be run on. * @package [`@augment-vir/assert`](https://www.npmjs.com/package/@augment-vir/assert) */ export type CustomOutputAsserter<FunctionToCall extends AnyFunction> = (actual: Awaited<ReturnType<FunctionToCall>>, expected: Awaited<ReturnType<FunctionToCall>>, failureMessage?: string | undefined) => void; type OutputReturn<FunctionToCall extends AnyFunction, Return> = Promise<any> extends ReturnType<NoInfer<FunctionToCall>> ? IsAny<ReturnType<FunctionToCall>> extends true ? Return : Promise<Return> : Return; export type OutputAssertWithoutAsserter = <const FunctionToCall extends AnyFunction>(functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined) => OutputReturn<NoInfer<FunctionToCall>, void>; export type OutputAssertWithAsserter = <const FunctionToCall extends AnyFunction>(asserter: CustomOutputAsserter<NoInfer<FunctionToCall>>, functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined) => OutputReturn<NoInfer<FunctionToCall>, void>; declare function assertOutput<const FunctionToCall extends AnyFunction>(functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined): OutputReturn<NoInfer<FunctionToCall>, void>; declare function assertOutput<const FunctionToCall extends AnyFunction>(asserter: CustomOutputAsserter<NoInfer<FunctionToCall>>, functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined): OutputReturn<NoInfer<FunctionToCall>, void>; export type OutputCheckWithoutAsserter = <const FunctionToCall extends AnyFunction>(functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined) => OutputReturn<NoInfer<FunctionToCall>, boolean>; export type OutputCheckWithAsserter = <const FunctionToCall extends AnyFunction>(asserter: CustomOutputAsserter<NoInfer<FunctionToCall>>, functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined) => OutputReturn<NoInfer<FunctionToCall>, boolean>; declare function checkOutput<const FunctionToCall extends AnyFunction>(functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined): OutputReturn<FunctionToCall, boolean>; declare function checkOutput<const FunctionToCall extends AnyFunction>(asserter: CustomOutputAsserter<NoInfer<FunctionToCall>>, functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined): OutputReturn<FunctionToCall, boolean>; export type OutputAssertWrapWithoutAsserter = <const FunctionToCall extends AnyFunction>(functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined) => OutputReturn<NoInfer<FunctionToCall>, Awaited<ReturnType<NoInfer<FunctionToCall>>>>; export type OutputAssertWrapWithAsserter = <const FunctionToCall extends AnyFunction>(asserter: CustomOutputAsserter<NoInfer<FunctionToCall>>, functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined) => OutputReturn<NoInfer<FunctionToCall>, Awaited<ReturnType<NoInfer<FunctionToCall>>>>; declare function assertWrapOutput<const FunctionToCall extends AnyFunction>(functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined): OutputReturn<FunctionToCall, Awaited<ReturnType<NoInfer<FunctionToCall>>>>; declare function assertWrapOutput<const FunctionToCall extends AnyFunction>(asserter: CustomOutputAsserter<NoInfer<FunctionToCall>>, functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined): OutputReturn<FunctionToCall, Awaited<ReturnType<NoInfer<FunctionToCall>>>>; export type OutputCheckWrapWithoutAsserter = <const FunctionToCall extends AnyFunction>(functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined) => OutputReturn<NoInfer<FunctionToCall>, Awaited<ReturnType<NoInfer<FunctionToCall>>> | undefined>; export type OutputCheckWrapWithAsserter = <const FunctionToCall extends AnyFunction>(asserter: CustomOutputAsserter<NoInfer<FunctionToCall>>, functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined) => OutputReturn<NoInfer<FunctionToCall>, Awaited<ReturnType<NoInfer<FunctionToCall>>> | undefined>; declare function checkWrapOutput<const FunctionToCall extends AnyFunction>(functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined): OutputReturn<FunctionToCall, Awaited<ReturnType<NoInfer<FunctionToCall>>> | undefined>; declare function checkWrapOutput<const FunctionToCall extends AnyFunction>(asserter: CustomOutputAsserter<NoInfer<FunctionToCall>>, functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, failureMessage?: string | undefined): OutputReturn<FunctionToCall, Awaited<ReturnType<NoInfer<FunctionToCall>>> | undefined>; export type OutputWaitUntilWithoutAsserter = <const FunctionToCall extends AnyFunction>(functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, options?: WaitUntilOptions | undefined, failureMessage?: string | undefined) => Promise<Awaited<ReturnType<NoInfer<FunctionToCall>>>>; export type OutputWaitUntilWithAsserter = <const FunctionToCall extends AnyFunction>(asserter: CustomOutputAsserter<NoInfer<FunctionToCall>>, functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, options?: WaitUntilOptions | undefined, failureMessage?: string | undefined) => Promise<Awaited<ReturnType<NoInfer<FunctionToCall>>>>; export declare function waitUntilOutput<const FunctionToCall extends AnyFunction>(functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, options?: WaitUntilOptions | undefined, failureMessage?: string | undefined): Promise<Awaited<ReturnType<NoInfer<FunctionToCall>>>>; export declare function waitUntilOutput<const FunctionToCall extends AnyFunction>(asserter: CustomOutputAsserter<NoInfer<FunctionToCall>>, functionToCall: FunctionToCall, inputs: Parameters<NoInfer<FunctionToCall>>, expectedOutput: Awaited<ReturnType<NoInfer<FunctionToCall>>>, options?: WaitUntilOptions | undefined, failureMessage?: string | undefined): Promise<Awaited<ReturnType<NoInfer<FunctionToCall>>>>; export declare const outputGuards: { assert: { /** * Asserts that the output of the given function deeply equals expectations. A custom asserter * can optionally be provided as the first argument to change the expectation checking from * "deeply equals" to whatever you want. * * Performs no type guarding. * * ```ts * import {assert} from '@augment-vir/assert'; * * assert.output((input: number) => String(input), [5], '5'); // passes * assert.output((input: number) => String(input), [10], '5'); // fails * * assert.output(assert.isLengthAtLeast, (input: number) => String(input), [5], 2); // fails * assert.output(assert.isLengthAtLeast, (input: number) => String(input), [10], 2); // passes * ``` * * @throws {@link AssertionError} If the assertion fails. */ output: typeof assertOutput; }; check: { /** * Checks that the output of the given function deeply equals expectations. A custom * asserter can optionally be provided as the first argument to change the expectation * checking from the default "deeply equals" to whatever you want. * * Performs no type guarding. * * ```ts * import {check} from '@augment-vir/assert'; * * check.output((input: number) => String(input), [5], '5'); // returns `true` * check.output((input: number) => String(input), [10], '5'); // returns `false` * * check.output(assert.isLengthAtLeast, (input: number) => String(input), [5], 2); // returns `false` * check.output(assert.isLengthAtLeast, (input: number) => String(input), [10], 2); // returns `true` * ``` */ output: typeof checkOutput; }; assertWrap: { /** * Asserts that the output of the given function deeply equals expectations. A custom * asserter can optionally be provided as the first argument to change the expectation * checking from the default "deeply equals" to whatever you want. Returns the output if the * assertion passes. * * Performs no type guarding. * * ```ts * import {assertWrap} from '@augment-vir/assert'; * * assertWrap.output((input: number) => String(input), [5], '5'); // returns `'5'` * assertWrap.output((input: number) => String(input), [10], '5'); // throws an error * * assertWrap.output(assert.isLengthAtLeast, (input: number) => String(input), [5], 2); // throws an error * assertWrap.output(assert.isLengthAtLeast, (input: number) => String(input), [10], 2); // returns `10` * ``` * * @returns The output if the assertion passes. * @throws {@link AssertionError} If the assertion fails. */ output: typeof assertWrapOutput; }; checkWrap: { /** * Asserts that the output of the given function deeply equals expectations. A custom * asserter can optionally be provided as the first argument to change the expectation * checking from the default "deeply equals" to whatever you want. Returns the output if the * check passes, otherwise `undefined`. * * Performs no type guarding. * * ```ts * import {checkWrap} from '@augment-vir/assert'; * * checkWrap.output((input: number) => String(input), [5], '5'); // returns `'5'` * checkWrap.output((input: number) => String(input), [10], '5'); // returns `undefined` * * checkWrap.output(assert.isLengthAtLeast, (input: number) => String(input), [5], 2); // returns `undefined` * checkWrap.output(assert.isLengthAtLeast, (input: number) => String(input), [10], 2); // returns `10` * ``` * * @returns The output if the assertion passes, otherwise `undefined`. */ output: typeof checkWrapOutput; }; waitUntil: { /** * Repeatedly calls a callback until its output deeply equals expectations. A custom * asserter can optionally be provided as the first argument to change the expectation * checking from the default "deeply equals" to whatever you want. * * Performs no type guarding. * * ```ts * import {waitUntil} from '@augment-vir/assert'; * * await waitUntil.output((input: number) => String(input), [5], '5'); // returns `'5'` * await waitUntil.output((input: number) => String(input), [10], '5'); // throws an error * * await waitUntil.output( * assert.isLengthAtLeast, * (input: number) => String(input), * [5], * 2, * ); // throws an error * await waitUntil.output( * assert.isLengthAtLeast, * (input: number) => String(input), * [10], * 2, * ); // returns `10` * ``` * * @throws {@link AssertionError} If the assertion fails. */ output: typeof waitUntilOutput; }; }; export {};