require_relative 'helpers/helper' require 'event' module Fidgit describe Event do before :each do class Test include Event end end after :each do Fidgit.send :remove_const, :Test end subject { Test } describe "events" do it "should initially be empty" do subject.events.should be_empty end end describe "event" do it "should add the event to the list of events handled" do subject.event :frog subject.events.should include :frog end it "should inherit parent's events and be able to add more" do Test.event :frog class Test2 < Test; end Test2.event :fish Test2.events.should include :frog Test2.events.should include :fish end end context "When included into a class that is instanced" do subject { Test.event :frog; Test.new } describe "#subscribe" do it "should add a handler as a block" do subject.subscribe(:frog) { puts "hello" } end it "should fail if the event name isn't handled by this object" do ->{ subject.subscribe(:unhandled_event) {} }.should raise_error ArgumentError end it "should add a handler as a method" do subject.stub! :handler subject.subscribe(:frog, subject.method(:handler)) end it "should fail if neither a method or a block is passed" do ->{ subject.subscribe(:frog) }.should raise_error ArgumentError end it "should fail if both a method and a block is passed" do subject.stub! :handler ->{ subject.subscribe(:frog, subject.method(:handler)) { } }.should raise_error ArgumentError end it "should return a Subscription" do handler = proc {} result = subject.subscribe(:frog, &handler) result.should be_a Fidgit::Event::Subscription result.handler.should be handler result.publisher.should be subject result.event.should equal :frog end it "should return a Subscription that can use Subscription#unsubscribe" do handler_ran = false subscription = subject.subscribe(:frog) { handler_ran = true } subscription.unsubscribe subject.publish :frog handler_ran.should be_false end end describe "#unsubscribe" do it "should accept a Subscription" do handler_ran = false subscription = subject.subscribe(:frog) { handler_ran = true } subject.unsubscribe subscription subject.publish :frog handler_ran.should be_false end it "should accept a handler" do handler_ran = false handler = proc { handler_ran = true } subject.subscribe(:frog, &handler) subject.unsubscribe handler subject.publish :frog handler_ran.should be_false end it "should accept an event and handler" do handler_ran = false handler = proc { handler_ran = true } subject.subscribe(:frog, &handler) subject.unsubscribe :frog, handler subject.publish :frog handler_ran.should be_false end it "should require 1..2 arguments" do ->{ subject.unsubscribe }.should raise_error ArgumentError ->{ subject.unsubscribe 1, 2, 3 }.should raise_error ArgumentError end it "should fail with bad types" do ->{ subject.unsubscribe 1 }.should raise_error TypeError ->{ subject.unsubscribe 1, ->{} }.should raise_error TypeError ->{ subject.unsubscribe :event, 2 }.should raise_error TypeError end it "should fail if passed a Subscription to another object" do subscription = Fidgit::Event::Subscription.new(Object.new.extend(Fidgit::Event), :event, proc {}) ->{ subject.unsubscribe subscription }.should raise_error ArgumentError end end describe "#publish" do it "should return nil if there are no handlers" do subject.publish(:frog).should be_nil end it "should return nil if there are no handlers that handle the event" do subject.should_receive(:frog).with(subject) subject.should_receive(:handler).with(subject) subject.subscribe(:frog, subject.method(:handler)) subject.publish(:frog).should be_nil end it "should return :handled if a manual handler handled the event and not call other handlers" do subject.should_not_receive(:handler1) subject.should_receive(:handler2).with(subject).and_return(:handled) subject.subscribe(:frog, subject.method(:handler1)) subject.subscribe(:frog, subject.method(:handler2)) subject.publish(:frog).should == :handled end it "should return :handled if an automatic handler handled the event and not call other handlers" do subject.should_receive(:frog).with(subject).and_return(:handled) subject.should_not_receive(:handler2) subject.subscribe(:frog, subject.method(:handler2)) subject.publish(:frog).should == :handled end it "should pass the object as the first parameter" do subject.should_receive(:handler).with(subject) subject.subscribe(:frog, subject.method(:handler)) subject.publish :frog end it "should call all the handlers, once each" do subject.should_receive(:handler1).with(subject) subject.should_receive(:handler2).with(subject) subject.subscribe(:frog, subject.method(:handler1)) subject.subscribe(:frog, subject.method(:handler2)) subject.publish(:frog).should be_nil end it "should pass parameters passed to it" do subject.should_receive(:handler).with(subject, 1, 2) subject.subscribe(:frog, subject.method(:handler)) subject.publish(:frog, 1, 2).should be_nil end it "should do nothing if the subject is disabled" do subject.should_receive(:enabled?).and_return(false) subject.should_not_receive(:handler) subject.subscribe(:frog, subject.method(:handler)) subject.publish(:frog, 1, 2).should be_nil end it "should act normally if the subject is enabled" do subject.should_receive(:enabled?).and_return(true) subject.should_receive(:handler) subject.subscribe(:frog, subject.method(:handler)) subject.publish(:frog, 1, 2).should be_nil end it "should only call the handlers requested" do Test.event :fish subject.should_receive(:handler1).with(subject) subject.should_not_receive(:handler2) subject.subscribe(:frog, subject.method(:handler1)) subject.subscribe(:fish, subject.method(:handler2)) subject.publish(:frog).should be_nil end it "should automatically call a method on the publisher if it exists" do subject.should_receive(:frog).with(subject) subject.publish(:frog).should be_nil end it "should fail if the event name isn't handled by this object" do ->{ subject.publish(:unhandled_event) }.should raise_error ArgumentError end end end end end