Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 64442fc

Browse filesBrowse files
jasnellRafaelGSS
authored andcommitted
test: refactor test-abortcontroller to use node:test
Starting the long process of refactoring our own tests to use the node:test module and mocks. PR-URL: #54574 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent 4baf463 commit 64442fc
Copy full SHA for 64442fc

File tree

Expand file treeCollapse file tree

2 files changed

+142
-105
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+142
-105
lines changed
Open diff view settings
Collapse file
+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Flags: --no-warnings --expose-gc --expose-internals
2+
'use strict';
3+
require('../common');
4+
5+
const {
6+
strictEqual,
7+
} = require('assert');
8+
9+
const {
10+
test,
11+
} = require('node:test');
12+
13+
const {
14+
kWeakHandler,
15+
} = require('internal/event_target');
16+
17+
const { setTimeout: sleep } = require('timers/promises');
18+
19+
// The tests in this file depend on Node.js internal APIs. These are not necessarily
20+
// portable to other runtimes
21+
22+
test('A weak event listener should not prevent gc', async () => {
23+
// If the event listener is weak, however, it should not prevent gc
24+
let ref;
25+
function handler() {}
26+
{
27+
ref = new globalThis.WeakRef(AbortSignal.timeout(1_200_000));
28+
ref.deref().addEventListener('abort', handler, { [kWeakHandler]: {} });
29+
}
30+
31+
await sleep(10);
32+
globalThis.gc();
33+
strictEqual(ref.deref(), undefined);
34+
});
Collapse file
+108-105Lines changed: 108 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
// Flags: --no-warnings --expose-gc --expose-internals
1+
// Flags: --expose-gc
22
'use strict';
33

4-
const common = require('../common');
4+
require('../common');
55
const { inspect } = require('util');
66

77
const {
@@ -12,80 +12,93 @@ const {
1212
} = require('assert');
1313

1414
const {
15-
kWeakHandler,
16-
} = require('internal/event_target');
15+
test,
16+
mock,
17+
} = require('node:test');
1718

1819
const { setTimeout: sleep } = require('timers/promises');
1920

20-
{
21+
// All of the the tests in this file depend on public-facing Node.js APIs.
22+
// For tests that depend on Node.js internal APIs, please add them to
23+
// test-abortcontroller-internal.js instead.
24+
25+
test('Abort is fired with the correct event type on AbortControllers', () => {
2126
// Tests that abort is fired with the correct event type on AbortControllers
2227
const ac = new AbortController();
2328
ok(ac.signal);
24-
ac.signal.onabort = common.mustCall((event) => {
29+
30+
const fn = mock.fn((event) => {
2531
ok(event);
2632
strictEqual(event.type, 'abort');
2733
});
28-
ac.signal.addEventListener('abort', common.mustCall((event) => {
29-
ok(event);
30-
strictEqual(event.type, 'abort');
31-
}), { once: true });
34+
35+
ac.signal.onabort = fn;
36+
ac.signal.addEventListener('abort', fn);
37+
3238
ac.abort();
3339
ac.abort();
3440
ok(ac.signal.aborted);
35-
}
3641

37-
{
42+
strictEqual(fn.mock.calls.length, 2);
43+
});
44+
45+
test('Abort events are trusted', () => {
3846
// Tests that abort events are trusted
3947
const ac = new AbortController();
40-
ac.signal.addEventListener('abort', common.mustCall((event) => {
48+
49+
const fn = mock.fn((event) => {
4150
ok(event.isTrusted);
42-
}));
51+
});
52+
53+
ac.signal.onabort = fn;
4354
ac.abort();
44-
}
55+
strictEqual(fn.mock.calls.length, 1);
56+
});
4557

46-
{
58+
test('Abort events have the same isTrusted reference', () => {
4759
// Tests that abort events have the same `isTrusted` reference
4860
const first = new AbortController();
4961
const second = new AbortController();
5062
let ev1, ev2;
5163
const ev3 = new Event('abort');
52-
first.signal.addEventListener('abort', common.mustCall((event) => {
64+
65+
first.signal.addEventListener('abort', (event) => {
5366
ev1 = event;
54-
}));
55-
second.signal.addEventListener('abort', common.mustCall((event) => {
67+
});
68+
second.signal.addEventListener('abort', (event) => {
5669
ev2 = event;
57-
}));
70+
});
5871
first.abort();
5972
second.abort();
6073
const firstTrusted = Reflect.getOwnPropertyDescriptor(Object.getPrototypeOf(ev1), 'isTrusted').get;
6174
const secondTrusted = Reflect.getOwnPropertyDescriptor(Object.getPrototypeOf(ev2), 'isTrusted').get;
6275
const untrusted = Reflect.getOwnPropertyDescriptor(Object.getPrototypeOf(ev3), 'isTrusted').get;
6376
strictEqual(firstTrusted, secondTrusted);
6477
strictEqual(untrusted, firstTrusted);
65-
}
78+
});
6679

67-
{
80+
test('AbortSignal is impossible to construct manually', () => {
6881
// Tests that AbortSignal is impossible to construct manually
6982
const ac = new AbortController();
7083
throws(() => new ac.signal.constructor(), {
7184
code: 'ERR_ILLEGAL_CONSTRUCTOR',
7285
});
73-
}
74-
{
86+
});
87+
88+
test('Symbol.toStringTag is correct', () => {
7589
// Symbol.toStringTag
7690
const toString = (o) => Object.prototype.toString.call(o);
7791
const ac = new AbortController();
7892
strictEqual(toString(ac), '[object AbortController]');
7993
strictEqual(toString(ac.signal), '[object AbortSignal]');
80-
}
94+
});
8195

82-
{
96+
test('AbortSignal.abort() creates an already aborted signal', () => {
8397
const signal = AbortSignal.abort();
8498
ok(signal.aborted);
85-
}
99+
});
86100

87-
{
88-
// Test that AbortController properties and methods validate the receiver
101+
test('AbortController properties and methods valiate the receiver', () => {
89102
const acSignalGet = Object.getOwnPropertyDescriptor(
90103
AbortController.prototype,
91104
'signal'
@@ -115,10 +128,9 @@ const { setTimeout: sleep } = require('timers/promises');
115128
{ name: 'TypeError' }
116129
);
117130
}
118-
}
131+
});
119132

120-
{
121-
// Test that AbortSignal properties validate the receiver
133+
test('AbortSignal properties validate the receiver', () => {
122134
const signalAbortedGet = Object.getOwnPropertyDescriptor(
123135
AbortSignal.prototype,
124136
'aborted'
@@ -142,96 +154,87 @@ const { setTimeout: sleep } = require('timers/promises');
142154
{ name: 'TypeError' }
143155
);
144156
}
145-
}
157+
});
146158

