transitions 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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