From 71b659e171f9150f0c7737ce6ebce6bacee87d2d Mon Sep 17 00:00:00 2001 From: cjihrig Date: Thu, 8 Dec 2022 17:21:22 -0500 Subject: [PATCH] feat: add t.after() hook This commit adds an after() hook to the TestContext class. This hook can be used to clean up after a test finishes. PR-URL: https://github.com/nodejs/node/pull/45792 Reviewed-By: Moshe Atlow Reviewed-By: Matteo Collina (cherry picked from commit 215c5317d4837287fddb2e3b97872babd53183ac) --- README.md | 27 +++++++++++++++++++++++++++ lib/internal/test_runner/test.js | 7 ++++++- test/message/test_runner_hooks.js | 10 ++++++++-- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 10cd238..2ff9fa3 100644 --- a/README.md +++ b/README.md @@ -1035,6 +1035,33 @@ test('top level test', async (t) => { }); ``` +### `context.after([fn][, options])` + + + +* `fn` {Function|AsyncFunction} The hook function. The first argument + to this function is a [`TestContext`][] object. If the hook uses callbacks, + the callback function is passed as the second argument. **Default:** A no-op + function. +* `options` {Object} Configuration options for the hook. The following + properties are supported: + * `signal` {AbortSignal} Allows aborting an in-progress hook. + * `timeout` {number} A number of milliseconds the hook will fail after. + If unspecified, subtests inherit this value from their parent. + **Default:** `Infinity`. + +This function is used to create a hook that runs after the current test +finishes. + +```js +test('top level test', async (t) => { + t.after((t) => t.diagnostic(`finished running ${t.name}`)); + assert.ok('some relevant assertion here'); +}); +``` + ### `context.afterEach([, fn][, options])` * `fn` {Function|AsyncFunction} The hook function. The first argument diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index 98e1993..6b356fc 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -1,4 +1,4 @@ -// https://github.com/nodejs/node/blob/8302b0add01758713246117d3d0533cd212f160d/lib/internal/test_runner/test.js +// https://github.com/nodejs/node/blob/215c5317d4837287fddb2e3b97872babd53183ac/lib/internal/test_runner/test.js 'use strict' @@ -140,6 +140,10 @@ class TestContext { return subtest.start() } + after (fn, options) { + this.#test.createHook('after', fn, options) + } + beforeEach (fn, options) { this.#test.createHook('beforeEach', fn, options) } @@ -533,6 +537,7 @@ class Test extends AsyncResource { return } + await this.runHook('after', { args, ctx }) await afterEach() this.pass() } catch (err) { diff --git a/test/message/test_runner_hooks.js b/test/message/test_runner_hooks.js index 80af89a..bd38713 100644 --- a/test/message/test_runner_hooks.js +++ b/test/message/test_runner_hooks.js @@ -1,4 +1,4 @@ -// https://github.com/nodejs/node/blob/3759935ee29d8042d917d3ceaa768521c14413ff/test/message/test_runner_hooks.js +// https://github.com/nodejs/node/blob/215c5317d4837287fddb2e3b97872babd53183ac/test/message/test_runner_hooks.js // Flags: --no-warnings 'use strict' const common = require('../common') @@ -91,6 +91,8 @@ describe('afterEach throws and test fails', () => { test('test hooks', async (t) => { const testArr = [] + + t.after(common.mustCall((t) => testArr.push('after ' + t.name))) t.beforeEach((t) => testArr.push('beforeEach ' + t.name)) t.afterEach((t) => testArr.push('afterEach ' + t.name)) await t.test('1', () => testArr.push('1')) @@ -114,25 +116,29 @@ test('test hooks', async (t) => { }) test('t.beforeEach throws', async (t) => { + t.after(common.mustCall()) t.beforeEach(() => { throw new Error('beforeEach') }) await t.test('1', () => {}) await t.test('2', () => {}) }) test('t.afterEach throws', async (t) => { + t.after(common.mustCall()) t.afterEach(() => { throw new Error('afterEach') }) await t.test('1', () => {}) await t.test('2', () => {}) }) test('afterEach when test fails', async (t) => { + t.after(common.mustCall()) t.afterEach(common.mustCall(2)) await t.test('1', () => { throw new Error('test') }) await t.test('2', () => {}) }) test('afterEach throws and test fails', async (t) => { - afterEach(() => { throw new Error('afterEach') }) + t.after(common.mustCall()) + t.afterEach(() => { throw new Error('afterEach') }) await t.test('1', () => { throw new Error('test') }) await t.test('2', () => {}) })