diff --git a/index.d.cts b/index.d.cts new file mode 100644 index 0000000000..4205f6cdb8 --- /dev/null +++ b/index.d.cts @@ -0,0 +1,7 @@ +import type {TestFn} from './types/test-fn.cjs'; + +/** Call to declare a test, or chain to declare hooks or test modifiers */ +declare const test: TestFn; + +/** Call to declare a test, or chain to declare hooks or test modifiers */ +export = test; diff --git a/index.d.mts b/index.d.mts new file mode 100644 index 0000000000..7cbf28caf4 --- /dev/null +++ b/index.d.mts @@ -0,0 +1,12 @@ +import type {TestFn} from './types/test-fn.mjs'; + +export * from './types/assertions.mjs'; +export * from './types/try-fn.mjs'; +export * from './types/test-fn.mjs'; +export * from './types/subscribable.mjs'; + +/** Call to declare a test, or chain to declare hooks or test modifiers */ +declare const test: TestFn; + +/** Call to declare a test, or chain to declare hooks or test modifiers */ +export default test; diff --git a/index.d.ts b/index.d.ts deleted file mode 100644 index 50f1570d74..0000000000 --- a/index.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type {TestFn} from './types/test-fn.js'; - -export * from './types/assertions.js'; -export * from './types/try-fn.js'; -export * from './types/test-fn.js'; -export * from './types/subscribable.js'; - -/** Call to declare a test, or chain to declare hooks or test modifiers */ -declare const test: TestFn; - -/** Call to declare a test, or chain to declare hooks or test modifiers */ -export default test; diff --git a/package.json b/package.json index 454caa56cd..f97649058d 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "exports": { ".": { "import": { - "types": "./index.d.ts", + "types": "./index.d.mts", "default": "./entrypoints/main.mjs" }, "require": { @@ -22,7 +22,7 @@ "./eslint-plugin-helper": "./entrypoints/eslint-plugin-helper.cjs", "./plugin": { "import": { - "types": "./plugin.d.ts", + "types": "./plugin.d.mts", "default": "./entrypoints/plugin.mjs" }, "require": { @@ -43,8 +43,10 @@ "entrypoints", "lib", "types", - "index.d.ts", - "plugin.d.ts" + "index.d.cts", + "index.d.mts", + "plugin.d.cts", + "plugin.d.mts" ], "keywords": [ "🦄", diff --git a/plugin.d.ts b/plugin.d.cts similarity index 100% rename from plugin.d.ts rename to plugin.d.cts diff --git a/plugin.d.mts b/plugin.d.mts new file mode 100644 index 0000000000..a2f68e1797 --- /dev/null +++ b/plugin.d.mts @@ -0,0 +1,77 @@ +import {URL} from 'node:url'; + +export namespace SharedWorker { + export type ProtocolIdentifier = 'ava-4'; + + export type FactoryOptions = { + negotiateProtocol (supported: readonly ['ava-4']): Protocol; + // Add overloads for additional protocols. + }; + + export type Factory = (options: FactoryOptions) => void; + + export type Protocol = { + readonly initialData: Data; + readonly protocol: 'ava-4'; + broadcast: (data: Data) => BroadcastMessage; + ready: () => Protocol; + subscribe: () => AsyncIterableIterator>; + testWorkers: () => AsyncIterableIterator>; + }; + + export type BroadcastMessage = { + readonly id: string; + replies: () => AsyncIterableIterator>; + }; + + export type PublishedMessage = { + readonly id: string; + replies: () => AsyncIterableIterator>; + }; + + export type ReceivedMessage = { + readonly data: Data; + readonly id: string; + readonly testWorker: TestWorker; + reply: (data: Data) => PublishedMessage; + }; + + export type TestWorker = { + readonly id: string; + readonly file: string; + publish: (data: Data) => PublishedMessage; + subscribe: () => AsyncIterableIterator>; + teardown: (fn: (() => Promise) | (() => void)) => () => Promise; + }; + + export namespace Plugin { + export type RegistrationOptions = { + readonly filename: string | URL; + readonly initialData?: Data; + readonly supportedProtocols: readonly Identifier[]; + readonly teardown?: () => void; + }; + + export type Protocol = { + readonly available: Promise; + readonly currentlyAvailable: boolean; + readonly protocol: 'ava-4'; + publish: (data: Data) => PublishedMessage; + subscribe: () => AsyncIterableIterator>; + }; + + export type PublishedMessage = { + readonly id: string; + replies: () => AsyncIterableIterator>; + }; + + export type ReceivedMessage = { + readonly data: Data; + readonly id: string; + reply: (data: Data) => PublishedMessage; + }; + } +} + +export function registerSharedWorker(options: SharedWorker.Plugin.RegistrationOptions<'ava-4', Data>): SharedWorker.Plugin.Protocol; +// Add overloads for additional protocols. diff --git a/types/assertions.d.ts b/types/assertions.d.cts similarity index 100% rename from types/assertions.d.ts rename to types/assertions.d.cts diff --git a/types/assertions.d.mts b/types/assertions.d.mts new file mode 100644 index 0000000000..0d2c8506b8 --- /dev/null +++ b/types/assertions.d.mts @@ -0,0 +1,339 @@ +export type ErrorConstructor = new (...args: any[]) => Error; + +/** Specify one or more expectations the thrown error must satisfy. */ +export type ThrowsExpectation = { + /** The thrown error must have a code that equals the given string or number. */ + code?: string | number; + + /** The thrown error must be an instance of this constructor. */ + instanceOf?: ErrorConstructor; + + /** The thrown error must be strictly equal to this value. */ + is?: Error; + + /** The thrown error must have a message that equals the given string, or matches the regular expression. */ + message?: string | RegExp | ((message: string) => boolean); + + /** The thrown error must have a name that equals the given string. */ + name?: string; +}; + +export interface Assertions { + /** + * Assert that `actual` is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy), returning a boolean + * indicating whether the assertion passed. + */ + assert: AssertAssertion; + + /** + * Assert that `actual` is [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to + * `expected`, returning a boolean indicating whether the assertion passed. + */ + deepEqual: DeepEqualAssertion; + + /** + * Assert that `value` is like `selector`, returning a boolean indicating whether the assertion passed. + */ + like: LikeAssertion; + + /** Fail the test, always returning `false`. */ + fail: FailAssertion; + + /** + * Assert that `actual` is strictly false, returning a boolean indicating whether the assertion passed. + */ + false: FalseAssertion; + + /** + * Assert that `actual` is [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy), returning a boolean + * indicating whether the assertion passed. + */ + falsy: FalsyAssertion; + + /** + * Assert that `actual` is [the same + * value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) as `expected`, + * returning a boolean indicating whether the assertion passed. + */ + is: IsAssertion; + + /** + * Assert that `actual` is not [the same + * value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) as `expected`, + * returning a boolean indicating whether the assertion passed. + */ + not: NotAssertion; + + /** + * Assert that `actual` is not [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to + * `expected`, returning a boolean indicating whether the assertion passed. + */ + notDeepEqual: NotDeepEqualAssertion; + + /** + * Assert that `string` does not match the regular expression, returning a boolean indicating whether the assertion + * passed. + */ + notRegex: NotRegexAssertion; + + /** Assert that the function does not throw. */ + notThrows: NotThrowsAssertion; + + /** Assert that the async function does not throw, or that the promise does not reject. Must be awaited. */ + notThrowsAsync: NotThrowsAsyncAssertion; + + /** Count a passing assertion, always returning `true`. */ + pass: PassAssertion; + + /** + * Assert that `string` matches the regular expression, returning a boolean indicating whether the assertion passed. + */ + regex: RegexAssertion; + + /** + * Assert that `expected` is [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to a + * previously recorded [snapshot](https://github.com/concordancejs/concordance#serialization-details), or if + * necessary record a new snapshot. + */ + snapshot: SnapshotAssertion; + + /** + * Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value. + */ + throws: ThrowsAssertion; + + /** + * Assert that the async function throws [an error](https://www.npmjs.com/package/is-error), or the promise rejects + * with one. If so, returns a promise for the error value, which must be awaited. + */ + throwsAsync: ThrowsAsyncAssertion; + + /** + * Assert that `actual` is strictly true, returning a boolean indicating whether the assertion passed. + */ + true: TrueAssertion; + + /** + * Assert that `actual` is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy), returning a boolean + * indicating whether the assertion passed. + */ + truthy: TruthyAssertion; +} + +export interface AssertAssertion { + /** + * Assert that `actual` is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy), returning a boolean + * indicating whether the assertion passed. + */ + (actual: any, message?: string): boolean; + + /** Skip this assertion. */ + skip(actual: any, message?: string): void; +} + +export interface DeepEqualAssertion { + /** + * Assert that `actual` is [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to + * `expected`, returning a boolean indicating whether the assertion passed. + */ + (actual: Actual, expected: Expected, message?: string): actual is Expected; + + /** + * Assert that `actual` is [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to + * `expected`, returning a boolean indicating whether the assertion passed. + */ + (actual: Actual, expected: Expected, message?: string): expected is Actual; + + /** + * Assert that `actual` is [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to + * `expected`, returning a boolean indicating whether the assertion passed. + */ + (actual: Actual, expected: Expected, message?: string): boolean; + + /** Skip this assertion. */ + skip(actual: any, expected: any, message?: string): void; +} + +export interface LikeAssertion { + /** + * Assert that `value` is like `selector`, returning a boolean indicating whether the assertion passed. + */ + >(value: any, selector: Expected, message?: string): value is Expected; + + /** Skip this assertion. */ + skip(value: any, selector: any, message?: string): void; +} + +export interface FailAssertion { + /** Fail the test, always returning `false`. */ + (message?: string): boolean; + + /** Skip this assertion. */ + skip(message?: string): void; +} + +export interface FalseAssertion { + /** + * Assert that `actual` is strictly false, returning a boolean indicating whether the assertion passed. + */ + (actual: any, message?: string): actual is false; + + /** Skip this assertion. */ + skip(actual: any, message?: string): void; +} + +export interface FalsyAssertion { + /** + * Assert that `actual` is [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy), returning a boolean + * indicating whether the assertion passed. + */ + (actual: any, message?: string): boolean; + + /** Skip this assertion. */ + skip(actual: any, message?: string): void; +} + +export interface IsAssertion { + /** + * Assert that `actual` is [the same + * value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) as `expected`, + * returning a boolean indicating whether the assertion passed. + */ + (actual: Actual, expected: Expected, message?: string): actual is Expected; + + /** Skip this assertion. */ + skip(actual: any, expected: any, message?: string): void; +} + +export interface NotAssertion { + /** + * Assert that `actual` is not [the same + * value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) as `expected`, + * returning a boolean indicating whether the assertion passed. + */ + (actual: Actual, expected: Expected, message?: string): boolean; + + /** Skip this assertion. */ + skip(actual: any, expected: any, message?: string): void; +} + +export interface NotDeepEqualAssertion { + /** + * Assert that `actual` is not [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to + * `expected`, returning a boolean indicating whether the assertion passed. + */ + (actual: Actual, expected: Expected, message?: string): boolean; + + /** Skip this assertion. */ + skip(actual: any, expected: any, message?: string): void; +} + +export interface NotRegexAssertion { + /** + * Assert that `string` does not match the regular expression, returning a boolean indicating whether the assertion + * passed. + */ + (string: string, regex: RegExp, message?: string): boolean; + + /** Skip this assertion. */ + skip(string: string, regex: RegExp, message?: string): void; +} + +export interface NotThrowsAssertion { + /** Assert that the function does not throw. */ + (fn: () => any, message?: string): void; + + /** Skip this assertion. */ + skip(fn: () => any, message?: string): void; +} + +export interface NotThrowsAsyncAssertion { + /** Assert that the async function does not throw. You must await the result. */ + (fn: () => PromiseLike, message?: string): Promise; + + /** Assert that the promise does not reject. You must await the result. */ + (promise: PromiseLike, message?: string): Promise; // eslint-disable-line @typescript-eslint/unified-signatures + + /** Skip this assertion. */ + skip(nonThrower: any, message?: string): void; +} + +export interface PassAssertion { + /** Count a passing assertion, always returning `true`. */ + (message?: string): boolean; + + /** Skip this assertion. */ + skip(message?: string): void; +} + +export interface RegexAssertion { + /** + * Assert that `string` matches the regular expression, returning a boolean indicating whether the assertion passed. + */ + (string: string, regex: RegExp, message?: string): boolean; + + /** Skip this assertion. */ + skip(string: string, regex: RegExp, message?: string): void; +} + +export interface SnapshotAssertion { + /** + * Assert that `expected` is [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to a + * previously recorded [snapshot](https://github.com/concordancejs/concordance#serialization-details), or if + * necessary record a new snapshot. + */ + (expected: any, message?: string): void; + + /** Skip this assertion. */ + skip(expected: any, message?: string): void; +} + +export interface ThrowsAssertion { + /** + * Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value. + * The error must satisfy all expectations. Returns undefined when the assertion fails. + */ + (fn: () => any, expectations?: ThrowsExpectation, message?: string): ThrownError | undefined; + + /** Skip this assertion. */ + skip(fn: () => any, expectations?: any, message?: string): void; +} + +export interface ThrowsAsyncAssertion { + /** + * Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error + * value. Returns undefined when the assertion fails. You must await the result. The error must satisfy all expectations. + */ + (fn: () => PromiseLike, expectations?: ThrowsExpectation, message?: string): Promise; + + /** + * Assert that the promise rejects with [an error](https://www.npmjs.com/package/is-error). If so, returns the + * rejection reason. Returns undefined when the assertion fails. You must await the result. The error must satisfy all + * expectations. + */ + (promise: PromiseLike, expectations?: ThrowsExpectation, message?: string): Promise; // eslint-disable-line @typescript-eslint/unified-signatures + + /** Skip this assertion. */ + skip(thrower: any, expectations?: any, message?: string): void; +} + +export interface TrueAssertion { + /** + * Assert that `actual` is strictly true, returning a boolean indicating whether the assertion passed. + */ + (actual: any, message?: string): actual is true; + + /** Skip this assertion. */ + skip(actual: any, message?: string): void; +} + +export interface TruthyAssertion { + /** + * Assert that `actual` is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy), returning a boolean + * indicating whether the assertion passed. + */ + (actual: any, message?: string): boolean; + + /** Skip this assertion. */ + skip(actual: any, message?: string): void; +} diff --git a/types/subscribable.d.ts b/types/subscribable.d.cts similarity index 100% rename from types/subscribable.d.ts rename to types/subscribable.d.cts diff --git a/types/subscribable.d.mts b/types/subscribable.d.mts new file mode 100644 index 0000000000..3a3399bca1 --- /dev/null +++ b/types/subscribable.d.mts @@ -0,0 +1,6 @@ +export interface Subscribable { + subscribe(observer: { + error(error: any): void; + complete(): void; + }): void; +} diff --git a/types/test-fn.d.ts b/types/test-fn.d.cts similarity index 98% rename from types/test-fn.d.ts rename to types/test-fn.d.cts index 2b206cdb69..ee117ff72e 100644 --- a/types/test-fn.d.ts +++ b/types/test-fn.d.cts @@ -1,6 +1,6 @@ -import type {Assertions} from './assertions.js'; -import type {Subscribable} from './subscribable.js'; -import type {TryFn} from './try-fn.js'; +import type {Assertions} from './assertions.cjs'; +import type {Subscribable} from './subscribable.cjs'; +import type {TryFn} from './try-fn.cjs'; /** The `t` value passed to test & hook implementations. */ export interface ExecutionContext extends Assertions { diff --git a/types/test-fn.d.mts b/types/test-fn.d.mts new file mode 100644 index 0000000000..1658b71e41 --- /dev/null +++ b/types/test-fn.d.mts @@ -0,0 +1,231 @@ +import type {Assertions} from './assertions.mjs'; +import type {Subscribable} from './subscribable.mjs'; +import type {TryFn} from './try-fn.mjs'; + +/** The `t` value passed to test & hook implementations. */ +export interface ExecutionContext extends Assertions { + /** Test context, shared with hooks. */ + context: Context; + + /** Title of the test or hook. */ + readonly title: string; + + /** Whether the test has passed. Only accurate in afterEach hooks. */ + readonly passed: boolean; + + readonly log: LogFn; + readonly plan: PlanFn; + readonly teardown: TeardownFn; + readonly timeout: TimeoutFn; + readonly try: TryFn; +} + +export interface LogFn { + /** Log one or more values. */ + (...values: any[]): void; + + /** Skip logging. */ + skip(...values: any[]): void; +} + +export interface PlanFn { + /** + * Plan how many assertion there are in the test. The test will fail if the actual assertion count doesn't match the + * number of planned assertions. See [assertion planning](https://github.com/avajs/ava#assertion-planning). + */ + (count: number): void; + + /** Don't plan assertions. */ + skip(count: number): void; +} + +/** + * Set a timeout for the test, in milliseconds. The test will fail if the timeout is exceeded. + * The timeout is reset each time an assertion is made. + */ +export type TimeoutFn = (ms: number, message?: string) => void; + +/** Declare a function to be run after the test has ended. */ +export type TeardownFn = (fn: (() => Promise) | (() => void)) => void; + +export type ImplementationFn = + ((t: ExecutionContext, ...args: Args) => PromiseLike) | + ((t: ExecutionContext, ...args: Args) => Subscribable) | + ((t: ExecutionContext, ...args: Args) => void); + +export type TitleFn = (providedTitle: string | undefined, ...args: Args) => string; + +/** A reusable test or hook implementation. */ +export type Macro = { + /** The function that is executed when the macro is used. */ + readonly exec: ImplementationFn; + + /** Generates a test title when this macro is used. */ + readonly title?: TitleFn; +}; + +/** A test or hook implementation. */ +export type Implementation = ImplementationFn | Macro; + +export interface TestFn { + /** Declare a concurrent test. Additional arguments are passed to the implementation or macro. */ + (title: string, implementation: Implementation, ...args: Args): void; + + /** + * Declare a concurrent test that uses a macro. Additional arguments are passed to the macro. + * The macro is responsible for generating a unique test title. + */ + (macro: Macro, ...args: Args): void; + + after: AfterFn; + afterEach: AfterFn; + before: BeforeFn; + beforeEach: BeforeFn; + failing: FailingFn; + macro: MacroFn; + meta: Meta; + only: OnlyFn; + serial: SerialFn; + skip: SkipFn; + todo: TodoFn; +} + +export interface AfterFn { + /** + * Declare a hook that is run once, after all tests have passed. + * Additional arguments are passed to the implementation or macro. + */ + (title: string, implementation: Implementation, ...args: Args): void; + + /** + * Declare a hook that is run once, after all tests have passed. + * Additional arguments are passed to the implementation or macro. + */ + (implementation: Implementation, ...args: Args): void; + + always: AlwaysInterface; + skip: HookSkipFn; +} + +export interface AlwaysInterface { + /** + * Declare a hook that is run once, after all tests are done. + * Additional arguments are passed to the implementation or macro. + */ + (title: string, implementation: Implementation, ...args: Args): void; + + /** + * Declare a hook that is run once, after all tests are done. + * Additional arguments are passed to the implementation or macro. + */ + (implementation: Implementation, ...args: Args): void; + + skip: HookSkipFn; +} + +export interface BeforeFn { + /** + * Declare a hook that is run once, before all tests. + * Additional arguments are passed to the implementation or macro. + */ + (title: string, implementation: Implementation, ...args: Args): void; + + /** + * Declare a hook that is run once, before all tests. + * Additional arguments are passed to the implementation or macro. + */ + (implementation: Implementation, ...args: Args): void; + + skip: HookSkipFn; +} + +export interface FailingFn { + /** + * Declare a concurrent test that is expected to fail. + * Additional arguments are passed to the implementation or macro. + */ + (title: string, implementation: Implementation, ...args: Args): void; + + /** + * Declare a concurrent test, using a macro, that is expected to fail. + * Additional arguments are passed to the macro. The macro is responsible for generating a unique test title. + */ + (macro: Macro, ...args: Args): void; + + only: OnlyFn; + skip: SkipFn; +} + +export interface HookSkipFn { + /** Skip this hook. */ + (title: string, implementation: Implementation, ...args: Args): void; + + /** Skip this hook. */ + (implementation: Implementation, ...args: Args): void; +} + +export interface OnlyFn { + /** + * Declare a test. Only this test and others declared with `.only()` are run. + * Additional arguments are passed to the implementation or macro. + */ + (title: string, implementation: Implementation, ...args: Args): void; + + /** + * Declare a test that uses a macro. Only this test and others declared with `.only()` are run. + * Additional arguments are passed to the macro. The macro is responsible for generating a unique test title. + */ + (macro: Macro, ...args: Args): void; +} + +export interface SerialFn { + /** Declare a serial test. Additional arguments are passed to the implementation or macro. */ + (title: string, implementation: Implementation, ...args: Args): void; + + /** + * Declare a serial test that uses a macro. The macro is responsible for generating a unique test title. + */ + (macro: Macro, ...args: Args): void; + + after: AfterFn; + afterEach: AfterFn; + before: BeforeFn; + beforeEach: BeforeFn; + failing: FailingFn; + only: OnlyFn; + skip: SkipFn; + todo: TodoFn; +} + +export interface SkipFn { + /** Skip this test. */ + (title: string, implementation: Implementation, ...args: Args): void; + + /** Skip this test. */ + (macro: Macro, ...args: Args): void; +} + +/** Declare a test that should be implemented later. */ +export type TodoFn = (title: string) => void; + +export type MacroDeclarationOptions = { + /** The function that is executed when the macro is used. */ + exec: ImplementationFn; + + /** The function responsible for generating a unique title when the macro is used. */ + title: TitleFn; +}; + +export interface MacroFn { + /** Declare a reusable test implementation. */ + (/** The function that is executed when the macro is used. */ exec: ImplementationFn): Macro; + (declaration: MacroDeclarationOptions): Macro; // eslint-disable-line @typescript-eslint/unified-signatures +} + +export interface Meta { + /** Path to the test file being executed. */ + file: string; + + /** Directory where snapshots are stored. */ + snapshotDirectory: string; +} diff --git a/types/try-fn.d.ts b/types/try-fn.d.cts similarity index 96% rename from types/try-fn.d.ts rename to types/try-fn.d.cts index 8009df0c96..4a168115f2 100644 --- a/types/try-fn.d.ts +++ b/types/try-fn.d.cts @@ -1,4 +1,4 @@ -import type {Implementation} from './test-fn.js'; +import type {Implementation} from './test-fn.cjs'; export type CommitDiscardOptions = { /** diff --git a/types/try-fn.d.mts b/types/try-fn.d.mts new file mode 100644 index 0000000000..aeeab23bdf --- /dev/null +++ b/types/try-fn.d.mts @@ -0,0 +1,58 @@ +import type {Implementation} from './test-fn.mjs'; + +export type CommitDiscardOptions = { + /** + * Whether the logs should be included in those of the parent test. + */ + retainLogs?: boolean; +}; + +export interface AssertionError extends Error {} + +export interface TryResult { + /** + * Title of the attempt, helping you tell attempts aparts. + */ + title: string; + + /** + * Indicates whether all assertions passed, or at least one failed. + */ + passed: boolean; + + /** + * Errors raised for each failed assertion. + */ + errors: AssertionError[]; + + /** + * Logs created during the attempt using `t.log()`. Contains formatted values. + */ + logs: string[]; + + /** + * Commit the attempt. Counts as one assertion for the plan count. If the + * attempt failed, calling this will also cause your test to fail. + */ + commit(options?: CommitDiscardOptions): void; + + /** + * Discard the attempt. + */ + discard(options?: CommitDiscardOptions): void; +} + +export interface TryFn { + /** + * Attempt to run some assertions. The result must be explicitly committed or discarded or else + * the test will fail. The title may help distinguish attempts from one another. + */ + (title: string, fn: Implementation, ...args: Args): Promise; + + /** + * Attempt to run some assertions. The result must be explicitly committed or discarded or else + * the test will fail. + */ + (fn: Implementation, ...args: Args): Promise; +} +