state_machine 0.1.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.
@@ -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