Test API
On this page
Test authoring and assertions. Importing this module does not register tests or install runner globals. Registration and assertions are ordinary effectful calls; the test command initializes its internal runner explicitly. Unused imports can be eliminated.
Import from maligator:test. This API is experimental. Load declarations as described in Use TypeScript. Platform imports do not require a surface flag.
Import tests and assertions from maligator:test; run them with maligator test. Tests and hooks may return promises, which the runner awaits. describe callbacks register suites synchronously and cannot return promises.
export function sum(values: ReadonlyArray<number>): number {
return values.reduce((total, value) => total + value, 0);
}import { describe, expect, test } from "maligator:test";
import { sum } from "./sum.ts";
describe("sum", () => {
test("adds values", () => {
expect(sum([1, 2, 3])).toBe(6);
});
test("accepts an empty input", () => {
expect(sum([])).toBe(0);
});
});Run maligator test sum.test.ts. See Test an application for discovery, selection, watch, timeouts, and isolation.
Assertions throw on mismatch. Promise matchers return promises; await them. Hooks follow suite nesting, and cleanup hooks are still attempted after a failing test. .only focuses selection and emits a warning. The reference below includes every supported matcher; it does not imply support for other testing libraries' APIs.
test
Register a test in the current suite.
export const test: TestFunction;Types: TestFunction
describe
Register a nested suite in the current suite.
export const describe: DescribeFunction;Types: DescribeFunction
expect
Create fluent matchers for a received value.
export const expect: ExpectFunction;Types: ExpectFunction
beforeAll
Run once before tests in the current suite.
export const beforeAll: (callback: HookCallback) => void;Types: HookCallback
afterAll
Run once after tests in the current suite, including after test failures.
export const afterAll: (callback: HookCallback) => void;Types: HookCallback
beforeEach
Run before every selected descendant test. Ancestor hooks run before hooks declared by a nested suite.
export const beforeEach: (callback: HookCallback) => void;Types: HookCallback
afterEach
Run after every selected descendant test. Nested-suite hooks run before ancestor hooks.
export const afterEach: (callback: HookCallback) => void;Types: HookCallback
TestCallback
A test or hook body. Maligator waits for a returned promise or thenable before advancing the lifecycle.
type TestCallback = () => unknown;HookCallback
A lifecycle hook body, with the same async completion contract as a test.
type HookCallback = TestCallback;Types: TestCallback
Constructor
A constructable value accepted by expect.any.
type Constructor = abstract new (...args: Array<never>) => unknown;AsymmetricMatcher
Opaque partial-match value produced by helpers such as expect.objectContaining. It may be nested inside toEqual, toStrictEqual, and toMatchObject expectations.
Full TypeScript declaration
type AsymmetricMatcher = {
readonly __maligator_asymmetric__: string;
};AsymmetricMatcher.maligator_asymmetric
readonly __maligator_asymmetric__: string;Matchers
Matchers for a synchronously received value.
Full TypeScript declaration
type Matchers = {
/** Negate the following matcher. */
readonly not: Matchers;
/** Wait for the received promise to fulfill, then match its value. */
readonly resolves: AsyncMatchers;
/** Wait for the received promise to reject, then match its reason. */
readonly rejects: AsyncMatchers;
/** Require ECMAScript `Object.is` identity. */
toBe(expected: unknown): void;
/** Recursively compare enumerable object properties and array elements. */
toEqual(expected: unknown): void;
/**
* Recursively compare values while also requiring matching prototypes and
* matching sparse-array holes.
*/
toStrictEqual(expected: unknown): void;
/** Require a value other than `undefined`. */
toBeDefined(): void;
/** Require `undefined`. */
toBeUndefined(): void;
/** Require `null`. */
toBeNull(): void;
/** Require a truthy value. */
toBeTruthy(): void;
/** Require a falsy value. */
toBeFalsy(): void;
/** Require a string substring or an array element matched by identity. */
toContain(expected: unknown): void;
/** Require a numeric `.length` equal to `expected`. */
toHaveLength(expected: number): void;
/** Match a string against a substring or regular expression. */
toMatch(expected: string | RegExp): void;
/** Recursively require the enumerable properties present in `expected`. */
toMatchObject(expected: object): void;
/**
* Invoke the received function and require it to throw. The optional
* expectation may be a message substring, regular expression, error
* constructor, or error instance.
*/
toThrow(
expected?:
| string
| RegExp
| Error
| (abstract new (...args: Array<never>) => Error),
): void;
};Types: AsyncMatchers
Matchers.not
Negate the following matcher.
readonly not: Matchers;Types: Matchers
Matchers.resolves
Wait for the received promise to fulfill, then match its value.
readonly resolves: AsyncMatchers;Types: AsyncMatchers
Matchers.rejects
Wait for the received promise to reject, then match its reason.
readonly rejects: AsyncMatchers;Types: AsyncMatchers
Matchers.toBe
Require ECMAScript Object.is identity.
toBe(expected: unknown): void;Matchers.toEqual
Recursively compare enumerable object properties and array elements.
toEqual(expected: unknown): void;Matchers.toStrictEqual
Recursively compare values while also requiring matching prototypes and matching sparse-array holes.
toStrictEqual(expected: unknown): void;Matchers.toBeDefined
Require a value other than undefined.
toBeDefined(): void;Matchers.toBeUndefined
Require undefined.
toBeUndefined(): void;Matchers.toBeNull
Require null.
toBeNull(): void;Matchers.toBeTruthy
Require a truthy value.
toBeTruthy(): void;Matchers.toBeFalsy
Require a falsy value.
toBeFalsy(): void;Matchers.toContain
Require a string substring or an array element matched by identity.
toContain(expected: unknown): void;Matchers.toHaveLength
Require a numeric .length equal to expected.
toHaveLength(expected: number): void;Matchers.toMatch
Match a string against a substring or regular expression.
toMatch(expected: string | RegExp): void;Matchers.toMatchObject
Recursively require the enumerable properties present in expected.
toMatchObject(expected: object): void;Matchers.toThrow
Invoke the received function and require it to throw. The optional expectation may be a message substring, regular expression, error constructor, or error instance.
toThrow(
expected?:
| string
| RegExp
| Error
| (abstract new (...args: Array<never>) => Error),
): void;AsyncMatchers
Promise-returning matcher surface exposed by Matchers.resolves and Matchers.rejects. Await these calls so the test cannot finish before the assertion.
Full TypeScript declaration
type AsyncMatchers = {
/** Negate the following asynchronous matcher. */
readonly not: AsyncMatchers;
toBe(expected: unknown): Promise<void>;
toEqual(expected: unknown): Promise<void>;
toStrictEqual(expected: unknown): Promise<void>;
toBeDefined(): Promise<void>;
toBeUndefined(): Promise<void>;
toBeNull(): Promise<void>;
toBeTruthy(): Promise<void>;
toBeFalsy(): Promise<void>;
toContain(expected: unknown): Promise<void>;
toHaveLength(expected: number): Promise<void>;
toMatch(expected: string | RegExp): Promise<void>;
toMatchObject(expected: object): Promise<void>;
toThrow(
expected?:
| string
| RegExp
| Error
| (abstract new (...args: Array<never>) => Error),
): Promise<void>;
};AsyncMatchers.not
Negate the following asynchronous matcher.
readonly not: AsyncMatchers;Types: AsyncMatchers
AsyncMatchers.toBe
toBe(expected: unknown): Promise<void>;AsyncMatchers.toEqual
toEqual(expected: unknown): Promise<void>;AsyncMatchers.toStrictEqual
toStrictEqual(expected: unknown): Promise<void>;AsyncMatchers.toBeDefined
toBeDefined(): Promise<void>;AsyncMatchers.toBeUndefined
toBeUndefined(): Promise<void>;AsyncMatchers.toBeNull
toBeNull(): Promise<void>;AsyncMatchers.toBeTruthy
toBeTruthy(): Promise<void>;AsyncMatchers.toBeFalsy
toBeFalsy(): Promise<void>;AsyncMatchers.toContain
toContain(expected: unknown): Promise<void>;AsyncMatchers.toHaveLength
toHaveLength(expected: number): Promise<void>;AsyncMatchers.toMatch
toMatch(expected: string | RegExp): Promise<void>;AsyncMatchers.toMatchObject
toMatchObject(expected: object): Promise<void>;AsyncMatchers.toThrow
toThrow(
expected?:
| string
| RegExp
| Error
| (abstract new (...args: Array<never>) => Error),
): Promise<void>;ExpectFunction
Assertion entrypoint and Maligator-owned asymmetric matcher factories.
Full TypeScript declaration
type ExpectFunction = {
/** Create matchers for `received`. The assertion position is captured here. */
(received: unknown): Matchers;
/** Match a primitive of the corresponding built-in kind or an instance. */
any(constructorValue: Constructor): AsymmetricMatcher;
/** Match any value except `null` and `undefined`. */
anything(): AsymmetricMatcher;
/** Match a string containing `pattern` or satisfying the regular expression. */
stringMatching(pattern: string | RegExp): AsymmetricMatcher;
/** Match an object containing all recursively matched properties in `value`. */
objectContaining(value: object): AsymmetricMatcher;
/** Match an array containing a match for every element in `value`. */
arrayContaining(value: Array<unknown>): AsymmetricMatcher;
};Types: Constructor, AsymmetricMatcher, Matchers
expect.any
Match a primitive of the corresponding built-in kind or an instance.
any(constructorValue: Constructor): AsymmetricMatcher;Types: Constructor, AsymmetricMatcher
expect.anything
Match any value except null and undefined.
anything(): AsymmetricMatcher;Types: AsymmetricMatcher
expect.stringMatching
Match a string containing pattern or satisfying the regular expression.
stringMatching(pattern: string | RegExp): AsymmetricMatcher;Types: AsymmetricMatcher
expect.objectContaining
Match an object containing all recursively matched properties in value.
objectContaining(value: object): AsymmetricMatcher;Types: AsymmetricMatcher
expect.arrayContaining
Match an array containing a match for every element in value.
arrayContaining(value: Array<unknown>): AsymmetricMatcher;Types: AsymmetricMatcher
TestFunction
Register tests in the current suite during module evaluation.
Full TypeScript declaration
type TestFunction = {
/** Register a test. Returned promises are awaited by the runner. */
(name: string, callback: TestCallback): void;
/** Register a skipped test without invoking its callback. */
skip(name: string, callback: TestCallback): void;
/** Register a named placeholder with no callback. */
todo(name: string): void;
/**
* Register a focused test. When any `.only` exists, non-focused tests are
* skipped and the runner emits a warning.
*/
only(name: string, callback: TestCallback): void;
/**
* Register one test for each row. Use `%#` in `name` for the zero-based row
* index. Array rows are spread into callback parameters.
*/
each<const Row extends ReadonlyArray<unknown>>(
rows: ReadonlyArray<Row>,
): (name: string, callback: (...values: [...Row]) => unknown) => void;
};Types: TestCallback
test.skip
Register a skipped test without invoking its callback.
skip(name: string, callback: TestCallback): void;Types: TestCallback
test.todo
Register a named placeholder with no callback.
todo(name: string): void;test.only
Register a focused test. When any .only exists, non-focused tests are
skipped and the runner emits a warning.
only(name: string, callback: TestCallback): void;Types: TestCallback
test.each
Register one test for each row. Use %# in name for the zero-based row
index. Array rows are spread into callback parameters.
each<const Row extends ReadonlyArray<unknown>>(
rows: ReadonlyArray<Row>,
): (name: string, callback: (...values: [...Row]) => unknown) => void;DescribeFunction
Register nested suites synchronously during module evaluation.
Full TypeScript declaration
type DescribeFunction = {
/** Register a suite. Suite callbacks must not return a promise. */
(name: string, callback: () => void): void;
/** Register a suite whose descendants are skipped. */
skip(name: string, callback: () => void): void;
/** Register a focused suite and emit the runner's focused-test warning. */
only(name: string, callback: () => void): void;
};describe.skip
Register a suite whose descendants are skipped.
skip(name: string, callback: () => void): void;describe.only
Register a focused suite and emit the runner's focused-test warning.
only(name: string, callback: () => void): void;