11'use strict' ;
22
3- const common = require ( '../common' ) ;
3+ require ( '../common' ) ;
44const { ok, strictEqual } = require ( 'assert' ) ;
5- const { setImmediate : pause } = require ( 'timers/promises' ) ;
5+ const { setImmediate : sleep } = require ( 'timers/promises' ) ;
66const {
77 transferableAbortSignal,
88 transferableAbortController,
99} = require ( 'util' ) ;
10+ const {
11+ test,
12+ mock,
13+ } = require ( 'node:test' ) ;
1014
11-
12- function deferred ( ) {
13- let res ;
14- const promise = new Promise ( ( resolve ) => res = resolve ) ;
15- return { res, promise } ;
16- }
17-
18- ( async ( ) => {
15+ test ( 'Can create a transferable abort controller' , async ( ) => {
1916 const ac = transferableAbortController ( ) ;
2017 const mc = new MessageChannel ( ) ;
2118
22- const deferred1 = deferred ( ) ;
23- const deferred2 = deferred ( ) ;
24- const resolvers = [ deferred1 , deferred2 ] ;
19+ const setup1 = Promise . withResolvers ( ) ;
20+ const setup2 = Promise . withResolvers ( ) ;
21+ const setupResolvers = [ setup1 , setup2 ] ;
22+
23+ const abort1 = Promise . withResolvers ( ) ;
24+ const abort2 = Promise . withResolvers ( ) ;
25+ const abort3 = Promise . withResolvers ( ) ;
26+ const abortResolvers = [ abort1 , abort2 , abort3 ] ;
2527
26- mc . port1 . onmessage = common . mustCall ( ( { data } ) => {
27- data . addEventListener ( 'abort' , common . mustCall ( ( ) => {
28+ mc . port1 . onmessage = ( { data } ) => {
29+ data . addEventListener ( 'abort' , ( ) => {
2830 strictEqual ( data . reason , 'boom' ) ;
29- } ) ) ;
30- resolvers . shift ( ) . res ( ) ;
31- } , 2 ) ;
31+ abortResolvers . shift ( ) . resolve ( ) ;
32+ } ) ;
33+ setupResolvers . shift ( ) . resolve ( ) ;
34+ } ;
3235
3336 mc . port2 . postMessage ( ac . signal , [ ac . signal ] ) ;
3437
@@ -39,45 +42,59 @@ function deferred() {
3942
4043 // Although we're using transfer semantics, the local AbortSignal
4144 // is still usable locally.
42- ac . signal . addEventListener ( 'abort' , common . mustCall ( ( ) => {
45+ ac . signal . addEventListener ( 'abort' , ( ) => {
4346 strictEqual ( ac . signal . reason , 'boom' ) ;
44- } ) ) ;
47+ abortResolvers . shift ( ) . resolve ( ) ;
48+ } ) ;
4549
46- await Promise . all ( [ deferred1 . promise , deferred2 . promise ] ) ;
50+ await Promise . all ( [ setup1 . promise , setup2 . promise ] ) ;
4751
4852 ac . abort ( 'boom' ) ;
4953
54+ await Promise . all ( [ abort1 . promise , abort2 . promise , abort3 . promise ] ) ;
55+
5056 // Because the postMessage used by the underlying AbortSignal
5157 // takes at least one turn of the event loop to be processed,
5258 // and because it is unref'd, it won't, by itself, keep the
5359 // event loop open long enough for the test to complete, so
5460 // we schedule two back to back turns of the event to ensure
5561 // the loop runs long enough for the test to complete.
56- await pause ( ) ;
57- await pause ( ) ;
62+ await sleep ( ) ;
63+ await sleep ( ) ;
5864
59- } ) ( ) . then ( common . mustCall ( ) ) ;
65+ } ) ;
6066
61- {
67+ test ( 'Can create a transferable abort signal' , async ( ) => {
6268 const signal = transferableAbortSignal ( AbortSignal . abort ( 'boom' ) ) ;
6369 ok ( signal . aborted ) ;
6470 strictEqual ( signal . reason , 'boom' ) ;
6571 const mc = new MessageChannel ( ) ;
66- mc . port1 . onmessage = common . mustCall ( ( { data } ) => {
72+ const { promise, resolve } = Promise . withResolvers ( ) ;
73+ mc . port1 . onmessage = ( { data } ) => {
6774 ok ( data instanceof AbortSignal ) ;
6875 ok ( data . aborted ) ;
6976 strictEqual ( data . reason , 'boom' ) ;
7077 mc . port1 . close ( ) ;
71- } ) ;
78+ resolve ( ) ;
79+ } ;
7280 mc . port2 . postMessage ( signal , [ signal ] ) ;
73- }
81+ await promise ;
82+ } ) ;
7483
75- {
76- // The cloned AbortSignal does not keep the event loop open
77- // waiting for the abort to be triggered.
84+ test ( 'A cloned AbortSignal does not keep the event loop open' , async ( ) => {
7885 const ac = transferableAbortController ( ) ;
7986 const mc = new MessageChannel ( ) ;
80- mc . port1 . onmessage = common . mustCall ( ) ;
87+ const fn = mock . fn ( ) ;
88+ mc . port1 . onmessage = fn ;
8189 mc . port2 . postMessage ( ac . signal , [ ac . signal ] ) ;
8290 mc . port2 . close ( ) ;
83- }
91+ // Because the postMessage used by the underlying AbortSignal
92+ // takes at least one turn of the event loop to be processed,
93+ // and because it is unref'd, it won't, by itself, keep the
94+ // event loop open long enough for the test to complete, so
95+ // we schedule two back to back turns of the event to ensure
96+ // the loop runs long enough for the test to complete.
97+ await sleep ( ) ;
98+ await sleep ( ) ;
99+ strictEqual ( fn . mock . calls . length , 1 ) ;
100+ } ) ;
0 commit comments