finite_machine 0.8.1 → 0.9.0

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