finite_machine 0.12.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -1
  3. data/README.md +1 -1
  4. data/lib/finite_machine.rb +3 -1
  5. data/lib/finite_machine/choice_merger.rb +2 -2
  6. data/lib/finite_machine/dsl.rb +4 -4
  7. data/lib/finite_machine/message_queue.rb +0 -1
  8. data/lib/finite_machine/state_machine.rb +3 -3
  9. data/lib/finite_machine/two_phase_lock.rb +6 -6
  10. data/lib/finite_machine/version.rb +1 -1
  11. metadata +20 -146
  12. data/Rakefile +0 -12
  13. data/benchmarks/memory_profile.rb +0 -11
  14. data/benchmarks/memory_usage.rb +0 -28
  15. data/examples/atm.rb +0 -45
  16. data/examples/bug_system.rb +0 -145
  17. data/finite_machine.gemspec +0 -30
  18. data/spec/integration/system_spec.rb +0 -93
  19. data/spec/performance/benchmark_spec.rb +0 -54
  20. data/spec/spec_helper.rb +0 -34
  21. data/spec/unit/alias_target_spec.rb +0 -89
  22. data/spec/unit/async_callbacks_spec.rb +0 -28
  23. data/spec/unit/auto_methods_spec.rb +0 -44
  24. data/spec/unit/callable/call_spec.rb +0 -111
  25. data/spec/unit/callbacks_spec.rb +0 -851
  26. data/spec/unit/can_spec.rb +0 -88
  27. data/spec/unit/cancel_callbacks_spec.rb +0 -46
  28. data/spec/unit/choice_spec.rb +0 -295
  29. data/spec/unit/define_spec.rb +0 -55
  30. data/spec/unit/definition_spec.rb +0 -98
  31. data/spec/unit/event_names_spec.rb +0 -15
  32. data/spec/unit/events_map/add_spec.rb +0 -23
  33. data/spec/unit/events_map/choice_transition_spec.rb +0 -25
  34. data/spec/unit/events_map/clear_spec.rb +0 -13
  35. data/spec/unit/events_map/events_spec.rb +0 -16
  36. data/spec/unit/events_map/inspect_spec.rb +0 -22
  37. data/spec/unit/events_map/match_transition_spec.rb +0 -35
  38. data/spec/unit/events_map/move_to_spec.rb +0 -45
  39. data/spec/unit/events_map/states_for_spec.rb +0 -17
  40. data/spec/unit/events_spec.rb +0 -390
  41. data/spec/unit/handlers_spec.rb +0 -120
  42. data/spec/unit/hook_event/any_state_or_event_spec.rb +0 -13
  43. data/spec/unit/hook_event/build_spec.rb +0 -13
  44. data/spec/unit/hook_event/eql_spec.rb +0 -34
  45. data/spec/unit/hook_event/initialize_spec.rb +0 -23
  46. data/spec/unit/hook_event/notify_spec.rb +0 -12
  47. data/spec/unit/hooks/clear_spec.rb +0 -16
  48. data/spec/unit/hooks/find_spec.rb +0 -19
  49. data/spec/unit/hooks/inspect_spec.rb +0 -25
  50. data/spec/unit/hooks/register_spec.rb +0 -17
  51. data/spec/unit/if_unless_spec.rb +0 -314
  52. data/spec/unit/initial_spec.rb +0 -190
  53. data/spec/unit/inspect_spec.rb +0 -22
  54. data/spec/unit/is_spec.rb +0 -49
  55. data/spec/unit/log_transitions_spec.rb +0 -24
  56. data/spec/unit/logger_spec.rb +0 -36
  57. data/spec/unit/message_queue_spec.rb +0 -62
  58. data/spec/unit/new_spec.rb +0 -50
  59. data/spec/unit/respond_to_spec.rb +0 -34
  60. data/spec/unit/state_parser/parse_spec.rb +0 -56
  61. data/spec/unit/states_spec.rb +0 -28
  62. data/spec/unit/subscribers_spec.rb +0 -40
  63. data/spec/unit/target_spec.rb +0 -225
  64. data/spec/unit/terminated_spec.rb +0 -85
  65. data/spec/unit/transition/check_conditions_spec.rb +0 -55
  66. data/spec/unit/transition/inspect_spec.rb +0 -25
  67. data/spec/unit/transition/matches_spec.rb +0 -21
  68. data/spec/unit/transition/states_spec.rb +0 -29
  69. data/spec/unit/transition/to_state_spec.rb +0 -19
  70. data/spec/unit/trigger_spec.rb +0 -18
  71. data/spec/unit/undefined_transition/eql_spec.rb +0 -15
  72. data/tasks/console.rake +0 -11
  73. data/tasks/coverage.rake +0 -11
  74. data/tasks/spec.rake +0 -34
