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