From 152c816b5cd5fc8ae04047691c4e7902c2effa97 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 23 Apr 2018 11:01:19 +0100 Subject: [PATCH] Add documentation and tests of EventEmitter implementation --- .../public/coffee/utils/EventEmitter.coffee | 7 ++ .../coffee/utils/EventEmitterTests.coffee | 67 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 services/web/test/unit_frontend/coffee/utils/EventEmitterTests.coffee diff --git a/services/web/public/coffee/utils/EventEmitter.coffee b/services/web/public/coffee/utils/EventEmitter.coffee index b0fe5f1a36..73e14e233d 100644 --- a/services/web/public/coffee/utils/EventEmitter.coffee +++ b/services/web/public/coffee/utils/EventEmitter.coffee @@ -1,4 +1,11 @@ define [], () -> + # Simple event emitter implementation, but has a slightly unusual API for + # removing specific listeners. If a specific listener needs to be removed + # (instead of all listeners), then it needs to use a "namespace": + # Create a listener on the foo event with bar namespace: .on 'foo.bar' + # Trigger all events for the foo event (including namespaces): .trigger 'foo' + # Remove all listeners for the foo event (including namespaces): .off 'foo' + # Remove a listener for the foo event with the bar namespace: .off 'foo.bar' class EventEmitter on: (event, callback) -> @events ||= {} diff --git a/services/web/test/unit_frontend/coffee/utils/EventEmitterTests.coffee b/services/web/test/unit_frontend/coffee/utils/EventEmitterTests.coffee new file mode 100644 index 0000000000..c2d05f768c --- /dev/null +++ b/services/web/test/unit_frontend/coffee/utils/EventEmitterTests.coffee @@ -0,0 +1,67 @@ +define ['utils/EventEmitter'], (EventEmitter) -> + describe 'EventEmitter', () -> + beforeEach () -> + @eventEmitter = new EventEmitter + + it 'calls listeners', () -> + cb1 = sinon.stub() + cb2 = sinon.stub() + @eventEmitter.on 'foo', cb1 + @eventEmitter.on 'bar', cb2 + + @eventEmitter.trigger 'foo' + + expect(cb1).to.have.been.called + expect(cb2).to.not.have.been.called + + it 'calls multiple listeners', () -> + cb1 = sinon.stub() + cb2 = sinon.stub() + @eventEmitter.on 'foo', cb1 + @eventEmitter.on 'foo', cb2 + + @eventEmitter.trigger 'foo' + + expect(cb1).to.have.been.called + expect(cb2).to.have.been.called + + it 'calls listeners with namespace', () -> + cb1 = sinon.stub() + cb2 = sinon.stub() + @eventEmitter.on 'foo', cb1 + @eventEmitter.on 'foo.bar', cb2 + + @eventEmitter.trigger 'foo' + + expect(cb1).to.have.been.called + expect(cb2).to.have.been.called + + it 'removes listeners', () -> + cb = sinon.stub() + @eventEmitter.on 'foo', cb + @eventEmitter.off 'foo' + + @eventEmitter.trigger 'foo' + + expect(cb).to.not.have.been.called + + it 'removes namespaced listeners', () -> + cb = sinon.stub() + @eventEmitter.on 'foo.bar', cb + @eventEmitter.off 'foo.bar' + + @eventEmitter.trigger 'foo' + + expect(cb).to.not.have.been.called + + it 'does not remove unnamespaced listeners if off called with namespace', () -> + cb1 = sinon.stub() + cb2 = sinon.stub() + @eventEmitter.on 'foo', cb1 + @eventEmitter.on 'foo.bar', cb2 + @eventEmitter.off 'foo.bar' + + @eventEmitter.trigger 'foo' + + expect(cb1).to.have.been.called + expect(cb2).to.not.have.been.called