• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4const assert = require('assert');
5const { on, EventEmitter } = require('events');
6
7async function basic() {
8  const ee = new EventEmitter();
9  process.nextTick(() => {
10    ee.emit('foo', 'bar');
11    // 'bar' is a spurious event, we are testing
12    // that it does not show up in the iterable
13    ee.emit('bar', 24);
14    ee.emit('foo', 42);
15  });
16
17  const iterable = on(ee, 'foo');
18
19  const expected = [['bar'], [42]];
20
21  for await (const event of iterable) {
22    const current = expected.shift();
23
24    assert.deepStrictEqual(current, event);
25
26    if (expected.length === 0) {
27      break;
28    }
29  }
30  assert.strictEqual(ee.listenerCount('foo'), 0);
31  assert.strictEqual(ee.listenerCount('error'), 0);
32}
33
34async function error() {
35  const ee = new EventEmitter();
36  const _err = new Error('kaboom');
37  process.nextTick(() => {
38    ee.emit('error', _err);
39  });
40
41  const iterable = on(ee, 'foo');
42  let looped = false;
43  let thrown = false;
44
45  try {
46    // eslint-disable-next-line no-unused-vars
47    for await (const event of iterable) {
48      looped = true;
49    }
50  } catch (err) {
51    thrown = true;
52    assert.strictEqual(err, _err);
53  }
54  assert.strictEqual(thrown, true);
55  assert.strictEqual(looped, false);
56}
57
58async function errorDelayed() {
59  const ee = new EventEmitter();
60  const _err = new Error('kaboom');
61  process.nextTick(() => {
62    ee.emit('foo', 42);
63    ee.emit('error', _err);
64  });
65
66  const iterable = on(ee, 'foo');
67  const expected = [[42]];
68  let thrown = false;
69
70  try {
71    for await (const event of iterable) {
72      const current = expected.shift();
73      assert.deepStrictEqual(current, event);
74    }
75  } catch (err) {
76    thrown = true;
77    assert.strictEqual(err, _err);
78  }
79  assert.strictEqual(thrown, true);
80  assert.strictEqual(ee.listenerCount('foo'), 0);
81  assert.strictEqual(ee.listenerCount('error'), 0);
82}
83
84async function throwInLoop() {
85  const ee = new EventEmitter();
86  const _err = new Error('kaboom');
87
88  process.nextTick(() => {
89    ee.emit('foo', 42);
90  });
91
92  try {
93    for await (const event of on(ee, 'foo')) {
94      assert.deepStrictEqual(event, [42]);
95      throw _err;
96    }
97  } catch (err) {
98    assert.strictEqual(err, _err);
99  }
100
101  assert.strictEqual(ee.listenerCount('foo'), 0);
102  assert.strictEqual(ee.listenerCount('error'), 0);
103}
104
105async function next() {
106  const ee = new EventEmitter();
107  const iterable = on(ee, 'foo');
108
109  process.nextTick(function() {
110    ee.emit('foo', 'bar');
111    ee.emit('foo', 42);
112    iterable.return();
113  });
114
115  const results = await Promise.all([
116    iterable.next(),
117    iterable.next(),
118    iterable.next()
119  ]);
120
121  assert.deepStrictEqual(results, [{
122    value: ['bar'],
123    done: false
124  }, {
125    value: [42],
126    done: false
127  }, {
128    value: undefined,
129    done: true
130  }]);
131
132  assert.deepStrictEqual(await iterable.next(), {
133    value: undefined,
134    done: true
135  });
136}
137
138async function nextError() {
139  const ee = new EventEmitter();
140  const iterable = on(ee, 'foo');
141  const _err = new Error('kaboom');
142  process.nextTick(function() {
143    ee.emit('error', _err);
144  });
145  const results = await Promise.allSettled([
146    iterable.next(),
147    iterable.next(),
148    iterable.next()
149  ]);
150  assert.deepStrictEqual(results, [{
151    status: 'rejected',
152    reason: _err
153  }, {
154    status: 'fulfilled',
155    value: {
156      value: undefined,
157      done: true
158    }
159  }, {
160    status: 'fulfilled',
161    value: {
162      value: undefined,
163      done: true
164    }
165  }]);
166  assert.strictEqual(ee.listeners('error').length, 0);
167}
168
169async function iterableThrow() {
170  const ee = new EventEmitter();
171  const iterable = on(ee, 'foo');
172
173  process.nextTick(() => {
174    ee.emit('foo', 'bar');
175    ee.emit('foo', 42); // lost in the queue
176    iterable.throw(_err);
177  });
178
179  const _err = new Error('kaboom');
180  let thrown = false;
181
182  assert.throws(() => {
183    // No argument
184    iterable.throw();
185  }, {
186    message: 'The "EventEmitter.AsyncIterator" property must be' +
187    ' an instance of Error. Received undefined',
188    name: 'TypeError'
189  });
190
191  const expected = [['bar'], [42]];
192
193  try {
194    for await (const event of iterable) {
195      assert.deepStrictEqual(event, expected.shift());
196    }
197  } catch (err) {
198    thrown = true;
199    assert.strictEqual(err, _err);
200  }
201  assert.strictEqual(thrown, true);
202  assert.strictEqual(expected.length, 0);
203  assert.strictEqual(ee.listenerCount('foo'), 0);
204  assert.strictEqual(ee.listenerCount('error'), 0);
205}
206
207async function run() {
208  const funcs = [
209    basic,
210    error,
211    errorDelayed,
212    throwInLoop,
213    next,
214    nextError,
215    iterableThrow
216  ];
217
218  for (const fn of funcs) {
219    await fn();
220  }
221}
222
223run().then(common.mustCall());
224