147-
{
159+
test('AbortController inspection depth 1 or null works', () => {
148160
const ac = new AbortController();
149161
strictEqual(inspect(ac, { depth: 1 }),
150162
'AbortController { signal: [AbortSignal] }');
151163
strictEqual(inspect(ac, { depth: null }),
152164
'AbortController { signal: AbortSignal { aborted: false } }');
153-
}
165+
});
154166

155-
{
167+
test('AbortSignal reason is set correctly', () => {
156168
// Test AbortSignal.reason
157169
const ac = new AbortController();
158170
ac.abort('reason');
159171
strictEqual(ac.signal.reason, 'reason');
160-
}
172+
});
161173

162-
{
174+
test('AbortSignal reasonable is set correctly with AbortSignal.abort()', () => {
163175
// Test AbortSignal.reason
164176
const signal = AbortSignal.abort('reason');
165177
strictEqual(signal.reason, 'reason');
166-
}
178+
});
167179

168-
{
180+
test('AbortSignal.timeout() works as expected', async () => {
169181
// Test AbortSignal timeout
170182
const signal = AbortSignal.timeout(10);
171183
ok(!signal.aborted);
172-
setTimeout(common.mustCall(() => {
184+
185+
const { promise, resolve } = Promise.withResolvers();
186+
187+
const fn = mock.fn(() => {
173188
ok(signal.aborted);
174189
strictEqual(signal.reason.name, 'TimeoutError');
175190
strictEqual(signal.reason.code, 23);
176-
}), 20);
177-
}
178-
179-
{
180-
(async () => {
181-
// Test AbortSignal timeout doesn't prevent the signal
182-
// from being garbage collected.
183-
let ref;
184-
{
185-
ref = new globalThis.WeakRef(AbortSignal.timeout(1_200_000));
186-
}
187-
188-
await sleep(10);
189-
globalThis.gc();
190-
strictEqual(ref.deref(), undefined);
191-
})().then(common.mustCall());
192-
193-
(async () => {
194-
// Test that an AbortSignal with a timeout is not gc'd while
195-
// there is an active listener on it.
196-
let ref;
197-
function handler() {}
198-
{
199-
ref = new globalThis.WeakRef(AbortSignal.timeout(1_200_000));
200-
ref.deref().addEventListener('abort', handler);
201-
}
202-
203-
await sleep(10);
204-
globalThis.gc();
205-
notStrictEqual(ref.deref(), undefined);
206-
ok(ref.deref() instanceof AbortSignal);
207-
208-
ref.deref().removeEventListener('abort', handler);
209-
210-
await sleep(10);
211-
globalThis.gc();
212-
strictEqual(ref.deref(), undefined);
213-
})().then(common.mustCall());
214-
215-
(async () => {
216-
// If the event listener is weak, however, it should not prevent gc
217-
let ref;
218-
function handler() {}
219-
{
220-
ref = new globalThis.WeakRef(AbortSignal.timeout(1_200_000));
221-
ref.deref().addEventListener('abort', handler, { [kWeakHandler]: {} });
222-
}
223-
224-
await sleep(10);
225-
globalThis.gc();
226-
strictEqual(ref.deref(), undefined);
227-
})().then(common.mustCall());
228-
229-
// Setting a long timeout (20 minutes here) should not
230-
// keep the Node.js process open (the timer is unref'd)
191+
resolve();
192+
});
193+
194+
setTimeout(fn, 20);
195+
await promise;
196+
});
197+
198+
test('AbortSignal.timeout() does not prevent the signal from being collected', async () => {
199+
// Test AbortSignal timeout doesn't prevent the signal
200+
// from being garbage collected.
201+
let ref;
202+
{
203+
ref = new globalThis.WeakRef(AbortSignal.timeout(1_200_000));
204+
}
205+
206+
await sleep(10);
207+
globalThis.gc();
208+
strictEqual(ref.deref(), undefined);
209+
});
210+
211+
test('AbortSignal with a timeout is not collected while there is an active listener', async () => {
212+
// Test that an AbortSignal with a timeout is not gc'd while
213+
// there is an active listener on it.
214+
let ref;
215+
function handler() {}
216+
{
217+
ref = new globalThis.WeakRef(AbortSignal.timeout(1_200_000));
218+
ref.deref().addEventListener('abort', handler);
219+
}
220+
221+
await sleep(10);
222+
globalThis.gc();
223+
notStrictEqual(ref.deref(), undefined);
224+
ok(ref.deref() instanceof AbortSignal);
225+
226+
ref.deref().removeEventListener('abort', handler);
227+
228+
await sleep(10);
229+
globalThis.gc();
230+
strictEqual(ref.deref(), undefined);
231+
});
232+
233+
test('Setting a long timeout should not keep the process open', () => {
231234
AbortSignal.timeout(1_200_000);
232-
}
235+
});
233236

