transitions 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +18 -1
  3. data/.travis.yml +5 -0
  4. data/CHANGELOG.md +4 -0
  5. data/Gemfile +7 -6
  6. data/LICENSE.txt +21 -0
  7. data/README.md +9 -4
  8. data/Rakefile +9 -4
  9. data/bin/console +7 -0
  10. data/lib/active_model/transitions.rb +19 -12
  11. data/lib/transitions.rb +15 -15
  12. data/lib/transitions/event.rb +19 -15
  13. data/lib/transitions/machine.rb +23 -22
  14. data/lib/transitions/presenter.rb +2 -6
  15. data/lib/transitions/state.rb +10 -7
  16. data/lib/transitions/state_transition.rb +37 -6
  17. data/lib/transitions/version.rb +1 -1
  18. data/transitions.gemspec +23 -24
  19. metadata +39 -45
  20. data/.ruby-gemset +0 -1
  21. data/MIT-LICENSE.txt +0 -21
  22. data/test/active_record/test_active_record.rb +0 -326
  23. data/test/active_record/test_active_record_scopes.rb +0 -64
  24. data/test/active_record/test_active_record_timestamps.rb +0 -132
  25. data/test/active_record/test_custom_select.rb +0 -33
  26. data/test/event/test_event.rb +0 -72
  27. data/test/event/test_event_arguments.rb +0 -29
  28. data/test/event/test_event_being_fired.rb +0 -26
  29. data/test/event/test_event_checks.rb +0 -33
  30. data/test/helper.rb +0 -18
  31. data/test/machine/machine_template.rb +0 -27
  32. data/test/machine/test_available_states_listing.rb +0 -24
  33. data/test/machine/test_fire_event_machine.rb +0 -29
  34. data/test/machine/test_machine.rb +0 -66
  35. data/test/state/test_state.rb +0 -71
  36. data/test/state/test_state_predicate_method.rb +0 -32
  37. data/test/state_transition/test_state_transition.rb +0 -45
  38. data/test/state_transition/test_state_transition_event_failed_callback.rb +0 -36
  39. data/test/state_transition/test_state_transition_event_fired_callback.rb +0 -44
  40. data/test/state_transition/test_state_transition_guard_check.rb +0 -66
  41. data/test/state_transition/test_state_transition_on_transition_callback.rb +0 -48
  42. data/test/state_transition/test_state_transition_success_callback.rb +0 -49
