Skip to content

Commit 50c854b

Browse files
MoLowruyadorno
authored andcommittedAug 22, 2022
test_runner: fix top level describe queuing
PR-URL: #43998 Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
1 parent 9763e2f commit 50c854b

File tree

6 files changed

+208
-89
lines changed

6 files changed

+208
-89
lines changed
 

‎lib/internal/test_runner/test.js

+7-10
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

+44-11
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,6 @@ describe('level 0a', { concurrency: 4 }, () => {
149149
return p0a;
150150
});
151151

152-
describe('top level', { concurrency: 2 }, () => {
153-
it('+long running', async () => {
154-
return new Promise((resolve, reject) => {
155-
setTimeout(resolve, 3000).unref();
156-
});
157-
});
158-
159-
describe('+short running', async () => {
160-
it('++short running', async () => {});
161-
});
162-
});
163152

164153
describe('invalid subtest - pass but subtest fails', () => {
165154
setImmediate(() => {
@@ -339,3 +328,47 @@ describe('timeouts', () => {
339328
setTimeout(done, 10);
340329
});
341330
});
331+
332+
describe('successful thenable', () => {
333+
it('successful thenable', () => {
334+
let thenCalled = false;
335+
return {
336+
get then() {
337+
if (thenCalled) throw new Error();
338+
thenCalled = true;
339+
return (successHandler) => successHandler();
340+
},
341+
};
342+
});
343+
344+
it('rejected thenable', () => {
345+
let thenCalled = false;
346+
return {
347+
get then() {
348+
if (thenCalled) throw new Error();
349+
thenCalled = true;
350+
return (_, errorHandler) => errorHandler(new Error('custom error'));
351+
},
352+
};
353+
});
354+
355+
let thenCalled = false;
356+
return {
357+
get then() {
358+
if (thenCalled) throw new Error();
359+
thenCalled = true;
360+
return (successHandler) => successHandler();
361+
},
362+
};
363+
});
364+
365+
describe('rejected thenable', () => {
366+
let thenCalled = false;
367+
return {
368+
get then() {
369+
if (thenCalled) throw new Error();
370+
thenCalled = true;
371+
return (_, errorHandler) => errorHandler(new Error('custom error'));
372+
},
373+
};
374+
});

‎test/message/test_runner_describe_it.out

+80-61
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
@@ -237,45 +242,23 @@ ok 23 - level 0a
237242
---
238243
duration_ms: *
239244
...
240-
# Subtest: top level
241-
# Subtest: +long running
242-
ok 1 - +long running
243-
---
244-
duration_ms: *
245-
...
246-
# Subtest: +short running
247-
# Subtest: ++short running
248-
ok 1 - ++short running
249-
---
250-
duration_ms: *
251-
...
252-
1..1
253-
ok 2 - +short running
254-
---
255-
duration_ms: *
256-
...
257-
1..2
258-
ok 24 - top level
259-
---
260-
duration_ms: *
261-
...
262245
# Subtest: invalid subtest - pass but subtest fails
263-
ok 25 - invalid subtest - pass but subtest fails
246+
ok 24 - invalid subtest - pass but subtest fails
264247
---
265248
duration_ms: *
266249
...
267250
# Subtest: sync skip option
268-
ok 26 - sync skip option # SKIP
251+
ok 25 - sync skip option # SKIP
269252
---
270253
duration_ms: *
271254
...
272255
# Subtest: sync skip option with message
273-
ok 27 - sync skip option with message # SKIP this is skipped
256+
ok 26 - sync skip option with message # SKIP this is skipped
274257
---
275258
duration_ms: *
276259
...
277260
# Subtest: sync skip option is false fail
278-
not ok 28 - sync skip option is false fail
261+
not ok 27 - sync skip option is false fail
279262
---
280263
duration_ms: *
281264
failureType: 'testCodeFailure'
@@ -291,67 +274,67 @@ not ok 28 - sync skip option is false fail
291274
*
292275
...
293276
# Subtest: <anonymous>
294-
ok 29 - <anonymous>
277+
ok 28 - <anonymous>
295278
---
296279
duration_ms: *
297280
...
298281
# Subtest: functionOnly
299-
ok 30 - functionOnly
282+
ok 29 - functionOnly
300283
---
301284
duration_ms: *
302285
...
303286
# Subtest: <anonymous>
304-
ok 31 - <anonymous>
287+
ok 30 - <anonymous>
305288
---
306289
duration_ms: *
307290
...
308291
# Subtest: test with only a name provided
309-
ok 32 - test with only a name provided
292+
ok 31 - test with only a name provided
310293
---
311294
duration_ms: *
312295
...
313296
# Subtest: <anonymous>
314-
ok 33 - <anonymous>
297+
ok 32 - <anonymous>
315298
---
316299
duration_ms: *
317300
...
318301
# Subtest: <anonymous>
319-
ok 34 - <anonymous> # SKIP
302+
ok 33 - <anonymous> # SKIP
320303
---
321304
duration_ms: *
322305
...
323306
# Subtest: test with a name and options provided
324-
ok 35 - test with a name and options provided # SKIP
307+
ok 34 - test with a name and options provided # SKIP
325308
---
326309
duration_ms: *
327310
...
328311
# Subtest: functionAndOptions
329-
ok 36 - functionAndOptions # SKIP
312+
ok 35 - functionAndOptions # SKIP
330313
---
331314
duration_ms: *
332315
...
333316
# Subtest: escaped description \\ \# \\\#\\
334-
ok 37 - escaped description \\ \# \\\#\\
317+
ok 36 - escaped description \\ \# \\\#\\
335318
---
336319
duration_ms: *
337320
...
338321
# Subtest: escaped skip message
339-
ok 38 - escaped skip message # SKIP \#skip
322+
ok 37 - escaped skip message # SKIP \#skip
340323
---
341324
duration_ms: *
342325
...
343326
# Subtest: escaped todo message
344-
ok 39 - escaped todo message # TODO \#todo
327+
ok 38 - escaped todo message # TODO \#todo
345328
---
346329
duration_ms: *
347330
...
348331
# Subtest: callback pass
349-
ok 40 - callback pass
332+
ok 39 - callback pass
350333
---
351334
duration_ms: *
352335
...
353336
# Subtest: callback fail
354-
not ok 41 - callback fail
337+
not ok 40 - callback fail
355338
---
356339
duration_ms: *
357340
failureType: 'testCodeFailure'
@@ -362,30 +345,30 @@ not ok 41 - callback fail
362345
*
363346
...
364347
# Subtest: sync t is this in test
365-
ok 42 - sync t is this in test
348+
ok 41 - sync t is this in test
366349
---
367350
duration_ms: *
368351
...
369352
# Subtest: async t is this in test
370-
ok 43 - async t is this in test
353+
ok 42 - async t is this in test
371354
---
372355
duration_ms: *
373356
...
374357
# Subtest: callback t is this in test
375-
ok 44 - callback t is this in test
358+
ok 43 - callback t is this in test
376359
---
377360
duration_ms: *
378361
...
379362
# Subtest: callback also returns a Promise
380-
not ok 45 - callback also returns a Promise
363+
not ok 44 - callback also returns a Promise
381364
---
382365
duration_ms: *
383366
failureType: 'callbackAndPromisePresent'
384367
error: 'passed a callback but also returned a Promise'
385368
code: 'ERR_TEST_FAILURE'
386369
...
387370
# Subtest: callback throw
388-
not ok 46 - callback throw
371+
not ok 45 - callback throw
389372
---
390373
duration_ms: *
391374
failureType: 'testCodeFailure'
@@ -401,7 +384,7 @@ not ok 46 - callback throw
401384
*
402385
...
403386
# Subtest: callback called twice
404-
not ok 47 - callback called twice
387+
not ok 46 - callback called twice
405388
---
406389
duration_ms: *
407390
failureType: 'multipleCallbackInvocations'
@@ -412,12 +395,12 @@ not ok 47 - callback called twice
412395
*
413396
...
414397
# Subtest: callback called twice in different ticks
415-
ok 48 - callback called twice in different ticks
398+
ok 47 - callback called twice in different ticks
416399
---
417400
duration_ms: *
418401
...
419402
# Subtest: callback called twice in future tick
420-
not ok 49 - callback called twice in future tick
403+
not ok 48 - callback called twice in future tick
421404
---
422405
duration_ms: *
423406
failureType: 'uncaughtException'
@@ -427,7 +410,7 @@ not ok 49 - callback called twice in future tick
427410
*
428411
...
429412
# Subtest: callback async throw
430-
not ok 50 - callback async throw
413+
not ok 49 - callback async throw
431414
---
432415
duration_ms: *
433416
failureType: 'uncaughtException'
@@ -437,20 +420,20 @@ not ok 50 - callback async throw
437420
*
438421
...
439422
# Subtest: callback async throw after done
440-
ok 51 - callback async throw after done
423+
ok 50 - callback async throw after done
441424
---
442425
duration_ms: *
443426
...
444427
# Subtest: custom inspect symbol fail
445-
not ok 52 - custom inspect symbol fail
428+
not ok 51 - custom inspect symbol fail
446429
---
447430
duration_ms: *
448431
failureType: 'testCodeFailure'
449432
error: 'customized'
450433
code: 'ERR_TEST_FAILURE'
451434
...
452435
# Subtest: custom inspect symbol that throws fail
453-
not ok 53 - custom inspect symbol that throws fail
436+
not ok 52 - custom inspect symbol that throws fail
454437
---
455438
duration_ms: *
456439
failureType: 'testCodeFailure'
@@ -501,7 +484,7 @@ not ok 53 - custom inspect symbol that throws fail
501484
*
502485
...
503486
1..2
504-
not ok 54 - subtest sync throw fails
487+
not ok 53 - subtest sync throw fails
505488
---
506489
duration_ms: *
507490
failureType: 'subtestsFailed'
@@ -518,7 +501,7 @@ not ok 54 - subtest sync throw fails
518501
code: 'ERR_TEST_FAILURE'
519502
...
520503
1..1
521-
not ok 55 - describe sync throw fails
504+
not ok 54 - describe sync throw fails
522505
---
523506
duration_ms: *
524507
failureType: 'testCodeFailure'
@@ -546,7 +529,7 @@ not ok 55 - describe sync throw fails
546529
code: 'ERR_TEST_FAILURE'
547530
...
548531
1..1
549-
not ok 56 - describe async throw fails
532+
not ok 55 - describe async throw fails
550533
---
551534
duration_ms: *
552535
failureType: 'testCodeFailure'
@@ -573,7 +556,7 @@ not ok 56 - describe async throw fails
573556
error: 'test timed out after 5ms'
574557
code: 'ERR_TEST_FAILURE'
575558
stack: |-
576-
*
559+
async Promise.all (index 0)
577560
...
578561
# Subtest: timed out callback test
579562
not ok 2 - timed out callback test
@@ -594,15 +577,51 @@ not ok 56 - describe async throw fails
594577
duration_ms: *
595578
...
596579
1..4
597-
not ok 57 - timeouts
580+
not ok 56 - timeouts
598581
---
599582
duration_ms: *
600583
failureType: 'subtestsFailed'
601584
error: '2 subtests failed'
602585
code: 'ERR_TEST_FAILURE'
603586
...
587+
# Subtest: successful thenable
588+
# Subtest: successful thenable
589+
ok 1 - successful thenable
590+
---
591+
duration_ms: *
592+
...
593+
# Subtest: rejected thenable
594+
not ok 2 - rejected thenable
595+
---
596+
duration_ms: *
597+
failureType: 'testCodeFailure'
598+
error: 'custom error'
599+
code: 'ERR_TEST_FAILURE'
600+
stack: |-
601+
*
602+
*
603+
...
604+
1..2
605+
not ok 57 - successful thenable
606+
---
607+
duration_ms: *
608+
failureType: 'subtestsFailed'
609+
error: '1 subtest failed'
610+
code: 'ERR_TEST_FAILURE'
611+
...
612+
# Subtest: rejected thenable
613+
not ok 58 - rejected thenable
614+
---
615+
duration_ms: *
616+
failureType: 'testCodeFailure'
617+
error: 'custom error'
618+
code: 'ERR_TEST_FAILURE'
619+
stack: |-
620+
*
621+
*
622+
...
604623
# Subtest: invalid subtest fail
605-
not ok 58 - invalid subtest fail
624+
not ok 59 - invalid subtest fail
606625
---
607626
duration_ms: *
608627
failureType: 'parentAlreadyFinished'
@@ -611,16 +630,16 @@ not ok 58 - invalid subtest fail
611630
stack: |-
612631
*
613632
...
614-
1..58
633+
1..59
615634
# 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.
616635
# 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.
617636
# 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.
618637
# 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.
619638
# 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.
620639
# 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
622-
# pass 23
623-
# fail 21
640+
# tests 59
641+
# pass 22
642+
# fail 23
624643
# cancelled 0
625644
# skipped 9
626645
# todo 5

‎test/message/test_runner_output.js

+22
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

+18-5
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

+37-2
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)
Please sign in to comment.