state_machine 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,298 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class TransitionTest < Test::Unit::TestCase
4
+ def setup
5
+ @machine = PluginAWeek::StateMachine::Machine.new(Switch, 'state', :initial => 'off')
6
+ @event = PluginAWeek::StateMachine::Event.new(@machine, 'turn_on')
7
+ @transition = PluginAWeek::StateMachine::Transition.new(@event, 'off', 'on')
8
+ end
9
+
10
+ def test_should_have_a_from_state
11
+ assert_equal 'off', @transition.from_state
12
+ end
13
+
14
+ def test_should_have_a_to_state
15
+ assert_equal 'on', @transition.to_state
16
+ end
17
+
18
+ def test_should_not_be_a_loopback
19
+ assert !@transition.loopback?
20
+ end
21
+
22
+ def test_should_not_be_able_to_perform_if_record_state_is_not_from_state
23
+ record = new_switch(:state => 'on')
24
+ assert !@transition.can_perform_on?(record)
25
+ end
26
+
27
+ def test_should_be_able_to_perform_if_record_state_is_from_state
28
+ record = new_switch(:state => 'off')
29
+ assert @transition.can_perform_on?(record)
30
+ end
31
+ end
32
+
33
+ class TransitionWithoutFromStateTest < Test::Unit::TestCase
34
+ def setup
35
+ @machine = PluginAWeek::StateMachine::Machine.new(Switch, 'state', :initial => 'off')
36
+ @event = PluginAWeek::StateMachine::Event.new(@machine, 'turn_on')
37
+ @transition = PluginAWeek::StateMachine::Transition.new(@event, nil, 'on')
38
+ end
39
+
40
+ def test_should_not_have_a_from_state
41
+ assert_nil @transition.from_state
42
+ end
43
+
44
+ def test_should_be_able_to_perform_on_all_states
45
+ record = new_switch(:state => 'off')
46
+ assert @transition.can_perform_on?(record)
47
+
48
+ record = new_switch(:state => 'on')
49
+ assert @transition.can_perform_on?(record)
50
+ end
51
+ end
52
+
53
+ class TransitionWithLoopbackTest < Test::Unit::TestCase
54
+ def setup
55
+ @machine = PluginAWeek::StateMachine::Machine.new(Switch, 'state', :initial => 'off')
56
+ @event = PluginAWeek::StateMachine::Event.new(@machine, 'turn_on')
57
+ @transition = PluginAWeek::StateMachine::Transition.new(@event, 'on', 'on')
58
+ end
59
+
60
+ def test_should_have_a_from_state
61
+ assert_equal 'on', @transition.from_state
62
+ end
63
+
64
+ def test_should_have_a_to_state
65
+ assert_equal 'on', @transition.to_state
66
+ end
67
+
68
+ def test_should_be_a_loopback
69
+ assert @transition.loopback?
70
+ end
71
+
72
+ def test_should_be_able_to_perform_if_record_is_in_from_state
73
+ record = new_switch(:state => 'on')
74
+ assert @transition.can_perform_on?(record)
75
+ end
76
+ end
77
+
78
+ class TransitionAfterBeingPerformedTest < Test::Unit::TestCase
79
+ def setup
80
+ @machine = PluginAWeek::StateMachine::Machine.new(Switch, 'state', :initial => 'off')
81
+ @event = PluginAWeek::StateMachine::Event.new(@machine, 'turn_on')
82
+ @transition = PluginAWeek::StateMachine::Transition.new(@event, 'off', 'on')
83
+
84
+ @record = create_switch(:state => 'off')
85
+ @transition.perform(@record)
86
+ @record.reload
87
+ end
88
+
89
+ def test_should_update_the_state_to_the_to_state
90
+ assert_equal 'on', @record.state
91
+ end
92
+
93
+ def test_should_no_longer_be_able_to_perform_on_the_record
94
+ assert !@transition.can_perform_on?(@record)
95
+ end
96
+ end
97
+
98
+ class TransitionWithLoopbackAfterBeingPerformedTest < Test::Unit::TestCase
99
+ def setup
100
+ @machine = PluginAWeek::StateMachine::Machine.new(Switch, 'state', :initial => 'off')
101
+ @event = PluginAWeek::StateMachine::Event.new(@machine, 'turn_on')
102
+ @transition = PluginAWeek::StateMachine::Transition.new(@event, 'on', 'on')
103
+
104
+ @record = create_switch(:state => 'on')
105
+ @transition.perform(@record)
106
+ @record.reload
107
+ end
108
+
109
+ def test_should_not_update_the_attribute
110
+ assert_equal 'on', @record.state
111
+ end
112
+
113
+ def test_should_still_be_able_to_perform_on_the_record
114
+ assert @transition.can_perform_on?(@record)
115
+ end
116
+ end
117
+
118
+ class TransitionWithCallbacksTest < Test::Unit::TestCase
119
+ def setup
120
+ @machine = PluginAWeek::StateMachine::Machine.new(Switch, 'state', :initial => 'off')
121
+ @event = PluginAWeek::StateMachine::Event.new(@machine, 'turn_on')
122
+ @transition = PluginAWeek::StateMachine::Transition.new(@event, 'off', 'on')
123
+ @record = create_switch(:state => 'off')
124
+
125
+ Switch.define_callbacks :before_exit_state_off, :before_enter_state_on, :after_exit_state_off, :after_enter_state_on
126
+ end
127
+
128
+ def test_should_not_perform_if_before_exit_callback_fails
129
+ Switch.before_exit_state_off Proc.new {|record| false}
130
+ Switch.before_enter_state_on Proc.new {|record| record.callbacks << 'before_enter'; true}
131
+ Switch.after_exit_state_off Proc.new {|record| record.callbacks << 'after_exit'; true}
132
+ Switch.after_enter_state_on Proc.new {|record| record.callbacks << 'after_enter'; true}
133
+
134
+ assert !@transition.perform(@record)
135
+ assert_equal %w(), @record.callbacks
136
+ end
137
+
138
+ def test_should_not_perform_if_before_enter_callback_fails
139
+ Switch.before_exit_state_off Proc.new {|record| record.callbacks << 'before_exit'; true}
140
+ Switch.before_enter_state_on Proc.new {|record| false}
141
+ Switch.after_exit_state_off Proc.new {|record| record.callbacks << 'after_exit'; true}
142
+ Switch.after_enter_state_on Proc.new {|record| record.callbacks << 'after_enter'; true}
143
+
144
+ assert !@transition.perform(@record)
145
+ assert_equal %w(before_exit), @record.callbacks
146
+ end
147
+
148
+ def test_should_not_perform_if_after_exit_callback_fails
149
+ Switch.before_exit_state_off Proc.new {|record| record.callbacks << 'before_exit'; true}
150
+ Switch.before_enter_state_on Proc.new {|record| record.callbacks << 'before_enter'; true}
151
+ Switch.after_exit_state_off Proc.new {|record| false}
152
+ Switch.after_enter_state_on Proc.new {|record| record.callbacks << 'after_enter'; true}
153
+
154
+ assert !@transition.perform(@record)
155
+ assert_equal %w(before_exit before_enter), @record.callbacks
156
+ end
157
+
158
+ def test_should_not_perform_if_after_enter_callback_fails
159
+ Switch.before_exit_state_off Proc.new {|record| record.callbacks << 'before_exit'; true}
160
+ Switch.before_enter_state_on Proc.new {|record| record.callbacks << 'before_enter'; true}
161
+ Switch.after_exit_state_off Proc.new {|record| record.callbacks << 'after_exit'; true}
162
+ Switch.after_enter_state_on Proc.new {|record| false}
163
+
164
+ assert !@transition.perform(@record)
165
+ assert_equal %w(before_exit before_enter after_exit), @record.callbacks
166
+ end
167
+
168
+ def test_should_perform_if_all_callbacks_are_successful
169
+ Switch.before_exit_state_off Proc.new {|record| record.callbacks << 'before_exit'; true}
170
+ Switch.before_enter_state_on Proc.new {|record| record.callbacks << 'before_enter'; true}
171
+ Switch.after_exit_state_off Proc.new {|record| record.callbacks << 'after_exit'; true}
172
+ Switch.after_enter_state_on Proc.new {|record| record.callbacks << 'after_enter'; true}
173
+
174
+ assert @transition.perform(@record)
175
+ assert_equal %w(before_exit before_enter after_exit after_enter), @record.callbacks
176
+ end
177
+
178
+ def teardown
179
+ Switch.class_eval do
180
+ @before_exit_state_off_callbacks = nil
181
+ @before_enter_state_on_callbacks = nil
182
+ @after_exit_state_off_callbacks = nil
183
+ @after_enter_state_on_callbacks = nil
184
+ end
185
+ end
186
+ end
187
+
188
+ class TransitionWithoutFromStateAndCallbacksTest < Test::Unit::TestCase
189
+ def setup
190
+ @machine = PluginAWeek::StateMachine::Machine.new(Switch, 'state', :initial => 'off')
191
+ @event = PluginAWeek::StateMachine::Event.new(@machine, 'turn_on')
192
+ @transition = PluginAWeek::StateMachine::Transition.new(@event, nil, 'on')
193
+ @record = create_switch(:state => 'off')
194
+
195
+ Switch.define_callbacks :before_exit_state_off, :before_enter_state_on, :after_exit_state_off, :after_enter_state_on
196
+ end
197
+
198
+ def test_should_not_perform_if_before_exit_callback_fails
199
+ Switch.before_exit_state_off Proc.new {|record| false}
200
+ Switch.before_enter_state_on Proc.new {|record| record.callbacks << 'before_enter'; true}
201
+ Switch.after_exit_state_off Proc.new {|record| record.callbacks << 'after_exit'; true}
202
+ Switch.after_enter_state_on Proc.new {|record| record.callbacks << 'after_enter'; true}
203
+
204
+ assert !@transition.perform(@record)
205
+ assert_equal %w(), @record.callbacks
206
+ end
207
+
208
+ def test_should_not_perform_if_before_enter_callback_fails
209
+ Switch.before_exit_state_off Proc.new {|record| record.callbacks << 'before_exit'; true}
210
+ Switch.before_enter_state_on Proc.new {|record| false}
211
+ Switch.after_exit_state_off Proc.new {|record| record.callbacks << 'after_exit'; true}
212
+ Switch.after_enter_state_on Proc.new {|record| record.callbacks << 'after_enter'; true}
213
+
214
+ assert !@transition.perform(@record)
215
+ assert_equal %w(before_exit), @record.callbacks
216
+ end
217
+
218
+ def test_should_not_perform_if_after_exit_callback_fails
219
+ Switch.before_exit_state_off Proc.new {|record| record.callbacks << 'before_exit'; true}
220
+ Switch.before_enter_state_on Proc.new {|record| record.callbacks << 'before_enter'; true}
221
+ Switch.after_exit_state_off Proc.new {|record| false}
222
+ Switch.after_enter_state_on Proc.new {|record| record.callbacks << 'after_enter'; true}
223
+
224
+ assert !@transition.perform(@record)
225
+ assert_equal %w(before_exit before_enter), @record.callbacks
226
+ end
227
+
228
+ def test_should_not_perform_if_after_enter_callback_fails
229
+ Switch.before_exit_state_off Proc.new {|record| record.callbacks << 'before_exit'; true}
230
+ Switch.before_enter_state_on Proc.new {|record| record.callbacks << 'before_enter'; true}
231
+ Switch.after_exit_state_off Proc.new {|record| record.callbacks << 'after_exit'; true}
232
+ Switch.after_enter_state_on Proc.new {|record| false}
233
+
234
+ assert !@transition.perform(@record)
235
+ assert_equal %w(before_exit before_enter after_exit), @record.callbacks
236
+ end
237
+
238
+ def test_should_perform_if_all_callbacks_are_successful
239
+ Switch.before_exit_state_off Proc.new {|record| record.callbacks << 'before_exit'; true}
240
+ Switch.before_enter_state_on Proc.new {|record| record.callbacks << 'before_enter'; true}
241
+ Switch.after_exit_state_off Proc.new {|record| record.callbacks << 'after_exit'; true}
242
+ Switch.after_enter_state_on Proc.new {|record| record.callbacks << 'after_enter'; true}
243
+
244
+ assert @transition.perform(@record)
245
+ assert_equal %w(before_exit before_enter after_exit after_enter), @record.callbacks
246
+ end
247
+
248
+ def teardown
249
+ Switch.class_eval do
250
+ @before_exit_state_off_callbacks = nil
251
+ @before_enter_state_on_callbacks = nil
252
+ @after_exit_state_off_callbacks = nil
253
+ @after_enter_state_on_callbacks = nil
254
+ end
255
+ end
256
+ end
257
+
258
+ class TransitionWithLoopbackAndCallbacksTest < Test::Unit::TestCase
259
+ def setup
260
+ @machine = PluginAWeek::StateMachine::Machine.new(Switch, 'state', :initial => 'off')
261
+ @event = PluginAWeek::StateMachine::Event.new(@machine, 'turn_on')
262
+ @transition = PluginAWeek::StateMachine::Transition.new(@event, 'on', 'on')
263
+ @record = create_switch(:state => 'on')
264
+
265
+ Switch.define_callbacks :before_exit_state_off, :before_enter_state_on, :after_exit_state_off, :after_enter_state_on
266
+ Switch.before_exit_state_off Proc.new {|record| record.callbacks << 'before_exit'; true}
267
+ Switch.before_enter_state_on Proc.new {|record| record.callbacks << 'before_enter'; true}
268
+ Switch.after_exit_state_off Proc.new {|record| record.callbacks << 'after_exit'; true}
269
+ Switch.after_enter_state_on Proc.new {|record| record.callbacks << 'after_enter'; true}
270
+
271
+ assert @transition.perform(@record)
272
+ end
273
+
274
+ def test_should_not_run_before_exit_callbacks
275
+ assert !@record.callbacks.include?('before_exit')
276
+ end
277
+
278
+ def test_should_not_run_before_enter_callbacks
279
+ assert !@record.callbacks.include?('before_enter')
280
+ end
281
+
282
+ def test_should_not_run_after_exit_callbacks
283
+ assert !@record.callbacks.include?('after_exit')
284
+ end
285
+
286
+ def test_should_not_run_after_enter_callbacks
287
+ assert !@record.callbacks.include?('after_enter')
288
+ end
289
+
290
+ def teardown
291
+ Switch.class_eval do
292
+ @before_exit_state_off_callbacks = nil
293
+ @before_enter_state_on_callbacks = nil
294
+ @after_exit_state_off_callbacks = nil
295
+ @after_enter_state_on_callbacks = nil
296
+ end
297
+ end
298
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: state_machine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Pfeifer
8
+ autorequire: state_machine
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-05-05 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: aaron@pluginaweek.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/state_machine.rb
26
+ - lib/state_machine
27
+ - lib/state_machine/machine.rb
28
+ - lib/state_machine/event.rb
29
+ - lib/state_machine/transition.rb
30
+ - test/factory.rb
31
+ - test/app_root
32
+ - test/app_root/db
33
+ - test/app_root/db/migrate
34
+ - test/app_root/db/migrate/004_create_vehicles.rb
35
+ - test/app_root/db/migrate/003_create_highways.rb
36
+ - test/app_root/db/migrate/002_create_auto_shops.rb
37
+ - test/app_root/db/migrate/001_create_switches.rb
38
+ - test/app_root/app
39
+ - test/app_root/app/models
40
+ - test/app_root/app/models/auto_shop.rb
41
+ - test/app_root/app/models/switch.rb
42
+ - test/app_root/app/models/vehicle.rb
43
+ - test/app_root/app/models/motorcycle.rb
44
+ - test/app_root/app/models/toggle_switch.rb
45
+ - test/app_root/app/models/car.rb
46
+ - test/app_root/app/models/highway.rb
47
+ - test/functional
48
+ - test/functional/state_machine_test.rb
49
+ - test/test_helper.rb
50
+ - test/unit
51
+ - test/unit/event_test.rb
52
+ - test/unit/machine_test.rb
53
+ - test/unit/transition_test.rb
54
+ - test/unit/state_machine_test.rb
55
+ - CHANGELOG
56
+ - init.rb
57
+ - MIT-LICENSE
58
+ - Rakefile
59
+ - README
60
+ has_rdoc: true
61
+ homepage: http://www.pluginaweek.org
62
+ post_install_message:
63
+ rdoc_options: []
64
+
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.1.0
83
+ signing_key:
84
+ specification_version: 2
85
+ summary: Adds support for creating state machines for attributes within a model
86
+ test_files:
87
+ - test/functional/state_machine_test.rb
88
+ - test/unit/event_test.rb
89
+ - test/unit/machine_test.rb
90
+ - test/unit/transition_test.rb
91
+ - test/unit/state_machine_test.rb