diff --git a/docs/02-execution-context.md b/docs/02-execution-context.md index 65200eed0..ae398fa2c 100644 --- a/docs/02-execution-context.md +++ b/docs/02-execution-context.md @@ -45,3 +45,5 @@ You cannot use `t.teardown()` in hooks either. ## `t.timeout(ms)` Set a timeout for the test, in milliseconds. The test will fail if this timeout is exceeded. The timeout is reset each time an assertion is made. + +Use `t.timeout.clear()` to clear the timeout and restore the default behavior. diff --git a/entrypoints/main.d.ts b/entrypoints/main.d.mts similarity index 100% rename from entrypoints/main.d.ts rename to entrypoints/main.d.mts diff --git a/entrypoints/plugin.d.ts b/entrypoints/plugin.d.mts similarity index 100% rename from entrypoints/plugin.d.ts rename to entrypoints/plugin.d.mts diff --git a/lib/test.js b/lib/test.js index 1e6922532..40782171f 100644 --- a/lib/test.js +++ b/lib/test.js @@ -79,6 +79,10 @@ class ExecutionContext extends Assertions { test.timeout(ms, message); }; + this.timeout.clear = () => { + test.clearTimeout(); + }; + this.teardown = callback => { test.addTeardown(callback); }; @@ -289,7 +293,6 @@ export default class Test { this.pendingAttemptCount = 0; this.planCount = null; this.startedAt = 0; - this.timeoutMs = 0; this.timeoutTimer = null; } @@ -418,7 +421,6 @@ export default class Test { } this.clearTimeout(); - this.timeoutMs = ms; this.timeoutTimer = nowAndTimers.setCappedTimeout(() => { this.saveFirstError(new Error(message ?? 'Test timeout exceeded')); @@ -427,19 +429,11 @@ export default class Test { } }, ms); - this.notifyTimeoutUpdate(this.timeoutMs); + this.notifyTimeoutUpdate(ms); } refreshTimeout() { - if (!this.timeoutTimer) { - return; - } - - if (this.timeoutTimer.refresh) { - this.timeoutTimer.refresh(); - } else { - this.timeout(this.timeoutMs); - } + this.timeoutTimer?.refresh(); } clearTimeout() { diff --git a/package.json b/package.json index 3757d0032..58bb83637 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "exports": { ".": { "import": { - "types": "./entrypoints/main.d.ts", + "types": "./entrypoints/main.d.mts", "default": "./entrypoints/main.mjs" }, "require": { @@ -22,7 +22,7 @@ "./eslint-plugin-helper": "./entrypoints/eslint-plugin-helper.cjs", "./plugin": { "import": { - "types": "./entrypoints/plugin.d.ts", + "types": "./entrypoints/plugin.d.mts", "default": "./entrypoints/plugin.mjs" }, "require": { diff --git a/test-tap/test.js b/test-tap/test.js index 4a8e41938..261e108e2 100644 --- a/test-tap/test.js +++ b/test-tap/test.js @@ -589,6 +589,18 @@ test('timeout is refreshed on assert', {skip: ciInfo.isCI}, t => ava(async a => t.equal(result.passed, true); })); +test('timeout can be cleared', {skip: ciInfo.isCI}, t => ava(async a => { + a.timeout(100); + a.plan(2); + await Promise.all([ + delay(50).then(() => a.pass()), + delay(100).then(() => a.timeout.clear()), + delay(350).then(() => a.pass()), + ]); +}).run().then(result => { + t.equal(result.passed, true); +})); + test('teardown passing test', t => { const teardown = sinon.spy(); return ava(a => { diff --git a/test-types/import-in-cts/assertions-as-type-guards.cts b/test-types/import-in-cts/assertions-as-type-guards.cts index 45f2518a5..3ada9756a 100644 --- a/test-types/import-in-cts/assertions-as-type-guards.cts +++ b/test-types/import-in-cts/assertions-as-type-guards.cts @@ -1,4 +1,4 @@ -import test from 'ava'; +import test from '../../entrypoints/main.cjs'; import {expectType} from 'tsd'; type Expected = {foo: 'bar'}; diff --git a/test-types/import-in-cts/context.cts b/test-types/import-in-cts/context.cts index f2901be88..f0423f1bb 100644 --- a/test-types/import-in-cts/context.cts +++ b/test-types/import-in-cts/context.cts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-empty-function */ -import anyTest, {ExecutionContext, TestFn} from 'ava'; +import anyTest, {ExecutionContext, TestFn} from '../../entrypoints/main.cjs'; import {expectError, expectType} from 'tsd'; interface Context { diff --git a/test-types/import-in-cts/deep-equal.cts b/test-types/import-in-cts/deep-equal.cts index acb850262..2e9369243 100644 --- a/test-types/import-in-cts/deep-equal.cts +++ b/test-types/import-in-cts/deep-equal.cts @@ -1,4 +1,4 @@ -import test from 'ava'; +import test from '../../entrypoints/main.cjs'; import {expectType} from 'tsd'; test('actual extends expected', t => { diff --git a/test-types/import-in-cts/implementation-result.cts b/test-types/import-in-cts/implementation-result.cts index ea3ccfcda..064eb8384 100644 --- a/test-types/import-in-cts/implementation-result.cts +++ b/test-types/import-in-cts/implementation-result.cts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-empty-function */ -import test from 'ava'; +import test from '../../entrypoints/main.cjs'; test.after('return anything else', _t => ({ foo: 'bar', diff --git a/test-types/import-in-cts/like.cts b/test-types/import-in-cts/like.cts index ecc641097..c3962bec1 100644 --- a/test-types/import-in-cts/like.cts +++ b/test-types/import-in-cts/like.cts @@ -1,4 +1,4 @@ -import test from 'ava'; +import test from '../../entrypoints/main.cjs'; test('like', t => { t.like({ diff --git a/test-types/import-in-cts/macros.cts b/test-types/import-in-cts/macros.cts index b8b8a8f47..949bdbf61 100644 --- a/test-types/import-in-cts/macros.cts +++ b/test-types/import-in-cts/macros.cts @@ -1,5 +1,5 @@ /* eslint-disable no-lone-blocks */ -import test, {ExecutionContext} from 'ava'; +import test, {ExecutionContext} from '../../entrypoints/main.cjs'; import {expectType} from 'tsd'; // Typed arguments through generics. diff --git a/test-types/import-in-cts/snapshot.cts b/test-types/import-in-cts/snapshot.cts index ab166b253..7bfd5681c 100644 --- a/test-types/import-in-cts/snapshot.cts +++ b/test-types/import-in-cts/snapshot.cts @@ -1,4 +1,4 @@ -import test from 'ava'; +import test from '../../entrypoints/main.cjs'; import {expectError} from 'tsd'; test('snapshot', t => { diff --git a/test-types/import-in-cts/teardown.cts b/test-types/import-in-cts/teardown.cts index baaa4628e..16ba129b5 100644 --- a/test-types/import-in-cts/teardown.cts +++ b/test-types/import-in-cts/teardown.cts @@ -1,4 +1,4 @@ -import test from 'ava'; +import test from '../../entrypoints/main.cjs'; test('test', t => { t.teardown(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function diff --git a/test-types/import-in-cts/throws.cts b/test-types/import-in-cts/throws.cts index 088cce716..6bae10904 100644 --- a/test-types/import-in-cts/throws.cts +++ b/test-types/import-in-cts/throws.cts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-empty-function */ -import test from 'ava'; +import test from '../../entrypoints/main.cjs'; import {expectType} from 'tsd'; class CustomError extends Error { diff --git a/test-types/import-in-cts/timeout.cts b/test-types/import-in-cts/timeout.cts new file mode 100644 index 000000000..40770e9dc --- /dev/null +++ b/test-types/import-in-cts/timeout.cts @@ -0,0 +1,6 @@ +import test from '../../entrypoints/main.cjs'; + +test('test', t => { + t.timeout(100); + t.timeout.clear(); +}); diff --git a/test-types/import-in-cts/try-commit.cts b/test-types/import-in-cts/try-commit.cts index c207a050b..869df0101 100644 --- a/test-types/import-in-cts/try-commit.cts +++ b/test-types/import-in-cts/try-commit.cts @@ -1,4 +1,4 @@ -import test, {ExecutionContext} from 'ava'; +import test, {ExecutionContext} from '../../entrypoints/main.cjs'; import {expectType} from 'tsd'; test('attempt', async t => { diff --git a/test-types/module/assertions-as-type-guards.ts b/test-types/module/assertions-as-type-guards.ts index 45f2518a5..36763b98f 100644 --- a/test-types/module/assertions-as-type-guards.ts +++ b/test-types/module/assertions-as-type-guards.ts @@ -1,6 +1,7 @@ -import test from 'ava'; import {expectType} from 'tsd'; +import test from '../../entrypoints/main.mjs'; + type Expected = {foo: 'bar'}; const expected: Expected = {foo: 'bar'}; diff --git a/test-types/module/context.ts b/test-types/module/context.ts index b8d516a1f..b0ffdf79b 100644 --- a/test-types/module/context.ts +++ b/test-types/module/context.ts @@ -1,8 +1,9 @@ /* eslint-disable @typescript-eslint/no-empty-function */ -import type {ExecutionContext, TestFn} from 'ava'; -import anyTest from 'ava'; import {expectError, expectType} from 'tsd'; +import type {ExecutionContext, TestFn} from '../../entrypoints/main.mjs'; +import anyTest from '../../entrypoints/main.mjs'; + type Context = { foo: string; }; diff --git a/test-types/module/deep-equal.ts b/test-types/module/deep-equal.ts index acb850262..69565fb9d 100644 --- a/test-types/module/deep-equal.ts +++ b/test-types/module/deep-equal.ts @@ -1,6 +1,7 @@ -import test from 'ava'; import {expectType} from 'tsd'; +import test from '../../entrypoints/main.mjs'; + test('actual extends expected', t => { type Expected = {foo: [1, 2, 3]}; const expected: Expected = {foo: [1, 2, 3]}; diff --git a/test-types/module/implementation-result.ts b/test-types/module/implementation-result.ts index ea3ccfcda..bae67ab88 100644 --- a/test-types/module/implementation-result.ts +++ b/test-types/module/implementation-result.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-empty-function */ -import test from 'ava'; +import test from '../../entrypoints/main.mjs'; test.after('return anything else', _t => ({ foo: 'bar', diff --git a/test-types/module/like.ts b/test-types/module/like.ts index ecc641097..971b8c75a 100644 --- a/test-types/module/like.ts +++ b/test-types/module/like.ts @@ -1,4 +1,4 @@ -import test from 'ava'; +import test from '../../entrypoints/main.mjs'; test('like', t => { t.like({ diff --git a/test-types/module/macros.ts b/test-types/module/macros.ts index 5d016857c..5c27803fd 100644 --- a/test-types/module/macros.ts +++ b/test-types/module/macros.ts @@ -1,7 +1,8 @@ -import type {ExecutionContext} from 'ava'; -import test from 'ava'; import {expectType} from 'tsd'; +import type {ExecutionContext} from '../../entrypoints/main.mjs'; +import test from '../../entrypoints/main.mjs'; + // Typed arguments through generics. { const hasLength = test.macro<[string, number]>((t, input, expected) => { @@ -118,7 +119,7 @@ test('has length 3 (inferred)', (t, input, expected) => { t.is(input, expected); }, 'foo', 3); -test.skip('skip', (t, input, expected) => { // eslint-disable-line ava/no-skip-test +test.skip('skip', (t, input, expected) => { expectType(input); expectType(expected); // @ts-expect-error TS2345 diff --git a/test-types/module/snapshot.ts b/test-types/module/snapshot.ts index ab166b253..08b1b155a 100644 --- a/test-types/module/snapshot.ts +++ b/test-types/module/snapshot.ts @@ -1,6 +1,7 @@ -import test from 'ava'; import {expectError} from 'tsd'; +import test from '../../entrypoints/main.mjs'; + test('snapshot', t => { t.snapshot({foo: 'bar'}); t.snapshot(null, 'a snapshot with a message'); diff --git a/test-types/module/teardown.ts b/test-types/module/teardown.ts index baaa4628e..dd7fa1eb3 100644 --- a/test-types/module/teardown.ts +++ b/test-types/module/teardown.ts @@ -1,4 +1,4 @@ -import test from 'ava'; +import test from '../../entrypoints/main.mjs'; test('test', t => { t.teardown(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function diff --git a/test-types/module/throws.ts b/test-types/module/throws.ts index 088cce716..76c1ce47f 100644 --- a/test-types/module/throws.ts +++ b/test-types/module/throws.ts @@ -1,7 +1,8 @@ /* eslint-disable @typescript-eslint/no-empty-function */ -import test from 'ava'; import {expectType} from 'tsd'; +import test from '../../entrypoints/main.mjs'; + class CustomError extends Error { foo: string; diff --git a/test-types/module/timeout.ts b/test-types/module/timeout.ts new file mode 100644 index 000000000..c96a5b647 --- /dev/null +++ b/test-types/module/timeout.ts @@ -0,0 +1,6 @@ +import test from '../../entrypoints/main.mjs'; + +test('test', t => { + t.timeout(100); + t.timeout.clear(); +}); diff --git a/test-types/module/try-commit.ts b/test-types/module/try-commit.ts index e726ce2c7..8dd53cc16 100644 --- a/test-types/module/try-commit.ts +++ b/test-types/module/try-commit.ts @@ -1,7 +1,8 @@ -import type {ExecutionContext} from 'ava'; -import test from 'ava'; import {expectType} from 'tsd'; +import type {ExecutionContext} from '../../entrypoints/main.mjs'; +import test from '../../entrypoints/main.mjs'; + test('attempt', async t => { const attempt = await t.try( (u, a, b) => { @@ -55,11 +56,11 @@ test('all possible variants to pass to t.try', async t => { void t.try('test', (tt, a, b) => tt.is(a.length, b), 'hello', 5); // Macro with title - const macro1 = test.macro<[string, number]>({ // eslint-disable-line ava/no-nested-tests + const macro1 = test.macro<[string, number]>({ exec: (tt, a, b) => tt.is(a.length, b), title: (title, a, b) => `${title ? `${String(title)} ` : ''}str: "${String(a)}" with len: "${String(b)}"`, }); - const macro2 = test.macro<[string, number]>((tt, a, b) => { // eslint-disable-line ava/no-nested-tests + const macro2 = test.macro<[string, number]>((tt, a, b) => { tt.is(a.slice(b), ''); }); diff --git a/test/watch-mode/helpers/watch.js b/test/watch-mode/helpers/watch.js index bd7cd21d6..ab553cdae 100644 --- a/test/watch-mode/helpers/watch.js +++ b/test/watch-mode/helpers/watch.js @@ -88,7 +88,7 @@ export const withFixture = fixture => async (t, task) => { idlePromise = new Promise(() => {}); assertingIdle = false; // TODO: When testing using AVA 6, enable for better managed timeouts. - // t.timeout(0); + // t.timeout.clear(); if (failedIdleAssertion) { failedIdleAssertion = false; t.fail('Watcher performed a test run while it should have been idle'); diff --git a/types/test-fn.d.cts b/types/test-fn.d.cts index 8eb16785d..e64e4ffee 100644 --- a/types/test-fn.d.cts +++ b/types/test-fn.d.cts @@ -39,11 +39,16 @@ export type PlanFn = { 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; +export type TimeoutFn = { + /** + * 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. + */ + (ms: number, message?: string): void; + + /** Clear the timeout and restore the default behavior. */ + clear(): void; +} /** Declare a function to be run after the test has ended. */ export type TeardownFn = (fn: (() => Promise) | (() => void)) => void;