@@ -1,24 +0,0 @@
1
- require 'helper'
2
-
3
- class Bender
4
- include Transitions
5
-
6
- state_machine do
7
- state :drinking
8
- state :smoking
9
- state :gambling
10
-
11
- event :cough do
12
- transitions from: :smoking, to: :gambling
13
- end
14
- end
15
- end
16
-
17
- class TestAvailableStatesListing < Test::Unit::TestCase
18
- test 'available_states should return the states for the state machine' do
19
- assert_equal [:drinking, :gambling, :smoking], Bender.available_states
20
- end
21
- test 'available_events should return the events for the state machine' do
22
- assert_equal [:cough], Bender.available_events
23
- end
24
- end
@@ -1,29 +0,0 @@
1
- require 'helper'
2
- require_relative './machine_template'
3
-
4
- class TestFireEventMachine < Test::Unit::TestCase
5
- def setup
6
- @record = MachineTestSubject.new
7
- @machine = MachineTestSubject.get_state_machine
8
- @event = @machine.events_for(@record.current_state).first
9
- assert_not_nil @event
10
- end
11
-
12
- test 'fire_event returns true if state transition was successful' do
13
- @machine.stubs(:transition_to_new_state).returns(:closed)
14
-
15
- assert_equal true, @machine.fire_event(@event, @record, false)
16
- end
17
-
18
- test 'fire_event returns false if state transition was unsuccessful' do
19
- @machine.stubs(:transition_to_new_state).returns(false)
20
-
21
- assert_equal false, @machine.fire_event(@event, @record, false)
22
- end
23
-
24
- test 'fire_event returns false if state transition raises' do
25
- @machine.stubs(:transition_to_new_state).raises(StandardError)
26
-
27
- assert_equal false, @machine.fire_event(@event, @record, false)
28
- end
29
- end
@@ -1,66 +0,0 @@
1
- require 'helper'
2
-
3
- class MachineTestSubject
4
- include Transitions
5
-
6
- state_machine initial: :closed do
7
- state :open
8
- state :closed
9
-
10
- event :shutdown do
11
- transitions from: :open, to: :closed
12
- end
13
-
14
- event :timeout do
15
- transitions from: :open, to: :closed
16
- end
17
-
18
- event :restart do
19
- transitions from: :closed, to: :open, guard: :restart_allowed?
20
- end
21
- end
22
-
23
- def restart_allowed?(allowed = true)
24
- allowed
25
- end
26
- end
27
-
28
- class TransitionsMachineTest < Test::Unit::TestCase
29
- test 'sets #initial_state from :initial option' do
30
- assert_equal :closed, MachineTestSubject.get_state_machine.initial_state
31
- end
32
-
33
- test '`get_state_machine` returns Transitions::Machine' do
34
- assert_kind_of Transitions::Machine, MachineTestSubject.get_state_machine
35
- end
36
-
37
- test 'finds events for given state' do
38
- events = MachineTestSubject.get_state_machine.events_for(:open)
39
- assert events.include?(:shutdown)
40
- assert events.include?(:timeout)
41
- end
42
-
43
- test 'knows all available transitions for current state' do
44
- machine = MachineTestSubject.new
45
- assert_equal [:restart], machine.available_transitions
46
- machine.restart
47
- assert_equal [:shutdown, :timeout], machine.available_transitions
48
- end
49
-
50
- test 'knows that it can use a transition when it is available' do
51
- machine = MachineTestSubject.new
52
- machine.restart
53
- assert machine.can_transition?(:shutdown)
54
- end
55
-
56
- test "knows that it can't use a transition when it is unavailable" do
57
- machine = MachineTestSubject.new
58
- assert machine.cant_transition?(:shutdown)
59
- end
60
-
61
- test "knows that it can't transition to a state denied by a guard" do
62
- machine = MachineTestSubject.new
63
- assert machine.can_execute_restart? true
64
- refute machine.can_execute_restart? false
65
- end
66
- end
@@ -1,71 +0,0 @@
1
- require 'helper'
2
-
3
- class TestState < Test::Unit::TestCase
4
- def setup
5
- machine = Class.new do
6
- include Transitions
7
- state_machine do
8
- end
9
- end.get_state_machine
10
- state_name = :astate
11
- @options = { machine: machine, custom_key: :my_key }
12
- @state = Transitions::State.new(state_name, @options)
13
- end
14
-
15
- def new_state_name
16
- Random.alphanumeric(16)
17
- end
18
-
19
- test 'sets the name' do
20
- assert_equal :astate, @state.name
21
- end
22
-
23
- test 'sets the display_name from name' do
24
- assert_equal 'Astate', @state.display_name
25
- end
26
-
27
- test 'sets the display_name from options' do
28
- assert_equal 'A State', Transitions::State.new(new_state_name, @options.merge(display: 'A State')).display_name
29
- end
30
-
31
- test 'sets the options and expose them as options' do
32
- @options.delete(:machine)
33
- state = Transitions::State.new new_state_name, @options
34
- assert_equal @options, state.options
35
- end
36
-
37
- test 'equals a symbol of the same name' do
38
- assert_equal @state, :astate
39
- end
40
-
41
- test 'equals a State of the same name' do
42
- assert_equal @state, @state
43
- end
44
-
45
- test 'should send a message to the record for an action if the action is present as a symbol' do
46
- state = Transitions::State.new new_state_name, @options.merge(entering: :foo)
47
-
48
- record = stub
49
- record.expects(:foo)
50
-
51
- state.call_action(:entering, record)
52
- end
53
-
54
- test 'should send a message to the record for an action if the action is present as a string' do
55
- state = Transitions::State.new new_state_name, @options.merge(entering: 'foo')
56
-
57
- record = stub
58
- record.expects(:foo)
59
-
60
- state.call_action(:entering, record)
61
- end
62
-
63
- test 'should call a proc, passing in the record for an action if the action is present' do
64
- state = Transitions::State.new new_state_name, @options.merge(entering: proc(&:foobar))
65
-
66
- record = stub
67
- record.expects(:foobar)
68
-
69
- state.call_action(:entering, record)
70
- end
71
- end
@@ -1,32 +0,0 @@
1
- require 'helper'
2
-
3
- class Bus
4
- include Transitions
5
-
6
- state_machine do
7
- state :parking
8
- end
9
- end
10
-
11
- class TestStatePredicateMethod < Test::Unit::TestCase
12
- def setup
13
- @bus = Bus.new
14
- end
15
-
16
- test 'should generate predicate methods for states' do
17
- assert_true @bus.respond_to?(:parking?)
18
- assert_true @bus.send(:parking?)
19
- end
20
-
21
- test 'should raise `InvalidMethodOverride` if we try to overwrite existing methods' do
22
- assert_raise(Transitions::InvalidMethodOverride) do
23
- Class.new do
24
- include Transitions
25
-
26
- state_machine do
27
- state :frozen
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,45 +0,0 @@
1
- require 'helper'
2
-
3
- class TestStateTransition < Test::Unit::TestCase
4
- test 'should set from, to, and opts attr readers' do
5
- opts = { from: 'foo', to: 'bar', guard: 'g' }
6
- st = Transitions::StateTransition.new(opts)
7
-
8
- assert_equal opts[:from], st.from
9
- assert_equal opts[:to], st.to
10
- assert_equal opts, st.options
11
- end
12
-
13
- test 'should pass equality check if from and to are the same' do
14
- opts = { from: 'foo', to: 'bar', guard: 'g' }
15
- st = Transitions::StateTransition.new(opts)
16
-
17
- obj = stub
18
- obj.stubs(:from).returns(opts[:from])
19
- obj.stubs(:to).returns(opts[:to])
20
-
21
- assert_equal st, obj
22
- end
23
-
24
- test 'should fail equality check if from are not the same' do
25
- opts = { from: 'foo', to: 'bar', guard: 'g' }
26
- st = Transitions::StateTransition.new(opts)
27
-
28
- obj = stub
29
- obj.stubs(:from).returns('blah')
30
- obj.stubs(:to).returns(opts[:to])
31
-
32
- assert_not_equal st, obj
33
- end
34
-
35
- test 'should fail equality check if to are not the same' do
36
- opts = { from: 'foo', to: 'bar', guard: 'g' }
37
- st = Transitions::StateTransition.new(opts)
38
-
39
- obj = stub
40
- obj.stubs(:from).returns(opts[:from])
41
- obj.stubs(:to).returns('blah')
42
-
43
- assert_not_equal st, obj
44
- end
45
- end
@@ -1,36 +0,0 @@
1
- require 'helper'
2
-
3
- class Car
4
- include Transitions
5
-
6
- state_machine do
7
- state :parked
8
- state :driving
9
- state :switched_off
10
-
11
- event :start_driving do
12
- transitions from: :parked, to: :driving
13
- end
14
-
15
- event :switch_off_engine do
16
- transitions from: :parked, to: :switched_off
17
- end
18
- end
19
- end
20
-
21
- class TestStateTransitionEventFailedCallback < Test::Unit::TestCase
22
- def setup
23
- @car = Car.new
24
- end
25
-
26
- test "should execute the event_failed_callback and don't raise error if callback is defined" do
27
- @car.start_driving
28
- @car.expects(:event_failed).with(:switch_off_engine)
29
- @car.switch_off_engine
30
- end
31
-
32
- test "should just re-raise any error on transition if the event_failed_callback isn't defined" do
33
- @car.start_driving
34
- assert_raise(Transitions::InvalidTransition) { @car.switch_off_engine }
35
- end
36
- end
@@ -1,44 +0,0 @@
1
- require 'helper'
2
-
3
- class Car
4
- include Transitions
5
-
6
- state_machine do
7
- state :parked
8
- state :driving
9
-
10
- event :start_driving do
11
- transitions from: :parked, to: :driving
12
- end
13
- end
14
- end
15
-
16
- class TestStateTransitionEventFiredCallback < Test::Unit::TestCase
17
- def setup
18
- @car = Car.new
19
- end
20
-
21
- test 'should execute the event_fired callback after successfull event execution if it callback is defined' do
22
- @car.stubs(:event_fired)
23
- @car.expects(:event_fired).with(:parked, :driving, :start_driving).once
24
-
25
- @car.start_driving!
26
- end
27
-
28
- test 'should not execute the event_fired callback after successfull event execution if it callback is not defined' do
29
- pend 'Test fails right now although functionality is working as expected'
30
- # This test fails right now even though it works as expected in the console.
31
- # The reason for this is, that mocha's `expects` does a little bit more than just set up an expectation,
32
- # it actually defines this method if it doesn't exist or at least it overwrites respond_to?
33
- # @car.respond_to?(:event_fired)
34
- # returns false before the `expects` call, but true after.
35
- # Hence, this test fails.
36
- # Something like
37
- # @car.instance_eval { undef :event_fired }
38
- # doesn't work either, probably because expects just overwrites respond_to?
39
- # but does not define the method
40
- # How to fix?
41
- @car.expects(:event_fired).never
42
- @car.start_driving!
43
- end
44
- end
@@ -1,66 +0,0 @@
1
- require 'helper'
2
-
3
- class TestStateTransitionGuardCheck < Test::Unit::TestCase
4
- args = [:foo, 'bar']
5
-
6
- test 'should return true of there is no guard' do
7
- opts = { from: 'foo', to: 'bar' }
8
- st = Transitions::StateTransition.new(opts)
9
-
10
- assert st.executable?(nil, *args)
11
- end
12
-
13
- test 'should call the method on the object if guard is a symbol' do
14
- opts = { from: 'foo', to: 'bar', guard: :test_guard }
15
- st = Transitions::StateTransition.new(opts)
16
-
17
- obj = stub
18
- obj.expects(:test_guard).with(*args)
19
-
20
- st.executable?(obj, *args)
21
- end
22
-
23
- test 'should call the method on the object if guard is a string' do
24
- opts = { from: 'foo', to: 'bar', guard: 'test_guard' }
25
- st = Transitions::StateTransition.new(opts)
26
-
27
- obj = stub
28
- obj.expects(:test_guard).with(*args)
29
-
30
- st.executable?(obj, *args)
31
- end
32
-
33
- test 'should call the proc passing the object if the guard is a proc' do
34
- opts = { from: 'foo', to: 'bar', guard: proc { |o, *args| o.test_guard(*args) } }
35
- st = Transitions::StateTransition.new(opts)
36
-
37
- obj = stub
38
- obj.expects(:test_guard).with(*args)
39
-
40
- st.executable?(obj, *args)
41
- end
42
-
43
- test 'should call the callable passing the object if the guard responds to #call' do
44
- callable = Object.new
45
- callable.define_singleton_method(:call) { |obj, *args| obj.test_guard(*args) }
46
-
47
- opts = { from: 'foo', to: 'bar', guard: callable }
48
- st = Transitions::StateTransition.new(opts)
49
-
50
- obj = stub
51
- obj.expects(:test_guard).with(*args)
52
-
53
- st.executable?(obj, *args)
54
- end
55
-
56
- test 'should call the method on the object if guard is a symbol' do
57
- opts = { from: 'foo', to: 'bar', guard: [:test_guard, :test_another_guard] }
58
- st = Transitions::StateTransition.new(opts)
59
-
60
- obj = stub
61
- obj.expects(:test_guard).with(*args).returns(true)
62
- obj.expects(:test_another_guard).with(*args).returns(true)
63
-
64
- assert st.executable?(obj, *args)
65
- end
66
- end
@@ -1,48 +0,0 @@
1
- require 'helper'
2
-
3
- class Truck
4
- include Transitions
5
- attr_reader :test_recorder
6
-
7
- def initialize
8
- @test_recorder = []
9
- end
10
-
11
- state_machine do
12
- state :parked
13
- state :running
14
- state :driving
15
-
16
- event :turn_key do
17
- transitions from: :parked, to: :running, on_transition: :start_engine
18
- end
19
-
20
- event :start_driving do
21
- transitions from: :parked, to: :driving, on_transition: [:start_engine, :loosen_handbrake, :push_gas_pedal]
22
- end
23
- end
24
-
25
- %w(start_engine loosen_handbrake push_gas_pedal).each do |m|
26
- define_method(m) { @test_recorder << m }
27
- end
28
- end
29
-
30
- class TestStateTransitionCallbacks < Test::Unit::TestCase
31
- test "should execute callback defined via 'on_transition'" do
32
- truck = Truck.new
33
- truck.expects(:start_engine)
34
- truck.turn_key!
35
- end
36
-
37
- test "should execute multiple callbacks defined via 'on_transition' in the same order they were defined" do
38
- # This test requires some explanation: We started out with something like this:
39
- # truck.expects(:start_engine).in_sequence(on_transition_sequence)
40
- # Which, after a while (don't ask me why) caused some weird problems and seemed to fail randomly.
41
- # Hence the workaround below.
42
-
43
- truck = Truck.new
44
-
45
- truck.start_driving!
46
- assert_equal truck.test_recorder, [:start_engine, :loosen_handbrake, :push_gas_pedal].map(&:to_s)
47
- end
48
- end