# Test API

Maligator 0.1.0-alpha.35 · Experimental
Source revision: c27b6cae5dcbe612a78ebe5388652738e35f229f
Canonical: https://maligator.ddv.tools/api/test

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](/guides/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.


```typescript sum.ts
export function sum(values: ReadonlyArray<number>): number {
	return values.reduce((total, value) => total + value, 0);
}
```



```typescript sum.test.ts
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](/guides/testing) 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.

<a id="test"></a>

## test

Register a test in the current suite.

```typescript
export const test: TestFunction;
```

Types: [`TestFunction`](/api/test#TestFunction)



<a id="describe"></a>

## describe

Register a nested suite in the current suite.

```typescript
export const describe: DescribeFunction;
```

Types: [`DescribeFunction`](/api/test#DescribeFunction)



<a id="expect"></a>

## expect

Create fluent matchers for a received value.

```typescript
export const expect: ExpectFunction;
```

Types: [`ExpectFunction`](/api/test#ExpectFunction)



<a id="beforeAll"></a>

## beforeAll

Run once before tests in the current suite.

```typescript
export const beforeAll: (callback: HookCallback) => void;
```

Types: [`HookCallback`](/api/test#HookCallback)



<a id="afterAll"></a>

## afterAll

Run once after tests in the current suite, including after test failures.

```typescript
export const afterAll: (callback: HookCallback) => void;
```

Types: [`HookCallback`](/api/test#HookCallback)



<a id="beforeEach"></a>

## beforeEach

Run before every selected descendant test. Ancestor hooks run before hooks
declared by a nested suite.

```typescript
export const beforeEach: (callback: HookCallback) => void;
```

Types: [`HookCallback`](/api/test#HookCallback)



<a id="afterEach"></a>

## afterEach

Run after every selected descendant test. Nested-suite hooks run before
ancestor hooks.

```typescript
export const afterEach: (callback: HookCallback) => void;
```

Types: [`HookCallback`](/api/test#HookCallback)



<a id="TestCallback"></a>

## TestCallback

A test or hook body. Maligator waits for a returned promise or thenable before advancing the lifecycle.

```typescript
type TestCallback = () => unknown;
```


<a id="HookCallback"></a>

## HookCallback

A lifecycle hook body, with the same async completion contract as a test.

```typescript
type HookCallback = TestCallback;
```

Types: [`TestCallback`](/api/test#TestCallback)



<a id="Constructor"></a>

## Constructor

A constructable value accepted by [`expect.any`](/api/test#expect.any).

```typescript
type Constructor = abstract new (...args: Array<never>) => unknown;
```


<a id="AsymmetricMatcher"></a>

## AsymmetricMatcher

Opaque partial-match value produced by helpers such as [`expect.objectContaining`](/api/test#expect.objectContaining). It may be nested inside `toEqual`, `toStrictEqual`, and `toMatchObject` expectations.
<details><summary>Full TypeScript declaration</summary>


```typescript
type AsymmetricMatcher = {
		readonly __maligator_asymmetric__: string;
	};
```

</details>


<a id="AsymmetricMatcher.__maligator_asymmetric__"></a>

### AsymmetricMatcher.__maligator_asymmetric__



```typescript
readonly __maligator_asymmetric__: string;
```


<a id="Matchers"></a>

## Matchers

Matchers for a synchronously received value.
<details><summary>Full TypeScript declaration</summary>


```typescript
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`](/api/test#AsyncMatchers)


</details>


<a id="Matchers.not"></a>

### Matchers.not

Negate the following matcher.

```typescript
readonly not: Matchers;
```

Types: [`Matchers`](/api/test#Matchers)



<a id="Matchers.resolves"></a>

### Matchers.resolves

Wait for the received promise to fulfill, then match its value.

```typescript
readonly resolves: AsyncMatchers;
```

Types: [`AsyncMatchers`](/api/test#AsyncMatchers)



<a id="Matchers.rejects"></a>

### Matchers.rejects

Wait for the received promise to reject, then match its reason.

```typescript
readonly rejects: AsyncMatchers;
```

Types: [`AsyncMatchers`](/api/test#AsyncMatchers)



<a id="Matchers.toBe"></a>

### Matchers.toBe

Require ECMAScript `Object.is` identity.

```typescript
toBe(expected: unknown): void;
```


<a id="Matchers.toEqual"></a>

### Matchers.toEqual

Recursively compare enumerable object properties and array elements.

```typescript
toEqual(expected: unknown): void;
```


<a id="Matchers.toStrictEqual"></a>

### Matchers.toStrictEqual

Recursively compare values while also requiring matching prototypes and
matching sparse-array holes.

```typescript
toStrictEqual(expected: unknown): void;
```


<a id="Matchers.toBeDefined"></a>

### Matchers.toBeDefined

Require a value other than `undefined`.

```typescript
toBeDefined(): void;
```


<a id="Matchers.toBeUndefined"></a>

### Matchers.toBeUndefined

Require `undefined`.

```typescript
toBeUndefined(): void;
```


<a id="Matchers.toBeNull"></a>

### Matchers.toBeNull

Require `null`.

```typescript
toBeNull(): void;
```


<a id="Matchers.toBeTruthy"></a>

### Matchers.toBeTruthy

Require a truthy value.

```typescript
toBeTruthy(): void;
```


<a id="Matchers.toBeFalsy"></a>

### Matchers.toBeFalsy

Require a falsy value.

```typescript
toBeFalsy(): void;
```


<a id="Matchers.toContain"></a>

### Matchers.toContain

Require a string substring or an array element matched by identity.

```typescript
toContain(expected: unknown): void;
```


<a id="Matchers.toHaveLength"></a>

### Matchers.toHaveLength

Require a numeric `.length` equal to `expected`.

```typescript
toHaveLength(expected: number): void;
```


<a id="Matchers.toMatch"></a>

### Matchers.toMatch

Match a string against a substring or regular expression.

```typescript
toMatch(expected: string | RegExp): void;
```


<a id="Matchers.toMatchObject"></a>

### Matchers.toMatchObject

Recursively require the enumerable properties present in `expected`.

```typescript
toMatchObject(expected: object): void;
```


<a id="Matchers.toThrow"></a>

### 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.

```typescript
toThrow(
			expected?:
				| string
				| RegExp
				| Error
				| (abstract new (...args: Array<never>) => Error),
		): void;
```


<a id="AsyncMatchers"></a>

## AsyncMatchers

Promise-returning matcher surface exposed by [`Matchers.resolves`](/api/test#Matchers.resolves) and [`Matchers.rejects`](/api/test#Matchers.rejects). Await these calls so the test cannot finish before the assertion.
<details><summary>Full TypeScript declaration</summary>


```typescript
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>;
	};
