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