state_machine 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|