diff --git a/lib/events.js b/lib/events.js index 3ba2484ece938f..dacafff822e753 100644 --- a/lib/events.js +++ b/lib/events.js @@ -49,6 +49,7 @@ const { SymbolFor, SymbolAsyncIterator, SymbolDispose, + ArrayIsArray } = primordials; const kRejection = SymbolFor('nodejs.rejection'); @@ -888,7 +889,13 @@ function listenerCount(type, listener) { * @returns {any[]} */ EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; + const names = []; + for (const key of ReflectOwnKeys(this._events)) { + if(typeof this._events[key] === 'function' || ArrayIsArray(this._events[key]) && this._events[key].length > 0){ + names.push(key); + } + } + return names; }; function arrayClone(arr) { diff --git a/test/parallel/test-stream-event-names.js b/test/parallel/test-stream-event-names.js new file mode 100644 index 00000000000000..938b22d48ab0d6 --- /dev/null +++ b/test/parallel/test-stream-event-names.js @@ -0,0 +1,42 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const { Readable, Writable, Duplex } = require('stream'); + +{ + const stream = new Readable(); + assert.equal(stream.eventNames().length, 0); +} + +{ + const stream = new Readable(); + stream.on('foo', () => {}); + stream.on('data', () => {}); + stream.on('error', () => {}); + assert.deepStrictEqual(stream.eventNames(), ['error', 'data', 'foo']); +} + +{ + const stream = new Writable(); + assert.equal(stream.eventNames().length, 0); +} + +{ + const stream = new Writable(); + stream.on('foo', () => {}); + stream.on('drain', () => {}); + stream.on('prefinish', () => {}); + assert.deepStrictEqual(stream.eventNames(), ['prefinish', 'drain', 'foo']); +} +{ + const stream = new Duplex(); + assert.equal(stream.eventNames().length, 0); +} + +{ + const stream = new Duplex(); + stream.on('foo', () => {}); + stream.on('finish', () => {}); + assert.deepStrictEqual(stream.eventNames(), ['finish', 'foo']); +}