234-
{
237+
test('AbortSignal.reason should default', () => {
235238
// Test AbortSignal.reason default
236239
const signal = AbortSignal.abort();
237240
ok(signal.reason instanceof DOMException);
@@ -241,9 +244,9 @@ const { setTimeout: sleep } = require('timers/promises');
241244
ac.abort();
242245
ok(ac.signal.reason instanceof DOMException);
243246
strictEqual(ac.signal.reason.code, 20);
244-
}
247+
});
245248

246-
{
249+
test('abortSignal.throwIfAborted() works as expected', () => {
247250
// Test abortSignal.throwIfAborted()
248251
throws(() => AbortSignal.abort().throwIfAborted(), {
249252
code: 20,
@@ -253,21 +256,21 @@ const { setTimeout: sleep } = require('timers/promises');
253256
// Does not throw because it's not aborted.
254257
const ac = new AbortController();
255258
ac.signal.throwIfAborted();
256-
}
259+
});
257260

258-
{
261+
test('abortSignal.throwIfAobrted() works as expected (2)', () => {
259262
const originalDesc = Reflect.getOwnPropertyDescriptor(AbortSignal.prototype, 'aborted');
260263
const actualReason = new Error();
261264
Reflect.defineProperty(AbortSignal.prototype, 'aborted', { value: false });
262265
throws(() => AbortSignal.abort(actualReason).throwIfAborted(), actualReason);
263266
Reflect.defineProperty(AbortSignal.prototype, 'aborted', originalDesc);
264-
}
267+
});
265268

266-
{
269+
test('abortSignal.throwIfAobrted() works as expected (3)', () => {
267270
const originalDesc = Reflect.getOwnPropertyDescriptor(AbortSignal.prototype, 'reason');
268271
const actualReason = new Error();
269272
const fakeExcuse = new Error();
270273
Reflect.defineProperty(AbortSignal.prototype, 'reason', { value: fakeExcuse });
271274
throws(() => AbortSignal.abort(actualReason).throwIfAborted(), actualReason);
272275
Reflect.defineProperty(AbortSignal.prototype, 'reason', originalDesc);
273-
}
276+
});

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.