• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 EventEmitter = require('events');
26
27function listener1() {}
28
29function listener2() {}
30
31{
32  const ee = new EventEmitter();
33  ee.on('hello', listener1);
34  ee.on('removeListener', common.mustCall((name, cb) => {
35    assert.strictEqual(name, 'hello');
36    assert.strictEqual(cb, listener1);
37  }));
38  ee.removeListener('hello', listener1);
39  assert.deepStrictEqual([], ee.listeners('hello'));
40}
41
42{
43  const ee = new EventEmitter();
44  ee.on('hello', listener1);
45  ee.on('removeListener', common.mustNotCall());
46  ee.removeListener('hello', listener2);
47  assert.deepStrictEqual([listener1], ee.listeners('hello'));
48}
49
50{
51  const ee = new EventEmitter();
52  ee.on('hello', listener1);
53  ee.on('hello', listener2);
54  ee.once('removeListener', common.mustCall((name, cb) => {
55    assert.strictEqual(name, 'hello');
56    assert.strictEqual(cb, listener1);
57    assert.deepStrictEqual([listener2], ee.listeners('hello'));
58  }));
59  ee.removeListener('hello', listener1);
60  assert.deepStrictEqual([listener2], ee.listeners('hello'));
61  ee.once('removeListener', common.mustCall((name, cb) => {
62    assert.strictEqual(name, 'hello');
63    assert.strictEqual(cb, listener2);
64    assert.deepStrictEqual([], ee.listeners('hello'));
65  }));
66  ee.removeListener('hello', listener2);
67  assert.deepStrictEqual([], ee.listeners('hello'));
68}
69
70{
71  const ee = new EventEmitter();
72
73  function remove1() {
74    assert.fail('remove1 should not have been called');
75  }
76
77  function remove2() {
78    assert.fail('remove2 should not have been called');
79  }
80
81  ee.on('removeListener', common.mustCall(function(name, cb) {
82    if (cb !== remove1) return;
83    this.removeListener('quux', remove2);
84    this.emit('quux');
85  }, 2));
86  ee.on('quux', remove1);
87  ee.on('quux', remove2);
88  ee.removeListener('quux', remove1);
89}
90
91{
92  const ee = new EventEmitter();
93  ee.on('hello', listener1);
94  ee.on('hello', listener2);
95  ee.once('removeListener', common.mustCall((name, cb) => {
96    assert.strictEqual(name, 'hello');
97    assert.strictEqual(cb, listener1);
98    assert.deepStrictEqual([listener2], ee.listeners('hello'));
99    ee.once('removeListener', common.mustCall((name, cb) => {
100      assert.strictEqual(name, 'hello');
101      assert.strictEqual(cb, listener2);
102      assert.deepStrictEqual([], ee.listeners('hello'));
103    }));
104    ee.removeListener('hello', listener2);
105    assert.deepStrictEqual([], ee.listeners('hello'));
106  }));
107  ee.removeListener('hello', listener1);
108  assert.deepStrictEqual([], ee.listeners('hello'));
109}
110
111{
112  const ee = new EventEmitter();
113  const listener3 = common.mustCall(() => {
114    ee.removeListener('hello', listener4);
115  }, 2);
116  const listener4 = common.mustCall();
117
118  ee.on('hello', listener3);
119  ee.on('hello', listener4);
120
121  // listener4 will still be called although it is removed by listener 3.
122  ee.emit('hello');
123  // This is so because the internal listener array at time of emit
124  // was [listener3,listener4]
125
126  // Internal listener array [listener3]
127  ee.emit('hello');
128}
129
130{
131  const ee = new EventEmitter();
132
133  ee.once('hello', listener1);
134  ee.on('removeListener', common.mustCall((eventName, listener) => {
135    assert.strictEqual(eventName, 'hello');
136    assert.strictEqual(listener, listener1);
137  }));
138  ee.emit('hello');
139}
140
141{
142  const ee = new EventEmitter();
143
144  assert.deepStrictEqual(ee, ee.removeListener('foo', () => {}));
145}
146
147{
148  const ee = new EventEmitter();
149  const listener = () => {};
150  ee._events = undefined;
151  const e = ee.removeListener('foo', listener);
152  assert.strictEqual(e, ee);
153}
154
155{
156  const ee = new EventEmitter();
157
158  ee.on('foo', listener1);
159  ee.on('foo', listener2);
160  assert.deepStrictEqual(ee.listeners('foo'), [listener1, listener2]);
161
162  ee.removeListener('foo', listener1);
163  assert.strictEqual(ee._events.foo, listener2);
164
165  ee.on('foo', listener1);
166  assert.deepStrictEqual(ee.listeners('foo'), [listener2, listener1]);
167
168  ee.removeListener('foo', listener1);
169  assert.strictEqual(ee._events.foo, listener2);
170}
171