finite_machine 0.8.1 → 0.9.0

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/Gemfile +1 -1
  4. data/README.md +150 -35
  5. data/lib/finite_machine.rb +1 -0
  6. data/lib/finite_machine/catchable.rb +1 -1
  7. data/lib/finite_machine/definition.rb +61 -0
  8. data/lib/finite_machine/dsl.rb +45 -10
  9. data/lib/finite_machine/event.rb +17 -1
  10. data/lib/finite_machine/hook_event.rb +66 -7
  11. data/lib/finite_machine/observer.rb +3 -3
  12. data/lib/finite_machine/state_machine.rb +36 -28
  13. data/lib/finite_machine/version.rb +1 -1
  14. data/spec/spec_helper.rb +2 -2
  15. data/spec/unit/async_events_spec.rb +1 -1
  16. data/spec/unit/callbacks_spec.rb +23 -23
  17. data/spec/unit/can_spec.rb +22 -22
  18. data/spec/unit/event/eql_spec.rb +37 -0
  19. data/spec/unit/event/initialize_spec.rb +38 -0
  20. data/spec/unit/event/inspect_spec.rb +1 -1
  21. data/spec/unit/event_queue_spec.rb +2 -2
  22. data/spec/unit/events_chain/check_choice_conditions_spec.rb +2 -2
  23. data/spec/unit/events_chain/clear_spec.rb +1 -1
  24. data/spec/unit/events_chain/insert_spec.rb +1 -1
  25. data/spec/unit/events_spec.rb +17 -20
  26. data/spec/unit/hook_event/eql_spec.rb +37 -0
  27. data/spec/unit/hook_event/initialize_spec.rb +22 -0
  28. data/spec/unit/if_unless_spec.rb +6 -6
  29. data/spec/unit/initialize_spec.rb +6 -6
  30. data/spec/unit/is_spec.rb +12 -12
  31. data/spec/unit/logger_spec.rb +1 -1
  32. data/spec/unit/respond_to_spec.rb +2 -2
  33. data/spec/unit/standalone_spec.rb +72 -0
  34. data/spec/unit/subscribers_spec.rb +2 -2
  35. data/spec/unit/target_spec.rb +59 -10
  36. data/spec/unit/{finished_spec.rb → terminated_spec.rb} +38 -8
  37. metadata +15 -4
@@ -25,34 +25,34 @@ describe FiniteMachine, 'can?' do
25
25
 
26
26
  expect(fsm.current).to eql(:green)
27
27
 
28
- expect(fsm.can?(:slow)).to be_true
29
- expect(fsm.cannot?(:stop)).to be_true
30
- expect(fsm.can?(:ready)).to be_false
31
- expect(fsm.can?(:go)).to be_false
28
+ expect(fsm.can?(:slow)).to be(true)
29
+ expect(fsm.cannot?(:stop)).to be(true)
30
+ expect(fsm.can?(:ready)).to be(false)
31
+ expect(fsm.can?(:go)).to be(false)
32
32
 
33
33
  fsm.slow
34
34
  expect(fsm.current).to eql(:yellow)
35
35
 
36
- expect(fsm.can?(:slow)).to be_false
37
- expect(fsm.can?(:stop)).to be_true
38
- expect(fsm.can?(:ready)).to be_false
39
- expect(fsm.can?(:go)).to be_true
36
+ expect(fsm.can?(:slow)).to be(false)
37
+ expect(fsm.can?(:stop)).to be(true)
38
+ expect(fsm.can?(:ready)).to be(false)
39
+ expect(fsm.can?(:go)).to be(true)
40
40
 
41
41
  fsm.stop
42
42
  expect(fsm.current).to eql(:red)
43
43
 
44
- expect(fsm.can?(:slow)).to be_false
45
- expect(fsm.can?(:stop)).to be_false
46
- expect(fsm.can?(:ready)).to be_true
47
- expect(fsm.can?(:go)).to be_false
44
+ expect(fsm.can?(:slow)).to be(false)
45
+ expect(fsm.can?(:stop)).to be(false)
46
+ expect(fsm.can?(:ready)).to be(true)
47
+ expect(fsm.can?(:go)).to be(false)
48
48
 
