diff --git a/lib/dry/events/bus.rb b/lib/dry/events/bus.rb index 084c93d..f844b86 100644 --- a/lib/dry/events/bus.rb +++ b/lib/dry/events/bus.rb @@ -63,6 +63,8 @@ def detach(listener) listeners.each do |id, memo| memo.each do |tuple| current_listener, _ = tuple + next unless current_listener.is_a?(Method) + listeners[id].delete(tuple) if current_listener.receiver.equal?(listener) end end diff --git a/spec/unit/dry/events/publisher_spec.rb b/spec/unit/dry/events/publisher_spec.rb index 58abde6..5d80b4f 100644 --- a/spec/unit/dry/events/publisher_spec.rb +++ b/spec/unit/dry/events/publisher_spec.rb @@ -111,6 +111,41 @@ def listener.on_test_event; end end + describe "#unsubscribe" do + it "unsubscribes a listener" do + listener = Class.new do + attr_reader :captured + + def initialize + @captured = [] + end + + def on_test_event(event) + captured << event[:message] + end + end.new + + captured_by_block = [] + + publisher.subscribe(:test_event) do |event| + captured_by_block << event[:message] + end + publisher.subscribe(listener) + + publisher.publish(:test_event, message: "it works") + + expect(listener.captured).to eql(["it works"]) + expect(captured_by_block).to eql(["it works"]) + + publisher.unsubscribe(listener) + + publisher.publish(:test_event, message: "it works") + + expect(listener.captured).to eql(["it works"]) + expect(captured_by_block).to eql(["it works", "it works"]) + end + end + describe "#publish" do it "publishes an event" do result = []