/test/unit/event_collection_test.rb
Ruby | 398 lines | 305 code | 93 blank | 0 comment | 0 complexity | f810ba72d4ff363ad9a3af06661bc252 MD5 | raw file
- require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
- class EventCollectionByDefaultTest < Test::Unit::TestCase
- def setup
- @klass = Class.new
- @machine = StateMachine::Machine.new(@klass)
- @events = StateMachine::EventCollection.new(@machine)
- @object = @klass.new
- end
-
- def test_should_not_have_any_nodes
- assert_equal 0, @events.length
- end
-
- def test_should_have_a_machine
- assert_equal @machine, @events.machine
- end
-
- def test_should_not_have_any_valid_events_for_an_object
- assert @events.valid_for(@object).empty?
- end
-
- def test_should_not_have_any_transitions_for_an_object
- assert @events.transitions_for(@object).empty?
- end
- end
- class EventCollectionTest < Test::Unit::TestCase
- def setup
- machine = StateMachine::Machine.new(Class.new, :namespace => 'alarm')
- @events = StateMachine::EventCollection.new(machine)
-
- @events << @open = StateMachine::Event.new(machine, :enable)
- machine.events.concat(@events)
- end
-
- def test_should_index_by_name
- assert_equal @open, @events[:enable, :name]
- end
-
- def test_should_index_by_name_by_default
- assert_equal @open, @events[:enable]
- end
-
- def test_should_index_by_string_name
- assert_equal @open, @events['enable']
- end
-
- def test_should_index_by_qualified_name
- assert_equal @open, @events[:enable_alarm, :qualified_name]
- end
-
- def test_should_index_by_string_qualified_name
- assert_equal @open, @events['enable_alarm', :qualified_name]
- end
- end
- class EventStringCollectionTest < Test::Unit::TestCase
- def setup
- machine = StateMachine::Machine.new(Class.new, :namespace => 'alarm')
- @events = StateMachine::EventCollection.new(machine)
-
- @events << @open = StateMachine::Event.new(machine, 'enable')
- machine.events.concat(@events)
- end
-
- def test_should_index_by_name
- assert_equal @open, @events['enable', :name]
- end
-
- def test_should_index_by_name_by_default
- assert_equal @open, @events['enable']
- end
-
- def test_should_index_by_symbol_name
- assert_equal @open, @events[:enable]
- end
-
- def test_should_index_by_qualified_name
- assert_equal @open, @events['enable_alarm', :qualified_name]
- end
-
- def test_should_index_by_symbol_qualified_name
- assert_equal @open, @events[:enable_alarm, :qualified_name]
- end
- end
- class EventCollectionWithEventsWithTransitionsTest < Test::Unit::TestCase
- def setup
- @klass = Class.new
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
- @events = StateMachine::EventCollection.new(@machine)
-
- @machine.state :idling, :first_gear
-
- @events << @ignite = StateMachine::Event.new(@machine, :ignite)
- @ignite.transition :parked => :idling
-
- @events << @park = StateMachine::Event.new(@machine, :park)
- @park.transition :idling => :parked
-
- @events << @shift_up = StateMachine::Event.new(@machine, :shift_up)
- @shift_up.transition :parked => :first_gear
- @shift_up.transition :idling => :first_gear, :if => lambda{false}
-
- @machine.events.concat(@events)
-
- @object = @klass.new
- end
-
- def test_should_find_valid_events_based_on_current_state
- assert_equal [@ignite, @shift_up], @events.valid_for(@object)
- end
-
- def test_should_filter_valid_events_by_from_state
- assert_equal [@park], @events.valid_for(@object, :from => :idling)
- end
-
- def test_should_filter_valid_events_by_to_state
- assert_equal [@shift_up], @events.valid_for(@object, :to => :first_gear)
- end
-
- def test_should_filter_valid_events_by_event
- assert_equal [@ignite], @events.valid_for(@object, :on => :ignite)
- end
-
- def test_should_filter_valid_events_by_multiple_requirements
- assert_equal [], @events.valid_for(@object, :from => :idling, :to => :first_gear)
- end
-
- def test_should_allow_finding_valid_events_without_guards
- assert_equal [@shift_up], @events.valid_for(@object, :from => :idling, :to => :first_gear, :guard => false)
- end
-
- def test_should_find_valid_transitions_based_on_current_state
- assert_equal [
- StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
- StateMachine::Transition.new(@object, @machine, :shift_up, :parked, :first_gear)
- ], @events.transitions_for(@object)
- end
-
- def test_should_filter_valid_transitions_by_from_state
- assert_equal [StateMachine::Transition.new(@object, @machine, :park, :idling, :parked)], @events.transitions_for(@object, :from => :idling)
- end
-
- def test_should_filter_valid_transitions_by_to_state
- assert_equal [StateMachine::Transition.new(@object, @machine, :shift_up, :parked, :first_gear)], @events.transitions_for(@object, :to => :first_gear)
- end
-
- def test_should_filter_valid_transitions_by_event
- assert_equal [StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)], @events.transitions_for(@object, :on => :ignite)
- end
-
- def test_should_filter_valid_transitions_by_multiple_requirements
- assert_equal [], @events.transitions_for(@object, :from => :idling, :to => :first_gear)
- end
-
- def test_should_allow_finding_valid_transitions_without_guards
- assert_equal [StateMachine::Transition.new(@object, @machine, :shift_up, :idling, :first_gear)], @events.transitions_for(@object, :from => :idling, :to => :first_gear, :guard => false)
- end
- end
- class EventCollectionWithMultipleEventsTest < Test::Unit::TestCase
- def setup
- @klass = Class.new
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
- @events = StateMachine::EventCollection.new(@machine)
-
- @machine.state :first_gear
- @park, @shift_down = @machine.event :park, :shift_down
-
- @events << @park
- @park.transition :first_gear => :parked
-
- @events << @shift_down
- @shift_down.transition :first_gear => :parked
-
- @machine.events.concat(@events)
- end
-
- def test_should_only_include_all_valid_events_for_an_object
- object = @klass.new
- object.state = 'first_gear'
- assert_equal [@park, @shift_down], @events.valid_for(object)
- end
- end
- class EventCollectionWithoutMachineActionTest < Test::Unit::TestCase
- def setup
- @klass = Class.new
- @machine = StateMachine::Machine.new(@klass, :initial => :parked)
- @events = StateMachine::EventCollection.new(@machine)
- @events << StateMachine::Event.new(@machine, :ignite)
- @machine.events.concat(@events)
-
- @object = @klass.new
- end
-
- def test_should_not_have_an_attribute_transition
- assert_nil @events.attribute_transition_for(@object)
- end
- end
- class EventCollectionAttributeWithMachineActionTest < Test::Unit::TestCase
- def setup
- @klass = Class.new do
- def save
- end
- end
-
- @machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
- @events = StateMachine::EventCollection.new(@machine)
-
- @machine.state :parked, :idling
- @events << @ignite = StateMachine::Event.new(@machine, :ignite)
- @machine.events.concat(@events)
-
- @object = @klass.new
- end
-
- def test_should_not_have_transition_if_nil
- @object.state_event = nil
- assert_nil @events.attribute_transition_for(@object)
- end
-
- def test_should_not_have_transition_if_empty
- @object.state_event = ''
- assert_nil @events.attribute_transition_for(@object)
- end
-
- def test_should_have_invalid_transition_if_invalid_event_specified
- @object.state_event = 'invalid'
- assert_equal false, @events.attribute_transition_for(@object)
- end
-
- def test_should_have_invalid_transition_if_event_cannot_be_fired
- @object.state_event = 'ignite'
- assert_equal false, @events.attribute_transition_for(@object)
- end
-
- def test_should_have_valid_transition_if_event_can_be_fired
- @ignite.transition :parked => :idling
- @object.state_event = 'ignite'
-
- assert_instance_of StateMachine::Transition, @events.attribute_transition_for(@object)
- end
-
- def test_should_have_valid_transition_if_already_defined_in_transition_cache
- @ignite.transition :parked => :idling
- @object.state_event = nil
- @object.send(:state_event_transition=, transition = @ignite.transition_for(@object))
-
- assert_equal transition, @events.attribute_transition_for(@object)
- end
-
- def test_should_use_transition_cache_if_both_event_and_transition_are_present
- @ignite.transition :parked => :idling
- @object.state_event = 'ignite'
- @object.send(:state_event_transition=, transition = @ignite.transition_for(@object))
-
- assert_equal transition, @events.attribute_transition_for(@object)
- end
- end
- class EventCollectionAttributeWithNamespacedMachineTest < Test::Unit::TestCase
- def setup
- @klass = Class.new do
- def save
- end
- end
-
- @machine = StateMachine::Machine.new(@klass, :namespace => 'alarm', :initial => :active, :action => :save)
- @events = StateMachine::EventCollection.new(@machine)
-
- @machine.state :active, :off
- @events << @disable = StateMachine::Event.new(@machine, :disable)
- @machine.events.concat(@events)
-
- @object = @klass.new
- end
-
- def test_should_not_have_transition_if_nil
- @object.state_event = nil
- assert_nil @events.attribute_transition_for(@object)
- end
-
- def test_should_have_invalid_transition_if_event_cannot_be_fired
- @object.state_event = 'disable'
- assert_equal false, @events.attribute_transition_for(@object)
- end
-
- def test_should_have_valid_transition_if_event_can_be_fired
- @disable.transition :active => :off
- @object.state_event = 'disable'
-
- assert_instance_of StateMachine::Transition, @events.attribute_transition_for(@object)
- end
- end
- class EventCollectionWithValidationsTest < Test::Unit::TestCase
- def setup
- StateMachine::Integrations.const_set('Custom', Module.new do
- include StateMachine::Integrations::Base
-
- def invalidate(object, attribute, message, values = [])
- (object.errors ||= []) << generate_message(message, values)
- end
-
- def reset(object)
- object.errors = []
- end
- end)
-
- @klass = Class.new do
- attr_accessor :errors
-
- def initialize
- @errors = []
- super
- end
- end
-
- @machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save, :integration => :custom)
- @events = StateMachine::EventCollection.new(@machine)
-
- @parked, @idling = @machine.state :parked, :idling
- @events << @ignite = StateMachine::Event.new(@machine, :ignite)
- @machine.events.concat(@events)
-
- @object = @klass.new
- end
-
- def test_should_invalidate_if_invalid_event_specified
- @object.state_event = 'invalid'
- @events.attribute_transition_for(@object, true)
-
- assert_equal ['is invalid'], @object.errors
- end
-
- def test_should_invalidate_if_event_cannot_be_fired
- @object.state = 'idling'
- @object.state_event = 'ignite'
- @events.attribute_transition_for(@object, true)
-
- assert_equal ['cannot transition when idling'], @object.errors
- end
-
- def test_should_invalidate_with_human_name_if_invalid_event_specified
- @idling.human_name = 'waiting'
- @object.state = 'idling'
- @object.state_event = 'ignite'
- @events.attribute_transition_for(@object, true)
-
- assert_equal ['cannot transition when waiting'], @object.errors
- end
-
- def test_should_not_invalidate_event_can_be_fired
- @ignite.transition :parked => :idling
- @object.state_event = 'ignite'
- @events.attribute_transition_for(@object, true)
-
- assert_equal [], @object.errors
- end
-
- def teardown
- StateMachine::Integrations.send(:remove_const, 'Custom')
- end
- end
- class EventCollectionWithCustomMachineAttributeTest < Test::Unit::TestCase
- def setup
- @klass = Class.new do
- def save
- end
- end
-
- @machine = StateMachine::Machine.new(@klass, :state, :attribute => :state_id, :initial => :parked, :action => :save)
- @events = StateMachine::EventCollection.new(@machine)
-
- @machine.state :parked, :idling
- @events << @ignite = StateMachine::Event.new(@machine, :ignite)
- @machine.events.concat(@events)
-
- @object = @klass.new
- end
-
- def test_should_not_have_transition_if_nil
- @object.state_event = nil
- assert_nil @events.attribute_transition_for(@object)
- end
-
- def test_should_have_valid_transition_if_event_can_be_fired
- @ignite.transition :parked => :idling
- @object.state_event = 'ignite'
-
- assert_instance_of StateMachine::Transition, @events.attribute_transition_for(@object)
- end
- end