49
49
  fsm.ready
50
50
  expect(fsm.current).to eql(:yellow)
51
51
 
52
- expect(fsm.can?(:slow)).to be_false
53
- expect(fsm.can?(:stop)).to be_true
54
- expect(fsm.can?(:ready)).to be_false
55
- expect(fsm.can?(:go)).to be_true
52
+ expect(fsm.can?(:slow)).to be(false)
53
+ expect(fsm.can?(:stop)).to be(true)
54
+ expect(fsm.can?(:ready)).to be(false)
55
+ expect(fsm.can?(:go)).to be(true)
56
56
  end
57
57
 
58
58
  context 'with conditionl transition' do
@@ -66,13 +66,13 @@ describe FiniteMachine, 'can?' do
66
66
  }
67
67
  end
68
68
  expect(fsm.current).to eq(:green)
69
- expect(fsm.can?(:slow)).to be_true
70
- expect(fsm.can?(:stop)).to be_false
69
+ expect(fsm.can?(:slow)).to be(true)
70
+ expect(fsm.can?(:stop)).to be(false)
71
71
 
72
72
  fsm.slow
73
73
  expect(fsm.current).to eq(:yellow)
74
- expect(fsm.can?(:stop, false)).to be_false
75
- expect(fsm.can?(:stop, true)).to be_true
74
+ expect(fsm.can?(:stop, false)).to be(false)
75
+ expect(fsm.can?(:stop, true)).to be(true)
76
76
  end
77
77
 
78
78
  it "checks against target and grouped events" do
@@ -90,9 +90,9 @@ describe FiniteMachine, 'can?' do
90
90
  end
91
91
  expect(fsm.current).to eq(:initial)
92
92
 
93
- expect(fsm.can?(:bump)).to be_true
93
+ expect(fsm.can?(:bump)).to be(true)
94
94
  fsm.bump
95
- expect(fsm.can?(:bump)).to be_false
95
+ expect(fsm.can?(:bump)).to be(false)
96
96
  end
97
97
  end
98
98
  end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe FiniteMachine::Event, 'eql?' do
6
+ let(:machine) { double(:machine) }
7
+ let(:name) { :green }
8
+ let(:options) { {} }
9
+ let(:object) { described_class }
10
+
11
+ subject(:event) { object.new(machine, options) }
12
+
13
+ context 'with the same object' do
14
+ let(:other) { event }
15
+
16
+ it "equals" do
17
+ expect(event).to eql(other)
18
+ end
19
+ end
20
+
21
+ context 'with an equivalent object' do
22
+ let(:other) { event.dup }
23
+
24
+ it "equals" do
25
+ expect(event).to eql(other)
26
+ end
27
+ end
28
+
29
+ context "with an object having different name" do
30
+ let(:other_name) { :red }
31
+ let(:other) { object.new(machine, {name: other_name}) }
32
+
33
+ it "doesn't equal" do
34
+ expect(event).to_not eql(other)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe FiniteMachine::Event, 'new' do
6
+ let(:machine) { double(:machine) }
7
+ let(:name) { :green }
8
+ let(:options) { {} }
9
+ let(:object) { described_class }
10
+
11
+ subject(:event) { object.new(machine, options) }
12
+
13
+ context "by default" do
14
+ it "sets name to :none" do
15
+ expect(event.name).to eql(:none)
16
+ end
17
+
18
+ it "sets silent to false"do
19
+ expect(event.silent).to eql(false)
20
+ end
21
+ end
22
+
23
+ context "with custom data" do
24
+ let(:options) { {silent: true, name: name} }
25
+
26
+ it "sets name to :green" do
27
+ expect(event.name).to eql(name)
28
+ end
29
+
30
+ it "sets silent to true"do
31
+ expect(event.silent).to eql(true)
32
+ end
33
+ end
34
+
35
+ it "freezes object" do
36
+ expect { event.name = :red }.to raise_error(RuntimeError)
37
+ end
38
+ end
@@ -12,7 +12,7 @@ describe FiniteMachine::Event, '#inspect' do
12
12
  it "adds multiple transitions" do
