Просмотр исходного кода

Add documentation and tests of EventEmitter implementation

Alasdair Smith 8 лет назад
Родитель
Сommit
152c816b5c

+ 7 - 0
services/web/public/coffee/utils/EventEmitter.coffee

@@ -1,4 +1,11 @@
 define [], () ->
 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
 	class EventEmitter
 		on: (event, callback) ->
 		on: (event, callback) ->
 			@events ||= {}
 			@events ||= {}

+ 67 - 0
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