Skip to content

Commit 1fb235a

Browse files
committed
test_runner: preserve hook promise when executed twice
1 parent b876e00 commit 1fb235a

File tree

5 files changed

+99
-26
lines changed

5 files changed

+99
-26
lines changed

lib/internal/test_runner/test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ class Test extends AsyncResource {
567567
// eslint-disable-next-line no-use-before-define
568568
const hook = new TestHook(fn, options);
569569
if (name === 'before' || name === 'after') {
570-
hook.run = runOnce(hook.run);
570+
hook.run = runOnce(hook.run, true);
571571
}
572572
if (name === 'before' && this.startTime !== null) {
573573
// Test has already started, run the hook immediately
@@ -710,7 +710,7 @@ class Test extends AsyncResource {
710710
if (this.parent?.hooks.afterEach.length > 0 && !this.skipped) {
711711
await this.parent.runHook('afterEach', hookArgs);
712712
}
713-
});
713+
}, true);
714714

715715
let stopPromise;
716716

@@ -1081,7 +1081,7 @@ class Suite extends Test {
10811081
const hookArgs = this.getRunArgs();
10821082

10831083
let stopPromise;
1084-
const after = runOnce(() => this.runHook('after', hookArgs));
1084+
const after = runOnce(() => this.runHook('after', hookArgs), true);
10851085
try {
10861086
this.parent.activeSubtests++;
10871087
await this.buildSuite;

lib/internal/util.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -514,12 +514,15 @@ function isInsideNodeModules() {
514514
return false;
515515
}
516516

517-
function once(callback) {
517+
function once(callback, preserveReturnValue = false) {
518518
let called = false;
519+
let returnValue;
519520
return function(...args) {
520-
if (called) return;
521+
if (called) return returnValue;
521522
called = true;
522-
return ReflectApply(callback, this, args);
523+
const result = ReflectApply(callback, this, args);
524+
returnValue = preserveReturnValue ? result : undefined;
525+
return result;
523526
};
524527
}
525528

test/fixtures/test-runner/output/hooks.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
const common = require('../../../common');
33
const assert = require('assert');
44
const { test, describe, it, before, after, beforeEach, afterEach } = require('node:test');
5+
const { setTimeout } = require('node:timers/promises');
56

67
before((t) => t.diagnostic('before 1 called'));
78
after((t) => t.diagnostic('after 1 called'));
@@ -149,6 +150,55 @@ test('test hooks', async (t) => {
149150
});
150151

151152

153+
test('test hooks - async', async (t) => {
154+
const testArr = [];
155+
156+
t.before(async (t) => {
157+
testArr.push('before starting ' + t.name);
158+
await setTimeout(10);
159+
testArr.push('before ending ' + t.name);
160+
});
161+
t.after(async (t) => {
162+
testArr.push('after starting ' + t.name);
163+
await setTimeout(10);
164+
testArr.push('after ending ' + t.name);
165+
});
166+
t.beforeEach(async (t) => {
167+
testArr.push('beforeEach starting ' + t.name);
168+
await setTimeout(10);
169+
testArr.push('beforeEach ending ' + t.name);
170+
});
171+
t.afterEach(async (t) => {
172+
testArr.push('afterEach starting ' + t.name);
173+
await setTimeout(10);
174+
testArr.push('afterEach ending ' + t.name);
175+
});
176+
await t.test('1', async () => {
177+
testArr.push('1 starting');
178+
await setTimeout(10);
179+
testArr.push('1 ending');
180+
});
181+
await t.test('2', async () => {
182+
testArr.push('2 starting');
183+
await setTimeout(10);
184+
testArr.push('2 ending');
185+
});
186+
187+
t.after(common.mustCall(() => {
188+
assert.deepStrictEqual(testArr, [
189+
'before starting test hooks - async', 'before ending test hooks - async',
190+
'beforeEach starting 1', 'beforeEach ending 1',
191+
'1 starting', '1 ending',
192+
'afterEach starting 1', 'afterEach ending 1',
193+
'beforeEach starting 2', 'beforeEach ending 2',
194+
'2 starting', '2 ending',
195+
'afterEach starting 2', 'afterEach ending 2',
196+
'after starting test hooks - async', 'after ending test hooks - async',
197+
]);
198+
}));
199+
});
200+
201+
152202
test('test hooks - no subtests', async (t) => {
153203
const testArr = [];
154204

test/fixtures/test-runner/output/hooks.snapshot

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
- after() called
21
TAP version 13
32
# Subtest: describe hooks
43
# Subtest: 1
@@ -367,8 +366,25 @@ ok 11 - test hooks
367366
---
368367
duration_ms: *
369368
...
369+
# Subtest: test hooks - async
370+
# Subtest: 1
371+
ok 1 - 1
372+
---
373+
duration_ms: *
374+
...
375+
# Subtest: 2
376+
ok 2 - 2
377+
---
378+
duration_ms: *
379+
...
380+
- after() called
381+
1..2
382+
ok 12 - test hooks - async
383+
---
384+
duration_ms: *
385+
...
370386
# Subtest: test hooks - no subtests
371-
ok 12 - test hooks - no subtests
387+
ok 13 - test hooks - no subtests
372388
---
373389
duration_ms: *
374390
...
@@ -414,7 +430,7 @@ ok 12 - test hooks - no subtests
414430
*
415431
...
416432
1..2
417-
not ok 13 - t.before throws
433+
not ok 14 - t.before throws
418434
---
419435
duration_ms: *
420436
location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1'
@@ -434,7 +450,7 @@ not ok 13 - t.before throws
434450
*
435451
...
436452
# Subtest: t.before throws - no subtests
437-
not ok 14 - t.before throws - no subtests
453+
not ok 15 - t.before throws - no subtests
438454
---
439455
duration_ms: *
440456
location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1'
@@ -465,7 +481,7 @@ not ok 14 - t.before throws - no subtests
465481
duration_ms: *
466482
...
467483
1..2
468-
not ok 15 - t.after throws
484+
not ok 16 - t.after throws
469485
---
470486
duration_ms: *
471487
location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1'
@@ -485,7 +501,7 @@ not ok 15 - t.after throws
485501
*
486502
...
487503
# Subtest: t.after throws - no subtests
488-
not ok 16 - t.after throws - no subtests
504+
not ok 17 - t.after throws - no subtests
489505
---
490506
duration_ms: *
491507
location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1'
@@ -546,7 +562,7 @@ not ok 16 - t.after throws - no subtests
546562
*
547563
...
548564
1..2
549-
not ok 17 - t.beforeEach throws
565+
not ok 18 - t.beforeEach throws
550566
---
551567
duration_ms: *
552568
location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1'
@@ -596,7 +612,7 @@ not ok 17 - t.beforeEach throws
596612
*
597613
...
598614
1..2
599-
not ok 18 - t.afterEach throws
615+
not ok 19 - t.afterEach throws
600616
---
601617
duration_ms: *
602618
location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1'
@@ -630,7 +646,7 @@ not ok 18 - t.afterEach throws
630646
duration_ms: *
631647
...
632648
1..2
633-
not ok 19 - afterEach when test fails
649+
not ok 20 - afterEach when test fails
634650
---
635651
duration_ms: *
636652
location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1'
@@ -645,7 +661,7 @@ not ok 19 - afterEach when test fails
645661
duration_ms: *
646662
...
647663
1..1
648-
ok 20 - afterEach context when test passes
664+
ok 21 - afterEach context when test passes
649665
---
650666
duration_ms: *
651667
...
@@ -665,7 +681,7 @@ ok 20 - afterEach context when test passes
665681
*
666682
...
667683
1..1
668-
not ok 21 - afterEach context when test fails
684+
not ok 22 - afterEach context when test fails
669685
---
670686
duration_ms: *
671687
location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1'
@@ -714,7 +730,7 @@ not ok 21 - afterEach context when test fails
714730
*
715731
...
716732
1..2
717-
not ok 22 - afterEach throws and test fails
733+
not ok 23 - afterEach throws and test fails
718734
---
719735
duration_ms: *
720736
location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1'
@@ -723,7 +739,7 @@ not ok 22 - afterEach throws and test fails
723739
code: 'ERR_TEST_FAILURE'
724740
...
725741
# Subtest: t.after() is called if test body throws
726-
not ok 23 - t.after() is called if test body throws
742+
not ok 24 - t.after() is called if test body throws
727743
---
728744
duration_ms: *
729745
location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1'
@@ -748,7 +764,7 @@ not ok 23 - t.after() is called if test body throws
748764
code: 'ERR_TEST_FAILURE'
749765
...
750766
1..1
751-
not ok 24 - run after when before throws
767+
not ok 25 - run after when before throws
752768
---
753769
duration_ms: *
754770
type: 'suite'
@@ -767,14 +783,14 @@ not ok 24 - run after when before throws
767783
*
768784
*
769785
...
770-
1..24
786+
1..25
771787
# before 1 called
772788
# before 2 called
773789
# after 1 called
774790
# after 2 called
775-
# tests 49
791+
# tests 52
776792
# suites 12
777-
# pass 19
793+
# pass 22
778794
# fail 27
779795
# cancelled 3
780796
# skipped 0

test/fixtures/test-runner/output/hooks_spec_reporter.snapshot

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
- after() called
21
describe hooks
32
1 (*ms)
43
2 (*ms)
@@ -172,6 +171,11 @@
172171
nested 2 (*ms)
173172
nested (*ms)
174173
test hooks (*ms)
174+
test hooks - async
175+
1 (*ms)
176+
2 (*ms)
177+
- after() called
178+
test hooks - async (*ms)
175179
test hooks - no subtests (*ms)
176180
t.before throws
177181
1 (*ms)
@@ -396,9 +400,9 @@
396400
before 2 called
397401
after 1 called
398402
after 2 called
399-
tests 49
403+
tests 52
400404
suites 12
401-
pass 19
405+
pass 22
402406
fail 27
403407
cancelled 3
404408
skipped 0

0 commit comments

Comments
 (0)