13
13
  transition = double(:transition)
14
14
  event << transition
15
- expect(event.inspect).to eq("<#FiniteMachine::Event @name=test, @transitions=[#{transition.inspect}]>")
15
+ expect(event.inspect).to eq("<#FiniteMachine::Event @name=test, @silent=false, @transitions=[#{transition.inspect}]>")
16
16
  end
17
17
 
18
18
  it "prints event name" do
@@ -40,12 +40,12 @@ describe FiniteMachine::EventQueue do
40
40
  event1 = double(:event1, dispatch: true)
41
41
  event2 = double(:event2, dispatch: true)
42
42
  event3 = double(:event3, dispatch: true)
43
- expect(event_queue.alive?).to be_true
43
+ expect(event_queue.alive?).to be(true)
44
44
  event_queue << event1
45
45
  event_queue << event2
46
46
  event_queue.shutdown
47
47
  event_queue << event3
48
48
  sleep 0.001
49
- expect(event_queue.alive?).to be_false
49
+ expect(event_queue.alive?).to be(false)
50
50
  end
51
51
  end
@@ -12,9 +12,9 @@ describe FiniteMachine::EventsChain, '#clear' do
12
12
  it "clears chain events" do
13
13
  event = double(:event)
14
14
  chain.add(:validated, event)
15
- expect(chain.empty?).to be_false
15
+ expect(chain.empty?).to be(false)
16
16
 
17
17
  chain.clear
18
- expect(chain.empty?).to be_true
18
+ expect(chain.empty?).to be(true)
19
19
  end
20
20
  end
@@ -21,6 +21,6 @@ describe FiniteMachine::EventsChain, '#insert' do
21
21
  end
22
22
 
23
23
  it "fails to insert transition" do
24
- expect(chain.insert(:validated, transition)).to be_false
24
+ expect(chain.insert(:validated, transition)).to be(false)
25
25
  end
26
26
  end
@@ -21,6 +21,6 @@ describe FiniteMachine::EventsChain, '#insert' do
21
21
  end
22
22
 
23
23
  it "fails to insert transition" do
24
- expect(chain.insert(:validated, transition)).to be_false
24
+ expect(chain.insert(:validated, transition)).to be false
25
25
  end
26
26
  end
@@ -64,16 +64,16 @@ describe FiniteMachine, 'events' do
64
64
 
65
65
  expect(fsm.current).to eql(:green)
66
66
 
67
- expect(fsm.can?(:noop)).to be_true
68
- expect(fsm.can?(:slow)).to be_true
67
+ expect(fsm.can?(:noop)).to be true
68
+ expect(fsm.can?(:slow)).to be true
69
69
 
70
70
  fsm.noop
71
71
  expect(fsm.current).to eql(:green)
72
72
  fsm.slow
73
73
  expect(fsm.current).to eql(:yellow)
74
74
 
75
- expect(fsm.cannot?(:noop)).to be_true
76
- expect(fsm.cannot?(:slow)).to be_true
75
+ expect(fsm.cannot?(:noop)).to be true
76
+ expect(fsm.cannot?(:slow)).to be true
77
77
  end
78
78
 
79
79
  it "permits event from any state with :any 'from'" do
@@ -171,7 +171,7 @@ describe FiniteMachine, 'events' do
171
171
  }
172
172
  end
173
173
  expect(fsm.current).to eql(:green)
174
- expect(fsm.can?(:stop)).to be_false
174
+ expect(fsm.can?(:stop)).to be false
175
175
  fsm.stop!
176
176
  expect(fsm.current).to eql(:red)
177
177
  end
@@ -191,10 +191,10 @@ describe FiniteMachine, 'events' do
191
191
 
192
192
  expect(fsm.current).to eql(:green)
193
193
 
194
- expect(fsm.can?(:slow)).to be_true
195
- expect(fsm.can?(:stop)).to be_true
196
- expect(fsm.cannot?(:ready)).to be_true
197
- expect(fsm.cannot?(:go)).to be_true
194
+ expect(fsm.can?(:slow)).to be true
195
+ expect(fsm.can?(:stop)).to be true
196
+ expect(fsm.cannot?(:ready)).to be true
197
+ expect(fsm.cannot?(:go)).to be true
198
198
 
