1tube 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/test/api.d.ts +55 -13
- package/dist/test/api.js +5 -5
- package/dist/test/assert.d.ts +2 -0
- package/dist/test/assert.js +3 -3
- package/dist/test/core.d.ts +19 -0
- package/dist/test/core.js +100 -0
- package/dist/test/expect.d.ts +128 -0
- package/dist/test/expect.js +592 -0
- package/dist/test/node.d.ts +4 -7
- package/dist/test/node.js +26 -16
- package/package.json +1 -1
- package/src/cli/test.ts +16 -1
- package/src/test/api.ts +64 -13
- package/src/test/assert.ts +3 -3
- package/src/test/bun.ts +20 -24
- package/src/test/core.ts +130 -0
- package/src/test/expect.ts +720 -0
- package/src/test/node.ts +31 -31
package/dist/test/api.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The `1tube/test` contract every runner binding implements.
|
|
3
3
|
*
|
|
4
|
-
* Edge function tests import `test`, `describe`, hooks
|
|
5
|
-
* `1tube/test` instead of a specific runner, so the same
|
|
6
|
-
* `bun test` today and under another runtime's runner
|
|
7
|
-
* pool) later. Keep this surface to what every runner
|
|
8
|
-
* context argument, no runner-specific options.
|
|
4
|
+
* Edge function tests import `test`, `describe`, hooks, `expect`, mocks and
|
|
5
|
+
* assertions from `1tube/test` instead of a specific runner, so the same
|
|
6
|
+
* files run under `bun test` today and under another runtime's runner
|
|
7
|
+
* (node:test, a workerd pool) later. Keep this surface to what every runner
|
|
8
|
+
* can express: no test context argument, no runner-specific options.
|
|
9
9
|
*/
|
|
10
|
+
import type { Mock } from "./expect.ts";
|
|
10
11
|
export type TestFn = () => void | Promise<unknown>;
|
|
11
12
|
export type HookFn = () => void | Promise<unknown>;
|
|
12
13
|
export interface TestOptions {
|
|
@@ -17,18 +18,59 @@ export interface TestOptions {
|
|
|
17
18
|
/** Run only tests marked `only` (where the runner supports focusing). */
|
|
18
19
|
only?: boolean;
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
/** Row arguments for `.each`: array rows spread, anything else is one argument. */
|
|
22
|
+
export type EachArgs<Row> = Row extends readonly unknown[] ? Row : [Row];
|
|
23
|
+
export type RegisterTest = (name: string, fn: TestFn, options?: TestOptions) => void;
|
|
24
|
+
export interface TestFunction extends RegisterTest {
|
|
25
|
+
skip: RegisterTest;
|
|
26
|
+
only: RegisterTest;
|
|
24
27
|
/** A placeholder for a test that is not written yet. */
|
|
25
28
|
todo(name: string): void;
|
|
29
|
+
/** Register normally when `condition` is truthy, else as skipped. */
|
|
30
|
+
if(condition: unknown): RegisterTest;
|
|
31
|
+
/** Register as skipped when `condition` is truthy. */
|
|
32
|
+
skipIf(condition: unknown): RegisterTest;
|
|
33
|
+
/**
|
|
34
|
+
* One test per row. The name supports printf placeholders (`%s %d %i %f
|
|
35
|
+
* %j %o %p %#`) and `$key` for object rows.
|
|
36
|
+
*/
|
|
37
|
+
each<Row>(table: readonly Row[]): (name: string, fn: (...args: EachArgs<Row>) => void | Promise<unknown>, options?: TestOptions) => void;
|
|
26
38
|
}
|
|
27
|
-
export
|
|
28
|
-
|
|
29
|
-
skip
|
|
30
|
-
only
|
|
39
|
+
export type RegisterSuite = (name: string, fn: () => void) => void;
|
|
40
|
+
export interface DescribeFunction extends RegisterSuite {
|
|
41
|
+
skip: RegisterSuite;
|
|
42
|
+
only: RegisterSuite;
|
|
43
|
+
if(condition: unknown): RegisterSuite;
|
|
44
|
+
skipIf(condition: unknown): RegisterSuite;
|
|
45
|
+
each<Row>(table: readonly Row[]): (name: string, fn: (...args: EachArgs<Row>) => void) => void;
|
|
31
46
|
}
|
|
32
47
|
export type Hook = (fn: HookFn) => void;
|
|
48
|
+
type AnyFn = (...args: any[]) => any;
|
|
49
|
+
export interface MockFunction {
|
|
50
|
+
/** A mock function (records calls; optional implementation). */
|
|
51
|
+
<T extends AnyFn = AnyFn>(impl?: T): Mock<T>;
|
|
52
|
+
/**
|
|
53
|
+
* Replace a module for subsequently loaded importers. The specifier must
|
|
54
|
+
* be absolute — a shared helper can't know which file called it — so
|
|
55
|
+
* pass `import.meta.resolve("./dep.ts")` or a package name. The factory
|
|
56
|
+
* returns the module's exports (`default` for the default export).
|
|
57
|
+
*/
|
|
58
|
+
module(specifier: string | URL, factory: () => Record<string, unknown>): void;
|
|
59
|
+
/** Restore every `spyOn` replacement. */
|
|
60
|
+
restore(): void;
|
|
61
|
+
}
|
|
33
62
|
/** Which runner the active binding drives. */
|
|
34
63
|
export type TestRuntime = "bun" | "node";
|
|
64
|
+
/** What a runner binding provides; `createTestApi` builds the rest. */
|
|
65
|
+
export interface RunnerBase {
|
|
66
|
+
test(name: string, fn: TestFn, options: TestOptions): void;
|
|
67
|
+
todo(name: string): void;
|
|
68
|
+
describe(name: string, fn: () => void, mode: "run" | "skip" | "only"): void;
|
|
69
|
+
beforeAll: Hook;
|
|
70
|
+
afterAll: Hook;
|
|
71
|
+
beforeEach: Hook;
|
|
72
|
+
afterEach: Hook;
|
|
73
|
+
/** `specifier` is already checked to be absolute (path, file: URL or bare). */
|
|
74
|
+
mockModule(specifier: string, factory: () => Record<string, unknown>): void;
|
|
75
|
+
}
|
|
76
|
+
export {};
|
package/dist/test/api.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The `1tube/test` contract every runner binding implements.
|
|
3
3
|
*
|
|
4
|
-
* Edge function tests import `test`, `describe`, hooks
|
|
5
|
-
* `1tube/test` instead of a specific runner, so the same
|
|
6
|
-
* `bun test` today and under another runtime's runner
|
|
7
|
-
* pool) later. Keep this surface to what every runner
|
|
8
|
-
* context argument, no runner-specific options.
|
|
4
|
+
* Edge function tests import `test`, `describe`, hooks, `expect`, mocks and
|
|
5
|
+
* assertions from `1tube/test` instead of a specific runner, so the same
|
|
6
|
+
* files run under `bun test` today and under another runtime's runner
|
|
7
|
+
* (node:test, a workerd pool) later. Keep this surface to what every runner
|
|
8
|
+
* can express: no test context argument, no runner-specific options.
|
|
9
9
|
*/
|
|
10
10
|
export {};
|
package/dist/test/assert.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ type AnyConstructor = abstract new (...args: never[]) => unknown;
|
|
|
15
15
|
type ErrorClass<E extends Error = Error> = abstract new (...args: never[]) => E;
|
|
16
16
|
/** Readable, deterministic rendering of a value for failure messages. */
|
|
17
17
|
export declare function format(value: unknown): string;
|
|
18
|
+
/** Line-level diff of two formatted values (`-` actual, `+` expected). */
|
|
19
|
+
export declare function formatDiff(actual: unknown, expected: unknown): string;
|
|
18
20
|
/**
|
|
19
21
|
* Deep structural equality: same constructor, same own enumerable keys
|
|
20
22
|
* (strings and symbols), recursively equal values. `NaN` equals `NaN`;
|
package/dist/test/assert.js
CHANGED
|
@@ -99,7 +99,7 @@ export function format(value) {
|
|
|
99
99
|
return render(value);
|
|
100
100
|
}
|
|
101
101
|
/** Line-level diff of two formatted values (`-` actual, `+` expected). */
|
|
102
|
-
function
|
|
102
|
+
export function formatDiff(actual, expected) {
|
|
103
103
|
const a = format(actual).split("\n");
|
|
104
104
|
const b = format(expected).split("\n");
|
|
105
105
|
// LCS over lines: values printed for assertion failures are small.
|
|
@@ -245,7 +245,7 @@ export function assertFalse(expr, msg = "") {
|
|
|
245
245
|
export function assertEquals(actual, expected, msg) {
|
|
246
246
|
if (equal(actual, expected))
|
|
247
247
|
return;
|
|
248
|
-
throw new AssertionError(`Values are not equal${suffix(msg)}\n\n [Diff] Actual / Expected\n\n${
|
|
248
|
+
throw new AssertionError(`Values are not equal${suffix(msg)}\n\n [Diff] Actual / Expected\n\n${formatDiff(actual, expected)}\n`);
|
|
249
249
|
}
|
|
250
250
|
export function assertNotEquals(actual, expected, msg) {
|
|
251
251
|
if (!equal(actual, expected))
|
|
@@ -259,7 +259,7 @@ export function assertStrictEquals(actual, expected, msg) {
|
|
|
259
259
|
const sameRendering = format(actual) === format(expected);
|
|
260
260
|
throw new AssertionError(sameRendering
|
|
261
261
|
? `Values have the same structure but are not reference-equal${suffix(msg)}\n\n ${format(actual).replace(/\n/g, "\n ")}\n`
|
|
262
|
-
: `Values are not strictly equal${suffix(msg)}\n\n [Diff] Actual / Expected\n\n${
|
|
262
|
+
: `Values are not strictly equal${suffix(msg)}\n\n [Diff] Actual / Expected\n\n${formatDiff(actual, expected)}\n`);
|
|
263
263
|
}
|
|
264
264
|
export function assertNotStrictEquals(actual, expected, msg) {
|
|
265
265
|
if (!Object.is(actual, expected))
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the full `1tube/test` surface from a runner's minimal base, so
|
|
3
|
+
* `.each`, `.if`/`.skipIf`, `it`, mocks and title formatting behave the
|
|
4
|
+
* same on every runner.
|
|
5
|
+
*/
|
|
6
|
+
import type { DescribeFunction, Hook, MockFunction, RunnerBase, TestFunction } from "./api.ts";
|
|
7
|
+
export interface TestApi {
|
|
8
|
+
test: TestFunction;
|
|
9
|
+
it: TestFunction;
|
|
10
|
+
describe: DescribeFunction;
|
|
11
|
+
beforeAll: Hook;
|
|
12
|
+
afterAll: Hook;
|
|
13
|
+
beforeEach: Hook;
|
|
14
|
+
afterEach: Hook;
|
|
15
|
+
mock: MockFunction;
|
|
16
|
+
}
|
|
17
|
+
/** jest-style `.each` titles: printf placeholders, or `$path` for object rows. */
|
|
18
|
+
export declare function formatTitle(title: string, args: unknown[], index: number): string;
|
|
19
|
+
export declare function createTestApi(base: RunnerBase): TestApi;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the full `1tube/test` surface from a runner's minimal base, so
|
|
3
|
+
* `.each`, `.if`/`.skipIf`, `it`, mocks and title formatting behave the
|
|
4
|
+
* same on every runner.
|
|
5
|
+
*/
|
|
6
|
+
import { format } from "./assert.js";
|
|
7
|
+
import { createMock, restoreAllMocks } from "./expect.js";
|
|
8
|
+
const rowArgs = (row) => (Array.isArray(row) ? row : [row]);
|
|
9
|
+
/** jest-style `.each` titles: printf placeholders, or `$path` for object rows. */
|
|
10
|
+
export function formatTitle(title, args, index) {
|
|
11
|
+
const [first] = args;
|
|
12
|
+
if (args.length === 1 && first && typeof first === "object" && !Array.isArray(first) && /\$[A-Za-z_]/.test(title)) {
|
|
13
|
+
return title.replace(/\$([A-Za-z_$][\w$]*(?:\.[\w$]+)*)/g, (m, path) => {
|
|
14
|
+
let cur = first;
|
|
15
|
+
for (const p of path.split(".")) {
|
|
16
|
+
if (cur === null || cur === undefined)
|
|
17
|
+
return m;
|
|
18
|
+
cur = cur[p];
|
|
19
|
+
}
|
|
20
|
+
return typeof cur === "string" ? cur : format(cur);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
let i = 0;
|
|
24
|
+
return title.replace(/%[sdifjoOp#%]/g, (m) => {
|
|
25
|
+
if (m === "%%")
|
|
26
|
+
return "%";
|
|
27
|
+
if (m === "%#")
|
|
28
|
+
return String(index);
|
|
29
|
+
if (i >= args.length)
|
|
30
|
+
return m;
|
|
31
|
+
const v = args[i++];
|
|
32
|
+
switch (m) {
|
|
33
|
+
case "%s":
|
|
34
|
+
return typeof v === "string" ? v : format(v);
|
|
35
|
+
case "%d":
|
|
36
|
+
case "%i":
|
|
37
|
+
return String(typeof v === "bigint" ? v : Math.trunc(Number(v)));
|
|
38
|
+
case "%f":
|
|
39
|
+
return String(Number(v));
|
|
40
|
+
case "%j":
|
|
41
|
+
return JSON.stringify(v);
|
|
42
|
+
default:
|
|
43
|
+
return format(v);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function createTestApi(base) {
|
|
48
|
+
const register = (mode) => (name, fn, options = {}) => base.test(name, fn, {
|
|
49
|
+
...options,
|
|
50
|
+
skip: mode === "skip" || options.skip,
|
|
51
|
+
only: mode === "only" || options.only,
|
|
52
|
+
});
|
|
53
|
+
const test = Object.assign(register("run"), {
|
|
54
|
+
skip: register("skip"),
|
|
55
|
+
only: register("only"),
|
|
56
|
+
todo: (name) => base.todo(name),
|
|
57
|
+
if: (condition) => register(condition ? "run" : "skip"),
|
|
58
|
+
skipIf: (condition) => register(condition ? "skip" : "run"),
|
|
59
|
+
each: (table) => (name, fn, options) => {
|
|
60
|
+
table.forEach((row, index) => {
|
|
61
|
+
const args = rowArgs(row);
|
|
62
|
+
register("run")(formatTitle(name, args, index), (() => fn(...args)), options);
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
const suite = (mode) => (name, fn) => base.describe(name, fn, mode);
|
|
67
|
+
const describe = Object.assign(suite("run"), {
|
|
68
|
+
skip: suite("skip"),
|
|
69
|
+
only: suite("only"),
|
|
70
|
+
if: (condition) => suite(condition ? "run" : "skip"),
|
|
71
|
+
skipIf: (condition) => suite(condition ? "skip" : "run"),
|
|
72
|
+
each: (table) => (name, fn) => {
|
|
73
|
+
table.forEach((row, index) => {
|
|
74
|
+
const args = rowArgs(row);
|
|
75
|
+
suite("run")(formatTitle(name, args, index), () => fn(...args));
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
const mock = Object.assign((impl) => createMock(impl), {
|
|
80
|
+
module: (specifier, factory) => {
|
|
81
|
+
const s = specifier instanceof URL ? specifier.href : String(specifier);
|
|
82
|
+
if (s.startsWith("./") || s.startsWith("../") || s === "." || s === "..") {
|
|
83
|
+
throw new Error(`mock.module(${JSON.stringify(s)}): relative specifiers depend on the calling file, which a ` +
|
|
84
|
+
`shared helper can't see. Pass import.meta.resolve(${JSON.stringify(s)}) instead.`);
|
|
85
|
+
}
|
|
86
|
+
base.mockModule(s, factory);
|
|
87
|
+
},
|
|
88
|
+
restore: () => restoreAllMocks(),
|
|
89
|
+
});
|
|
90
|
+
return {
|
|
91
|
+
test,
|
|
92
|
+
it: test,
|
|
93
|
+
describe,
|
|
94
|
+
beforeAll: base.beforeAll,
|
|
95
|
+
afterAll: base.afterAll,
|
|
96
|
+
beforeEach: base.beforeEach,
|
|
97
|
+
afterEach: base.afterEach,
|
|
98
|
+
mock,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-agnostic `expect`, mock functions and spies for `1tube/test`.
|
|
3
|
+
*
|
|
4
|
+
* Pure TypeScript with no runtime imports — the same semantics under every
|
|
5
|
+
* runner. Matchers follow the jest conventions Bun's `bun:test` also uses
|
|
6
|
+
* (`toEqual` ignores `undefined` properties and object types,
|
|
7
|
+
* `toStrictEqual` does not, `toMatchObject` matches subsets, asymmetric
|
|
8
|
+
* matchers like `expect.objectContaining` nest anywhere), so tests written
|
|
9
|
+
* against `bun:test` port by changing the import line.
|
|
10
|
+
*/
|
|
11
|
+
declare const ASYMMETRIC: unique symbol;
|
|
12
|
+
export interface AsymmetricMatcher {
|
|
13
|
+
readonly [ASYMMETRIC]: true;
|
|
14
|
+
asymmetricMatch(other: unknown): boolean;
|
|
15
|
+
toString(): string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* jest-style deep equality. `strict` (toStrictEqual) additionally checks
|
|
19
|
+
* constructors, `undefined`-valued keys and array holes.
|
|
20
|
+
*/
|
|
21
|
+
export declare function deepEquals(a: unknown, b: unknown, strict?: boolean): boolean;
|
|
22
|
+
type AnyFn = (...args: any[]) => any;
|
|
23
|
+
export type MockResult<T> = {
|
|
24
|
+
type: "return";
|
|
25
|
+
value: T;
|
|
26
|
+
} | {
|
|
27
|
+
type: "throw";
|
|
28
|
+
value: unknown;
|
|
29
|
+
} | {
|
|
30
|
+
type: "incomplete";
|
|
31
|
+
value: undefined;
|
|
32
|
+
};
|
|
33
|
+
export interface MockState<T extends AnyFn> {
|
|
34
|
+
calls: Parameters<T>[];
|
|
35
|
+
results: MockResult<ReturnType<T>>[];
|
|
36
|
+
instances: unknown[];
|
|
37
|
+
lastCall: Parameters<T> | undefined;
|
|
38
|
+
}
|
|
39
|
+
export type Mock<T extends AnyFn = AnyFn> = T & {
|
|
40
|
+
readonly mock: MockState<T>;
|
|
41
|
+
mockImplementation(fn: T): Mock<T>;
|
|
42
|
+
mockImplementationOnce(fn: T): Mock<T>;
|
|
43
|
+
mockReturnValue(value: ReturnType<T>): Mock<T>;
|
|
44
|
+
mockReturnValueOnce(value: ReturnType<T>): Mock<T>;
|
|
45
|
+
mockResolvedValue(value: Awaited<ReturnType<T>>): Mock<T>;
|
|
46
|
+
mockResolvedValueOnce(value: Awaited<ReturnType<T>>): Mock<T>;
|
|
47
|
+
mockRejectedValue(value: unknown): Mock<T>;
|
|
48
|
+
mockRejectedValueOnce(value: unknown): Mock<T>;
|
|
49
|
+
mockName(name: string): Mock<T>;
|
|
50
|
+
getMockName(): string;
|
|
51
|
+
/** Forget recorded calls and results. */
|
|
52
|
+
mockClear(): Mock<T>;
|
|
53
|
+
/** mockClear() plus drop implementations. */
|
|
54
|
+
mockReset(): Mock<T>;
|
|
55
|
+
/** For spies: put the original method back. */
|
|
56
|
+
mockRestore(): void;
|
|
57
|
+
};
|
|
58
|
+
/** Create a mock function, optionally wrapping an implementation. */
|
|
59
|
+
export declare function createMock<T extends AnyFn = AnyFn>(impl?: T, restore?: () => void): Mock<T>;
|
|
60
|
+
export declare function isMock(v: unknown): v is Mock;
|
|
61
|
+
/** Replace `obj[key]` with a mock that calls through to the original. */
|
|
62
|
+
export declare function spyOn<O extends object, K extends keyof O>(obj: O, key: K): O[K] extends AnyFn ? Mock<O[K]> : never;
|
|
63
|
+
/** Restore every active spy (`mock.restore()`). */
|
|
64
|
+
export declare function restoreAllMocks(): void;
|
|
65
|
+
export interface Matchers<R> {
|
|
66
|
+
not: Matchers<R>;
|
|
67
|
+
toBe(expected: unknown): R;
|
|
68
|
+
toEqual(expected: unknown): R;
|
|
69
|
+
toStrictEqual(expected: unknown): R;
|
|
70
|
+
toMatchObject(expected: object): R;
|
|
71
|
+
toBeNull(): R;
|
|
72
|
+
toBeUndefined(): R;
|
|
73
|
+
toBeDefined(): R;
|
|
74
|
+
toBeTruthy(): R;
|
|
75
|
+
toBeFalsy(): R;
|
|
76
|
+
toBeNaN(): R;
|
|
77
|
+
toBeTypeOf(type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"): R;
|
|
78
|
+
toBeInstanceOf(ctor: abstract new (...args: never[]) => unknown): R;
|
|
79
|
+
toBeGreaterThan(n: number | bigint): R;
|
|
80
|
+
toBeGreaterThanOrEqual(n: number | bigint): R;
|
|
81
|
+
toBeLessThan(n: number | bigint): R;
|
|
82
|
+
toBeLessThanOrEqual(n: number | bigint): R;
|
|
83
|
+
toBeCloseTo(n: number, numDigits?: number): R;
|
|
84
|
+
toBeOneOf(values: readonly unknown[]): R;
|
|
85
|
+
toContain(item: unknown): R;
|
|
86
|
+
toContainEqual(item: unknown): R;
|
|
87
|
+
toInclude(substring: string): R;
|
|
88
|
+
toStartWith(prefix: string): R;
|
|
89
|
+
toEndWith(suffix: string): R;
|
|
90
|
+
toMatch(pattern: string | RegExp): R;
|
|
91
|
+
toHaveLength(n: number): R;
|
|
92
|
+
toHaveProperty(path: string | readonly (string | number)[], value?: unknown): R;
|
|
93
|
+
toBeEmpty(): R;
|
|
94
|
+
toThrow(expected?: string | RegExp | Error | (abstract new (...args: never[]) => unknown) | AsymmetricMatcher): R;
|
|
95
|
+
toThrowError(expected?: string | RegExp | Error | (abstract new (...args: never[]) => unknown) | AsymmetricMatcher): R;
|
|
96
|
+
toHaveBeenCalled(): R;
|
|
97
|
+
toHaveBeenCalledTimes(n: number): R;
|
|
98
|
+
toHaveBeenCalledWith(...args: unknown[]): R;
|
|
99
|
+
toHaveBeenLastCalledWith(...args: unknown[]): R;
|
|
100
|
+
toHaveBeenNthCalledWith(n: number, ...args: unknown[]): R;
|
|
101
|
+
toHaveReturned(): R;
|
|
102
|
+
toHaveReturnedTimes(n: number): R;
|
|
103
|
+
toHaveReturnedWith(value: unknown): R;
|
|
104
|
+
}
|
|
105
|
+
export interface Assertion extends Matchers<void> {
|
|
106
|
+
/** Await the promise, then match its value. */
|
|
107
|
+
resolves: Matchers<Promise<void>>;
|
|
108
|
+
/** Await the promise, then match its rejection reason. */
|
|
109
|
+
rejects: Matchers<Promise<void>>;
|
|
110
|
+
}
|
|
111
|
+
export interface Expect {
|
|
112
|
+
(actual: unknown, message?: string): Assertion;
|
|
113
|
+
anything(): AsymmetricMatcher;
|
|
114
|
+
any(ctor: unknown): AsymmetricMatcher;
|
|
115
|
+
objectContaining(obj: object): AsymmetricMatcher;
|
|
116
|
+
arrayContaining(items: readonly unknown[]): AsymmetricMatcher;
|
|
117
|
+
stringContaining(s: string): AsymmetricMatcher;
|
|
118
|
+
stringMatching(p: string | RegExp): AsymmetricMatcher;
|
|
119
|
+
closeTo(n: number, numDigits?: number): AsymmetricMatcher;
|
|
120
|
+
not: {
|
|
121
|
+
objectContaining(obj: object): AsymmetricMatcher;
|
|
122
|
+
arrayContaining(items: readonly unknown[]): AsymmetricMatcher;
|
|
123
|
+
stringContaining(s: string): AsymmetricMatcher;
|
|
124
|
+
stringMatching(p: string | RegExp): AsymmetricMatcher;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
export declare const expect: Expect;
|
|
128
|
+
export {};
|