From 0d1418ef7cb5191688b0c7000fc0763aeb8efdb8 Mon Sep 17 00:00:00 2001 From: Paul Melnikow Date: Fri, 12 Apr 2019 13:16:23 -0400 Subject: [PATCH] fix: Provide correct return value from source.emit() (#17) This rebases the work from #8 with minor modifications, and tests the return values directly (rather than adding a wide-bracket integration test). Adopts arrow functions in the test file. This was identified as the root cause of nock/nock#1485. Thanks to @rbrtribeiro for the fix! Close #8 Close #9 --- index.js | 16 ++++++-- tests/index.js | 109 ++++++++++++++++++++++++++++++------------------- 2 files changed, 78 insertions(+), 47 deletions(-) diff --git a/index.js b/index.js index 09dee82..ea46434 100644 --- a/index.js +++ b/index.js @@ -15,14 +15,22 @@ function propagate(events, source, dest) { return explicitPropagate(events, source, dest) } + const shouldPropagate = eventName => + events === undefined || events.includes(eventName) + const oldEmit = source.emit - source.emit = function(eventType) { - oldEmit.apply(source, arguments) + // Returns true if the event had listeners, false otherwise. + // https://nodejs.org/api/events.html#events_emitter_emit_eventname_args + source.emit = (eventName, ...args) => { + const oldEmitHadListeners = oldEmit.call(source, eventName, ...args) - if (!events || ~events.indexOf(eventType)) { - dest.emit.apply(dest, arguments) + let destEmitHadListeners = false + if (shouldPropagate(eventName)) { + destEmitHadListeners = dest.emit(eventName, ...args) } + + return oldEmitHadListeners || destEmitHadListeners } function end() { diff --git a/tests/index.js b/tests/index.js index 16a8356..6612a68 100644 --- a/tests/index.js +++ b/tests/index.js @@ -4,64 +4,64 @@ const { test } = require('tap') const { EventEmitter } = require('events') const propagate = require('..') -test('propagates events', function(t) { - t.plan(12) +test('propagates events', t => { + t.plan(16) const ee1 = new EventEmitter() const ee2 = new EventEmitter() propagate(ee1, ee2) - ee2.on('event-1', function(a, b, c) { + ee2.on('event-1', (a, b, c) => { t.equal(a, 'a') t.equal(b, 'b') t.equal(c, undefined) }) - ee2.on('event-2', function(a, b, c) { + ee2.on('event-2', (a, b, c) => { t.equal(a, 'c') t.equal(b, 'd') t.equal(c, undefined) }) - ee1.emit('event-1', 'a', 'b') - ee1.emit('event-1', 'a', 'b') - ee1.emit('event-2', 'c', 'd') - ee1.emit('event-2', 'c', 'd') + t.true(ee1.emit('event-1', 'a', 'b')) + t.true(ee1.emit('event-1', 'a', 'b')) + t.true(ee1.emit('event-2', 'c', 'd')) + t.true(ee1.emit('event-2', 'c', 'd')) }) -test('propagates can end', function(t) { - t.plan(1) +test('propagates can end', t => { + t.plan(3) const ee1 = new EventEmitter() const ee2 = new EventEmitter() const prop = propagate(ee1, ee2) - ee2.on('event', function() { + ee2.on('event', () => { t.ok('true', 'propagated') }) - ee1.emit('event') + t.true(ee1.emit('event')) prop.end() - ee1.emit('event') + t.false(ee1.emit('event')) }) -test('after propagation old one still emits', function(t) { - t.plan(2) +test('after propagation old one still emits', t => { + t.plan(4) const ee1 = new EventEmitter() const ee2 = new EventEmitter() const prop = propagate(ee1, ee2) - ee1.on('event', function() { + ee1.on('event', () => { t.ok('true', 'propagated') }) - ee1.emit('event') + t.true(ee1.emit('event')) prop.end() - ee1.emit('event') + t.true(ee1.emit('event')) }) -test('emit on source before destination', function(t) { - t.plan(1) +test('emit on source before destination', t => { + t.plan(2) const source = new EventEmitter() const dest = new EventEmitter() @@ -70,47 +70,47 @@ test('emit on source before destination', function(t) { // `count` should have been incremented by handler on source when handler on dest is invoked let count = 0 propagate(source, dest) - source.on('event', function() { + source.on('event', () => { count++ }) - dest.on('event', function() { + dest.on('event', () => { t.equal(count, 1, 'emit on source first') }) // Emit the events for assertion - source.emit('event') + t.true(source.emit('event')) }) -test('is able to propagate only certain events', function(t) { - t.plan(2) +test('is able to propagate only certain events', t => { + t.plan(6) const ee1 = new EventEmitter() const ee2 = new EventEmitter() // propagate only event-1 and event-2, leaving out const p = propagate(['event-1', 'event-2'], ee1, ee2) - ee2.on('event-1', function() { + ee2.on('event-1', () => { t.ok(true, 'event 1 received') }) - ee2.on('event-2', function(a, b, c) { + ee2.on('event-2', (a, b, c) => { t.ok(true, 'event 2 received') }) - ee2.on('event-3', function(a, b, c) { - t.ok(false, 'event 3 should not have been received') + ee2.on('event-3', (a, b, c) => { + t.fail('event 3 should not have been received') }) - ee1.emit('event-1') - ee1.emit('event-2') - ee1.emit('event-3') + t.true(ee1.emit('event-1')) + t.true(ee1.emit('event-2')) + t.false(ee1.emit('event-3')) p.end() - ee1.emit('event-1') + t.false(ee1.emit('event-1')) }) -test('is able to propagate and map certain events', function(t) { - t.plan(2) +test('is able to propagate and map certain events', t => { + t.plan(6) const ee1 = new EventEmitter() const ee2 = new EventEmitter() // propagate only event-1 and event-2, leaving out @@ -123,23 +123,46 @@ test('is able to propagate and map certain events', function(t) { ee2 ) - ee2.on('other-event-1', function() { + ee2.on('other-event-1', () => { t.ok(true, 'event 1 received') }) - ee2.on('other-event-2', function(a, b, c) { + ee2.on('other-event-2', (a, b, c) => { t.ok(true, 'event 2 received') }) - ee2.on('event-3', function(a, b, c) { - t.ok(false, 'event 3 should not have been received') + ee2.on('event-3', (a, b, c) => { + t.fail('event 3 should not have been received') + }) + + t.true(ee1.emit('event-1')) + t.true(ee1.emit('event-2')) + t.false(ee1.emit('event-3')) + + p.end() + + t.false(ee1.emit('event-1')) +}) + +test('is able to propagate a single event', t => { + t.plan(5) + const ee1 = new EventEmitter() + const ee2 = new EventEmitter() + const p = propagate('event-1', ee1, ee2) + + ee2.on('event-1', () => { + t.ok(true, 'event 1 received') + }) + + ee2.on('event-2', (a, b, c) => { + t.fail('event 3 should not have been received') }) - ee1.emit('event-1') - ee1.emit('event-2') - ee1.emit('event-3') + t.true(ee1.emit('event-1')) + t.false(ee1.emit('event-2')) p.end() - ee1.emit('event-1') + t.false(ee1.emit('event-1')) + t.false(ee1.emit('event-2')) })