@augment-vir/assert
Version:
A collection of assertions for test and production code alike.
183 lines (182 loc) • 14.3 kB
TypeScript
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 {};