edge-state-machine 0.0.2 → 0.0.3
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.
- data/README.rdoc +12 -9
- data/lib/active_record/edge-state-machine.rb +54 -9
- data/lib/edge-state-machine/event.rb +20 -91
- data/lib/edge-state-machine/exception.rb +8 -0
- data/lib/edge-state-machine/machine.rb +23 -68
- data/lib/edge-state-machine/state.rb +25 -23
- data/lib/edge-state-machine/transition.rb +32 -25
- data/lib/edge-state-machine/version.rb +1 -1
- data/lib/edge-state-machine.rb +51 -36
- data/lib/mongoid/edge-state-machine.rb +54 -9
- data/spec/active_record/active_record_helper.rb +2 -0
- data/spec/active_record/active_record_spec.rb +36 -144
- data/spec/active_record/samples/order.rb +47 -0
- data/spec/active_record/samples/traffic_light.rb +46 -0
- data/spec/event_spec.rb +13 -21
- data/spec/machine_spec.rb +11 -14
- data/spec/mongoid/mongoid_helper.rb +4 -2
- data/spec/mongoid/mongoid_spec.rb +35 -153
- data/spec/mongoid/samples/order.rb +54 -0
- data/spec/mongoid/samples/traffic_light.rb +46 -0
- data/spec/non_persistent/non_persistent_helper.rb +9 -0
- data/spec/non_persistent/non_persistent_spec.rb +80 -0
- data/spec/non_persistent/samples/dice.rb +31 -0
- data/spec/non_persistent/samples/microwave.rb +54 -0
- data/spec/non_persistent/samples/user.rb +23 -0
- data/spec/state_spec.rb +19 -14
- data/spec/transition_spec.rb +69 -31
- metadata +24 -14
@@ -1,99 +1,5 @@
|
|
1
1
|
require 'mongoid/mongoid_helper'
|
2
2
|
|
3
|
-
class MongoTrafficLight
|
4
|
-
include Mongoid::Document
|
5
|
-
include Mongoid::EdgeStateMachine
|
6
|
-
field :state
|
7
|
-
|
8
|
-
state_machine do
|
9
|
-
state :off
|
10
|
-
|
11
|
-
state :red
|
12
|
-
state :green
|
13
|
-
state :yellow
|
14
|
-
|
15
|
-
event :red_on do
|
16
|
-
transitions :to => :red, :from => [:yellow]
|
17
|
-
end
|
18
|
-
|
19
|
-
event :green_on do
|
20
|
-
transitions :to => :green, :from => [:red]
|
21
|
-
end
|
22
|
-
|
23
|
-
event :yellow_on do
|
24
|
-
transitions :to => :yellow, :from => [:green]
|
25
|
-
end
|
26
|
-
|
27
|
-
event :reset do
|
28
|
-
transitions :to => :red, :from => [:off]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class MongoProtectedTrafficLight < MongoTrafficLight
|
34
|
-
attr_protected :state
|
35
|
-
end
|
36
|
-
|
37
|
-
class MongoValidatingTrafficLight < MongoTrafficLight
|
38
|
-
validate {|t| errors.add(:base, 'This TrafficLight will never validate after creation') unless t.new_record? }
|
39
|
-
end
|
40
|
-
|
41
|
-
class MongoConditionalValidatingTrafficLight < MongoTrafficLight
|
42
|
-
validates :name, :presence => true, :length => { :within => 20..40 }, :confirmation => true, :if => :red?
|
43
|
-
end
|
44
|
-
|
45
|
-
class MongoOrder
|
46
|
-
include Mongoid::Document
|
47
|
-
include Mongoid::EdgeStateMachine
|
48
|
-
|
49
|
-
field :state, :type => String
|
50
|
-
field :order_number, :type => Integer
|
51
|
-
field :paid_at, :type => DateTime
|
52
|
-
field :prepared_on, :type => DateTime
|
53
|
-
field :dispatched_at, :type => DateTime
|
54
|
-
field :cancellation_date, :type => Date
|
55
|
-
|
56
|
-
state_machine do
|
57
|
-
state :opened
|
58
|
-
state :placed
|
59
|
-
state :paid
|
60
|
-
state :prepared
|
61
|
-
state :delivered
|
62
|
-
state :cancelled
|
63
|
-
|
64
|
-
# no timestamp col is being specified here - should be ignored
|
65
|
-
event :place do
|
66
|
-
transitions :from => :opened, :to => :placed
|
67
|
-
end
|
68
|
-
|
69
|
-
# should set paid_at timestamp
|
70
|
-
event :pay, :timestamp => true do
|
71
|
-
transitions :from => :placed, :to => :paid
|
72
|
-
end
|
73
|
-
|
74
|
-
# should set prepared_on
|
75
|
-
event :prepare, :timestamp => true do
|
76
|
-
transitions :from => :paid, :to => :prepared
|
77
|
-
end
|
78
|
-
|
79
|
-
# should set dispatched_at
|
80
|
-
event :deliver, :timestamp => "dispatched_at" do
|
81
|
-
transitions :from => :prepared, :to => :delivered
|
82
|
-
end
|
83
|
-
|
84
|
-
# should set cancellation_date
|
85
|
-
event :cancel, :timestamp => :cancellation_date do
|
86
|
-
transitions :from => [:placed, :paid, :prepared], :to => :cancelled
|
87
|
-
end
|
88
|
-
|
89
|
-
# should raise an exception as there is no timestamp col
|
90
|
-
event :reopen, :timestamp => true do
|
91
|
-
transitions :from => :cancelled, :to => :opened
|
92
|
-
end
|
93
|
-
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
3
|
describe "mongoid state machine" do
|
98
4
|
|
99
5
|
context "existing mongo document" do
|
@@ -121,7 +27,7 @@ describe "mongoid state machine" do
|
|
121
27
|
@light.reset
|
122
28
|
@light.current_state.should == :red
|
123
29
|
@light.reload
|
124
|
-
@light.state.should ==
|
30
|
+
@light.state.should == :off
|
125
31
|
end
|
126
32
|
|
127
33
|
it "should persists state on transition" do
|
@@ -131,8 +37,14 @@ describe "mongoid state machine" do
|
|
131
37
|
@light.state.should == "red"
|
132
38
|
end
|
133
39
|
|
40
|
+
it "should initialize the current state when loaded from database" do
|
41
|
+
@light.reset!
|
42
|
+
loaded_light = MongoTrafficLight.find(@light.id)
|
43
|
+
loaded_light.current_state.should == :red
|
44
|
+
end
|
45
|
+
|
134
46
|
it "should raise error on transition to an invalid state" do
|
135
|
-
expect { @light.yellow_on }.should raise_error EdgeStateMachine::
|
47
|
+
expect { @light.yellow_on }.should raise_error EdgeStateMachine::NoTransitionFound
|
136
48
|
@light.current_state.should == :off
|
137
49
|
end
|
138
50
|
|
@@ -145,8 +57,8 @@ describe "mongoid state machine" do
|
|
145
57
|
end
|
146
58
|
|
147
59
|
it "should not validate when try transition with wrong state " do
|
148
|
-
for s in @light.class.
|
149
|
-
@light.state = s
|
60
|
+
for s in @light.class.state_machines[:default].states.keys
|
61
|
+
@light.state = s
|
150
62
|
@light.valid?.should == true
|
151
63
|
end
|
152
64
|
@light.state = "invalid_one"
|
@@ -158,18 +70,37 @@ describe "mongoid state machine" do
|
|
158
70
|
expect {validating_light.reset!}.should raise_error Mongoid::Errors::Validations
|
159
71
|
end
|
160
72
|
|
161
|
-
|
162
|
-
|
73
|
+
it "should state query method used in a validation condition" do
|
74
|
+
validating_light = MongoConditionalValidatingTrafficLight.create!
|
163
75
|
#expect {validating_light.reset!}.should raise_error Mongoid::RecordInvalid
|
164
|
-
|
165
|
-
|
76
|
+
validating_light.off?.should == true
|
77
|
+
end
|
166
78
|
|
167
79
|
it "should reload the model when current state resets" do
|
168
80
|
@light.reset
|
169
81
|
@light.red?.should == true
|
170
82
|
@light.update_attribute(:state, 'green')
|
171
|
-
@light.reload.green?.should ==
|
172
|
-
|
83
|
+
@light.reload.green?.should == true # reloaded state should come from database
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "scopes" do
|
87
|
+
it "should be added for each state" do
|
88
|
+
MongoTrafficLight.should respond_to(:off)
|
89
|
+
MongoTrafficLight.should respond_to(:red)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should not be added for each state" do
|
93
|
+
#MongoTrafficLightNoScope.should_not respond_to(:off)
|
94
|
+
#MongoTrafficLightNoScope.should_not respond_to(:red)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should behave like scopes" do
|
98
|
+
3.times { MongoTrafficLight.create(:state => "off") }
|
99
|
+
3.times { MongoTrafficLight.create(:state => "red") }
|
100
|
+
# one was created before
|
101
|
+
MongoTrafficLight.off.count.should == 4
|
102
|
+
MongoTrafficLight.red.count.should == 3
|
103
|
+
end
|
173
104
|
end
|
174
105
|
end
|
175
106
|
|
@@ -198,54 +129,5 @@ describe "mongoid state machine" do
|
|
198
129
|
expect { @order.place! }.should_not raise_error
|
199
130
|
@order.state.should == "placed"
|
200
131
|
end
|
201
|
-
|
202
|
-
it "should set paid_at when moving to paid" do
|
203
|
-
@order = create_order(:placed)
|
204
|
-
@order.pay!
|
205
|
-
@order.reload
|
206
|
-
@order.paid_at.should_not be_nil
|
207
|
-
end
|
208
|
-
|
209
|
-
it "should set prepared_on when moving to prepared" do
|
210
|
-
@order = create_order(:paid)
|
211
|
-
@order.prepare!
|
212
|
-
@order.reload
|
213
|
-
@order.prepared_on.should_not be_nil
|
214
|
-
end
|
215
|
-
|
216
|
-
it "should set dispatched_at when moving to delivered" do
|
217
|
-
@order = create_order(:prepared)
|
218
|
-
@order.deliver!
|
219
|
-
@order.reload
|
220
|
-
@order.dispatched_at.should_not be_nil
|
221
|
-
end
|
222
|
-
|
223
|
-
it "should set cancellation_date when moving to cancelled" do
|
224
|
-
@order = create_order(:placed)
|
225
|
-
@order.cancel!
|
226
|
-
@order.reload
|
227
|
-
@order.cancellation_date.should_not be_nil
|
228
|
-
end
|
229
|
-
|
230
|
-
it "should raise an exception as there is no attribute when moving to reopened" do
|
231
|
-
@order = create_order(:cancelled)
|
232
|
-
expect { @order.re_open! }.should raise_error NoMethodError
|
233
|
-
@order.reload
|
234
|
-
end
|
235
|
-
|
236
|
-
it "should raise an exception when passing an invalid value to timestamp options" do
|
237
|
-
expect {
|
238
|
-
class MongoOrder
|
239
|
-
include Mongoid::Document
|
240
|
-
include Mongoid::EdgeStateMachine
|
241
|
-
|
242
|
-
state_machine do
|
243
|
-
event :replace, timestamp: 1 do
|
244
|
-
transitions :from => :prepared, :to => :placed
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
248
|
-
}.should raise_error ArgumentError
|
249
|
-
end
|
250
132
|
end
|
251
133
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'mongoid'
|
2
|
+
require 'mongoid/edge-state-machine'
|
3
|
+
|
4
|
+
class MongoOrder
|
5
|
+
include Mongoid::Document
|
6
|
+
include Mongoid::EdgeStateMachine
|
7
|
+
|
8
|
+
field :state, :type => String
|
9
|
+
field :order_number, :type => Integer
|
10
|
+
field :paid_at, :type => DateTime
|
11
|
+
field :prepared_on, :type => DateTime
|
12
|
+
field :dispatched_at, :type => DateTime
|
13
|
+
field :cancellation_date, :type => Date
|
14
|
+
|
15
|
+
state_machine do
|
16
|
+
state :opened
|
17
|
+
state :placed
|
18
|
+
state :paid
|
19
|
+
state :prepared
|
20
|
+
state :delivered
|
21
|
+
state :cancelled
|
22
|
+
|
23
|
+
# no timestamp col is being specified here - should be ignored
|
24
|
+
event :place do
|
25
|
+
transition :from => :opened, :to => :placed
|
26
|
+
end
|
27
|
+
|
28
|
+
# should set paid_at timestamp
|
29
|
+
event :pay do
|
30
|
+
transition :from => :placed, :to => :paid
|
31
|
+
end
|
32
|
+
|
33
|
+
# should set prepared_on
|
34
|
+
event :prepare do
|
35
|
+
transition :from => :paid, :to => :prepared
|
36
|
+
end
|
37
|
+
|
38
|
+
# should set dispatched_at
|
39
|
+
event :deliver do
|
40
|
+
transition :from => :prepared, :to => :delivered
|
41
|
+
end
|
42
|
+
|
43
|
+
# should set cancellation_date
|
44
|
+
event :cancel do
|
45
|
+
transition :from => [:placed, :paid, :prepared], :to => :cancelled
|
46
|
+
end
|
47
|
+
|
48
|
+
# should raise an exception as there is no timestamp col
|
49
|
+
event :reopen do
|
50
|
+
transition :from => :cancelled, :to => :opened
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'mongoid'
|
2
|
+
require 'mongoid/edge-state-machine'
|
3
|
+
|
4
|
+
class MongoTrafficLight
|
5
|
+
include Mongoid::Document
|
6
|
+
include Mongoid::EdgeStateMachine
|
7
|
+
field :state
|
8
|
+
|
9
|
+
state_machine do
|
10
|
+
create_scopes true
|
11
|
+
persisted_to :state
|
12
|
+
state :off
|
13
|
+
|
14
|
+
state :red
|
15
|
+
state :green
|
16
|
+
state :yellow
|
17
|
+
|
18
|
+
event :red_on do
|
19
|
+
transition :to => :red, :from => [:yellow]
|
20
|
+
end
|
21
|
+
|
22
|
+
event :green_on do
|
23
|
+
transition :to => :green, :from => [:red]
|
24
|
+
end
|
25
|
+
|
26
|
+
event :yellow_on do
|
27
|
+
transition :to => :yellow, :from => [:green]
|
28
|
+
end
|
29
|
+
|
30
|
+
event :reset do
|
31
|
+
transition :to => :red, :from => [:off]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class MongoProtectedTrafficLight < MongoTrafficLight
|
37
|
+
attr_protected :state
|
38
|
+
end
|
39
|
+
|
40
|
+
class MongoValidatingTrafficLight < MongoTrafficLight
|
41
|
+
validate {|t| errors.add(:base, 'This TrafficLight will never validate after creation') unless t.new_record? }
|
42
|
+
end
|
43
|
+
|
44
|
+
class MongoConditionalValidatingTrafficLight < MongoTrafficLight
|
45
|
+
validates :name, :presence => true, :length => { :within => 20..40 }, :confirmation => true, :if => :red?
|
46
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'non_persistent/samples/dice'
|
3
|
+
require 'non_persistent/samples/user'
|
4
|
+
require 'non_persistent/samples/microwave'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
|
9
|
+
require 'edge-state-machine'
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'non_persistent/non_persistent_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe Dice do
|
5
|
+
before do
|
6
|
+
@dice = Dice.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have a current state equals with the initial state" do
|
10
|
+
@dice.current_state_name.should == :one
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should have an event trigger method" do
|
14
|
+
@dice.should respond_to :roll
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should change state after the event method is called" do
|
18
|
+
@dice.roll
|
19
|
+
@dice.current_state_name.should_not == :one
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
describe User do
|
25
|
+
before do
|
26
|
+
@user = User.new
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should have a current state equals with the initial state" do
|
30
|
+
@user.current_state_name.should == :pending
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have an event trigger method" do
|
34
|
+
@user.should respond_to :activate
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have state verfification methods for each state" do
|
38
|
+
@user.pending?.should == true
|
39
|
+
@user.active?.should_not == true
|
40
|
+
@user.blocked?.should_not == true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should change state after the event method is called" do
|
44
|
+
@user.activate
|
45
|
+
@user.current_state_name.should == :active
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe Microwave do
|
50
|
+
before do
|
51
|
+
@microwave = Microwave.new
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should have a current state equals with the initial state" do
|
55
|
+
@microwave.current_state_name(:microwave).should == :unplugged
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should have an event trigger method" do
|
59
|
+
@microwave.should respond_to :plug_in
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should have state verfification methods for each state" do
|
63
|
+
@microwave.unplugged?.should == true
|
64
|
+
@microwave.plugged?.should_not == true
|
65
|
+
@microwave.door_opened?.should_not == true
|
66
|
+
@microwave.door_closed?.should_not == true
|
67
|
+
@microwave.started_in_grill_mode?.should_not == true
|
68
|
+
@microwave.started?.should_not == true
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should change state after the event method is called" do
|
72
|
+
@microwave.plug_in
|
73
|
+
@microwave.current_state_name(:microwave).should == :plugged
|
74
|
+
@microwave.plugged?.should == true
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should execute enter state action" do
|
78
|
+
@microwave.plug_in
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'edge-state-machine'
|
2
|
+
|
3
|
+
class Dice
|
4
|
+
include EdgeStateMachine
|
5
|
+
|
6
|
+
state_machine do
|
7
|
+
state :one
|
8
|
+
state :two
|
9
|
+
state :three
|
10
|
+
state :four
|
11
|
+
state :five
|
12
|
+
state :six
|
13
|
+
|
14
|
+
event :roll do
|
15
|
+
transition :from => [:one, :two, :three, :four, :five, :six],
|
16
|
+
:to => [:one, :two, :three, :four, :five, :six],
|
17
|
+
:guard => :roll_result,
|
18
|
+
:on_transition => :display_dice_rolling_animation
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def roll_result
|
23
|
+
# return one of the states, except the initial state
|
24
|
+
[:two, :three, :four, :five, :six][Random.rand(4)]
|
25
|
+
end
|
26
|
+
|
27
|
+
def display_dice_rolling_animation
|
28
|
+
# draw the new position of the dice
|
29
|
+
# p 'display dice'
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'edge-state-machine'
|
2
|
+
|
3
|
+
class Microwave
|
4
|
+
include EdgeStateMachine
|
5
|
+
|
6
|
+
state_machine :microwave do # name should be optional, if the name is not present, it should have a default name
|
7
|
+
# we give state machines names, so we can pun many machines inside a class
|
8
|
+
initial_state :unplugged # initial state should be optional, if the initial state is not present, the initial state will be the first defined state
|
9
|
+
|
10
|
+
state :plugged
|
11
|
+
|
12
|
+
state :unplugged
|
13
|
+
|
14
|
+
state :door_opened do
|
15
|
+
enter :light_on # enter should be executed on entering the state
|
16
|
+
exit :light_off # exit method should be executed on exiting the state
|
17
|
+
end
|
18
|
+
|
19
|
+
state :door_closed
|
20
|
+
|
21
|
+
state :started_in_grill_mode do
|
22
|
+
enter lambda { |t| p "Entering hate" } # should have support for Procs
|
23
|
+
exit :grill_off
|
24
|
+
end
|
25
|
+
|
26
|
+
state :started do
|
27
|
+
enter :microwaves_on
|
28
|
+
exit :microwaves_off
|
29
|
+
end
|
30
|
+
|
31
|
+
event :plug_in do
|
32
|
+
transition :from => :unplugged, :to => :plugged
|
33
|
+
end
|
34
|
+
|
35
|
+
event :open_door do
|
36
|
+
transition :from => :plugged, :to => :door_opened
|
37
|
+
end
|
38
|
+
|
39
|
+
event :close_door do
|
40
|
+
transition :from => :door_opened, :to => :door_closed, :on_transition => :put_food_in_the_microwave # we can put many actions in an Array for the on_transition parameter
|
41
|
+
end
|
42
|
+
|
43
|
+
event :start do
|
44
|
+
transition :from => :door_closed, :to => [:started, :started_in_grill_mode], :on_transition => :start_spinning_the_food, :guard => :grill_button_pressed? # the method grill_button_pressed? should choose the next state
|
45
|
+
end
|
46
|
+
|
47
|
+
event :stop do
|
48
|
+
transition :from => [:started, :started_in_grill_mode], :to => :door_closed
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def light_on
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'edge-state-machine'
|
2
|
+
|
3
|
+
class User
|
4
|
+
include EdgeStateMachine
|
5
|
+
|
6
|
+
state_machine do
|
7
|
+
state :pending # first one is initial state
|
8
|
+
state :active
|
9
|
+
state :blocked # the user in this state can't sign in
|
10
|
+
|
11
|
+
event :activate do
|
12
|
+
transition :from => [:pending], :to => :active, :on_transition => :do_activate
|
13
|
+
end
|
14
|
+
|
15
|
+
event :block do
|
16
|
+
transition :from => [:pending, :active], :to => :blocked
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def do_activate
|
21
|
+
# p 'do activate'
|
22
|
+
end
|
23
|
+
end
|
data/spec/state_spec.rb
CHANGED
@@ -16,11 +16,11 @@ class Car
|
|
16
16
|
state :driving
|
17
17
|
|
18
18
|
event :turn_key do
|
19
|
-
|
19
|
+
transition :from => :parked, :to => :running, :on_transition => :start_engine
|
20
20
|
end
|
21
21
|
|
22
22
|
event :start_driving do
|
23
|
-
|
23
|
+
transition :from => :parked, :to => :driving, :on_transition => [:start_engine, :loosen_handbrake, :push_gas_pedal]
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -33,7 +33,7 @@ class Car
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def new_state(options={})
|
36
|
-
EdgeStateMachine::State.new(@state_name
|
36
|
+
EdgeStateMachine::State.new(@state_name)
|
37
37
|
end
|
38
38
|
|
39
39
|
describe EdgeStateMachine::State do
|
@@ -41,7 +41,6 @@ describe EdgeStateMachine::State do
|
|
41
41
|
before do
|
42
42
|
@state_name = :astate
|
43
43
|
@machine = StateTestSubject.state_machine
|
44
|
-
@options = { :crazy_custom_key => "key", :machine => @machine }
|
45
44
|
end
|
46
45
|
|
47
46
|
it "should set the name" do
|
@@ -52,13 +51,14 @@ describe EdgeStateMachine::State do
|
|
52
51
|
new_state.display_name.should == "Astate"
|
53
52
|
end
|
54
53
|
|
55
|
-
it "should set the display_name from
|
56
|
-
|
54
|
+
it "should set the display_name from method" do
|
55
|
+
state = new_state
|
56
|
+
state.use_display_name('A State')
|
57
|
+
state.display_name.should == 'A State'
|
57
58
|
end
|
58
59
|
|
59
60
|
it "should set the options and expose them as options" do
|
60
|
-
|
61
|
-
new_state.options.should == @options
|
61
|
+
new_state.options.should_not == nil
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should be equal to a symbol of the same name" do
|
@@ -70,27 +70,32 @@ describe EdgeStateMachine::State do
|
|
70
70
|
end
|
71
71
|
|
72
72
|
it "should send a message to the record for an action if the action is present as a symbol" do
|
73
|
-
state = new_state
|
73
|
+
state = new_state
|
74
|
+
state.enter :foo
|
75
|
+
|
74
76
|
record = mock
|
75
77
|
record.should_receive(:foo)
|
76
|
-
|
78
|
+
|
79
|
+
state.execute_action(:enter, record)
|
77
80
|
end
|
78
81
|
|
79
82
|
it "should send a message to the record for an action if the action is present as a string" do
|
80
|
-
state = new_state
|
83
|
+
state = new_state
|
84
|
+
state.enter "foo"
|
81
85
|
|
82
86
|
record = mock
|
83
87
|
record.should_receive(:foo)
|
84
88
|
|
85
|
-
state.
|
89
|
+
state.execute_action(:enter, record)
|
86
90
|
end
|
87
91
|
|
88
92
|
it "should call a proc, passing in the record for an action if the action is present" do
|
89
|
-
state = new_state
|
93
|
+
state = new_state
|
94
|
+
state.exit Proc.new {|r| r.foobar}
|
90
95
|
|
91
96
|
record = mock
|
92
97
|
record.should_receive(:foobar)
|
93
98
|
|
94
|
-
state.
|
99
|
+
state.execute_action(:exit, record)
|
95
100
|
end
|
96
101
|
end
|