199
199
  fsm.slow; expect(fsm.current).to eql(:yellow)
200
200
  fsm.stop; expect(fsm.current).to eql(:red)
@@ -219,10 +219,10 @@ describe FiniteMachine, 'events' do
219
219
 
220
220
  expect(fsm.current).to eql(:green)
221
221
 
222
- expect(fsm.can?(:slow)).to be_true
223
- expect(fsm.can?(:stop)).to be_true
224
- expect(fsm.cannot?(:ready)).to be_true
225
- expect(fsm.cannot?(:go)).to be_true
222
+ expect(fsm.can?(:slow)).to be true
223
+ expect(fsm.can?(:stop)).to be true
224
+ expect(fsm.cannot?(:ready)).to be true
225
+ expect(fsm.cannot?(:go)).to be true
226
226
 
227
227
  fsm.slow; expect(fsm.current).to eql(:yellow)
228
228
  fsm.stop; expect(fsm.current).to eql(:red)
@@ -247,7 +247,7 @@ describe FiniteMachine, 'events' do
247
247
  end
248
248
 
249
249
  expect(fsm.current).to eql(:green)
250
- expect(fsm.can?(:stop)).to be_true
250
+ expect(fsm.can?(:stop)).to be true
251
251
  fsm.stop
252
252
  expect(fsm.current).to eql(:yellow)
253
253
  fsm.stop
@@ -272,12 +272,9 @@ describe FiniteMachine, 'events' do
272
272
  end
273
273
 
274
274
  expect(fsm.current).to eq(:initial)
275
- fsm.bump
276
- expect(fsm.current).to eq(:low)
277
- fsm.bump
278
- expect(fsm.current).to eq(:medium)
279
- fsm.bump
280
- expect(fsm.current).to eq(:high)
275
+ fsm.bump; expect(fsm.current).to eq(:low)
276
+ fsm.bump; expect(fsm.current).to eq(:medium)
277
+ fsm.bump; expect(fsm.current).to eq(:high)
281
278
  end
282
279
 
283
280
  it "returns values for events" do
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe FiniteMachine::HookEvent, 'eql?' do
6
+ let(:name) { :green }
7
+ let(:transition) { double(:transition) }
8
+ let(:data) { [:foo, :bar] }
9
+ let(:object) { described_class }
10
+
11
+ subject(:hook) { object.new(name, transition, *data) }
12
+
13
+ context 'with the same object' do
14
+ let(:other) { hook }
15
+
16
+ it "equals" do
17
+ expect(hook).to eql(other)
18
+ end
19
+ end
20
+
21
+ context 'with an equivalent object' do
22
+ let(:other) { hook.dup }
23
+
24
+ it "equals" do
25
+ expect(hook).to eql(other)
26
+ end
27
+ end
28
+
29
+ context "with an object having different name" do
30
+ let(:other_name) { :red }
31
+ let(:other) { object.new(other_name, transition, *data) }
32
+
33
+ it "doesn't equal" do
34
+ expect(hook).not_to eql(other)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe FiniteMachine::HookEvent, 'new' do
6
+ let(:name) { :green }
7
+ let(:transition) { double(:transition) }
8
+ let(:data) { [:foo, :bar] }
9
+ let(:object) { described_class }
10
+
11
+ subject(:hook) { object.new(name, transition, *data) }
12
+
13
+ it "exposes readers" do
14
+ expect(hook.name).to eql(name)
15
+ expect(hook.data).to eql(data)
16
+ expect(hook.type).to eql(object)
17
+ end
18
+
19
+ it "freezes object" do
20
+ expect { hook.name = :red }.to raise_error(RuntimeError)
21
+ end
22
+ end
@@ -139,13 +139,13 @@ describe FiniteMachine, ':if, :unless' do
139
139
  }
140
140
  end
141
141
  car.turn_engine_off