@@ -1,190 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe FiniteMachine, 'initial' do
4
-
5
- before(:each) {
6
- stub_const("DummyLogger", Class.new do
7
- attr_accessor :level
8
-
9
- def initialize
10
- @level = :pending
11
- end
12
- end)
13
- }
14
-
15
- it "defaults initial state to :none" do
16
- fsm = FiniteMachine.new do
17
- event :slow, :green => :yellow
18
- event :stop, :yellow => :red
19
- end
20
-
21
- expect(fsm.current).to eql(:none)
22
- end
23
-
24
- it "requires initial state transition from :none" do
25
- fsm = FiniteMachine.new do
26
- event :init, :none => :green
27
- event :slow, :green => :yellow
28
- event :stop, :yellow => :red
29
- end
30
-
31
- expect(fsm.current).to eql(:none)
32
- fsm.init
33
- expect(fsm.current).to eql(:green)
34
- end
35
-
36
- it "allows to specify inital state" do
37
- called = []
38
- fsm = FiniteMachine.new do
39
- initial :green
40
-
41
- event :slow, :green => :yellow
42
- event :stop, :yellow => :red
43
-
44
- on_exit :none do |event| called << 'on_exit_none' end
45
- on_enter :green do |event| called << 'on_enter_green' end
46
- end
47
- expect(fsm.current).to eql(:green)
48
- expect(called).to be_empty
49
- end
50
-
51
- it "allows to specify initial state through parameter" do
52
- fsm = FiniteMachine.new initial: :green do
53
- event :slow, :green => :yellow
54
- event :stop, :yellow => :red
55
- end
56
- expect(fsm.current).to eql(:green)
57
- end
58
-
59
- it "allows to specify deferred inital state" do
60
- fsm = FiniteMachine.new do
61
- initial :green, defer: true
62
-
63
- event :slow, :green => :yellow
64
- event :stop, :yellow => :red
65
- end
66
-
67
- expect(fsm.current).to eql(:none)
68
- fsm.init
69
- expect(fsm.current).to eql(:green)
70
- end
71
-
72
- it "raises error when specyfying initial without state name" do
73
- expect {
74
- FiniteMachine.new do
75
- initial defer: true
76
-
77
- event :slow, :green => :yellow
78
- event :stop, :yellow => :red
79
- end
80
- }.to raise_error(FiniteMachine::MissingInitialStateError)
81
- end
82
-
83
- it "allows to specify inital start event" do
84
- fsm = FiniteMachine.new do
85
- initial :green, event: :start
86
-
87
- event :slow, :green => :none
88
- event :stop, :yellow => :red
89
- end
90
-
91
- expect(fsm.current).to eql(:green)
92
- fsm.slow
93
- expect(fsm.current).to eql(:none)
94
- fsm.start
95
- expect(fsm.current).to eql(:green)
96
- end
97
-
98
- it "allows to specify deferred inital start event" do
99
- fsm = FiniteMachine.new do
100
- initial :green, event: :start, defer: true
101
-
102
- event :slow, :green => :yellow
103
- event :stop, :yellow => :red
104
- end
105
-
106
- expect(fsm.current).to eql(:none)
107
- fsm.start
108
- expect(fsm.current).to eql(:green)
109
- end
110
-
111
- it "evaluates initial state" do
112
- logger = DummyLogger.new
113
- fsm = FiniteMachine.new do
114
- initial logger.level
115
-
116
- event :slow, :green => :none
117
- event :stop, :yellow => :red
118
- end
119
- expect(fsm.current).to eql(:pending)
120
- end
121
-
122
- it "doesn't care about state type" do
123
- fsm = FiniteMachine.new do
124
- initial 1
125
-
126
- event :a, 1 => 2
127
- event :b, 2 => 3
128
- end
129
- expect(fsm.current).to eql(1)
130
- fsm.a
131
- expect(fsm.current).to eql(2)
132
- fsm.b
133
- expect(fsm.current).to eql(3)
134
- end
135
-
136
- it "allows to retrieve initial state" do
137
- fsm = FiniteMachine.new do
138
- initial :green
139
-
140
- event :slow, :green => :yellow
141
- event :stop, :yellow => :red
142
- end
143
- expect(fsm.current).to eq(:green)
144
- expect(fsm.initial_state).to eq(:green)
145
- fsm.slow
146
- expect(fsm.current).to eq(:yellow)
147
- expect(fsm.initial_state).to eq(:green)
148
- end
149
-
150
- it "allows to retrieve initial state for deferred" do
151
- fsm = FiniteMachine.new do
152
- initial :green, defer: true
153
-
154
- event :slow, :green => :yellow
155
- event :stop, :yellow => :red
156
- end
157
- expect(fsm.current).to eq(:none)
158
- expect(fsm.initial_state).to eq(:none)
159
- fsm.init
160
- expect(fsm.current).to eq(:green)
161
- expect(fsm.initial_state).to eq(:green)
162
- end
163
-
164
- it "allows to trigger callbacks on initial with :silent option" do
165
- called = []
166
- fsm = FiniteMachine.new do
167
- initial :green, silent: false
168
-
169
- event :slow, :green => :yellow
170
-
171
- on_enter :green do |event| called << 'on_enter_green' end
172
- end
173
- expect(fsm.current).to eq(:green)
174
- expect(called).to eq(['on_enter_green'])
175
- end
176
-
177
- it "allows to trigger callbacks on deferred initial state" do
178
- called = []
179
- fsm = FiniteMachine.new do
180
- initial :green, silent: false, defer: true
181
-
182
- event :slow, :green => :yellow
183
-
184
- on_enter :green do |event| called << 'on_enter_green' end
185
- end
186
- expect(fsm.current).to eq(:none)
187
- fsm.init
188
- expect(called).to eq(['on_enter_green'])
189
- end
190
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal
2
-
3
- RSpec.describe FiniteMachine, '#inspect' do
4
- it "print useful information about state machine" do
5
- fsm = FiniteMachine.new do
6
- initial :green
7
-
8
- event :slow, :green => :yellow
9
- event :stop, :yellow => :red
10
- end
11
- inspected = fsm.inspect
12
- expect(inspected).to match(/^<#FiniteMachine::StateMachine:0x#{fsm.object_id.to_s(16)} @states=\[.*\], @events=\[.*\], @transitions=\[.*\]>$/)
13
-
14
- event_names = eval inspected[/events=\[(.*?)\]/]
15
- states = eval inspected[/states=\[(.*?)\]/]
16
- transitions = eval inspected[/transitions=\[(.*?)\]/]
17
-
18
- expect(event_names).to match_array([:init, :slow, :stop])
19
- expect(states).to match_array([:none, :green, :yellow, :red])
20
- expect(transitions).to match_array([{:none => :green}, {:green => :yellow}, {:yellow => :red}])
21
- end
22
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe FiniteMachine, '#is?' do
4
-
5
- it "allows to check if state is reachable" do
6
- fsm = FiniteMachine.new do
7
- initial :green
8
-
9
- event :slow, :green => :yellow
10
- event :stop, :yellow => :red
11
- event :ready, :red => :yellow
12
- event :go, :yellow => :green
13
- end
14
-
15
- expect(fsm.current).to eql(:green)
16
-
17
- expect(fsm.is?(:green)).to be true
18
- expect(fsm.is?(:yellow)).to be false
19
- expect(fsm.is?([:green, :red])).to be true
20
- expect(fsm.is?([:yellow, :red])).to be false
21
-
22
- fsm.slow
23
-
24
- expect(fsm.is?(:green)).to be false
25
- expect(fsm.is?(:yellow)).to be true
26
- expect(fsm.is?([:green, :red])).to be false
27
- expect(fsm.is?([:yellow, :red])).to be true
28
- end
29
-
30
- it "defines helper methods to check current state" do
31
- fsm = FiniteMachine.new do
32
- initial :green
33
-
34
- event :slow, :green => :yellow
35
- event :stop, :yellow => :red
36
- event :ready, :red => :yellow
37
- event :go, :yellow => :green
38
- end
39
- expect(fsm.current).to eql(:green)
40
-
41
- expect(fsm.green?).to be true
42
- expect(fsm.yellow?).to be false
43
-
44
- fsm.slow
45
-
46
- expect(fsm.green?).to be false
47
- expect(fsm.yellow?).to be true
48
- end
49
- end
@@ -1,24 +0,0 @@
1
- RSpec.describe FiniteMachine, ':log_transitions' do
2
- let(:output) { StringIO.new('', 'w+')}
3
-
4
- before { FiniteMachine.logger = ::Logger.new(output) }
5
-
6
- after { FiniteMachine.logger = ::Logger.new($stderr) }
7
-
8
- it "logs transitions" do
9
- fsm = FiniteMachine.new log_transitions: true do
10
- initial :green
11
-
12
- event :slow, :green => :yellow
13
- event :stop, :yellow => :red
14
- end
15
-
16
- fsm.slow
17
- output.rewind
18
- expect(output.read).to match(/Transition: @event=slow green -> yellow/)
19
-
20
- fsm.stop(1, 2)
21
- output.rewind
22
- expect(output.read).to match(/Transition: @event=stop @with=\[1,2\] yellow -> red/)
23
- end
24
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe FiniteMachine::Logger do
4
- let(:message) { 'error' }
5
- let(:log) { spy }
6
-
7
- subject(:logger) { described_class }
8
-
9
- before { allow(FiniteMachine).to receive(:logger) { log } }
10
-
11
- it "debugs message call" do
12
- expect(log).to receive(:debug).with(message)
13
- logger.debug(message)
14
- end
15
-
16
- it "informs message call" do
17
- expect(log).to receive(:info).with(message)
18
- logger.info(message)
19
- end
20
-
21
- it "warns message call" do
22
- expect(log).to receive(:warn).with(message)
23
- logger.warn(message)
24
- end
25
-
26
- it "errors message call" do
27
- expect(log).to receive(:error).with(message)
28
- logger.error(message)
29
- end
30
-
31
- it "reports transition" do
32
- logger.report_transition(:go, :red, :green)
33
-
34
- expect(log).to have_received(:info).with("Transition: @event=go red -> green")
35
- end
36
- end
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe FiniteMachine::MessageQueue do
4
- it "dispatches all events" do
5
- event_queue = FiniteMachine::MessageQueue.new
6
- event_queue.start
7
- called = []
8
- event1 = double(:event1, dispatch: called << 'event1_dispatched')
9
- event2 = double(:event2, dispatch: called << 'event2_dispatched')
10
-
11
- expect(event_queue.size).to be_zero
12
-
13
- event_queue << event1
14
- event_queue << event2
15
- event_queue.join(0.001)
16
-
17
- expect(called).to match_array(['event1_dispatched', 'event2_dispatched'])
18
- event_queue.shutdown
19
- end
20
-
21
- it "logs error" do
22
- event_queue = FiniteMachine::MessageQueue.new
23
- event_queue.start
24
- event = spy(:event)
25
- allow(event).to receive(:dispatch) { raise }
26
- expect(FiniteMachine::Logger).to receive(:error)
27
- event_queue << event
28
- event_queue.join(0.02)
29
- expect(event_queue).to be_empty
30
- end
31
-
32
- it "notifies listeners" do
33
- event_queue = FiniteMachine::MessageQueue.new
34
- event_queue.start
35
- called = []
36
- event1 = double(:event1, dispatch: true)
37
- event2 = double(:event2, dispatch: true)
38
- event3 = double(:event3, dispatch: true)
39
- event_queue.subscribe(:listener1) { |event| called << event }
40
- event_queue << event1
41
- event_queue << event2
42
- event_queue << event3
43
- event_queue.join(0.02)
44
- event_queue.shutdown
45
- expect(called).to match_array([event1, event2, event3])
46
- end
47
-
48
- it "allows to shutdown event queue" do
49
- event_queue = FiniteMachine::MessageQueue.new
50
- event_queue.start
51
- event1 = double(:event1, dispatch: true)
52
- event2 = double(:event2, dispatch: true)
53
- event3 = double(:event3, dispatch: true)
54
- expect(event_queue.running?).to be(true)
55
- event_queue << event1
56
- event_queue << event2
57
- event_queue.shutdown
58
- event_queue << event3
59
- expect(event_queue.running?).to be(false)
60
- event_queue.join(0.001)
61
- end
62
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe FiniteMachine, '.new' do
4
- context 'with block' do
5
- it "creates system state machine" do
6
- fsm = FiniteMachine.new do
7
- initial :green
8
-
9
- event :slow, :green => :yellow
10
- event :stop, :yellow => :red
11
- event :ready, :red => :yellow
12
- event :go, :yellow => :green
13
- end
14
-
15
- expect(fsm.current).to eql(:green)
16
-
17
- fsm.slow
18
- expect(fsm.current).to eql(:yellow)
19
- fsm.stop
20
- expect(fsm.current).to eql(:red)
21
- fsm.ready
22
- expect(fsm.current).to eql(:yellow)
23
- fsm.go
24
- expect(fsm.current).to eql(:green)
25
- end
26
- end
27
-
28
- context 'without block' do
29
- it "creates state machine" do
30
- called = []
31
- fsm = FiniteMachine.new
32
- fsm.initial(:green)
33
- fsm.event(:slow, :green => :yellow)
34
- fsm.event(:stop, :yellow => :red)
35
- fsm.event(:ready,:red => :yellow)
36
- fsm.event(:go, :yellow => :green)
37
- fsm.on_enter(:yellow) { |event| called << 'on_enter_yellow' }
38
- fsm.handle(FiniteMachine::InvalidStateError) { |exception|
39
- called << 'error_handler'
40
- }
41
- fsm.init
42
- expect(fsm.current).to eql(:green)
43
- fsm.slow
44
- expect(fsm.current).to eql(:yellow)
45
- fsm.ready
46
- expect(fsm.current).to eql(:yellow)
47
- expect(called).to match_array(['on_enter_yellow', 'error_handler'])
48
- end
49
- end
50
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe FiniteMachine, '#respond_to' do
4
-
5
- subject(:fsm) {
6
- stub_const("Car", Class.new do
7
- def engine_on?
8
- true
9
- end
10
- end)
11
-
12
- FiniteMachine.new target: Car.new do
13
- initial :green
14
-
15
- event :slow, :green => :yellow
16
- end
17
- }
18
-
19
- it "knows about event name" do
20
- expect(fsm).to respond_to(:slow)
21
- end
22
-
23
- it "doesn't know about not implemented call" do
24
- expect(fsm).not_to respond_to(:not_implemented)
25
- end
26
-
27
- it "knows about event callback" do
28
- expect(fsm).to respond_to(:on_enter_slow)
29
- end
30
-
31
- it "doesn't know about target class methods" do
32
- expect(fsm).not_to respond_to(:engine_on?)
33
- end
34
- end