state_machine 0.3.1 → 0.4.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 +26 -0
- data/README.rdoc +254 -46
- data/Rakefile +29 -3
- data/examples/AutoShop_state.png +0 -0
- data/examples/Car_state.jpg +0 -0
- data/examples/Vehicle_state.png +0 -0
- data/lib/state_machine.rb +161 -116
- data/lib/state_machine/assertions.rb +21 -0
- data/lib/state_machine/callback.rb +168 -0
- data/lib/state_machine/eval_helpers.rb +67 -0
- data/lib/state_machine/event.rb +135 -101
- data/lib/state_machine/extensions.rb +83 -0
- data/lib/state_machine/guard.rb +115 -0
- data/lib/state_machine/integrations/active_record.rb +242 -0
- data/lib/state_machine/integrations/data_mapper.rb +198 -0
- data/lib/state_machine/integrations/data_mapper/observer.rb +153 -0
- data/lib/state_machine/integrations/sequel.rb +169 -0
- data/lib/state_machine/machine.rb +746 -352
- data/lib/state_machine/transition.rb +104 -212
- data/test/active_record.log +34865 -0
- data/test/classes/switch.rb +11 -0
- data/test/data_mapper.log +14015 -0
- data/test/functional/state_machine_test.rb +249 -15
- data/test/sequel.log +3835 -0
- data/test/test_helper.rb +3 -12
- data/test/unit/assertions_test.rb +13 -0
- data/test/unit/callback_test.rb +189 -0
- data/test/unit/eval_helpers_test.rb +92 -0
- data/test/unit/event_test.rb +247 -113
- data/test/unit/guard_test.rb +420 -0
- data/test/unit/integrations/active_record_test.rb +515 -0
- data/test/unit/integrations/data_mapper_test.rb +407 -0
- data/test/unit/integrations/sequel_test.rb +244 -0
- data/test/unit/invalid_transition_test.rb +1 -1
- data/test/unit/machine_test.rb +1056 -98
- data/test/unit/state_machine_test.rb +14 -113
- data/test/unit/transition_test.rb +269 -495
- metadata +44 -30
- data/test/app_root/app/models/auto_shop.rb +0 -34
- data/test/app_root/app/models/car.rb +0 -19
- data/test/app_root/app/models/highway.rb +0 -3
- data/test/app_root/app/models/motorcycle.rb +0 -3
- data/test/app_root/app/models/switch.rb +0 -23
- data/test/app_root/app/models/switch_observer.rb +0 -20
- data/test/app_root/app/models/toggle_switch.rb +0 -2
- data/test/app_root/app/models/vehicle.rb +0 -78
- data/test/app_root/config/environment.rb +0 -7
- data/test/app_root/db/migrate/001_create_switches.rb +0 -12
- data/test/app_root/db/migrate/002_create_auto_shops.rb +0 -13
- data/test/app_root/db/migrate/003_create_highways.rb +0 -11
- data/test/app_root/db/migrate/004_create_vehicles.rb +0 -16
- data/test/factory.rb +0 -77
data/test/test_helper.rb
CHANGED
@@ -1,13 +1,4 @@
|
|
1
|
-
|
2
|
-
$:.unshift("#{File.dirname(__FILE__)}/../../plugin_test_helper/lib")
|
3
|
-
require 'rubygems'
|
4
|
-
require 'plugin_test_helper'
|
1
|
+
require 'test/unit'
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# Mixin the factory helper
|
10
|
-
require File.expand_path("#{File.dirname(__FILE__)}/factory")
|
11
|
-
class Test::Unit::TestCase #:nodoc:
|
12
|
-
include Factory
|
13
|
-
end
|
3
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
4
|
+
require File.dirname(__FILE__) + '/../init'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class AssertionsTest < Test::Unit::TestCase
|
4
|
+
include StateMachine::Assertions
|
5
|
+
|
6
|
+
def test_should_not_raise_exception_if_key_is_valid
|
7
|
+
assert_nothing_raised { assert_valid_keys({:name => 'foo', :value => 'bar'}, :name, :value, :force) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_should_raise_exception_if_key_is_invalid
|
11
|
+
assert_raise(ArgumentError) { assert_valid_keys({:name => 'foo', :value => 'bar', :invalid => true}, :name, :value, :force) }
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class CallbackTest < Test::Unit::TestCase
|
4
|
+
def test_should_raise_exception_if_do_option_not_specified
|
5
|
+
assert_raise(ArgumentError) { StateMachine::Callback.new }
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_should_not_raise_exception_if_do_option_specified
|
9
|
+
assert_nothing_raised { StateMachine::Callback.new(:do => :run) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_should_raise_exception_if_invalid_option_specified
|
13
|
+
assert_raise(ArgumentError) { StateMachine::Callback.new(:do => :run, :invalid => true) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_should_not_bind_to_objects
|
17
|
+
assert !StateMachine::Callback.bind_to_object
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class CallbackByDefaultTest < Test::Unit::TestCase
|
22
|
+
def setup
|
23
|
+
@object = Object.new
|
24
|
+
@method = lambda {|*args| args.unshift(self)}
|
25
|
+
@callback = StateMachine::Callback.new(:do => @method)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_should_not_have_a_terminator
|
29
|
+
assert_nil @callback.terminator
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_should_have_a_guard_with_no_requirements
|
33
|
+
expected = {}
|
34
|
+
assert_equal expected, @callback.guard.requirements
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_should_not_bind_to_the_object
|
38
|
+
assert_equal [self, @object], @callback.call(@object)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_should_not_have_any_known_states
|
42
|
+
assert_equal [], @callback.known_states
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class CallbackWithOnlyMethodTest < Test::Unit::TestCase
|
47
|
+
def setup
|
48
|
+
@object = Object.new
|
49
|
+
@callback = StateMachine::Callback.new(lambda {true})
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_should_call_with_empty_context
|
53
|
+
assert @callback.call(@object)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class CallbackWithRequirementsTest < Test::Unit::TestCase
|
58
|
+
def setup
|
59
|
+
@object = Object.new
|
60
|
+
@callback = StateMachine::Callback.new(:from => 'off', :to => 'on', :on => 'turn_on', :do => lambda {true})
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_call_with_empty_context
|
64
|
+
assert @callback.call(@object, {})
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_should_not_call_if_from_not_included
|
68
|
+
assert !@callback.call(@object, :from => 'on')
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_should_not_call_if_to_not_included
|
72
|
+
assert !@callback.call(@object, :to => 'off')
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_should_not_call_if_on_not_included
|
76
|
+
assert !@callback.call(@object, :on => 'turn_off')
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_should_call_if_all_requirements_met
|
80
|
+
assert @callback.call(@object, :from => 'off', :to => 'on', :on => 'turn_on')
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_should_include_in_known_states
|
84
|
+
assert_equal %w(off on), @callback.known_states.sort
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class CallbackWithIfConditionalTest < Test::Unit::TestCase
|
89
|
+
def setup
|
90
|
+
@object = Object.new
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_should_call_if_true
|
94
|
+
callback = StateMachine::Callback.new(:if => lambda {true}, :do => lambda {true})
|
95
|
+
assert callback.call(@object)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_should_not_call_if_false
|
99
|
+
callback = StateMachine::Callback.new(:if => lambda {false}, :do => lambda {true})
|
100
|
+
assert !callback.call(@object)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class CallbackWithUnlessConditionalTest < Test::Unit::TestCase
|
105
|
+
def setup
|
106
|
+
@object = Object.new
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_should_call_if_false
|
110
|
+
callback = StateMachine::Callback.new(:unless => lambda {false}, :do => lambda {true})
|
111
|
+
assert callback.call(@object)
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_should_not_call_if_true
|
115
|
+
callback = StateMachine::Callback.new(:unless => lambda {true}, :do => lambda {true})
|
116
|
+
assert !callback.call(@object)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class CallbackWithoutTerminatorTest < Test::Unit::TestCase
|
121
|
+
def setup
|
122
|
+
@object = Object.new
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_should_not_halt_if_result_is_false
|
126
|
+
callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => nil)
|
127
|
+
assert_nothing_thrown { callback.call(@object) }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
class CallbackWithTerminatorTest < Test::Unit::TestCase
|
132
|
+
def setup
|
133
|
+
@object = Object.new
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_should_not_halt_if_terminator_does_not_match
|
137
|
+
callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => lambda {|result| false})
|
138
|
+
assert_nothing_thrown { callback.call(@object) }
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_should_halt_if_terminator_matches
|
142
|
+
callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => lambda {|result| true})
|
143
|
+
assert_throws(:halt) { callback.call(@object) }
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
class CallbackWithoutArgumentsTest < Test::Unit::TestCase
|
148
|
+
def setup
|
149
|
+
@object = Object.new
|
150
|
+
@callback = StateMachine::Callback.new(:do => lambda {|object| object})
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_should_call_method_with_object_as_argument
|
154
|
+
assert_equal @object, @callback.call(@object, {}, 1, 2, 3)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
class CallbackWithArgumentsTest < Test::Unit::TestCase
|
159
|
+
def setup
|
160
|
+
@object = Object.new
|
161
|
+
@callback = StateMachine::Callback.new(:do => lambda {|*args| args})
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_should_call_method_with_all_arguments
|
165
|
+
assert_equal [@object, 1, 2, 3], @callback.call(@object, {}, 1, 2, 3)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
class CallbackWithUnboundObjectTest < Test::Unit::TestCase
|
170
|
+
def setup
|
171
|
+
@object = Object.new
|
172
|
+
@callback = StateMachine::Callback.new(:do => lambda {|*args| args.unshift(self)})
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_should_call_method_outside_the_context_of_the_object
|
176
|
+
assert_equal [self, @object, 1, 2, 3], @callback.call(@object, {}, 1, 2, 3)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
class CallbackWithBoundObjectTest < Test::Unit::TestCase
|
181
|
+
def setup
|
182
|
+
@object = Object.new
|
183
|
+
@callback = StateMachine::Callback.new(:do => lambda {|*args| args.unshift(self)}, :bind_to_object => true)
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_should_call_method_within_the_context_of_the_object
|
187
|
+
assert_equal [@object, 1, 2, 3], @callback.call(@object, {}, 1, 2, 3)
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class EvalHelperTest < Test::Unit::TestCase
|
4
|
+
include StateMachine::EvalHelpers
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@object = Object.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_should_raise_exception_if_method_is_not_symbol_string_or_proc
|
11
|
+
assert_raise(ArgumentError) { evaluate_method(@object, 1) }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class EvalHelpersSymbolTest < Test::Unit::TestCase
|
16
|
+
include StateMachine::EvalHelpers
|
17
|
+
|
18
|
+
def setup
|
19
|
+
class << (@object = Object.new)
|
20
|
+
def callback
|
21
|
+
true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_should_call_method_on_object_with_no_arguments
|
27
|
+
assert evaluate_method(@object, :callback, 1, 2, 3)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class EvalHelperSymbolWithArgumentsTest < Test::Unit::TestCase
|
32
|
+
include StateMachine::EvalHelpers
|
33
|
+
|
34
|
+
def setup
|
35
|
+
class << (@object = Object.new)
|
36
|
+
def callback(*args)
|
37
|
+
args
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_should_call_method_with_all_arguments
|
43
|
+
assert_equal [1, 2, 3], evaluate_method(@object, :callback, 1, 2, 3)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class EvalHelperStringTest < Test::Unit::TestCase
|
48
|
+
include StateMachine::EvalHelpers
|
49
|
+
|
50
|
+
def setup
|
51
|
+
@object = Object.new
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_should_evaluate_string
|
55
|
+
assert_equal 1, evaluate_method(@object, '1')
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_should_evaluate_string_within_object_context
|
59
|
+
@object.instance_variable_set('@value', 1)
|
60
|
+
assert_equal 1, evaluate_method(@object, '@value')
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_ignore_additional_arguments
|
64
|
+
assert_equal 1, evaluate_method(@object, '1', 2, 3, 4)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class EvalHelperProcTest < Test::Unit::TestCase
|
69
|
+
include StateMachine::EvalHelpers
|
70
|
+
|
71
|
+
def setup
|
72
|
+
@object = Object.new
|
73
|
+
@proc = lambda {|obj| obj}
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_should_call_proc_with_object_as_argument
|
77
|
+
assert_equal @object, evaluate_method(@object, @proc, 1, 2, 3)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class EvalHelperProcWithArgumentsTest < Test::Unit::TestCase
|
82
|
+
include StateMachine::EvalHelpers
|
83
|
+
|
84
|
+
def setup
|
85
|
+
@object = Object.new
|
86
|
+
@proc = lambda {|*args| args}
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_should_call_method_with_all_arguments
|
90
|
+
assert_equal [@object, 1, 2, 3], evaluate_method(@object, @proc, 1, 2, 3)
|
91
|
+
end
|
92
|
+
end
|
data/test/unit/event_test.rb
CHANGED
@@ -2,10 +2,22 @@ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
|
2
2
|
|
3
3
|
class EventTest < Test::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
@machine =
|
6
|
-
@event =
|
5
|
+
@machine = StateMachine::Machine.new(Class.new)
|
6
|
+
@event = StateMachine::Event.new(@machine, 'turn_on')
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_should_raise_exception_if_invalid_option_specified
|
10
|
+
assert_raise(ArgumentError) {StateMachine::Event.new(@machine, 'turn_on', :invalid => true)}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class EventByDefaultTest < Test::Unit::TestCase
|
15
|
+
def setup
|
16
|
+
@klass = Class.new
|
17
|
+
@machine = StateMachine::Machine.new(@klass)
|
18
|
+
@event = StateMachine::Event.new(@machine, 'turn_on')
|
7
19
|
|
8
|
-
@
|
20
|
+
@object = @klass.new
|
9
21
|
end
|
10
22
|
|
11
23
|
def test_should_have_a_machine
|
@@ -16,49 +28,77 @@ class EventTest < Test::Unit::TestCase
|
|
16
28
|
assert_equal 'turn_on', @event.name
|
17
29
|
end
|
18
30
|
|
19
|
-
def
|
20
|
-
assert @event.
|
31
|
+
def test_should_not_have_any_guards
|
32
|
+
assert @event.guards.empty?
|
21
33
|
end
|
22
34
|
|
23
|
-
def
|
24
|
-
assert @
|
35
|
+
def test_should_have_no_known_states
|
36
|
+
assert @event.known_states.empty?
|
25
37
|
end
|
26
38
|
|
27
|
-
def
|
28
|
-
assert
|
39
|
+
def test_should_not_be_able_to_fire
|
40
|
+
assert !@event.can_fire?(@object)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_should_not_have_a_next_transition
|
44
|
+
assert_nil @event.next_transition(@object)
|
29
45
|
end
|
30
46
|
|
31
47
|
def test_should_define_an_event_predicate_on_the_owner_class
|
32
|
-
assert @
|
48
|
+
assert @object.respond_to?(:can_turn_on?)
|
33
49
|
end
|
34
50
|
|
35
|
-
def
|
36
|
-
|
51
|
+
def test_should_define_an_event_transition_accessor_on_the_owner_class
|
52
|
+
assert @object.respond_to?(:next_turn_on_transition)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_should_define_an_event_action_on_the_owner_class
|
56
|
+
assert @object.respond_to?(:turn_on)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_should_define_an_event_bang_action_on_the_owner_class
|
60
|
+
assert @object.respond_to?(:turn_on!)
|
37
61
|
end
|
38
62
|
end
|
39
63
|
|
40
|
-
class
|
64
|
+
class EventTransitionsTest < Test::Unit::TestCase
|
41
65
|
def setup
|
42
|
-
@machine =
|
43
|
-
@event =
|
66
|
+
@machine = StateMachine::Machine.new(Class.new)
|
67
|
+
@event = StateMachine::Event.new(@machine, 'turn_on')
|
44
68
|
end
|
45
69
|
|
46
70
|
def test_should_raise_exception_if_invalid_option_specified
|
47
71
|
assert_raise(ArgumentError) {@event.transition(:invalid => true)}
|
48
72
|
end
|
49
73
|
|
50
|
-
def
|
51
|
-
|
74
|
+
def test_should_not_raise_exception_if_to_option_not_specified
|
75
|
+
assert_nothing_raised {@event.transition(:from => 'off')}
|
52
76
|
end
|
53
77
|
|
54
78
|
def test_should_not_raise_exception_if_from_option_not_specified
|
55
79
|
assert_nothing_raised {@event.transition(:to => 'on')}
|
56
80
|
end
|
57
81
|
|
82
|
+
def test_should_not_allow_on_option
|
83
|
+
assert_raise(ArgumentError) {@event.transition(:on => 'turn_on')}
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_should_not_allow_except_to_option
|
87
|
+
assert_raise(ArgumentError) {@event.transition(:except_to => 'off')}
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_should_not_allow_except_on_option
|
91
|
+
assert_raise(ArgumentError) {@event.transition(:except_on => 'turn_on')}
|
92
|
+
end
|
93
|
+
|
58
94
|
def test_should_allow_transitioning_without_a_from_state
|
59
95
|
assert @event.transition(:to => 'on')
|
60
96
|
end
|
61
97
|
|
98
|
+
def test_should_allow_transitioning_without_a_to_state
|
99
|
+
assert @event.transition(:from => 'off')
|
100
|
+
end
|
101
|
+
|
62
102
|
def test_should_allow_transitioning_from_a_single_state
|
63
103
|
assert @event.transition(:to => 'on', :from => 'off')
|
64
104
|
end
|
@@ -68,168 +108,262 @@ class EventDefiningTransitionsTest < Test::Unit::TestCase
|
|
68
108
|
end
|
69
109
|
|
70
110
|
def test_should_have_transitions
|
71
|
-
|
72
|
-
assert_equal [
|
111
|
+
guard = @event.transition(:to => 'on')
|
112
|
+
assert_equal [guard], @event.guards
|
73
113
|
end
|
74
114
|
end
|
75
115
|
|
76
116
|
class EventAfterBeingCopiedTest < Test::Unit::TestCase
|
77
117
|
def setup
|
78
|
-
@machine =
|
79
|
-
@event =
|
118
|
+
@machine = StateMachine::Machine.new(Class.new)
|
119
|
+
@event = StateMachine::Event.new(@machine, 'turn_on')
|
120
|
+
@event.known_states # Call so that it's cached
|
80
121
|
@copied_event = @event.dup
|
81
122
|
end
|
82
123
|
|
83
|
-
def
|
84
|
-
assert_not_same @
|
124
|
+
def test_should_not_have_the_same_collection_of_guards
|
125
|
+
assert_not_same @event.guards, @copied_event.guards
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_should_not_have_the_same_collection_of_known_states
|
129
|
+
assert_not_same @event.known_states, @copied_event.known_states
|
85
130
|
end
|
86
131
|
end
|
87
132
|
|
88
133
|
class EventWithoutTransitionsTest < Test::Unit::TestCase
|
89
134
|
def setup
|
90
|
-
@
|
91
|
-
@
|
92
|
-
@
|
135
|
+
@klass = Class.new
|
136
|
+
@machine = StateMachine::Machine.new(@klass)
|
137
|
+
@event = StateMachine::Event.new(@machine, 'turn_on')
|
138
|
+
@object = @klass.new
|
93
139
|
end
|
94
140
|
|
95
141
|
def test_should_not_be_able_to_fire
|
96
|
-
assert !@event.can_fire?(@
|
142
|
+
assert !@event.can_fire?(@object)
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_should_not_have_a_next_transition
|
146
|
+
assert_nil @event.next_transition(@object)
|
97
147
|
end
|
98
148
|
|
99
149
|
def test_should_not_fire
|
100
|
-
assert !@event.fire(@
|
150
|
+
assert !@event.fire(@object)
|
101
151
|
end
|
102
152
|
|
103
153
|
def test_should_not_change_the_current_state
|
104
|
-
@event.fire(@
|
105
|
-
|
154
|
+
@event.fire(@object)
|
155
|
+
assert_nil @object.state
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
class EventWithTransitionsTest < Test::Unit::TestCase
|
160
|
+
def setup
|
161
|
+
@klass = Class.new
|
162
|
+
@machine = StateMachine::Machine.new(@klass)
|
163
|
+
@event = StateMachine::Event.new(@machine, 'turn_on')
|
164
|
+
@event.transition(:to => 'on', :from => 'off')
|
165
|
+
@event.transition(:to => 'on', :except_from => 'maybe')
|
106
166
|
end
|
107
167
|
|
108
|
-
def
|
109
|
-
|
168
|
+
def test_should_include_all_transition_states_in_known_states
|
169
|
+
assert_equal %w(maybe off on), @event.known_states.sort
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_should_include_new_transition_states_after_calling_known_states
|
173
|
+
@event.known_states
|
174
|
+
@event.transition(:to => 'error')
|
175
|
+
|
176
|
+
assert_equal %w(error maybe off on), @event.known_states.sort
|
110
177
|
end
|
111
178
|
end
|
112
179
|
|
113
|
-
class
|
180
|
+
class EventWithoutMatchingTransitionsTest < Test::Unit::TestCase
|
181
|
+
def setup
|
182
|
+
@klass = Class.new
|
183
|
+
@machine = StateMachine::Machine.new(@klass)
|
184
|
+
@event = StateMachine::Event.new(@machine, 'turn_on')
|
185
|
+
@event.transition(:to => 'on', :from => 'off')
|
186
|
+
|
187
|
+
@object = @klass.new
|
188
|
+
@object.state = 'on'
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_should_not_be_able_to_fire
|
192
|
+
assert !@event.can_fire?(@object)
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_should_not_have_a_next_transition
|
196
|
+
assert_nil @event.next_transition(@object)
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_should_not_fire
|
200
|
+
assert !@event.fire(@object)
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_should_not_change_the_current_state
|
204
|
+
@event.fire(@object)
|
205
|
+
assert_equal 'on', @object.state
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
class EventWithMatchingDisabledTransitionsTest < Test::Unit::TestCase
|
114
210
|
def setup
|
115
|
-
@
|
116
|
-
@
|
117
|
-
@event
|
118
|
-
@
|
211
|
+
@klass = Class.new
|
212
|
+
@machine = StateMachine::Machine.new(@klass)
|
213
|
+
@event = StateMachine::Event.new(@machine, 'turn_on')
|
214
|
+
@event.transition(:to => 'on', :from => 'off', :if => lambda {false})
|
215
|
+
|
216
|
+
@object = @klass.new
|
217
|
+
@object.state = 'off'
|
119
218
|
end
|
120
219
|
|
121
|
-
def
|
122
|
-
assert !@event.can_fire?(@
|
220
|
+
def test_should_not_be_able_to_fire
|
221
|
+
assert !@event.can_fire?(@object)
|
123
222
|
end
|
124
223
|
|
125
|
-
def
|
126
|
-
|
127
|
-
assert_equal 'off', @switch.state
|
224
|
+
def test_should_not_have_a_next_transition
|
225
|
+
assert_nil @event.next_transition(@object)
|
128
226
|
end
|
129
227
|
|
130
|
-
def
|
131
|
-
|
132
|
-
assert_equal 'off', @switch.state
|
228
|
+
def test_should_not_fire
|
229
|
+
assert !@event.fire(@object)
|
133
230
|
end
|
134
231
|
|
135
|
-
def
|
136
|
-
@event.
|
137
|
-
|
232
|
+
def test_should_not_change_the_current_state
|
233
|
+
@event.fire(@object)
|
234
|
+
assert_equal 'off', @object.state
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
class EventWithMatchingEnabledTransitionsTest < Test::Unit::TestCase
|
239
|
+
def setup
|
240
|
+
@klass = Class.new
|
241
|
+
@machine = StateMachine::Machine.new(@klass)
|
242
|
+
@event = StateMachine::Event.new(@machine, 'turn_on')
|
243
|
+
@event.transition(:to => 'on', :from => 'off')
|
244
|
+
|
245
|
+
@object = @klass.new
|
246
|
+
@object.state = 'off'
|
138
247
|
end
|
139
248
|
|
140
|
-
def
|
141
|
-
@event.
|
142
|
-
assert @event.fire(@switch)
|
143
|
-
assert_equal 'on', @switch.state
|
249
|
+
def test_should_be_able_to_fire
|
250
|
+
assert @event.can_fire?(@object)
|
144
251
|
end
|
145
252
|
|
146
|
-
def
|
147
|
-
@event.
|
148
|
-
|
149
|
-
assert_equal '
|
253
|
+
def test_should_have_a_next_transition
|
254
|
+
transition = @event.next_transition(@object)
|
255
|
+
assert_not_nil transition
|
256
|
+
assert_equal 'off', transition.from
|
257
|
+
assert_equal 'on', transition.to
|
258
|
+
assert_equal 'turn_on', transition.event
|
150
259
|
end
|
151
260
|
|
152
|
-
def
|
153
|
-
@event.
|
154
|
-
assert @event.fire(@switch)
|
155
|
-
assert_equal 'on', @switch.state
|
261
|
+
def test_should_fire
|
262
|
+
assert @event.fire(@object)
|
156
263
|
end
|
157
264
|
|
158
|
-
def
|
159
|
-
@event.
|
160
|
-
@
|
161
|
-
|
265
|
+
def test_should_change_the_current_state
|
266
|
+
@event.fire(@object)
|
267
|
+
assert_equal 'on', @object.state
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
class EventWithTransitionWithoutToStateTest < Test::Unit::TestCase
|
272
|
+
def setup
|
273
|
+
@klass = Class.new
|
274
|
+
@machine = StateMachine::Machine.new(@klass)
|
275
|
+
@event = StateMachine::Event.new(@machine, 'turn_off')
|
276
|
+
@event.transition(:from => 'off')
|
162
277
|
|
163
|
-
@
|
164
|
-
|
278
|
+
@object = @klass.new
|
279
|
+
@object.state = 'off'
|
280
|
+
end
|
281
|
+
|
282
|
+
def test_should_be_able_to_fire
|
283
|
+
assert @event.can_fire?(@object)
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_should_have_a_next_transition
|
287
|
+
transition = @event.next_transition(@object)
|
288
|
+
assert_not_nil transition
|
289
|
+
assert_equal 'off', transition.from
|
290
|
+
assert_equal 'off', transition.to
|
291
|
+
assert_equal 'turn_off', transition.event
|
165
292
|
end
|
166
293
|
|
167
|
-
def
|
168
|
-
@event.
|
169
|
-
@switch.fail_validation = true
|
170
|
-
assert_raise(ActiveRecord::RecordInvalid) {@event.fire!(@switch)}
|
294
|
+
def test_should_fire
|
295
|
+
assert @event.fire(@object)
|
171
296
|
end
|
172
297
|
|
173
|
-
def
|
174
|
-
@event.
|
175
|
-
@
|
176
|
-
|
298
|
+
def test_should_not_change_the_current_state
|
299
|
+
@event.fire(@object)
|
300
|
+
assert_equal 'off', @object.state
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
class EventWithTransitionWithDynamicToStateTest < Test::Unit::TestCase
|
305
|
+
def setup
|
306
|
+
@klass = Class.new
|
307
|
+
@machine = StateMachine::Machine.new(@klass)
|
308
|
+
@event = StateMachine::Event.new(@machine, 'turn_on')
|
309
|
+
@event.transition(:to => lambda {'on'}, :from => 'off')
|
177
310
|
|
178
|
-
@
|
179
|
-
|
311
|
+
@object = @klass.new
|
312
|
+
@object.state = 'off'
|
313
|
+
end
|
314
|
+
|
315
|
+
def test_should_be_able_to_fire
|
316
|
+
assert @event.can_fire?(@object)
|
317
|
+
end
|
318
|
+
|
319
|
+
def test_should_have_a_next_transition
|
320
|
+
transition = @event.next_transition(@object)
|
321
|
+
assert_not_nil transition
|
322
|
+
assert_equal 'off', transition.from
|
323
|
+
assert_equal 'on', transition.to
|
324
|
+
assert_equal 'turn_on', transition.event
|
180
325
|
end
|
181
326
|
|
182
|
-
def
|
183
|
-
@event.
|
184
|
-
@switch.fail_save = true
|
185
|
-
assert_raise(ActiveRecord::RecordNotSaved) {@event.fire!(@switch)}
|
327
|
+
def test_should_fire
|
328
|
+
assert @event.fire(@object)
|
186
329
|
end
|
187
330
|
|
188
|
-
def
|
189
|
-
@event.
|
190
|
-
|
191
|
-
assert_equal 'on', @switch.state
|
331
|
+
def test_should_change_the_current_state
|
332
|
+
@event.fire(@object)
|
333
|
+
assert_equal 'on', @object.state
|
192
334
|
end
|
193
335
|
end
|
194
336
|
|
195
|
-
class
|
337
|
+
class EventWithMultipleTransitionsTest < Test::Unit::TestCase
|
196
338
|
def setup
|
197
|
-
@
|
198
|
-
@
|
199
|
-
@event
|
200
|
-
@
|
339
|
+
@klass = Class.new
|
340
|
+
@machine = StateMachine::Machine.new(@klass)
|
341
|
+
@event = StateMachine::Event.new(@machine, 'turn_on')
|
342
|
+
@event.transition(:to => 'on', :from => 'on')
|
343
|
+
@event.transition(:to => 'on', :from => 'off') # This one should get used
|
201
344
|
|
202
|
-
|
345
|
+
@object = @klass.new
|
346
|
+
@object.state = 'off'
|
203
347
|
end
|
204
348
|
|
205
|
-
def
|
206
|
-
|
207
|
-
assert @event.fire(@switch)
|
208
|
-
assert_equal 'on', @switch.state
|
209
|
-
assert_equal 'pending', Switch.find(:all).last.state
|
349
|
+
def test_should_be_able_to_fire
|
350
|
+
assert @event.can_fire?(@object)
|
210
351
|
end
|
211
352
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
assert_equal
|
217
|
-
|
218
|
-
Switch.destroy_all
|
353
|
+
def test_should_have_a_next_transition
|
354
|
+
transition = @event.next_transition(@object)
|
355
|
+
assert_not_nil transition
|
356
|
+
assert_equal 'off', transition.from
|
357
|
+
assert_equal 'on', transition.to
|
358
|
+
assert_equal 'turn_on', transition.event
|
219
359
|
end
|
220
360
|
|
221
|
-
|
222
|
-
|
223
|
-
Switch.before_transition_state lambda {|record| Switch.create(:state => 'pending'); false}, :from => 'off'
|
224
|
-
assert_raise(PluginAWeek::StateMachine::InvalidTransition) {@event.fire!(@switch)}
|
225
|
-
assert_equal 1, Switch.count
|
226
|
-
ensure
|
227
|
-
Switch.destroy_all
|
361
|
+
def test_should_fire
|
362
|
+
assert @event.fire(@object)
|
228
363
|
end
|
229
364
|
|
230
|
-
def
|
231
|
-
|
232
|
-
|
233
|
-
end
|
365
|
+
def test_should_change_the_current_state
|
366
|
+
@event.fire(@object)
|
367
|
+
assert_equal 'on', @object.state
|
234
368
|
end
|
235
369
|
end
|