Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add t.timeout.clear() to restore default behavior #3221

Merged
merged 2 commits into from Jul 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/02-execution-context.md
Expand Up @@ -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.
File renamed without changes.
File renamed without changes.
18 changes: 6 additions & 12 deletions lib/test.js
Expand Up @@ -79,6 +79,10 @@
test.timeout(ms, message);
};

this.timeout.clear = () => {
test.clearTimeout();

Check warning on line 83 in lib/test.js

View check run for this annotation

Codecov / codecov/patch

lib/test.js#L83

Added line #L83 was not covered by tests
};

this.teardown = callback => {
test.addTeardown(callback);
};
Expand Down Expand Up @@ -289,7 +293,6 @@
this.pendingAttemptCount = 0;
this.planCount = null;
this.startedAt = 0;
this.timeoutMs = 0;
this.timeoutTimer = null;
}

Expand Down Expand Up @@ -418,7 +421,6 @@
}

this.clearTimeout();
this.timeoutMs = ms;
this.timeoutTimer = nowAndTimers.setCappedTimeout(() => {
this.saveFirstError(new Error(message ?? 'Test timeout exceeded'));

Expand All @@ -427,19 +429,11 @@
}
}, 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() {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -11,7 +11,7 @@
"exports": {
".": {
"import": {
"types": "./entrypoints/main.d.ts",
"types": "./entrypoints/main.d.mts",
"default": "./entrypoints/main.mjs"
},
"require": {
Expand All @@ -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": {
Expand Down
12 changes: 12 additions & 0 deletions test-tap/test.js
Expand Up @@ -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 => {
Expand Down
2 changes: 1 addition & 1 deletion 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'};
Expand Down
2 changes: 1 addition & 1 deletion 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 {
Expand Down
2 changes: 1 addition & 1 deletion 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 => {
Expand Down
2 changes: 1 addition & 1 deletion 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',
Expand Down
2 changes: 1 addition & 1 deletion 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({
Expand Down
2 changes: 1 addition & 1 deletion 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.
Expand Down
2 changes: 1 addition & 1 deletion 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 => {
Expand Down
2 changes: 1 addition & 1 deletion 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
Expand Down
2 changes: 1 addition & 1 deletion 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 {
Expand Down
6 changes: 6 additions & 0 deletions 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();
});
2 changes: 1 addition & 1 deletion 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 => {
Expand Down
3 changes: 2 additions & 1 deletion 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'};

Expand Down
5 changes: 3 additions & 2 deletions 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;
};
Expand Down
3 changes: 2 additions & 1 deletion 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]};
Expand Down
2 changes: 1 addition & 1 deletion 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',
Expand Down
2 changes: 1 addition & 1 deletion test-types/module/like.ts
@@ -1,4 +1,4 @@
import test from 'ava';
import test from '../../entrypoints/main.mjs';

test('like', t => {
t.like({
Expand Down
7 changes: 4 additions & 3 deletions 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) => {
Expand Down Expand Up @@ -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<string>(input);
expectType<number>(expected);
// @ts-expect-error TS2345
Expand Down
3 changes: 2 additions & 1 deletion 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');
Expand Down
2 changes: 1 addition & 1 deletion 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
Expand Down
3 changes: 2 additions & 1 deletion 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;

Expand Down
6 changes: 6 additions & 0 deletions test-types/module/timeout.ts
@@ -0,0 +1,6 @@
import test from '../../entrypoints/main.mjs';

test('test', t => {
t.timeout(100);
t.timeout.clear();
});
9 changes: 5 additions & 4 deletions 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) => {
Expand Down Expand Up @@ -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), '');
});

Expand Down
2 changes: 1 addition & 1 deletion test/watch-mode/helpers/watch.js
Expand Up @@ -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');
Expand Down
15 changes: 10 additions & 5 deletions types/test-fn.d.cts
Expand Up @@ -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)) => void;
Expand Down