simple_state_machine 0.5.3 → 0.6.2
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.
- checksums.yaml +7 -0
- data/Changelog.rdoc +23 -0
- data/README.rdoc +154 -100
- data/lib/simple_state_machine/active_record.rb +2 -62
- data/lib/simple_state_machine/decorator/active_record.rb +68 -0
- data/lib/simple_state_machine/decorator/default.rb +91 -0
- data/lib/simple_state_machine/railtie.rb +1 -1
- data/lib/simple_state_machine/simple_state_machine.rb +8 -251
- data/lib/simple_state_machine/state_machine.rb +88 -0
- data/lib/simple_state_machine/state_machine_definition.rb +72 -0
- data/lib/simple_state_machine/tools/graphviz.rb +21 -0
- data/lib/simple_state_machine/tools/inspector.rb +44 -0
- data/lib/simple_state_machine/transition.rb +40 -0
- data/lib/simple_state_machine/version.rb +1 -1
- data/lib/simple_state_machine.rb +13 -3
- data/lib/tasks/graphviz.rake +31 -0
- metadata +37 -150
- data/.gitignore +0 -1
- data/.rspec +0 -3
- data/Gemfile +0 -4
- data/Rakefile +0 -28
- data/autotest/discover.rb +0 -1
- data/examples/conversation.rb +0 -33
- data/examples/lamp.rb +0 -21
- data/examples/relationship.rb +0 -87
- data/examples/traffic_light.rb +0 -17
- data/examples/user.rb +0 -37
- data/lib/tasks/graphiz.rake +0 -13
- data/rails/graphiz.rake +0 -16
- data/simple_state_machine.gemspec +0 -31
- data/spec/active_record_spec.rb +0 -223
- data/spec/decorator_spec.rb +0 -195
- data/spec/examples_spec.rb +0 -60
- data/spec/mountable_spec.rb +0 -24
- data/spec/simple_state_machine_spec.rb +0 -129
- data/spec/spec_helper.rb +0 -7
- data/spec/state_machine_definition_spec.rb +0 -89
- data/spec/state_machine_spec.rb +0 -26
data/spec/active_record_spec.rb
DELETED
@@ -1,223 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
require "rubygems"
|
4
|
-
require "bundler"
|
5
|
-
Bundler.require
|
6
|
-
#Bundler.setup(:test)#, :activerecord)
|
7
|
-
require 'active_record'
|
8
|
-
require 'examples/user'
|
9
|
-
|
10
|
-
ActiveRecord::Base.logger = Logger.new "test.log"
|
11
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3",
|
12
|
-
:database => ":memory:")
|
13
|
-
|
14
|
-
def setup_db
|
15
|
-
ActiveRecord::Schema.define(:version => 1) do
|
16
|
-
create_table :users do |t|
|
17
|
-
t.column :id, :integer
|
18
|
-
t.column :name, :string
|
19
|
-
t.column :state, :string
|
20
|
-
t.column :activation_code, :string
|
21
|
-
t.column :created_at, :datetime
|
22
|
-
t.column :updated_at, :datetime
|
23
|
-
end
|
24
|
-
create_table :tickets do |t|
|
25
|
-
t.column :id, :integer
|
26
|
-
t.column :ssm_state, :string
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def teardown_db
|
32
|
-
ActiveRecord::Base.connection.tables.each do |table|
|
33
|
-
ActiveRecord::Base.connection.drop_table(table)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
class Ticket < ActiveRecord::Base
|
38
|
-
extend SimpleStateMachine::ActiveRecord
|
39
|
-
|
40
|
-
state_machine_definition.state_method = :ssm_state
|
41
|
-
|
42
|
-
def after_initialize
|
43
|
-
self.ssm_state ||= 'open'
|
44
|
-
end
|
45
|
-
|
46
|
-
event :close, :open => :closed
|
47
|
-
end
|
48
|
-
|
49
|
-
describe ActiveRecord do
|
50
|
-
|
51
|
-
before do
|
52
|
-
setup_db
|
53
|
-
end
|
54
|
-
|
55
|
-
after do
|
56
|
-
teardown_db
|
57
|
-
end
|
58
|
-
|
59
|
-
it "has a default state" do
|
60
|
-
User.new.should be_new
|
61
|
-
end
|
62
|
-
|
63
|
-
# TODO needs nesting/grouping, seems to have some duplication
|
64
|
-
|
65
|
-
describe "event_and_save" do
|
66
|
-
it "persists transitions" do
|
67
|
-
user = User.create!(:name => 'name')
|
68
|
-
user.invite_and_save.should == true
|
69
|
-
User.find(user.id).should be_invited
|
70
|
-
User.find(user.id).activation_code.should_not be_nil
|
71
|
-
end
|
72
|
-
|
73
|
-
it "persist transitions even when state is attr_protected" do
|
74
|
-
user_class = Class.new(User)
|
75
|
-
user_class.instance_eval { attr_protected :state }
|
76
|
-
user = user_class.create!(:name => 'name', :state => 'x')
|
77
|
-
user.should be_new
|
78
|
-
user.invite_and_save
|
79
|
-
user.reload.should be_invited
|
80
|
-
end
|
81
|
-
|
82
|
-
it "persists transitions when using send and a symbol" do
|
83
|
-
user = User.create!(:name => 'name')
|
84
|
-
user.send(:invite_and_save).should == true
|
85
|
-
User.find(user.id).should be_invited
|
86
|
-
User.find(user.id).activation_code.should_not be_nil
|
87
|
-
end
|
88
|
-
|
89
|
-
it "raises an error if an invalid state_transition is called" do
|
90
|
-
user = User.create!(:name => 'name')
|
91
|
-
expect {
|
92
|
-
user.confirm_invitation_and_save 'abc'
|
93
|
-
}.to raise_error(SimpleStateMachine::IllegalStateTransitionError,
|
94
|
-
"You cannot 'confirm_invitation' when state is 'new'")
|
95
|
-
end
|
96
|
-
|
97
|
-
it "returns false and keeps state if record is invalid" do
|
98
|
-
user = User.new
|
99
|
-
user.should be_new
|
100
|
-
user.should_not be_valid
|
101
|
-
user.invite_and_save.should == false
|
102
|
-
user.should be_new
|
103
|
-
end
|
104
|
-
|
105
|
-
it "returns false, keeps state and keeps errors if event adds errors" do
|
106
|
-
user = User.create!(:name => 'name')
|
107
|
-
user.invite_and_save!
|
108
|
-
user.should be_invited
|
109
|
-
user.confirm_invitation_and_save('x').should == false
|
110
|
-
user.should be_invited
|
111
|
-
user.errors.entries.should == [['activation_code', 'is invalid']]
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
describe "event_and_save!" do
|
117
|
-
|
118
|
-
it "persists transitions" do
|
119
|
-
user = User.create!(:name => 'name')
|
120
|
-
user.invite_and_save!.should == true
|
121
|
-
User.find(user.id).should be_invited
|
122
|
-
User.find(user.id).activation_code.should_not be_nil
|
123
|
-
end
|
124
|
-
|
125
|
-
it "persist transitions even when state is attr_protected" do
|
126
|
-
user_class = Class.new(User)
|
127
|
-
user_class.instance_eval { attr_protected :state }
|
128
|
-
user = user_class.create!(:name => 'name', :state => 'x')
|
129
|
-
user.should be_new
|
130
|
-
user.invite_and_save!
|
131
|
-
user.reload.should be_invited
|
132
|
-
end
|
133
|
-
|
134
|
-
it "raises an error if an invalid state_transition is called" do
|
135
|
-
user = User.create!(:name => 'name')
|
136
|
-
expect {
|
137
|
-
user.confirm_invitation_and_save! 'abc'
|
138
|
-
}.to raise_error(SimpleStateMachine::IllegalStateTransitionError,
|
139
|
-
"You cannot 'confirm_invitation' when state is 'new'")
|
140
|
-
end
|
141
|
-
|
142
|
-
it "raises a RecordInvalid and keeps state if record is invalid" do
|
143
|
-
user = User.new
|
144
|
-
user.should be_new
|
145
|
-
user.should_not be_valid
|
146
|
-
expect {
|
147
|
-
user.invite_and_save!
|
148
|
-
}.to raise_error(ActiveRecord::RecordInvalid,
|
149
|
-
"Validation failed: Name can't be blank")
|
150
|
-
user.should be_new
|
151
|
-
end
|
152
|
-
|
153
|
-
it "raises a RecordInvalid and keeps state if event adds errors" do
|
154
|
-
user = User.create!(:name => 'name')
|
155
|
-
user.invite_and_save!
|
156
|
-
user.should be_invited
|
157
|
-
expect {
|
158
|
-
user.confirm_invitation_and_save!('x')
|
159
|
-
}.to raise_error(ActiveRecord::RecordInvalid,
|
160
|
-
"Validation failed: Activation code is invalid")
|
161
|
-
user.should be_invited
|
162
|
-
end
|
163
|
-
|
164
|
-
end
|
165
|
-
|
166
|
-
describe "event" do
|
167
|
-
it "persists transitions" do
|
168
|
-
user = User.create!(:name => 'name')
|
169
|
-
user.invite.should == true
|
170
|
-
User.find(user.id).should be_invited
|
171
|
-
User.find(user.id).activation_code.should_not be_nil
|
172
|
-
end
|
173
|
-
|
174
|
-
it "returns false, keeps state and keeps errors if event adds errors" do
|
175
|
-
user = User.create!(:name => 'name')
|
176
|
-
user.invite_and_save!
|
177
|
-
user.should be_invited
|
178
|
-
user.confirm_invitation('x').should == false
|
179
|
-
user.should be_invited
|
180
|
-
user.errors.entries.should == [['activation_code', 'is invalid']]
|
181
|
-
end
|
182
|
-
|
183
|
-
end
|
184
|
-
|
185
|
-
describe "event!" do
|
186
|
-
|
187
|
-
it "persists transitions" do
|
188
|
-
user = User.create!(:name => 'name')
|
189
|
-
user.invite!.should == true
|
190
|
-
User.find(user.id).should be_invited
|
191
|
-
User.find(user.id).activation_code.should_not be_nil
|
192
|
-
end
|
193
|
-
|
194
|
-
it "raises a RecordInvalid and keeps state if record is invalid" do
|
195
|
-
user = User.new
|
196
|
-
user.should be_new
|
197
|
-
user.should_not be_valid
|
198
|
-
expect { user.invite! }.to raise_error(ActiveRecord::RecordInvalid, "Validation failed: Name can't be blank")
|
199
|
-
user.should be_new
|
200
|
-
end
|
201
|
-
|
202
|
-
end
|
203
|
-
|
204
|
-
describe 'custom state method' do
|
205
|
-
|
206
|
-
it "persists transitions" do
|
207
|
-
ticket = Ticket.create!
|
208
|
-
ticket.should be_open
|
209
|
-
ticket.close!.should == true
|
210
|
-
ticket.should be_closed
|
211
|
-
end
|
212
|
-
|
213
|
-
it "persists transitions with !" do
|
214
|
-
ticket = Ticket.create!
|
215
|
-
ticket.should be_open
|
216
|
-
ticket.close!
|
217
|
-
ticket.should be_closed
|
218
|
-
end
|
219
|
-
|
220
|
-
end
|
221
|
-
|
222
|
-
end
|
223
|
-
|
data/spec/decorator_spec.rb
DELETED
@@ -1,195 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
describe SimpleStateMachine::Decorator do
|
4
|
-
|
5
|
-
context "given a class" do
|
6
|
-
before do
|
7
|
-
klass = Class.new do
|
8
|
-
# TODO remove the need for defining this method
|
9
|
-
def self.state_machine_definition
|
10
|
-
@state_machine_definition ||= SimpleStateMachine::StateMachineDefinition.new
|
11
|
-
end
|
12
|
-
end
|
13
|
-
decorator = SimpleStateMachine::Decorator.new klass
|
14
|
-
decorator.decorate SimpleStateMachine::Transition.new(:event, :state1, :state2)
|
15
|
-
@instance = klass.new
|
16
|
-
@instance.state = 'state1'
|
17
|
-
end
|
18
|
-
|
19
|
-
describe "#initialize" do
|
20
|
-
it "defines a state_machine method" do
|
21
|
-
@instance.state_machine.should be_an(SimpleStateMachine::StateMachine)
|
22
|
-
end
|
23
|
-
|
24
|
-
it "defines a state getter method" do
|
25
|
-
@instance.should respond_to(:state)
|
26
|
-
end
|
27
|
-
|
28
|
-
it "defines a state setter method" do
|
29
|
-
@instance.should respond_to(:state=)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe "#decorate" do
|
34
|
-
it "defines state_helper_methods for both states" do
|
35
|
-
@instance.state1?.should == true
|
36
|
-
@instance.state2?.should == false
|
37
|
-
end
|
38
|
-
|
39
|
-
it "defines an event method" do
|
40
|
-
@instance.should respond_to(:event)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "given a class with predefined public methods" do
|
46
|
-
before do
|
47
|
-
klass = Class.new do
|
48
|
-
# TODO remove the need for defining this method
|
49
|
-
def self.state_machine_definition
|
50
|
-
@state_machine_definition ||= SimpleStateMachine::StateMachineDefinition.new
|
51
|
-
end
|
52
|
-
# predefined methods
|
53
|
-
def state1?() "state1" end
|
54
|
-
def state2?() "state2" end
|
55
|
-
def event() "predefined method" end
|
56
|
-
end
|
57
|
-
transition = SimpleStateMachine::Transition.new(:event, :state1, :state2)
|
58
|
-
decorator = SimpleStateMachine::Decorator.new klass
|
59
|
-
decorator.decorate transition
|
60
|
-
klass.state_machine_definition.transitions << transition
|
61
|
-
@instance = klass.new
|
62
|
-
@instance.state = 'state1'
|
63
|
-
end
|
64
|
-
|
65
|
-
describe "#initialize" do
|
66
|
-
it "defines a state_machine method" do
|
67
|
-
@instance.state_machine.should be_an(SimpleStateMachine::StateMachine)
|
68
|
-
end
|
69
|
-
|
70
|
-
it "defines a state getter method" do
|
71
|
-
@instance.should respond_to(:state)
|
72
|
-
end
|
73
|
-
|
74
|
-
it "defines a state setter method" do
|
75
|
-
@instance.should respond_to(:state=)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
describe "#decorate" do
|
80
|
-
it "does not overwrite predefined state_helper_methods" do
|
81
|
-
@instance.state1?.should == "state1"
|
82
|
-
@instance.state2?.should == "state2"
|
83
|
-
end
|
84
|
-
|
85
|
-
it "does not overwrite predefined event method" do
|
86
|
-
@instance.event.should == "predefined method"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context "given a class with predefined protected methods" do
|
92
|
-
before do
|
93
|
-
klass = Class.new do
|
94
|
-
# TODO remove the need for defining this method
|
95
|
-
def self.state_machine_definition
|
96
|
-
@state_machine_definition ||= SimpleStateMachine::StateMachineDefinition.new
|
97
|
-
end
|
98
|
-
# predefined methods
|
99
|
-
protected
|
100
|
-
def state1?() "state1" end
|
101
|
-
def state2?() "state2" end
|
102
|
-
def event() "predefined method" end
|
103
|
-
end
|
104
|
-
transition = SimpleStateMachine::Transition.new(:event, :state1, :state2)
|
105
|
-
decorator = SimpleStateMachine::Decorator.new klass
|
106
|
-
decorator.decorate transition
|
107
|
-
klass.state_machine_definition.transitions << transition
|
108
|
-
@instance = klass.new
|
109
|
-
@instance.state = 'state1'
|
110
|
-
end
|
111
|
-
|
112
|
-
describe "#initialize" do
|
113
|
-
it "defines a state_machine method" do
|
114
|
-
@instance.state_machine.should be_an(SimpleStateMachine::StateMachine)
|
115
|
-
end
|
116
|
-
|
117
|
-
it "defines a state getter method" do
|
118
|
-
@instance.should respond_to(:state)
|
119
|
-
end
|
120
|
-
|
121
|
-
it "defines a state setter method" do
|
122
|
-
@instance.should respond_to(:state=)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
describe "#decorate" do
|
127
|
-
it "does not overwrite predefined protected state_helper_methods" do
|
128
|
-
@instance.send(:state1?).should == "state1"
|
129
|
-
@instance.send(:state2?).should == "state2"
|
130
|
-
end
|
131
|
-
|
132
|
-
it "keeps predefined protected state_helper_methods protected" do
|
133
|
-
expect { @instance.state1? }.to raise_error(NoMethodError)
|
134
|
-
expect { @instance.state2? }.to raise_error(NoMethodError)
|
135
|
-
end
|
136
|
-
|
137
|
-
it "does not overwrite predefined protected event method" do
|
138
|
-
@instance.event.should == "predefined method"
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
context "given a class with predefined private methods" do
|
144
|
-
before do
|
145
|
-
klass = Class.new do
|
146
|
-
# TODO the need for defining this method
|
147
|
-
def self.state_machine_definition
|
148
|
-
@state_machine_definition ||= SimpleStateMachine::StateMachineDefinition.new
|
149
|
-
end
|
150
|
-
# predefined methods
|
151
|
-
private
|
152
|
-
def state1?() "state1" end
|
153
|
-
def state2?() "state2" end
|
154
|
-
def event() "predefined method" end
|
155
|
-
end
|
156
|
-
transition = SimpleStateMachine::Transition.new(:event, :state1, :state2)
|
157
|
-
decorator = SimpleStateMachine::Decorator.new klass
|
158
|
-
decorator.decorate transition
|
159
|
-
klass.state_machine_definition.transitions << transition
|
160
|
-
@instance = klass.new
|
161
|
-
@instance.state = 'state1'
|
162
|
-
end
|
163
|
-
|
164
|
-
describe "#initialize" do
|
165
|
-
it "defines a state_machine method" do
|
166
|
-
@instance.state_machine.should be_an(SimpleStateMachine::StateMachine)
|
167
|
-
end
|
168
|
-
|
169
|
-
it "defines a state getter method" do
|
170
|
-
@instance.should respond_to(:state)
|
171
|
-
end
|
172
|
-
|
173
|
-
it "defines a state setter method" do
|
174
|
-
@instance.should respond_to(:state=)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
describe "#decorate" do
|
179
|
-
it "does not overwrite predefined private state_helper_methods" do
|
180
|
-
@instance.send(:state1?).should == "state1"
|
181
|
-
@instance.send(:state2?).should == "state2"
|
182
|
-
end
|
183
|
-
|
184
|
-
it "keeps predefined private state_helper_methods private" do
|
185
|
-
expect { @instance.state1? }.to raise_error(NoMethodError)
|
186
|
-
expect { @instance.state2? }.to raise_error(NoMethodError)
|
187
|
-
end
|
188
|
-
|
189
|
-
it "does not overwrite predefined protected event method" do
|
190
|
-
@instance.event.should == "predefined method"
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
end
|
data/spec/examples_spec.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
describe "Examples" do
|
4
|
-
describe "TrafficLight" do
|
5
|
-
it "changes to the next state" do
|
6
|
-
tl = TrafficLight.new
|
7
|
-
tl.should be_green
|
8
|
-
tl.change_state
|
9
|
-
tl.should be_orange
|
10
|
-
tl.change_state
|
11
|
-
tl.should be_red
|
12
|
-
tl.change_state
|
13
|
-
tl.should be_green
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe "Lamp" do
|
18
|
-
it "changes between :on and :off" do
|
19
|
-
lamp = Lamp.new
|
20
|
-
lamp.should be_off
|
21
|
-
lamp.push_button1
|
22
|
-
lamp.should be_on
|
23
|
-
lamp.push_button2
|
24
|
-
lamp.should be_off
|
25
|
-
lamp.push_button2
|
26
|
-
lamp.should be_on
|
27
|
-
lamp.push_button1
|
28
|
-
lamp.should be_off
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe "Conversation" do
|
33
|
-
it "is :unread by default" do
|
34
|
-
conversation = Conversation.new
|
35
|
-
conversation.should be_unread
|
36
|
-
end
|
37
|
-
|
38
|
-
it "changes to read on view" do
|
39
|
-
conversation = Conversation.new
|
40
|
-
conversation.view
|
41
|
-
conversation.should be_read
|
42
|
-
end
|
43
|
-
|
44
|
-
it "changes to closed on close" do
|
45
|
-
conversation = Conversation.new
|
46
|
-
conversation.close
|
47
|
-
conversation.should be_closed
|
48
|
-
end
|
49
|
-
|
50
|
-
it "changes to closed on close if :read" do
|
51
|
-
conversation = Conversation.new
|
52
|
-
conversation.view
|
53
|
-
conversation.close
|
54
|
-
conversation.should be_closed
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
|
data/spec/mountable_spec.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
describe "Mountable" do
|
4
|
-
before do
|
5
|
-
mountable_class = Class.new(SimpleStateMachine::StateMachineDefinition) do
|
6
|
-
def initialize(subject)
|
7
|
-
self.lazy_decorator = lambda { SimpleStateMachine::Decorator.new(subject) }
|
8
|
-
add_transition(:event, :state1, :state2)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
klass = Class.new do
|
12
|
-
extend SimpleStateMachine::Mountable
|
13
|
-
self.state_machine_definition = mountable_class.new self
|
14
|
-
end
|
15
|
-
@instance = klass.new
|
16
|
-
@instance.state = 'state1'
|
17
|
-
end
|
18
|
-
|
19
|
-
it "has state_helper methods" do
|
20
|
-
@instance.should be_state1
|
21
|
-
@instance.should_not be_state2
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
@@ -1,129 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
require 'cgi'
|
3
|
-
|
4
|
-
describe SimpleStateMachine do
|
5
|
-
|
6
|
-
it "has an error that extends RuntimeError" do
|
7
|
-
SimpleStateMachine::IllegalStateTransitionError.superclass.should == RuntimeError
|
8
|
-
end
|
9
|
-
|
10
|
-
describe ".event" do
|
11
|
-
|
12
|
-
before do
|
13
|
-
@klass = Class.new do
|
14
|
-
extend SimpleStateMachine
|
15
|
-
def initialize(state = 'state1')
|
16
|
-
@state = state
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
it "changes state if event has multiple transitions" do
|
22
|
-
klass = Class.new(@klass)
|
23
|
-
klass.instance_eval do
|
24
|
-
event :event, :state1 => :state2, :state2 => :state3
|
25
|
-
end
|
26
|
-
example = klass.new
|
27
|
-
example.should be_state1
|
28
|
-
example.event
|
29
|
-
example.should be_state2
|
30
|
-
example.event
|
31
|
-
example.should be_state3
|
32
|
-
end
|
33
|
-
|
34
|
-
it "changes state if event has multiple froms" do
|
35
|
-
klass = Class.new(@klass)
|
36
|
-
klass.instance_eval do
|
37
|
-
event :event, [:state1, :state2] => :state3
|
38
|
-
end
|
39
|
-
example = klass.new
|
40
|
-
example.event
|
41
|
-
example.should be_state3
|
42
|
-
example = klass.new 'state2'
|
43
|
-
example.should be_state2
|
44
|
-
example.event
|
45
|
-
example.should be_state3
|
46
|
-
end
|
47
|
-
|
48
|
-
it "changes state if event has all as from" do
|
49
|
-
klass = Class.new(@klass)
|
50
|
-
klass.instance_eval do
|
51
|
-
event :other_event, :state1 => :state2
|
52
|
-
event :event, :all => :state3
|
53
|
-
end
|
54
|
-
example = klass.new
|
55
|
-
example.event
|
56
|
-
example.should be_state3
|
57
|
-
example = klass.new 'state2'
|
58
|
-
example.should be_state2
|
59
|
-
example.event
|
60
|
-
example.should be_state3
|
61
|
-
end
|
62
|
-
|
63
|
-
it "changes state when state is a symbol instead of a string" do
|
64
|
-
klass = Class.new(@klass)
|
65
|
-
klass.instance_eval do
|
66
|
-
event :event, :state1 => :state2
|
67
|
-
end
|
68
|
-
example = klass.new :state1
|
69
|
-
example.state.should == :state1
|
70
|
-
example.send(:event)
|
71
|
-
example.should be_state2
|
72
|
-
end
|
73
|
-
|
74
|
-
it "changes state to error_state when error can be caught" do
|
75
|
-
class_with_error = Class.new(@klass)
|
76
|
-
class_with_error.instance_eval do
|
77
|
-
define_method :raise_error do
|
78
|
-
raise RuntimeError.new
|
79
|
-
end
|
80
|
-
event :raise_error, :state1 => :state2, RuntimeError => :failed
|
81
|
-
end
|
82
|
-
example = class_with_error.new
|
83
|
-
example.should be_state1
|
84
|
-
example.raise_error
|
85
|
-
example.should be_failed
|
86
|
-
end
|
87
|
-
|
88
|
-
it "raises an error if an invalid state_transition is called" do
|
89
|
-
klass = Class.new(@klass)
|
90
|
-
klass.instance_eval do
|
91
|
-
event :event, :state1 => :state2
|
92
|
-
event :event2, :state2 => :state3
|
93
|
-
end
|
94
|
-
example = klass.new
|
95
|
-
lambda { example.event2 }.should raise_error(SimpleStateMachine::IllegalStateTransitionError, "You cannot 'event2' when state is 'state1'")
|
96
|
-
end
|
97
|
-
|
98
|
-
it "returns what the decorated method returns" do
|
99
|
-
klass = Class.new(@klass)
|
100
|
-
klass.instance_eval do
|
101
|
-
event :event1, :state1 => :state2
|
102
|
-
define_method :event2 do
|
103
|
-
'event2'
|
104
|
-
end
|
105
|
-
event :event2, :state2 => :state3
|
106
|
-
end
|
107
|
-
example = klass.new
|
108
|
-
example.event1.should == nil
|
109
|
-
example.event2.should == 'event2'
|
110
|
-
end
|
111
|
-
|
112
|
-
it "calls existing methods" do
|
113
|
-
klass = Class.new(@klass)
|
114
|
-
klass.instance_eval do
|
115
|
-
attr_accessor :event_called
|
116
|
-
define_method :event do
|
117
|
-
@event_called = true
|
118
|
-
end
|
119
|
-
event :event, :state1 => :state2
|
120
|
-
end
|
121
|
-
example = klass.new
|
122
|
-
example.event
|
123
|
-
example.event_called.should == true
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
end
|
129
|
-
|
data/spec/spec_helper.rb
DELETED