142
- expect(car.engine_on?).to be_false
142
+ expect(car.engine_on?).to be false
143
143
  expect(fsm.current).to eql(:neutral)
144
144
  fsm.start
145
145
  expect(fsm.current).to eql(:neutral)
146
146
 
147
147
  car.turn_engine_on
148
- expect(car.engine_on?).to be_true
148
+ expect(car.engine_on?).to be true
149
149
  expect(fsm.current).to eql(:neutral)
150
150
  fsm.start
151
151
  expect(fsm.current).to eql(:one)
@@ -189,13 +189,13 @@ describe FiniteMachine, ':if, :unless' do
189
189
  }
190
190
  end
191
191
  car.turn_engine_off
192
- expect(car.engine_on?).to be_false
192
+ expect(car.engine_on?).to be false
193
193
  expect(fsm.current).to eql(:neutral)
194
194
  fsm.start
195
195
  expect(fsm.current).to eql(:neutral)
196
196
 
197
197
  car.turn_engine_on
198
- expect(car.engine_on?).to be_true
198
+ expect(car.engine_on?).to be true
199
199
  expect(fsm.current).to eql(:neutral)
200
200
  fsm.start
201
201
  expect(fsm.current).to eql(:one)
@@ -217,13 +217,13 @@ describe FiniteMachine, ':if, :unless' do
217
217
  }
218
218
  end
219
219
  car.turn_engine_off
220
- expect(car.engine_on?).to be_false
220
+ expect(car.engine_on?).to be false
221
221
  expect(fsm.current).to eql(:neutral)
222
222
  fsm.start
223
223
  expect(fsm.current).to eql(:neutral)
224
224
 
225
225
  car.turn_engine_on
226
- expect(car.engine_on?).to be_true
226
+ expect(car.engine_on?).to be true
227
227
  expect(fsm.current).to eql(:neutral)
228
228
  fsm.start
229
229
  expect(fsm.current).to eql(:one)
@@ -69,7 +69,7 @@ describe FiniteMachine, 'initialize' do
69
69
 
70
70
  it "allows to specify deferred inital state" do
71
71
  fsm = FiniteMachine.define do
72
- initial state: :green, defer: true
72
+ initial :green, defer: true
73
73
 
74
74
  events {
75
75
  event :slow, :green => :yellow
@@ -97,7 +97,7 @@ describe FiniteMachine, 'initialize' do
97
97
 
98
98
  it "allows to specify inital start event" do
99
99
  fsm = FiniteMachine.define do
100
- initial state: :green, event: :start
100
+ initial :green, event: :start
101
101
 
102
102
  events {
103
103
  event :slow, :green => :none
@@ -114,7 +114,7 @@ describe FiniteMachine, 'initialize' do
114
114
 
115
115
  it "allows to specify deferred inital start event" do
116
116
  fsm = FiniteMachine.define do
117
- initial state: :green, event: :start, defer: true
117
+ initial :green, event: :start, defer: true
118
118
 
119
119
  events {
120
120
  event :slow, :green => :yellow
@@ -173,7 +173,7 @@ describe FiniteMachine, 'initialize' do
173
173
 
174
174
  it "allows to retrieve initial state for deferred" do
175
175
  fsm = FiniteMachine.define do
176
- initial state: :green, defer: true
176
+ initial :green, defer: true
177
177
 
178
178
  events {
179
179
  event :slow, :green => :yellow
@@ -190,7 +190,7 @@ describe FiniteMachine, 'initialize' do
190
190
  it "allows to trigger callbacks on initial with :silent option" do
191
191
  called = []
192
192
  fsm = FiniteMachine.define do
193
- initial state: :green, silent: false
193
+ initial :green, silent: false
194
194
 
195
195
  events {
196
196
  event :slow, :green => :yellow
@@ -206,7 +206,7 @@ describe FiniteMachine, 'initialize' do
206
206
  it "allows to trigger callbacks on deferred initial state" do
207
207
  called = []
208
208
  fsm = FiniteMachine.define do
209
- initial state: :green, silent: false, defer: true
209
+ initial :green, silent: false, defer: true
210
210
 
211
211
  events {
212
212
  event :slow, :green => :yellow