• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --expose-internals --no-warnings --expose-gc
2'use strict';
3const common = require('../common');
4const {
5  setMaxListeners,
6  EventEmitter,
7} = require('events');
8const assert = require('assert');
9const { kWeakHandler } = require('internal/event_target');
10const { setTimeout } = require('timers/promises');
11
12common.expectWarning({
13  MaxListenersExceededWarning: [
14    ['Possible EventTarget memory leak detected. 3 foo listeners added to ' +
15     'EventTarget. Use events.setMaxListeners() ' +
16     'to increase limit'],
17    ['Possible EventTarget memory leak detected. 3 foo listeners added to ' +
18     '[MessagePort [EventTarget]]. ' +
19     'Use events.setMaxListeners() to increase ' +
20     'limit'],
21    ['Possible EventTarget memory leak detected. 3 foo listeners added to ' +
22     '[MessagePort [EventTarget]]. ' +
23     'Use events.setMaxListeners() to increase ' +
24     'limit'],
25    ['Possible EventTarget memory leak detected. 3 foo listeners added to ' +
26     '[AbortSignal]. ' +
27     'Use events.setMaxListeners() to increase ' +
28     'limit'],
29  ],
30});
31
32
33{
34  const et = new EventTarget();
35  setMaxListeners(2, et);
36  et.addEventListener('foo', () => {});
37  et.addEventListener('foo', () => {});
38  et.addEventListener('foo', () => {});
39}
40
41{
42  // No warning emitted because prior limit was only for that
43  // one EventTarget.
44  const et = new EventTarget();
45  et.addEventListener('foo', () => {});
46  et.addEventListener('foo', () => {});
47  et.addEventListener('foo', () => {});
48}
49
50{
51  const mc = new MessageChannel();
52  setMaxListeners(2, mc.port1);
53  mc.port1.addEventListener('foo', () => {});
54  mc.port1.addEventListener('foo', () => {});
55  mc.port1.addEventListener('foo', () => {});
56}
57
58{
59  // Set the default for newly created EventTargets
60  setMaxListeners(2);
61  const mc = new MessageChannel();
62  mc.port1.addEventListener('foo', () => {});
63  mc.port1.addEventListener('foo', () => {});
64  mc.port1.addEventListener('foo', () => {});
65
66  const ac = new AbortController();
67  ac.signal.addEventListener('foo', () => {});
68  ac.signal.addEventListener('foo', () => {});
69  ac.signal.addEventListener('foo', () => {});
70}
71
72{
73  // It works for EventEmitters also
74  const ee = new EventEmitter();
75  setMaxListeners(2, ee);
76  assert.strictEqual(ee.getMaxListeners(), 2);
77}
78
79{
80  (async () => {
81    // Test that EventTarget listener don't emit MaxListenersExceededWarning for weak listeners that GCed
82    const et = new EventTarget();
83    setMaxListeners(2, et);
84
85    for (let i = 0; i <= 3; i++) {
86      et.addEventListener('foo', () => {}, {
87        [kWeakHandler]: {},
88      });
89
90      await setTimeout(0);
91      global.gc();
92    }
93  })().then(common.mustCall(), common.mustNotCall());
94}
95