1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23const common = require('../common'); 24const assert = require('assert'); 25const events = require('events'); 26 27 28function expect(expected) { 29 const actual = []; 30 process.on('exit', function() { 31 assert.deepStrictEqual(actual.sort(), expected.sort()); 32 }); 33 function listener(name) { 34 actual.push(name); 35 } 36 return common.mustCall(listener, expected.length); 37} 38 39{ 40 const ee = new events.EventEmitter(); 41 const noop = common.mustNotCall(); 42 ee.on('foo', noop); 43 ee.on('bar', noop); 44 ee.on('baz', noop); 45 ee.on('baz', noop); 46 const fooListeners = ee.listeners('foo'); 47 const barListeners = ee.listeners('bar'); 48 const bazListeners = ee.listeners('baz'); 49 ee.on('removeListener', expect(['bar', 'baz', 'baz'])); 50 ee.removeAllListeners('bar'); 51 ee.removeAllListeners('baz'); 52 assert.deepStrictEqual(ee.listeners('foo'), [noop]); 53 assert.deepStrictEqual(ee.listeners('bar'), []); 54 assert.deepStrictEqual(ee.listeners('baz'), []); 55 // After calling removeAllListeners(), 56 // the old listeners array should stay unchanged. 57 assert.deepStrictEqual(fooListeners, [noop]); 58 assert.deepStrictEqual(barListeners, [noop]); 59 assert.deepStrictEqual(bazListeners, [noop, noop]); 60 // After calling removeAllListeners(), 61 // new listeners arrays is different from the old. 62 assert.notStrictEqual(ee.listeners('bar'), barListeners); 63 assert.notStrictEqual(ee.listeners('baz'), bazListeners); 64} 65 66{ 67 const ee = new events.EventEmitter(); 68 ee.on('foo', common.mustNotCall()); 69 ee.on('bar', common.mustNotCall()); 70 // Expect LIFO order 71 ee.on('removeListener', expect(['foo', 'bar', 'removeListener'])); 72 ee.on('removeListener', expect(['foo', 'bar'])); 73 ee.removeAllListeners(); 74 assert.deepStrictEqual([], ee.listeners('foo')); 75 assert.deepStrictEqual([], ee.listeners('bar')); 76} 77 78{ 79 const ee = new events.EventEmitter(); 80 ee.on('removeListener', common.mustNotCall()); 81 // Check for regression where removeAllListeners() throws when 82 // there exists a 'removeListener' listener, but there exists 83 // no listeners for the provided event type. 84 ee.removeAllListeners.bind(ee, 'foo'); 85} 86 87{ 88 const ee = new events.EventEmitter(); 89 let expectLength = 2; 90 ee.on('removeListener', function(name, noop) { 91 assert.strictEqual(expectLength--, this.listeners('baz').length); 92 }); 93 ee.on('baz', common.mustNotCall()); 94 ee.on('baz', common.mustNotCall()); 95 ee.on('baz', common.mustNotCall()); 96 assert.strictEqual(ee.listeners('baz').length, expectLength + 1); 97 ee.removeAllListeners('baz'); 98 assert.strictEqual(ee.listeners('baz').length, 0); 99} 100 101{ 102 const ee = new events.EventEmitter(); 103 assert.deepStrictEqual(ee, ee.removeAllListeners()); 104} 105 106{ 107 const ee = new events.EventEmitter(); 108 ee._events = undefined; 109 assert.strictEqual(ee, ee.removeAllListeners()); 110} 111 112{ 113 const ee = new events.EventEmitter(); 114 const symbol = Symbol('symbol'); 115 const noop = common.mustNotCall(); 116 ee.on(symbol, noop); 117 118 ee.on('removeListener', common.mustCall((...args) => { 119 assert.deepStrictEqual(args, [symbol, noop]); 120 })); 121 122 ee.removeAllListeners(); 123} 124