```

</details>


<a id="AsyncMatchers.not"></a>

### AsyncMatchers.not

Negate the following asynchronous matcher.

```typescript
readonly not: AsyncMatchers;
```

Types: [`AsyncMatchers`](/api/test#AsyncMatchers)



<a id="AsyncMatchers.toBe"></a>

### AsyncMatchers.toBe



```typescript
toBe(expected: unknown): Promise<void>;
```


<a id="AsyncMatchers.toEqual"></a>

### AsyncMatchers.toEqual



```typescript
toEqual(expected: unknown): Promise<void>;
```


<a id="AsyncMatchers.toStrictEqual"></a>

### AsyncMatchers.toStrictEqual



```typescript
toStrictEqual(expected: unknown): Promise<void>;
```


<a id="AsyncMatchers.toBeDefined"></a>

### AsyncMatchers.toBeDefined



```typescript
toBeDefined(): Promise<void>;
```


<a id="AsyncMatchers.toBeUndefined"></a>

### AsyncMatchers.toBeUndefined



```typescript
toBeUndefined(): Promise<void>;
```


<a id="AsyncMatchers.toBeNull"></a>

### AsyncMatchers.toBeNull



```typescript
toBeNull(): Promise<void>;
```


<a id="AsyncMatchers.toBeTruthy"></a>

### AsyncMatchers.toBeTruthy



```typescript
toBeTruthy(): Promise<void>;
```


<a id="AsyncMatchers.toBeFalsy"></a>

### AsyncMatchers.toBeFalsy



```typescript
toBeFalsy(): Promise<void>;
```


<a id="AsyncMatchers.toContain"></a>

### AsyncMatchers.toContain



```typescript
toContain(expected: unknown): Promise<void>;
```


<a id="AsyncMatchers.toHaveLength"></a>

### AsyncMatchers.toHaveLength



```typescript
toHaveLength(expected: number): Promise<void>;
```


<a id="AsyncMatchers.toMatch"></a>

### AsyncMatchers.toMatch



```typescript
toMatch(expected: string | RegExp): Promise<void>;
```


<a id="AsyncMatchers.toMatchObject"></a>

### AsyncMatchers.toMatchObject



```typescript
toMatchObject(expected: object): Promise<void>;
```


<a id="AsyncMatchers.toThrow"></a>

### AsyncMatchers.toThrow



```typescript
toThrow(
			expected?:
				| string
				| RegExp
				| Error
				| (abstract new (...args: Array<never>) => Error),
		): Promise<void>;
