Skip to content

Commit 0b3dce9

Browse files
committed
test_runner: fix top level describe queuing
1 parent 26e2742 commit 0b3dce9

File tree

6 files changed

+173
-21
lines changed

6 files changed

+173
-21
lines changed

lib/internal/test_runner/test.js

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -561,25 +561,22 @@ class Suite extends Test {
561561

562562
try {
563563
const context = { signal: this.signal };
564-
this.buildSuite = this.runInAsyncScope(this.fn, context, [context]);
564+
this.buildSuite = PromisePrototypeThen(
565+
PromiseResolve(this.runInAsyncScope(this.fn, context, [context])),
566+
undefined,
567+
(err) => {
568+
this.fail(new ERR_TEST_FAILURE(err, kTestCodeFailure));
569+
});
565570
} catch (err) {
566571
this.fail(new ERR_TEST_FAILURE(err, kTestCodeFailure));
567572
}
568573
this.fn = () => {};
569574
this.buildPhaseFinished = true;
570575
}
571576

572-
start() {
573-
return this.run();
574-
}
575-
576577
async run() {
577-
try {
578-
await this.buildSuite;
579-
} catch (err) {
580-
this.fail(new ERR_TEST_FAILURE(err, kTestCodeFailure));
581-
}
582578
this.parent.activeSubtests++;
579+
await this.buildSuite;
583580
this.startTime = hrtime();
584581

585582
if (this[kShouldAbort]()) {

test/message/test_runner_describe_it.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,3 +339,47 @@ describe('timeouts', () => {
339339
setTimeout(done, 10);
340340
});
341341
});
342+
343+
describe('successful thenable', () => {
344+
it('successful thenable', () => {
345+
let thenCalled = false;
346+
return {
347+
get then() {
348+
if (thenCalled) throw new Error();
349+
thenCalled = true;
350+
return (successHandler) => successHandler();
351+
},
352+
};
353+
});
354+
355+
it('rejected thenable', () => {
356+
let thenCalled = false;
357+
return {
358+
get then() {
359+
if (thenCalled) throw new Error();
360+
thenCalled = true;
361+
return (_, errorHandler) => errorHandler(new Error('custom error'));
362+
},
363+
};
364+
});
365+
366+
let thenCalled = false;
367+
return {
368+
get then() {
369+
if (thenCalled) throw new Error();
370+
thenCalled = true;
371+
return (successHandler) => successHandler();
372+
},
373+
};
374+
});
375+
376+
describe('rejected thenable', () => {
377+
let thenCalled = false;
378+
return {
379+
get then() {
380+
if (thenCalled) throw new Error();
381+
thenCalled = true;
382+
return (_, errorHandler) => errorHandler(new Error('custom error'));
383+
},
384+
};
385+
});

test/message/test_runner_describe_it.out

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ not ok 3 - sync fail todo # TODO
2424
*
2525
*
2626
*
27+
*
2728
...
2829
# Subtest: sync fail todo with message
2930
not ok 4 - sync fail todo with message # TODO this is a failing todo
@@ -74,6 +75,7 @@ not ok 8 - sync throw fail
7475
*
7576
*
7677
*
78+
*
7779
...
7880
# Subtest: async skip pass
7981
ok 9 - async skip pass # SKIP
@@ -100,6 +102,7 @@ not ok 11 - async throw fail
100102
*
101103
*
102104
*
105+
*
103106
...
104107
# Subtest: async skip fail
105108
not ok 12 - async skip fail
@@ -128,6 +131,7 @@ not ok 13 - async assertion fail
128131
*
129132
*
130133
*
134+
*
131135
...
132136
# Subtest: resolve pass
133137
ok 14 - resolve pass
@@ -149,6 +153,7 @@ not ok 15 - reject fail
149153
*
150154
*
151155
*
156+
*
152157
...
153158
# Subtest: unhandled rejection - passes but warns
154159
ok 16 - unhandled rejection - passes but warns
@@ -601,8 +606,44 @@ not ok 57 - timeouts
601606
error: '2 subtests failed'
602607
code: 'ERR_TEST_FAILURE'
603608
...
609+
# Subtest: successful thenable
610+
# Subtest: successful thenable
611+
ok 1 - successful thenable
612+
---
613+
duration_ms: *
614+
...
615+
# Subtest: rejected thenable
616+
not ok 2 - rejected thenable
617+
---
618+
duration_ms: *
619+
failureType: 'testCodeFailure'
620+
error: 'custom error'
621+
code: 'ERR_TEST_FAILURE'
622+
stack: |-
623+
*
624+
*
625+
...
626+
1..2
627+
not ok 58 - successful thenable
628+
---
629+
duration_ms: *
630+
failureType: 'subtestsFailed'
631+
error: '1 subtest failed'
632+
code: 'ERR_TEST_FAILURE'
633+
...
634+
# Subtest: rejected thenable
635+
not ok 59 - rejected thenable
636+
---
637+
duration_ms: *
638+
failureType: 'testCodeFailure'
639+
error: 'custom error'
640+
code: 'ERR_TEST_FAILURE'
641+
stack: |-
642+
*
643+
*
644+
...
604645
# Subtest: invalid subtest fail
605-
not ok 58 - invalid subtest fail
646+
not ok 60 - invalid subtest fail
606647
---
607648
duration_ms: *
608649
failureType: 'parentAlreadyFinished'
@@ -611,16 +652,16 @@ not ok 58 - invalid subtest fail
611652
stack: |-
612653
*
613654
...
614-
1..58
655+
1..60
615656
# Warning: Test "unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.
616657
# Warning: Test "async unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from async unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.
617658
# Warning: Test "immediate throw - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from immediate throw fail" and would have caused the test to fail, but instead triggered an uncaughtException event.
618659
# Warning: Test "immediate reject - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from immediate reject fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.
619660
# Warning: Test "callback called twice in different ticks" generated asynchronous activity after the test ended. This activity created the error "Error [ERR_TEST_FAILURE]: callback invoked multiple times" and would have caused the test to fail, but instead triggered an uncaughtException event.
620661
# Warning: Test "callback async throw after done" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event.
621-
# tests 58
662+
# tests 60
622663
# pass 23
623-
# fail 21
664+
# fail 23
624665
# cancelled 0
625666
# skipped 9
626667
# todo 5

