requireFile.expand_path(File.dirname(__FILE__)+'/../test_helper')classCallbackTest<Test::Unit::TestCasedeftest_should_raise_exception_if_invalid_type_specifiedexception=assert_raise(ArgumentError){StateMachine::Callback.new(:invalid){}}assert_equal'Type must be :before, :after, :around, or :failure',exception.messageenddeftest_should_not_raise_exception_if_using_before_typeassert_nothing_raised{StateMachine::Callback.new(:before){}}enddeftest_should_not_raise_exception_if_using_after_typeassert_nothing_raised{StateMachine::Callback.new(:after){}}enddeftest_should_not_raise_exception_if_using_around_typeassert_nothing_raised{StateMachine::Callback.new(:around){}}enddeftest_should_not_raise_exception_if_using_failure_typeassert_nothing_raised{StateMachine::Callback.new(:failure){}}enddeftest_should_raise_exception_if_no_methods_specifiedexception=assert_raise(ArgumentError){StateMachine::Callback.new(:before)}assert_equal'Method(s) for callback must be specified',exception.messageenddeftest_should_not_raise_exception_if_method_specified_in_do_optionassert_nothing_raised{StateMachine::Callback.new(:before,:do=>:run)}enddeftest_should_not_raise_exception_if_method_specified_as_argumentassert_nothing_raised{StateMachine::Callback.new(:before,:run)}enddeftest_should_not_raise_exception_if_method_specified_as_blockassert_nothing_raised{StateMachine::Callback.new(:before,:run){}}enddeftest_should_not_raise_exception_if_implicit_option_specifiedassert_nothing_raised{StateMachine::Callback.new(:before,:do=>:run,:invalid=>:valid)}enddeftest_should_not_bind_to_objectsassert!StateMachine::Callback.bind_to_objectenddeftest_should_not_have_a_terminatorassert_nilStateMachine::Callback.terminatorendendclassCallbackByDefaultTest<Test::Unit::TestCasedefsetup@callback=StateMachine::Callback.new(:before){}enddeftest_should_have_typeassert_equal:before,@callback.typeenddeftest_should_not_have_a_terminatorassert_nil@callback.terminatorenddeftest_should_have_a_branch_with_all_matcher_requirementsassert_equalStateMachine::AllMatcher.instance,@callback.branch.event_requirementassert_equalStateMachine::AllMatcher.instance,@callback.branch.state_requirements.first[:from]assert_equalStateMachine::AllMatcher.instance,@callback.branch.state_requirements.first[:to]enddeftest_should_not_have_any_known_statesassert_equal[],@callback.known_statesendendclassCallbackWithMethodArgumentTest<Test::Unit::TestCasedefsetup@callback=StateMachine::Callback.new(:before,lambda{|*args|@args=args})@object=Object.new@result=@callback.call(@object)enddeftest_should_be_successfulassert@resultenddeftest_should_call_with_empty_contextassert_equal[@object],@argsendendclassCallbackWithMultipleMethodArgumentsTest<Test::Unit::TestCasedefsetup@callback=StateMachine::Callback.new(:before,:run_1,:run_2)class<<@object=Object.newattr_accessor:callbacksdefrun_1(@callbacks||=[])<<:run_1enddefrun_2(@callbacks||=[])<<:run_2endend@result=@callback.call(@object)enddeftest_should_be_successfulassert@resultenddeftest_should_call_each_callback_in_orderassert_equal[:run_1,:run_2],@object.callbacksendendclassCallbackWithDoMethodTest<Test::Unit::TestCasedefsetup@callback=StateMachine::Callback.new(:before,:do=>lambda{|*args|@args=args})@object=Object.new@result=@callback.call(@object)enddeftest_should_be_successfulassert@resultenddeftest_should_call_with_empty_contextassert_equal[@object],@argsendendclassCallbackWithMultipleDoMethodsTest<Test::Unit::TestCasedefsetup@callback=StateMachine::Callback.new(:before,:do=>[:run_1,:run_2])class<<@object=Object.newattr_accessor:callbacksdefrun_1(@callbacks||=[])<<:run_1enddefrun_2(@callbacks||=[])<<:run_2endend@result=@callback.call(@object)enddeftest_should_be_successfulassert@resultenddeftest_should_call_each_callback_in_orderassert_equal[:run_1,:run_2],@object.callbacksendendclassCallbackWithBlockTest<Test::Unit::TestCasedefsetup@callback=StateMachine::Callback.new(:before)do|*args|@args=argsend@object=Object.new@result=@callback.call(@object)enddeftest_should_be_successfulassert@resultenddeftest_should_call_with_empty_contextassert_equal[@object],@argsendendclassCallbackWithMixedMethodsTest<Test::Unit::TestCasedefsetup@callback=StateMachine::Callback.new(:before,:run_argument,:do=>:run_do)do|object|object.callbacks<<:blockendclass<<@object=Object.newattr_accessor:callbacksdefrun_argument(@callbacks||=[])<<:argumentenddefrun_do(@callbacks||=[])<<:doendend@result=@callback.call(@object)enddeftest_should_be_successfulassert@resultenddeftest_should_call_each_callback_in_orderassert_equal[:argument,:do,:block],@object.callbacksendendclassCallbackWithExplicitRequirementsTest<Test::Unit::TestCasedefsetup@object=Object.new@callback=StateMachine::Callback.new(:before,:from=>:parked,:to=>:idling,:on=>:ignite,:do=>lambda{})enddeftest_should_call_with_empty_contextassert@callback.call(@object,{})enddeftest_should_not_call_if_from_not_includedassert!@callback.call(@object,:from=>:idling)enddeftest_should_not_call_if_to_not_includedassert!@callback.call(@object,:to=>:parked)enddeftest_should_not_call_if_on_not_includedassert!@callback.call(@object,:on=>:park)enddeftest_should_call_if_all_requirements_metassert@callback.call(@object,:from=>:parked,:to=>:idling,:on=>:ignite)enddeftest_should_include_in_known_statesassert_equal[:parked,:idling],@callback.known_statesendendclassCallbackWithImplicitRequirementsTest<Test::Unit::TestCasedefsetup@object=Object.new@callback=StateMachine::Callback.new(:before,:parked=>:idling,:on=>:ignite,:do=>lambda{})enddeftest_should_call_with_empty_contextassert@callback.call(@object,{})enddeftest_should_not_call_if_from_not_includedassert!@callback.call(@object,:from=>:idling)enddeftest_should_not_call_if_to_not_includedassert!@callback.call(@object,:to=>:parked)enddeftest_should_not_call_if_on_not_includedassert!@callback.call(@object,:on=>:park)enddeftest_should_call_if_all_requirements_metassert@callback.call(@object,:from=>:parked,:to=>:idling,:on=>:ignite)enddeftest_should_include_in_known_statesassert_equal[:parked,:idling],@callback.known_statesendendclassCallbackWithIfConditionTest<Test::Unit::TestCasedefsetup@object=Object.newenddeftest_should_call_if_truecallback=StateMachine::Callback.new(:before,:if=>lambda{true},:do=>lambda{})assertcallback.call(@object)enddeftest_should_not_call_if_falsecallback=StateMachine::Callback.new(:before,:if=>lambda{false},:do=>lambda{})assert!callback.call(@object)endendclassCallbackWithUnlessConditionTest<Test::Unit::TestCasedefsetup@object=Object.newenddeftest_should_call_if_falsecallback=StateMachine::Callback.new(:before,:unless=>lambda{false},:do=>lambda{})assertcallback.call(@object)enddeftest_should_not_call_if_truecallback=StateMachine::Callback.new(:before,:unless=>lambda{true},:do=>lambda{})assert!callback.call(@object)endendclassCallbackWithoutTerminatorTest<Test::Unit::TestCasedefsetup@object=Object.newenddeftest_should_not_halt_if_result_is_falsecallback=StateMachine::Callback.new(:before,:do=>lambda{false},:terminator=>nil)assert_nothing_thrown{callback.call(@object)}endendclassCallbackWithTerminatorTest<Test::Unit::TestCasedefsetup@object=Object.newenddeftest_should_not_halt_if_terminator_does_not_matchcallback=StateMachine::Callback.new(:before,:do=>lambda{false},:terminator=>lambda{|result|result==true})assert_nothing_thrown{callback.call(@object)}enddeftest_should_halt_if_terminator_matchescallback=StateMachine::Callback.new(:before,:do=>lambda{false},:terminator=>lambda{|result|result==false})assert_throws(:halt){callback.call(@object)}enddeftest_should_halt_if_terminator_matches_any_methodcallback=StateMachine::Callback.new(:before,:do=>[lambda{true},lambda{false}],:terminator=>lambda{|result|result==false})assert_throws(:halt){callback.call(@object)}endendclassCallbackWithoutArgumentsTest<Test::Unit::TestCasedefsetup@callback=StateMachine::Callback.new(:before,:do=>lambda{|object|@arg=object})@object=Object.new@callback.call(@object,{},1,2,3)enddeftest_should_call_method_with_object_as_argumentassert_equal@object,@argendendclassCallbackWithArgumentsTest<Test::Unit::TestCasedefsetup@callback=StateMachine::Callback.new(:before,:do=>lambda{|*args|@args=args})@object=Object.new@callback.call(@object,{},1,2,3)enddeftest_should_call_method_with_all_argumentsassert_equal[@object,1,2,3],@argsendendclassCallbackWithUnboundMethodTest<Test::Unit::TestCasedefsetup@callback=StateMachine::Callback.new(:before,:do=>lambda{|*args|@context=args.unshift(self)})@object=Object.new@callback.call(@object,{},1,2,3)enddeftest_should_call_method_outside_the_context_of_the_objectassert_equal[self,@object,1,2,3],@contextendendclassCallbackWithBoundMethodTest<Test::Unit::TestCasedefsetup@object=Object.newenddeftest_should_call_method_within_the_context_of_the_object_for_block_methodscontext=nilcallback=StateMachine::Callback.new(:before,:do=>lambda{|*args|context=[self]+args},:bind_to_object=>true)callback.call(@object,{},1,2,3)assert_equal[@object,1,2,3],contextenddeftest_should_ignore_option_for_symbolic_methodsclass<<@objectattr_reader:contextdefafter_ignite(*args)@context=argsendendcallback=StateMachine::Callback.new(:before,:do=>:after_ignite,:bind_to_object=>true)callback.call(@object)assert_equal[],@object.contextenddeftest_should_ignore_option_for_string_methodscallback=StateMachine::Callback.new(:before,:do=>'[1,2,3]',:bind_to_object=>true)assertcallback.call(@object)endendclassCallbackWithMultipleBoundMethodsTest<Test::Unit::TestCasedefsetup@object=Object.newfirst_context=nilsecond_context=nil@callback=StateMachine::Callback.new(:before,:do=>[lambda{first_context =self},lambda{second_context =self}],:bind_to_object=>true)@callback.call(@object)@first_context=first_context@second_context=second_contextenddeftest_should_call_each_method_within_the_context_of_the_objectassert_equal@object,@first_contextassert_equal@object,@second_contextendendclassCallbackWithApplicationBoundObjectTest<Test::Unit::TestCasedefsetup@original_bind_to_object=StateMachine::Callback.bind_to_objectStateMachine::Callback.bind_to_object=truecontext=nil@callback=StateMachine::Callback.new(:before,:do=>lambda{|*args|context=self})@object=Object.new@callback.call(@object)@context=contextenddeftest_should_call_method_within_the_context_of_the_objectassert_equal@object,@contextenddefteardownStateMachine::Callback.bind_to_object=@original_bind_to_objectendendclassCallbackWithBoundMethodAndArgumentsTest<Test::Unit::TestCasedefsetup@object=Object.newenddeftest_should_include_single_argument_if_specifiedcontext=nilcallback=StateMachine::Callback.new(:before,:do=>lambda{|arg1|context=[arg1]},:bind_to_object=>true)callback.call(@object,{},1)assert_equal[1],contextenddeftest_should_include_multiple_arguments_if_specifiedcontext=nilcallback=StateMachine::Callback.new(:before,:do=>lambda{|arg1,arg2,arg3|context=[arg1,arg2,arg3]},:bind_to_object=>true)callback.call(@object,{},1,2,3)assert_equal[1,2,3],contextenddeftest_should_include_arguments_if_splat_usedcontext=nilcallback=StateMachine::Callback.new(:before,:do=>lambda{|*args|context=args},:bind_to_object=>true)callback.call(@object,{},1,2,3)assert_equal[1,2,3],contextendendclassCallbackWithApplicationTerminatorTest<Test::Unit::TestCasedefsetup@original_terminator=StateMachine::Callback.bind_to_objectStateMachine::Callback.terminator=lambda{|result|result==false}@object=Object.newenddeftest_should_not_halt_if_terminator_does_not_matchcallback=StateMachine::Callback.new(:before,:do=>lambda{true})assert_nothing_thrown{callback.call(@object)}enddeftest_should_halt_if_terminator_matchescallback=StateMachine::Callback.new(:before,:do=>lambda{false})assert_throws(:halt){callback.call(@object)}enddefteardownStateMachine::Callback.bind_to_object=@original_bind_to_objectendendclassCallbackWithAroundTypeAndBlockTest<Test::Unit::TestCasedefsetup@object=Object.new@callbacks=[]enddeftest_should_evaluate_before_without_aftercallback=StateMachine::Callback.new(:around,lambda{|*args|block=args.pop;@args=args;block.call})assertcallback.call(@object)assert_equal[@object],@argsenddeftest_should_evaluate_after_without_beforecallback=StateMachine::Callback.new(:around,lambda{|*args|block=args.pop;block.call;@args=args})assertcallback.call(@object)assert_equal[@object],@argsenddeftest_should_halt_if_not_yieldedcallback=StateMachine::Callback.new(:around,lambda{|block|})assert_throws(:halt){callback.call(@object)}enddeftest_should_call_block_after_beforecallback=StateMachine::Callback.new(:around,lambda{|block|@callbacks<<:before;block.call})assertcallback.call(@object){@callbacks<<:block}assert_equal[:before,:block],@callbacksenddeftest_should_call_block_before_after@callbacks=[]callback=StateMachine::Callback.new(:around,lambda{|block|block.call;@callbacks<<:after})assertcallback.call(@object){@callbacks<<:block}assert_equal[:block,:after],@callbacksenddeftest_should_halt_if_block_haltscallback=StateMachine::Callback.new(:around,lambda{|block|block.call;@callbacks<<:after})assert_throws(:halt){callback.call(@object){throw:halt}}assert_equal[],@callbacksendendclassCallbackWithAroundTypeAndMultipleMethodsTest<Test::Unit::TestCasedefsetup@callback=StateMachine::Callback.new(:around,:run_1,:run_2)class<<@object=Object.newattr_accessor:before_callbacksattr_accessor:after_callbacksdefrun_1(@before_callbacks||=[])<<:run_1yield(@after_callbacks||=[])<<:run_1enddefrun_2(@before_callbacks||=[])<<:run_2yield(@after_callbacks||=[])<<:run_2endendenddeftest_should_succeedassert@callback.call(@object)enddeftest_should_evaluate_before_callbacks_in_order@callback.call(@object)assert_equal[:run_1,:run_2],@object.before_callbacksenddeftest_should_evaluate_after_callbacks_in_reverse_order@callback.call(@object)assert_equal[:run_2,:run_1],@object.after_callbacksenddeftest_should_call_block_after_before_callbacks@callback.call(@object){(@object.before_callbacks||=[])<<:block}assert_equal[:run_1,:run_2,:block],@object.before_callbacksenddeftest_should_call_block_before_after_callbacks@callback.call(@object){(@object.after_callbacks||=[])<<:block}assert_equal[:block,:run_2,:run_1],@object.after_callbacksenddeftest_should_halt_if_first_doesnt_yieldclass<<@objectdefrun_1(@before_callbacks||=[])<<:run_1endendcatch(:halt)do@callback.call(@object){(@object.before_callbacks||=[])<<:block}endassert_equal[:run_1],@object.before_callbacksassert_nil@object.after_callbacksenddeftest_should_halt_if_last_doesnt_yieldclass<<@objectdefrun_2(@before_callbacks||=[])<<:run_2endendcatch(:halt){@callback.call(@object)}assert_equal[:run_1,:run_2],@object.before_callbacksassert_nil@object.after_callbacksenddeftest_should_not_evaluate_further_methods_if_after_haltsclass<<@objectdefrun_2(@before_callbacks||=[])<<:run_2yield(@after_callbacks||=[])<<:run_2throw:haltendendcatch(:halt){@callback.call(@object)}assert_equal[:run_1,:run_2],@object.before_callbacksassert_equal[:run_2],@object.after_callbacksendendclassCallbackWithAroundTypeAndArgumentsTest<Test::Unit::TestCasedefsetup@object=Object.newenddeftest_should_include_object_if_specifiedcallback=StateMachine::Callback.new(:around,lambda{|object,block|@args=[object];block.call})callback.call(@object)assert_equal[@object],@argsenddeftest_should_include_arguments_if_specifiedcallback=StateMachine::Callback.new(:around,lambda{|object,arg1,arg2,arg3,block|@args=[object,arg1,arg2,arg3];block.call})callback.call(@object,{},1,2,3)assert_equal[@object,1,2,3],@argsenddeftest_should_include_arguments_if_splat_usedcallback=StateMachine::Callback.new(:around,lambda{|*args|block=args.pop;@args=args;block.call})callback.call(@object,{},1,2,3)assert_equal[@object,1,2,3],@argsendendclassCallbackWithAroundTypeAndTerminatorTest<Test::Unit::TestCasedefsetup@object=Object.newenddeftest_should_not_halt_if_terminator_does_not_matchcallback=StateMachine::Callback.new(:around,:do=>lambda{|block|block.call(false);false},:terminator=>lambda{|result|result==true})assert_nothing_thrown{callback.call(@object)}enddeftest_should_not_halt_if_terminator_matchescallback=StateMachine::Callback.new(:around,:do=>lambda{|block|block.call(false);false},:terminator=>lambda{|result|result==false})assert_nothing_thrown{callback.call(@object)}endendclassCallbackWithAroundTypeAndBoundMethodTest<Test::Unit::TestCasedefsetup@object=Object.newenddeftest_should_call_method_within_the_context_of_the_objectcontext=nilcallback=StateMachine::Callback.new(:around,:do=>lambda{|block|context=self;block.call},:bind_to_object=>true)callback.call(@object,{},1,2,3)assert_equal@object,contextenddeftest_should_include_arguments_if_specifiedcontext=nilcallback=StateMachine::Callback.new(:around,:do=>lambda{|*args|block=args.pop;context=args;block.call},:bind_to_object=>true)callback.call(@object,{},1,2,3)assert_equal[1,2,3],contextendend