```


<a id="ExpectFunction"></a>

## ExpectFunction

Assertion entrypoint and Maligator-owned asymmetric matcher factories.
<details><summary>Full TypeScript declaration</summary>


```typescript
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`](/api/test#Constructor), [`AsymmetricMatcher`](/api/test#AsymmetricMatcher), [`Matchers`](/api/test#Matchers)


</details>


<a id="expect.any"></a>

### expect.any

Match a primitive of the corresponding built-in kind or an instance.

```typescript
any(constructorValue: Constructor): AsymmetricMatcher;
```

Types: [`Constructor`](/api/test#Constructor), [`AsymmetricMatcher`](/api/test#AsymmetricMatcher)



<a id="expect.anything"></a>

### expect.anything

Match any value except `null` and `undefined`.

```typescript
anything(): AsymmetricMatcher;
```

Types: [`AsymmetricMatcher`](/api/test#AsymmetricMatcher)



<a id="expect.stringMatching"></a>

### expect.stringMatching

Match a string containing `pattern` or satisfying the regular expression.

```typescript
stringMatching(pattern: string | RegExp): AsymmetricMatcher;
```

Types: [`AsymmetricMatcher`](/api/test#AsymmetricMatcher)



<a id="expect.objectContaining"></a>

### expect.objectContaining

Match an object containing all recursively matched properties in `value`.

```typescript
objectContaining(value: object): AsymmetricMatcher;
```

Types: [`AsymmetricMatcher`](/api/test#AsymmetricMatcher)



<a id="expect.arrayContaining"></a>

### expect.arrayContaining

Match an array containing a match for every element in `value`.

```typescript
arrayContaining(value: Array<unknown>): AsymmetricMatcher;
```

Types: [`AsymmetricMatcher`](/api/test#AsymmetricMatcher)



<a id="TestFunction"></a>

## TestFunction

Register tests in the current suite during module evaluation.
<details><summary>Full TypeScript declaration</summary>


```typescript
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`](/api/test#TestCallback)


</details>


<a id="test.skip"></a>

### test.skip

Register a skipped test without invoking its callback.

```typescript
skip(name: string, callback: TestCallback): void;
```

Types: [`TestCallback`](/api/test#TestCallback)



<a id="test.todo"></a>

### test.todo

Register a named placeholder with no callback.

```typescript
todo(name: string): void;
```


<a id="test.only"></a>

### test.only

Register a focused test. When any `.only` exists, non-focused tests are
skipped and the runner emits a warning.

```typescript
only(name: string, callback: TestCallback): void;
```

Types: [`TestCallback`](/api/test#TestCallback)



<a id="test.each"></a>

### test.each

Register one test for each row. Use `%#` in `name` for the zero-based row
index. Array rows are spread into callback parameters.

```typescript
each<const Row extends ReadonlyArray<unknown>>(
			rows: ReadonlyArray<Row>,
		): (name: string, callback: (...values: [...Row]) => unknown) => void;
```


<a id="DescribeFunction"></a>

## DescribeFunction

Register nested suites synchronously during module evaluation.
<details><summary>Full TypeScript declaration</summary>


```typescript
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;
	};
```

</details>


<a id="describe.skip"></a>

### describe.skip

Register a suite whose descendants are skipped.

```typescript
skip(name: string, callback: () => void): void;
```


<a id="describe.only"></a>

### describe.only

Register a focused suite and emit the runner's focused-test warning.

```typescript
only(name: string, callback: () => void): void;
```