test/message/test_runner_output.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,25 @@ test('large timeout async test is ok', { timeout: 30_000_000 }, async (t) => {
349349
test('large timeout callback test is ok', { timeout: 30_000_000 }, (t, done) => {
350350
setTimeout(done, 10);
351351
});
352+
353+
test('successful thenable', () => {
354+
let thenCalled = false;
355+
return {
356+
get then() {
357+
if (thenCalled) throw new Error();
358+
thenCalled = true;
359+
return (successHandler) => successHandler();
360+
},
361+
};
362+
});
363+
364+
test('rejected thenable', () => {
365+
let thenCalled = false;
366+
return {
367+
get then() {
368+
if (thenCalled) throw new Error();
369+
thenCalled = true;
370+
return (_, errorHandler) => errorHandler('custom error');
371+
},
372+
};
373+
});

test/message/test_runner_output.out

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -588,8 +588,21 @@ ok 60 - large timeout callback test is ok
588588
---
589589
duration_ms: *
590590
...
591+
# Subtest: successful thenable
592+
ok 61 - successful thenable
593+
---
594+
duration_ms: *
595+
...
596+
# Subtest: rejected thenable
597+
not ok 62 - rejected thenable
598+
---
599+
duration_ms: *
600+
failureType: 'testCodeFailure'
601+
error: 'custom error'
602+
code: 'ERR_TEST_FAILURE'
603+
...
591604
# Subtest: invalid subtest fail
592-
not ok 61 - invalid subtest fail
605+
not ok 63 - invalid subtest fail
593606
---
594607
duration_ms: *
595608
failureType: 'parentAlreadyFinished'
@@ -598,16 +611,16 @@ not ok 61 - invalid subtest fail
598611
stack: |-
599612
*
600613
...
601-
1..61
614+
1..63
602615
# Warning: Test "unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.
603616
# Warning: Test "async unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from async unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.
604617
# Warning: Test "immediate throw - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from immediate throw fail" and would have caused the test to fail, but instead triggered an uncaughtException event.
605618
# Warning: Test "immediate reject - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from immediate reject fail" and would have caused the test to fail, but instead triggered an unhandledRejection event.
606619
# Warning: Test "callback called twice in different ticks" generated asynchronous activity after the test ended. This activity created the error "Error [ERR_TEST_FAILURE]: callback invoked multiple times" and would have caused the test to fail, but instead triggered an uncaughtException event.
607620
# Warning: Test "callback async throw after done" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event.
608-
# tests 61
609-
# pass 26
610-
# fail 18
621+
# tests 63
622+
# pass 27
623+
# fail 19
611624
# cancelled 2
612625
# skipped 10
613626
# todo 5

test/parallel/test-runner-concurrency.js

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
2-
require('../common');
3-
const { describe, it } = require('node:test');
2+
const common = require('../common');
3+
const { describe, it, test } = require('node:test');
44
const assert = require('assert');
55

66
describe('Concurrency option (boolean) = true ', { concurrency: true }, () => {
@@ -27,3 +27,38 @@ describe(
2727
});
2828
}
2929
);
30+
31+
{
32+
// make sure tests run in order when root concurrency is 1 (default)
33+
const tree = [];
34+
const expectedTestTree = common.mustCall(() => {
35+
assert.deepStrictEqual(tree, [
36+
'suite 1', 'nested', 'suite 2',
37+
'1', '2', 'nested 1', 'nested 2',
38+
'test', 'test 1', 'test 2',
39+
]);
40+
});
41+
42+
describe('suite 1', () => {
43+
tree.push('suite 1');
44+
it('1', () => tree.push('1'));
45+
it('2', () => tree.push('2'));
46+
47+
describe('nested', () => {
48+
tree.push('nested');
49+
it('nested 1', () => tree.push('nested 1'));
50+
it('nested 2', () => tree.push('nested 2'));
51+
});
52+
});
53+
54+
test('test', async (t) => {
55+
tree.push('test');
56+
await t.test('test1', () => tree.push('test 1'));
57+
await t.test('test 2', () => tree.push('test 2'));
58+
});
59+
60+
describe('suite 2', () => {
61+
tree.push('suite 2');
62+
it('should run after other suites', expectedTestTree)
63+
})
64+
}

0 commit comments

Comments
 (0)