1// Flags: --expose-gc
2'use strict';
3
4const common = require('../common');
5const { aborted } = require('util');
6const assert = require('assert');
7const { getEventListeners } = require('events');
8const { spawn } = require('child_process');
9
10{
11  // Test aborted works when provided a resource
12  const ac = new AbortController();
13  aborted(ac.signal, {}).then(common.mustCall());
14  ac.abort();
15  assert.strictEqual(ac.signal.aborted, true);
16  assert.strictEqual(getEventListeners(ac.signal, 'abort').length, 0);
17}
18
19{
20  // Test aborted with gc cleanup
21  const ac = new AbortController();
22  aborted(ac.signal, {}).then(common.mustNotCall());
23  setImmediate(() => {
24    global.gc();
25    ac.abort();
26    assert.strictEqual(ac.signal.aborted, true);
27    assert.strictEqual(getEventListeners(ac.signal, 'abort').length, 0);
28  });
29}
30
31{
32  // Fails with error if not provided abort signal
33  Promise.all([{}, null, undefined, Symbol(), [], 1, 0, 1n, true, false, 'a', () => {}].map((sig) =>
34    assert.rejects(aborted(sig, {}), {
35      code: 'ERR_INVALID_ARG_TYPE',
36    })
37  )).then(common.mustCall());
38}
39
40{
41  // Fails if not provided a resource
42  const ac = new AbortController();
43  Promise.all([null, undefined, 0, 1, 0n, 1n, Symbol(), '', 'a'].map((resource) =>
44    assert.rejects(aborted(ac.signal, resource), {
45      code: 'ERR_INVALID_ARG_TYPE',
46    })
47  )).then(common.mustCall());
48}
49
50{
51  const childProcess = spawn(process.execPath, ['--input-type=module']);
52  childProcess.on('exit', common.mustCall((code) => {
53    assert.strictEqual(code, 13);
54  }));
55  childProcess.stdin.end(`
56    import { aborted } from 'node:util';
57    await aborted(new AbortController().signal, {});
58  `);
59}
60