stateflow 0.2.3 → 0.3.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.
- data/CHANGELOG.rdoc +7 -1
- data/README.rdoc +21 -17
- data/Rakefile +3 -3
- data/lib/stateflow.rb +9 -5
- data/lib/stateflow/event.rb +2 -2
- data/lib/stateflow/persistence/active_record.rb +4 -3
- data/lib/stateflow/persistence/mongo_mapper.rb +4 -3
- data/lib/stateflow/persistence/mongoid.rb +3 -2
- data/lib/stateflow/persistence/none.rb +2 -2
- data/spec/spec_helper.rb +0 -8
- data/spec/stateflow_spec.rb +105 -94
- data/stateflow.gemspec +11 -2
- metadata +50 -4
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
= Version 0.3.0
|
2
|
+
* Added a non bang method for events (Check README)
|
3
|
+
* Added tests to persistence layers (About time!)
|
4
|
+
* Changed the way the persistence layers save to model
|
5
|
+
* Protected state column is now supported!
|
6
|
+
|
1
7
|
= Version 0.2.3
|
2
8
|
* Silence depreciation warnings (Fixing irritating issue)
|
3
9
|
|
@@ -12,4 +18,4 @@
|
|
12
18
|
* Changed the persistence layers to use write_attribute, instead of update_attribute - Thanks to achirkunov
|
13
19
|
|
14
20
|
= Version 0.1.2
|
15
|
-
* Fixed Mongoid support - Thanks bmartin for pointing that out
|
21
|
+
* Fixed Mongoid support - Thanks bmartin for pointing that out
|
data/README.rdoc
CHANGED
@@ -35,18 +35,18 @@ You can set the default column with the state_column function in the stateflow b
|
|
35
35
|
|
36
36
|
require 'rubygems'
|
37
37
|
require 'stateflow'
|
38
|
-
|
38
|
+
|
39
39
|
# No persistence
|
40
40
|
Stateflow.persistence :none
|
41
41
|
|
42
42
|
class Robot
|
43
43
|
include Stateflow
|
44
|
-
|
44
|
+
|
45
45
|
stateflow do
|
46
46
|
initial :green
|
47
|
-
|
47
|
+
|
48
48
|
state :green, :yellow, :red
|
49
|
-
|
49
|
+
|
50
50
|
event :change_color do
|
51
51
|
transitions :from => :green, :to => :yellow
|
52
52
|
transitions :from => :yellow, :to => :red
|
@@ -54,61 +54,65 @@ You can set the default column with the state_column function in the stateflow b
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
== Advanced Example
|
59
59
|
|
60
60
|
require 'rubygems'
|
61
61
|
require 'stateflow'
|
62
|
-
|
62
|
+
|
63
63
|
# No persistence
|
64
64
|
Stateflow.persistence :none
|
65
65
|
|
66
66
|
class Test
|
67
67
|
include Stateflow
|
68
|
-
|
68
|
+
|
69
69
|
stateflow do
|
70
|
-
|
70
|
+
|
71
71
|
initial :love
|
72
|
-
|
72
|
+
|
73
73
|
state :love do
|
74
74
|
enter lambda { |t| p "Entering love" }
|
75
75
|
exit :exit_love
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
state :hate do
|
79
79
|
enter lambda { |t| p "Entering hate" }
|
80
80
|
exit lambda { |t| p "Exiting hate" }
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
state :mixed do
|
84
84
|
enter lambda { |t| p "Entering mixed" }
|
85
85
|
exit lambda { |t| p "Exiting mixed" }
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
event :b do
|
89
89
|
transitions :from => :love, :to => :hate, :if => :no_ice_cream
|
90
90
|
transitions :from => :hate, :to => :love
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
event :a do
|
94
94
|
transitions :from => :love, :to => [:hate, :mixed], :decide => :likes_ice_cream?
|
95
95
|
transitions :from => [:hate, :mixed], :to => :love
|
96
96
|
end
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
def likes_ice_cream?
|
100
100
|
rand(10) > 5 ? :mixed : :hate
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
def exit_love
|
104
104
|
p "Exiting love"
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
def no_ice_cream
|
108
108
|
rand(4) > 2 ? true : false
|
109
109
|
end
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
|
+
== Bang event vs non-bang event
|
113
|
+
|
114
|
+
Bang events will save the model after call, where the non bang event will just update the state and call the transitions. (ie. model.change! vs model.change)
|
115
|
+
|
112
116
|
== Extra's
|
113
117
|
|
114
118
|
* When transitioning states, the previous state from which you have transitioned to can be accessed via `_previous_state`. See tests for more information.
|
data/Rakefile
CHANGED
@@ -2,11 +2,11 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('stateflow', '0.
|
5
|
+
Echoe.new('stateflow', '0.3.0') do |p|
|
6
6
|
p.description = "State machine that allows dynamic transitions for business workflows"
|
7
7
|
p.url = "http://github.com/ryanza/stateflow"
|
8
8
|
p.author = "Ryan Oberholzer"
|
9
9
|
p.email = "ryan@platform45.com"
|
10
10
|
p.ignore_pattern = ["tmp/*", "script/*"]
|
11
|
-
p.development_dependencies = ["rspec"]
|
12
|
-
end
|
11
|
+
p.development_dependencies = ["rspec", "activerecord", "mongoid >=2.0.0.beta.20", "sqlite3-ruby"]
|
12
|
+
end
|
data/lib/stateflow.rb
CHANGED
@@ -27,8 +27,12 @@ module Stateflow
|
|
27
27
|
end
|
28
28
|
|
29
29
|
@machine.events.keys.each do |key|
|
30
|
+
define_method "#{key}" do
|
31
|
+
fire_event(key, :save => false)
|
32
|
+
end
|
33
|
+
|
30
34
|
define_method "#{key}!" do
|
31
|
-
fire_event(key)
|
35
|
+
fire_event(key, :save => true)
|
32
36
|
end
|
33
37
|
end
|
34
38
|
end
|
@@ -41,8 +45,8 @@ module Stateflow
|
|
41
45
|
@current_state ||= load_from_persistence.nil? ? machine.initial_state : machine.states[load_from_persistence.to_sym]
|
42
46
|
end
|
43
47
|
|
44
|
-
def
|
45
|
-
save_to_persistence(new_state.name.to_s)
|
48
|
+
def set_current_state(new_state, options)
|
49
|
+
save_to_persistence(new_state.name.to_s, options)
|
46
50
|
@current_state = new_state
|
47
51
|
end
|
48
52
|
|
@@ -51,10 +55,10 @@ module Stateflow
|
|
51
55
|
end
|
52
56
|
|
53
57
|
private
|
54
|
-
def fire_event(event_name)
|
58
|
+
def fire_event(event_name, options = {})
|
55
59
|
event = machine.events[event_name.to_sym]
|
56
60
|
raise Stateflow::NoEventFound.new("No event matches #{event_name}") if event.nil?
|
57
|
-
event.fire(current_state, self)
|
61
|
+
event.fire(current_state, self, options)
|
58
62
|
end
|
59
63
|
end
|
60
64
|
|
data/lib/stateflow/event.rb
CHANGED
@@ -10,7 +10,7 @@ module Stateflow
|
|
10
10
|
instance_eval(&transitions)
|
11
11
|
end
|
12
12
|
|
13
|
-
def fire(current_state, klass)
|
13
|
+
def fire(current_state, klass, options)
|
14
14
|
transition = @transitions.select{ |t| t.from.include? current_state.name }.first
|
15
15
|
raise NoTransitionFound.new("No transition found for event #{@name}") if transition.nil?
|
16
16
|
|
@@ -20,7 +20,7 @@ module Stateflow
|
|
20
20
|
raise NoStateFound.new("Invalid state #{transition.to.to_s} for transition.") if new_state.nil?
|
21
21
|
|
22
22
|
current_state.execute_action(:exit, klass)
|
23
|
-
klass.
|
23
|
+
klass.set_current_state(new_state, options)
|
24
24
|
|
25
25
|
klass._previous_state = current_state.name.to_s
|
26
26
|
new_state.execute_action(:enter, klass)
|
@@ -13,8 +13,9 @@ module Stateflow
|
|
13
13
|
self.send machine.state_column.to_sym
|
14
14
|
end
|
15
15
|
|
16
|
-
def save_to_persistence(new_state)
|
17
|
-
self.
|
16
|
+
def save_to_persistence(new_state, options)
|
17
|
+
self.send("#{machine.state_column}=".to_sym, new_state)
|
18
|
+
self.save if options[:save]
|
18
19
|
end
|
19
20
|
|
20
21
|
def ensure_initial_state
|
@@ -23,4 +24,4 @@ module Stateflow
|
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
26
|
-
end
|
27
|
+
end
|
@@ -11,8 +11,9 @@ module Stateflow
|
|
11
11
|
self.send machine.state_column.to_sym
|
12
12
|
end
|
13
13
|
|
14
|
-
def save_to_persistence(new_state)
|
15
|
-
self.
|
14
|
+
def save_to_persistence(new_state, options)
|
15
|
+
self.send("#{machine.state_column}=".to_sym, new_state)
|
16
|
+
self.save if options[:save]
|
16
17
|
end
|
17
18
|
|
18
19
|
def ensure_initial_state
|
@@ -21,4 +22,4 @@ module Stateflow
|
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
24
|
-
end
|
25
|
+
end
|
@@ -11,8 +11,9 @@ module Stateflow
|
|
11
11
|
self.send machine.state_column.to_sym
|
12
12
|
end
|
13
13
|
|
14
|
-
def save_to_persistence(new_state)
|
15
|
-
self.
|
14
|
+
def save_to_persistence(new_state, options = {})
|
15
|
+
self.send("#{machine.state_column}=".to_sym, new_state)
|
16
|
+
self.save if options[:save]
|
16
17
|
end
|
17
18
|
|
18
19
|
def ensure_initial_state
|
data/spec/spec_helper.rb
CHANGED
@@ -2,11 +2,3 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
3
|
|
4
4
|
require 'stateflow'
|
5
|
-
|
6
|
-
require 'spec'
|
7
|
-
require 'spec/autorun'
|
8
|
-
|
9
|
-
Stateflow.persistence = :none
|
10
|
-
|
11
|
-
Spec::Runner.configure do |config|
|
12
|
-
end
|
data/spec/stateflow_spec.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
Stateflow.persistence = :none
|
4
|
+
|
3
5
|
class Robot
|
4
6
|
include Stateflow
|
5
|
-
|
7
|
+
|
6
8
|
stateflow do
|
7
9
|
initial :green
|
8
|
-
|
10
|
+
|
9
11
|
state :green, :yellow, :red
|
10
|
-
|
12
|
+
|
11
13
|
event :change_color do
|
12
14
|
transitions :from => :green, :to => :yellow
|
13
15
|
transitions :from => :yellow, :to => :red
|
@@ -16,32 +18,32 @@ class Robot
|
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
|
-
class Car
|
21
|
+
class Car
|
20
22
|
include Stateflow
|
21
|
-
|
23
|
+
|
22
24
|
stateflow do
|
23
25
|
initial :parked
|
24
|
-
|
26
|
+
|
25
27
|
state :parked do
|
26
28
|
enter do
|
27
29
|
"Entering parked"
|
28
30
|
end
|
29
|
-
|
31
|
+
|
30
32
|
exit do
|
31
33
|
"Exiting parked"
|
32
34
|
end
|
33
35
|
end
|
34
|
-
|
36
|
+
|
35
37
|
state :driving do
|
36
38
|
enter do
|
37
39
|
"Entering parked"
|
38
40
|
end
|
39
41
|
end
|
40
|
-
|
42
|
+
|
41
43
|
event :drive do
|
42
44
|
transitions :from => :parked, :to => :driving
|
43
45
|
end
|
44
|
-
|
46
|
+
|
45
47
|
event :park do
|
46
48
|
transitions :from => :driving, :to => :parked
|
47
49
|
end
|
@@ -50,10 +52,10 @@ end
|
|
50
52
|
|
51
53
|
class Bob
|
52
54
|
include Stateflow
|
53
|
-
|
55
|
+
|
54
56
|
stateflow do
|
55
57
|
state :yellow, :red, :purple
|
56
|
-
|
58
|
+
|
57
59
|
event :change_hair_color do
|
58
60
|
transitions :from => :purple, :to => :yellow
|
59
61
|
transitions :from => :yellow, :to => :red
|
@@ -64,47 +66,47 @@ end
|
|
64
66
|
|
65
67
|
class Dater
|
66
68
|
include Stateflow
|
67
|
-
|
69
|
+
|
68
70
|
stateflow do
|
69
71
|
state :single, :dating, :married
|
70
|
-
|
72
|
+
|
71
73
|
event :take_out do
|
72
74
|
transitions :from => :single, :to => :dating
|
73
75
|
end
|
74
|
-
|
76
|
+
|
75
77
|
event :gift do
|
76
78
|
transitions :from => :dating, :to => [:single, :married], :decide => :girls_mood?
|
77
79
|
end
|
78
|
-
|
80
|
+
|
79
81
|
event :blank_decision do
|
80
82
|
transitions :from => :single, :to => [:single, :married], :decide => :girls_mood?
|
81
83
|
end
|
82
|
-
|
84
|
+
|
83
85
|
event :fail do
|
84
86
|
transitions :from => :dating, :to => [:single, :married]
|
85
87
|
end
|
86
88
|
end
|
87
|
-
|
89
|
+
|
88
90
|
def girls_mood?
|
89
91
|
end
|
90
92
|
end
|
91
93
|
|
92
94
|
class Priority
|
93
95
|
include Stateflow
|
94
|
-
|
96
|
+
|
95
97
|
stateflow do
|
96
98
|
initial :medium
|
97
99
|
state :low, :medium, :high
|
98
|
-
|
100
|
+
|
99
101
|
event :low do
|
100
102
|
transitions :from => any, :to => :low
|
101
103
|
end
|
102
|
-
|
103
|
-
event :medium do
|
104
|
+
|
105
|
+
event :medium do
|
104
106
|
transitions :from => any, :to => :medium
|
105
|
-
end
|
106
|
-
|
107
|
-
event :high do
|
107
|
+
end
|
108
|
+
|
109
|
+
event :high do
|
108
110
|
transitions :from => any, :to => :high
|
109
111
|
end
|
110
112
|
end
|
@@ -112,176 +114,185 @@ end
|
|
112
114
|
|
113
115
|
class Stater
|
114
116
|
include Stateflow
|
115
|
-
|
117
|
+
|
116
118
|
stateflow do
|
117
119
|
initial :bill
|
118
|
-
|
120
|
+
|
119
121
|
state :bob, :bill
|
120
|
-
|
122
|
+
|
121
123
|
event :lolcats do
|
122
124
|
transitions :from => :bill, :to => :bob
|
123
125
|
end
|
124
126
|
end
|
125
127
|
end
|
126
|
-
|
128
|
+
|
127
129
|
|
128
130
|
describe Stateflow do
|
129
131
|
describe "class methods" do
|
130
132
|
it "should respond to stateflow block to setup the intial stateflow" do
|
131
133
|
Robot.should respond_to(:stateflow)
|
132
134
|
end
|
133
|
-
|
135
|
+
|
134
136
|
it "should respond to the machine attr accessor" do
|
135
137
|
Robot.should respond_to(:machine)
|
136
138
|
end
|
137
139
|
end
|
138
|
-
|
140
|
+
|
139
141
|
describe "instance methods" do
|
140
142
|
before(:each) do
|
141
143
|
@r = Robot.new
|
142
144
|
end
|
143
|
-
|
145
|
+
|
144
146
|
it "should respond to current state" do
|
145
147
|
@r.should respond_to(:current_state)
|
146
148
|
end
|
147
|
-
|
149
|
+
|
148
150
|
it "should respond to the current state setter" do
|
149
|
-
@r.should respond_to(:
|
151
|
+
@r.should respond_to(:set_current_state)
|
150
152
|
end
|
151
|
-
|
153
|
+
|
152
154
|
it "should respond to the current machine" do
|
153
155
|
@r.should respond_to(:machine)
|
154
156
|
end
|
155
|
-
|
157
|
+
|
156
158
|
it "should respond to load from persistence" do
|
157
159
|
@r.should respond_to(:load_from_persistence)
|
158
160
|
end
|
159
|
-
|
161
|
+
|
160
162
|
it "should respond to save to persistence" do
|
161
163
|
@r.should respond_to(:save_to_persistence)
|
162
164
|
end
|
163
165
|
end
|
164
|
-
|
166
|
+
|
165
167
|
describe "initial state" do
|
166
168
|
it "should set the initial state" do
|
167
169
|
robot = Robot.new
|
168
170
|
robot.current_state.name.should == :green
|
169
171
|
end
|
170
|
-
|
172
|
+
|
171
173
|
it "should return true for green?" do
|
172
174
|
robot = Robot.new
|
173
175
|
robot.green?.should be_true
|
174
176
|
end
|
175
|
-
|
177
|
+
|
176
178
|
it "should return false for yellow?" do
|
177
179
|
robot = Robot.new
|
178
180
|
robot.yellow?.should be_false
|
179
181
|
end
|
180
|
-
|
182
|
+
|
181
183
|
it "should return false for red?" do
|
182
184
|
robot = Robot.new
|
183
185
|
robot.red?.should be_false
|
184
186
|
end
|
185
|
-
|
187
|
+
|
186
188
|
it "should set the initial state to the first state set" do
|
187
189
|
bob = Bob.new
|
188
190
|
bob.current_state.name.should == :yellow
|
189
191
|
bob.yellow?.should be_true
|
190
192
|
end
|
191
193
|
end
|
192
|
-
|
194
|
+
|
193
195
|
it "robot class should contain red, yellow and green states" do
|
194
196
|
robot = Robot.new
|
195
197
|
robot.machine.states.keys.should include(:red, :yellow, :green)
|
196
198
|
end
|
197
|
-
|
199
|
+
|
198
200
|
describe "firing events" do
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
end
|
204
|
-
|
205
|
-
it "should call the fire_event method" do
|
206
|
-
robot = Robot.new
|
207
|
-
robot.should_receive(:fire_event).with(:change_color)
|
208
|
-
robot.change_color!
|
209
|
-
end
|
210
|
-
|
201
|
+
let(:robot) { Robot.new }
|
202
|
+
let(:event) { :change_color }
|
203
|
+
subject { robot }
|
204
|
+
|
211
205
|
it "should raise an exception if the event does not exist" do
|
212
|
-
robot = Robot.new
|
213
206
|
lambda { robot.send(:fire_event, :fake) }.should raise_error(Stateflow::NoEventFound)
|
214
207
|
end
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
208
|
+
|
209
|
+
shared_examples_for "an entity supporting state changes" do
|
210
|
+
context "when firing" do
|
211
|
+
after(:each) { subject.send(event_method) }
|
212
|
+
it "should call the fire method on event" do
|
213
|
+
subject.machine.events[event].should_receive(:fire)
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should call the fire_event method" do
|
217
|
+
subject.should_receive(:fire_event).with(event, {:save=>persisted})
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should update the current state" do
|
222
|
+
subject.current_state.name.should == :green
|
223
|
+
subject.send(event_method)
|
224
|
+
subject.current_state.name.should == :yellow
|
225
|
+
end
|
220
226
|
end
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
+
|
228
|
+
describe "bang event" do
|
229
|
+
let(:event_method) { :change_color! }
|
230
|
+
let(:persisted) { true }
|
231
|
+
it_should_behave_like "an entity supporting state changes"
|
232
|
+
end
|
233
|
+
|
234
|
+
describe "non-bang event" do
|
235
|
+
let(:event_method) { :change_color }
|
236
|
+
let(:persisted) { false }
|
237
|
+
it_should_behave_like "an entity supporting state changes"
|
227
238
|
end
|
228
|
-
|
239
|
+
|
229
240
|
describe "before filters" do
|
230
241
|
before(:each) do
|
231
242
|
@car = Car.new
|
232
243
|
end
|
233
|
-
|
244
|
+
|
234
245
|
it "should call the exit state before filter on the exiting old state" do
|
235
246
|
@car.machine.states[:parked].should_receive(:execute_action).with(:exit, @car)
|
236
247
|
@car.drive!
|
237
248
|
end
|
238
|
-
|
249
|
+
|
239
250
|
it "should call the enter state before filter on the entering new state" do
|
240
251
|
@car.machine.states[:driving].should_receive(:execute_action).with(:enter, @car)
|
241
252
|
@car.drive!
|
242
253
|
end
|
243
254
|
end
|
244
255
|
end
|
245
|
-
|
246
|
-
describe "persistence" do
|
256
|
+
|
257
|
+
describe "persistence" do
|
247
258
|
it "should attempt to persist the new state and the name should be a string" do
|
248
259
|
robot = Robot.new
|
249
|
-
robot.should_receive(:save_to_persistence).with("yellow")
|
260
|
+
robot.should_receive(:save_to_persistence).with("yellow", {:save=>true})
|
250
261
|
robot.change_color!
|
251
262
|
end
|
252
|
-
|
263
|
+
|
253
264
|
it "should attempt to read the initial state from the persistence" do
|
254
265
|
robot = Robot.new
|
255
|
-
|
266
|
+
|
256
267
|
def robot.load_from_persistence
|
257
268
|
:red
|
258
269
|
end
|
259
|
-
|
270
|
+
|
260
271
|
robot.current_state.name.should == :red
|
261
272
|
end
|
262
273
|
end
|
263
|
-
|
274
|
+
|
264
275
|
describe "dynamic to transitions" do
|
265
276
|
it "should raise an error without any decide argument" do
|
266
277
|
date = Dater.new
|
267
|
-
|
278
|
+
|
268
279
|
def date.load_from_persistence
|
269
280
|
:dating
|
270
281
|
end
|
271
|
-
|
282
|
+
|
272
283
|
lambda { date.fail! }.should raise_error(Stateflow::IncorrectTransition)
|
273
284
|
end
|
274
|
-
|
285
|
+
|
275
286
|
it "should raise an error if the decision method does not return a valid state" do
|
276
287
|
date = Dater.new
|
277
|
-
|
288
|
+
|
278
289
|
def date.girls_mood?
|
279
290
|
:lol
|
280
291
|
end
|
281
|
-
|
292
|
+
|
282
293
|
lambda { date.blank_decision! }.should raise_error(Stateflow::NoStateFound, "Decision did not return a state that was set in the 'to' argument")
|
283
294
|
end
|
284
|
-
|
295
|
+
|
285
296
|
it "should raise an error if the decision method returns blank/nil" do
|
286
297
|
date = Dater.new
|
287
298
|
|
@@ -290,27 +301,27 @@ describe Stateflow do
|
|
290
301
|
|
291
302
|
lambda { date.blank_decision! }.should raise_error(Stateflow::NoStateFound, "Decision did not return a state that was set in the 'to' argument")
|
292
303
|
end
|
293
|
-
|
304
|
+
|
294
305
|
it "should calculate the decide block or method and transition to the correct state" do
|
295
306
|
date = Dater.new
|
296
|
-
|
307
|
+
|
297
308
|
def date.load_from_persistence
|
298
309
|
:dating
|
299
310
|
end
|
300
|
-
|
311
|
+
|
301
312
|
date.current_state.name.should == :dating
|
302
|
-
|
313
|
+
|
303
314
|
def date.girls_mood?
|
304
315
|
:single
|
305
316
|
end
|
306
|
-
|
317
|
+
|
307
318
|
date.gift!
|
308
|
-
|
319
|
+
|
309
320
|
date.current_state.name.should == :single
|
310
321
|
end
|
311
322
|
end
|
312
|
-
|
313
|
-
describe "transitions from any" do
|
323
|
+
|
324
|
+
describe "transitions from any" do
|
314
325
|
it "should properly change state" do
|
315
326
|
priority = Priority.new
|
316
327
|
priority.low!
|
@@ -321,12 +332,12 @@ describe Stateflow do
|
|
321
332
|
priority.should be_high
|
322
333
|
end
|
323
334
|
end
|
324
|
-
|
335
|
+
|
325
336
|
describe "previous state" do
|
326
337
|
it "should display the previous state" do
|
327
338
|
stater = Stater.new
|
328
339
|
stater.lolcats!
|
329
|
-
|
340
|
+
|
330
341
|
stater._previous_state.should == "bill"
|
331
342
|
stater.current_state == "bob"
|
332
343
|
end
|
data/stateflow.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{stateflow}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.3.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Ryan Oberholzer"]
|
9
|
-
s.date = %q{2010-
|
9
|
+
s.date = %q{2010-12-08}
|
10
10
|
s.description = %q{State machine that allows dynamic transitions for business workflows}
|
11
11
|
s.email = %q{ryan@platform45.com}
|
12
12
|
s.extra_rdoc_files = ["CHANGELOG.rdoc", "README.rdoc", "lib/stateflow.rb", "lib/stateflow/event.rb", "lib/stateflow/exception.rb", "lib/stateflow/machine.rb", "lib/stateflow/persistence.rb", "lib/stateflow/persistence/active_record.rb", "lib/stateflow/persistence/mongo_mapper.rb", "lib/stateflow/persistence/mongoid.rb", "lib/stateflow/persistence/none.rb", "lib/stateflow/state.rb", "lib/stateflow/transition.rb"]
|
@@ -24,10 +24,19 @@ Gem::Specification.new do |s|
|
|
24
24
|
|
25
25
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
26
26
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
27
|
+
s.add_development_dependency(%q<activerecord>, [">= 0"])
|
28
|
+
s.add_development_dependency(%q<mongoid>, [">= 2.0.0.beta.20"])
|
29
|
+
s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
|
27
30
|
else
|
28
31
|
s.add_dependency(%q<rspec>, [">= 0"])
|
32
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
33
|
+
s.add_dependency(%q<mongoid>, [">= 2.0.0.beta.20"])
|
34
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
29
35
|
end
|
30
36
|
else
|
31
37
|
s.add_dependency(%q<rspec>, [">= 0"])
|
38
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
39
|
+
s.add_dependency(%q<mongoid>, [">= 2.0.0.beta.20"])
|
40
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
32
41
|
end
|
33
42
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stateflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 2
|
9
8
|
- 3
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ryan Oberholzer
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-12-08 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -32,6 +32,52 @@ dependencies:
|
|
32
32
|
version: "0"
|
33
33
|
type: :development
|
34
34
|
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: activerecord
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: mongoid
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 62196427
|
58
|
+
segments:
|
59
|
+
- 2
|
60
|
+
- 0
|
61
|
+
- 0
|
62
|
+
- beta
|
63
|
+
- 20
|
64
|
+
version: 2.0.0.beta.20
|
65
|
+
type: :development
|
66
|
+
version_requirements: *id003
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: sqlite3-ruby
|
69
|
+
prerelease: false
|
70
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
type: :development
|
80
|
+
version_requirements: *id004
|
35
81
|
description: State machine that allows dynamic transitions for business workflows
|
36
82
|
email: ryan@platform45.com
|
37
83
|
executables: []
|