state_machine 0.5.1 → 0.5.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.
- data/CHANGELOG.rdoc +7 -0
- data/Rakefile +1 -1
- data/lib/state_machine/assertions.rb +16 -0
- data/lib/state_machine/event.rb +7 -4
- data/lib/state_machine/guard.rb +113 -90
- data/lib/state_machine/machine.rb +1 -1
- data/lib/state_machine/matcher.rb +123 -0
- data/lib/state_machine/state.rb +3 -2
- data/test/active_record.log +3480 -20
- data/test/sequel.log +1071 -1
- data/test/unit/assertions_test.rb +27 -1
- data/test/unit/callback_test.rb +4 -3
- data/test/unit/event_test.rb +1 -1
- data/test/unit/guard_test.rb +64 -36
- data/test/unit/integrations/active_record_test.rb +15 -0
- data/test/unit/integrations/data_mapper_test.rb +15 -0
- data/test/unit/integrations/sequel_test.rb +15 -0
- data/test/unit/matcher_test.rb +155 -0
- data/test/unit/state_test.rb +1 -1
- metadata +5 -2
@@ -3,12 +3,38 @@ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
|
3
3
|
class AssertionsTest < Test::Unit::TestCase
|
4
4
|
include StateMachine::Assertions
|
5
5
|
|
6
|
+
def default_test
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class AssertValidKeysTest < AssertionsTest
|
6
11
|
def test_should_not_raise_exception_if_key_is_valid
|
7
12
|
assert_nothing_raised { assert_valid_keys({:name => 'foo', :value => 'bar'}, :name, :value, :force) }
|
8
13
|
end
|
9
14
|
|
10
15
|
def test_should_raise_exception_if_key_is_invalid
|
11
16
|
exception = assert_raise(ArgumentError) { assert_valid_keys({:name => 'foo', :value => 'bar', :invalid => true}, :name, :value, :force) }
|
12
|
-
|
17
|
+
assert_equal 'Invalid key(s): invalid', exception.message
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class AssertExclusiveKeysTest < AssertionsTest
|
22
|
+
def test_should_not_raise_exception_if_no_keys_found
|
23
|
+
assert_nothing_raised { assert_exclusive_keys({:on => :park}, :only, :except) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_should_not_raise_exception_if_one_key_found
|
27
|
+
assert_nothing_raised { assert_exclusive_keys({:only => :parked}, :only, :except) }
|
28
|
+
assert_nothing_raised { assert_exclusive_keys({:except => :parked}, :only, :except) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_raise_exception_if_two_keys_found
|
32
|
+
exception = assert_raise(ArgumentError) { assert_exclusive_keys({:only => :parked, :except => :parked}, :only, :except) }
|
33
|
+
assert_equal 'Conflicting keys: only, except', exception.message
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_raise_exception_if_multiple_keys_found
|
37
|
+
exception = assert_raise(ArgumentError) { assert_exclusive_keys({:only => :parked, :except => :parked, :on => :park}, :only, :except, :with) }
|
38
|
+
assert_equal 'Conflicting keys: only, except', exception.message
|
13
39
|
end
|
14
40
|
end
|
data/test/unit/callback_test.rb
CHANGED
@@ -31,9 +31,10 @@ class CallbackByDefaultTest < Test::Unit::TestCase
|
|
31
31
|
assert_nil @callback.terminator
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
35
|
-
|
36
|
-
assert_equal
|
34
|
+
def test_should_have_a_guard_with_all_matcher_requirements
|
35
|
+
assert_equal StateMachine::AllMatcher.instance, @callback.guard.event_requirement
|
36
|
+
assert_equal StateMachine::AllMatcher.instance, @callback.guard.state_requirement[:from]
|
37
|
+
assert_equal StateMachine::AllMatcher.instance, @callback.guard.state_requirement[:to]
|
37
38
|
end
|
38
39
|
|
39
40
|
def test_should_not_bind_to_the_object
|
data/test/unit/event_test.rb
CHANGED
@@ -64,7 +64,7 @@ class EventTest < Test::Unit::TestCase
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def test_should_use_pretty_inspect
|
67
|
-
assert_match
|
67
|
+
assert_match "#<StateMachine::Event name=:ignite transitions=[:parked => :idling]>", @event.inspect
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
data/test/unit/guard_test.rb
CHANGED
@@ -10,9 +10,12 @@ class GuardTest < Test::Unit::TestCase
|
|
10
10
|
assert_equal 'Invalid key(s): invalid', exception.message
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
13
|
+
def test_should_not_have_an_if_condition
|
14
|
+
assert_nil @guard.if_condition
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_should_not_have_an_unless_condition
|
18
|
+
assert_nil @guard.unless_condition
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
@@ -22,6 +25,18 @@ class GuardWithNoRequirementsTest < Test::Unit::TestCase
|
|
22
25
|
@guard = StateMachine::Guard.new
|
23
26
|
end
|
24
27
|
|
28
|
+
def test_should_use_all_matcher_for_event_requirement
|
29
|
+
assert_equal StateMachine::AllMatcher.instance, @guard.event_requirement
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_should_use_all_matcher_for_from_state_requirement
|
33
|
+
assert_equal StateMachine::AllMatcher.instance, @guard.state_requirement[:from]
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_use_all_matcher_for_to_state_requirement
|
37
|
+
assert_equal StateMachine::AllMatcher.instance, @guard.state_requirement[:to]
|
38
|
+
end
|
39
|
+
|
25
40
|
def test_should_match_nil_query
|
26
41
|
assert @guard.matches?(@object, nil)
|
27
42
|
end
|
@@ -41,6 +56,10 @@ class GuardWithFromRequirementTest < Test::Unit::TestCase
|
|
41
56
|
@guard = StateMachine::Guard.new(:from => :parked)
|
42
57
|
end
|
43
58
|
|
59
|
+
def test_should_use_a_whitelist_matcher
|
60
|
+
assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirement[:from]
|
61
|
+
end
|
62
|
+
|
44
63
|
def test_should_match_if_not_specified
|
45
64
|
assert @guard.matches?(@object, :to => :idling)
|
46
65
|
end
|
@@ -95,6 +114,10 @@ class GuardWithToRequirementTest < Test::Unit::TestCase
|
|
95
114
|
@guard = StateMachine::Guard.new(:to => :idling)
|
96
115
|
end
|
97
116
|
|
117
|
+
def test_should_use_a_whitelist_matcher
|
118
|
+
assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirement[:to]
|
119
|
+
end
|
120
|
+
|
98
121
|
def test_should_match_if_not_specified
|
99
122
|
assert @guard.matches?(@object, :from => :parked)
|
100
123
|
end
|
@@ -149,6 +172,10 @@ class GuardWithOnRequirementTest < Test::Unit::TestCase
|
|
149
172
|
@guard = StateMachine::Guard.new(:on => :ignite)
|
150
173
|
end
|
151
174
|
|
175
|
+
def test_should_use_a_whitelist_matcher
|
176
|
+
assert_instance_of StateMachine::WhitelistMatcher, @guard.event_requirement
|
177
|
+
end
|
178
|
+
|
152
179
|
def test_should_match_if_not_specified
|
153
180
|
assert @guard.matches?(@object, :from => :parked)
|
154
181
|
end
|
@@ -199,6 +226,10 @@ class GuardWithExceptFromRequirementTest < Test::Unit::TestCase
|
|
199
226
|
@guard = StateMachine::Guard.new(:except_from => :parked)
|
200
227
|
end
|
201
228
|
|
229
|
+
def test_should_use_a_blacklist_matcher
|
230
|
+
assert_instance_of StateMachine::BlacklistMatcher, @guard.state_requirement[:from]
|
231
|
+
end
|
232
|
+
|
202
233
|
def test_should_match_if_not_included
|
203
234
|
assert @guard.matches?(@object, :from => :idling)
|
204
235
|
end
|
@@ -249,6 +280,10 @@ class GuardWithExceptToRequirementTest < Test::Unit::TestCase
|
|
249
280
|
@guard = StateMachine::Guard.new(:except_to => :idling)
|
250
281
|
end
|
251
282
|
|
283
|
+
def test_should_use_a_blacklist_matcher
|
284
|
+
assert_instance_of StateMachine::BlacklistMatcher, @guard.state_requirement[:to]
|
285
|
+
end
|
286
|
+
|
252
287
|
def test_should_match_if_not_included
|
253
288
|
assert @guard.matches?(@object, :to => :parked)
|
254
289
|
end
|
@@ -299,6 +334,10 @@ class GuardWithExceptOnRequirementTest < Test::Unit::TestCase
|
|
299
334
|
@guard = StateMachine::Guard.new(:except_on => :ignite)
|
300
335
|
end
|
301
336
|
|
337
|
+
def test_should_use_a_blacklist_matcher
|
338
|
+
assert_instance_of StateMachine::BlacklistMatcher, @guard.event_requirement
|
339
|
+
end
|
340
|
+
|
302
341
|
def test_should_match_if_not_included
|
303
342
|
assert @guard.matches?(@object, :on => :park)
|
304
343
|
end
|
@@ -340,35 +379,23 @@ class GuardWithMultipleExceptOnRequirementsTest < Test::Unit::TestCase
|
|
340
379
|
end
|
341
380
|
|
342
381
|
class GuardWithConflictingFromRequirementsTest < Test::Unit::TestCase
|
343
|
-
def
|
344
|
-
|
345
|
-
|
346
|
-
end
|
347
|
-
|
348
|
-
def test_should_ignore_except_requirement
|
349
|
-
assert @guard.matches?(@object, :from => :parked)
|
382
|
+
def test_should_raise_an_exception
|
383
|
+
exception = assert_raise(ArgumentError) { StateMachine::Guard.new(:from => :parked, :except_from => :parked) }
|
384
|
+
assert_equal 'Conflicting keys: from, except_from', exception.message
|
350
385
|
end
|
351
386
|
end
|
352
387
|
|
353
388
|
class GuardWithConflictingToRequirementsTest < Test::Unit::TestCase
|
354
|
-
def
|
355
|
-
|
356
|
-
|
357
|
-
end
|
358
|
-
|
359
|
-
def test_should_ignore_except_requirement
|
360
|
-
assert @guard.matches?(@object, :to => :idling)
|
389
|
+
def test_should_raise_an_exception
|
390
|
+
exception = assert_raise(ArgumentError) { StateMachine::Guard.new(:to => :idling, :except_to => :idling) }
|
391
|
+
assert_equal 'Conflicting keys: to, except_to', exception.message
|
361
392
|
end
|
362
393
|
end
|
363
394
|
|
364
395
|
class GuardWithConflictingOnRequirementsTest < Test::Unit::TestCase
|
365
|
-
def
|
366
|
-
|
367
|
-
|
368
|
-
end
|
369
|
-
|
370
|
-
def test_should_ignore_except_requirement
|
371
|
-
assert @guard.matches?(@object, :on => :ignite)
|
396
|
+
def test_should_raise_an_exception
|
397
|
+
exception = assert_raise(ArgumentError) { StateMachine::Guard.new(:on => :ignite, :except_on => :ignite) }
|
398
|
+
assert_equal 'Conflicting keys: on, except_on', exception.message
|
372
399
|
end
|
373
400
|
end
|
374
401
|
|
@@ -440,6 +467,11 @@ class GuardWithIfConditionalTest < Test::Unit::TestCase
|
|
440
467
|
@object = Object.new
|
441
468
|
end
|
442
469
|
|
470
|
+
def test_should_have_an_if_condition
|
471
|
+
guard = StateMachine::Guard.new(:if => lambda {true})
|
472
|
+
assert_not_nil guard.if_condition
|
473
|
+
end
|
474
|
+
|
443
475
|
def test_should_match_if_true
|
444
476
|
guard = StateMachine::Guard.new(:if => lambda {true})
|
445
477
|
assert guard.matches?(@object)
|
@@ -456,6 +488,11 @@ class GuardWithUnlessConditionalTest < Test::Unit::TestCase
|
|
456
488
|
@object = Object.new
|
457
489
|
end
|
458
490
|
|
491
|
+
def test_should_have_an_unless_condition
|
492
|
+
guard = StateMachine::Guard.new(:unless => lambda {true})
|
493
|
+
assert_not_nil guard.unless_condition
|
494
|
+
end
|
495
|
+
|
459
496
|
def test_should_match_if_false
|
460
497
|
guard = StateMachine::Guard.new(:unless => lambda {false})
|
461
498
|
assert guard.matches?(@object)
|
@@ -468,18 +505,9 @@ class GuardWithUnlessConditionalTest < Test::Unit::TestCase
|
|
468
505
|
end
|
469
506
|
|
470
507
|
class GuardWithConflictingConditionalsTest < Test::Unit::TestCase
|
471
|
-
def
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
def test_should_match_if_true
|
476
|
-
guard = StateMachine::Guard.new(:if => lambda {true}, :unless => lambda {true})
|
477
|
-
assert guard.matches?(@object)
|
478
|
-
end
|
479
|
-
|
480
|
-
def test_should_not_match_if_false
|
481
|
-
guard = StateMachine::Guard.new(:if => lambda {false}, :unless => lambda {false})
|
482
|
-
assert !guard.matches?(@object)
|
508
|
+
def test_should_raise_an_exception
|
509
|
+
exception = assert_raise(ArgumentError) { StateMachine::Guard.new(:if => lambda {true}, :unless => lambda {true}) }
|
510
|
+
assert_equal 'Conflicting keys: if, unless', exception.message
|
483
511
|
end
|
484
512
|
end
|
485
513
|
|
@@ -307,6 +307,21 @@ begin
|
|
307
307
|
end
|
308
308
|
end
|
309
309
|
|
310
|
+
class MachineWithComplexPluralizationTest < ActiveRecord::TestCase
|
311
|
+
def setup
|
312
|
+
@model = new_model
|
313
|
+
@machine = StateMachine::Machine.new(@model, :status)
|
314
|
+
end
|
315
|
+
|
316
|
+
def test_should_create_singular_with_scope
|
317
|
+
assert @model.respond_to?(:with_status)
|
318
|
+
end
|
319
|
+
|
320
|
+
def test_should_create_plural_with_scope
|
321
|
+
assert @model.respond_to?(:with_statuses)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
310
325
|
class MachineWithCallbacksTest < ActiveRecord::TestCase
|
311
326
|
def setup
|
312
327
|
@model = new_model
|
@@ -201,6 +201,21 @@ begin
|
|
201
201
|
end
|
202
202
|
end
|
203
203
|
|
204
|
+
class MachineWithComplexPluralizationTest < BaseTestCase
|
205
|
+
def setup
|
206
|
+
@resource = new_resource
|
207
|
+
@machine = StateMachine::Machine.new(@resource, :status)
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_should_create_singular_with_scope
|
211
|
+
assert @resource.respond_to?(:with_status)
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_should_create_plural_with_scope
|
215
|
+
assert @resource.respond_to?(:with_statuses)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
204
219
|
class MachineWithNonColumnStateAttributeDefinedTest < BaseTestCase
|
205
220
|
def setup
|
206
221
|
@resource = new_resource do
|
@@ -202,6 +202,21 @@ begin
|
|
202
202
|
end
|
203
203
|
end
|
204
204
|
|
205
|
+
class MachineWithComplexPluralizationTest < BaseTestCase
|
206
|
+
def setup
|
207
|
+
@model = new_model
|
208
|
+
@machine = StateMachine::Machine.new(@model, :status)
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_should_create_singular_with_scope
|
212
|
+
assert @model.respond_to?(:with_status)
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_should_create_plural_with_scope
|
216
|
+
assert @model.respond_to?(:with_statuses)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
205
220
|
class MachineWithCallbacksTest < BaseTestCase
|
206
221
|
def setup
|
207
222
|
@model = new_model
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class MatcherByDefaultTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@matcher = StateMachine::Matcher.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_should_have_no_values
|
9
|
+
assert_equal [], @matcher.values
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_should_filter_all_values
|
13
|
+
assert_equal [], @matcher.filter([:parked, :idling])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class MatcherWithValueTest < Test::Unit::TestCase
|
18
|
+
def setup
|
19
|
+
@matcher = StateMachine::Matcher.new(nil)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_should_have_values
|
23
|
+
assert_equal [nil], @matcher.values
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_should_filter_unknown_values
|
27
|
+
assert_equal [nil], @matcher.filter([nil, :parked])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class MatcherWithMultipleValuesTest < Test::Unit::TestCase
|
32
|
+
def setup
|
33
|
+
@matcher = StateMachine::Matcher.new([:parked, :idling])
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_have_values
|
37
|
+
assert_equal [:parked, :idling], @matcher.values
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_should_filter_unknown_values
|
41
|
+
assert_equal [:parked], @matcher.filter([:parked, :first_gear])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class AllMatcherTest < Test::Unit::TestCase
|
46
|
+
def setup
|
47
|
+
@matcher = StateMachine::AllMatcher.instance
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_should_have_no_values
|
51
|
+
assert_equal [], @matcher.values
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_should_always_match
|
55
|
+
[nil, :parked, :idling].each {|value| assert @matcher.matches?(value)}
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_should_not_filter_any_values
|
59
|
+
assert_equal [:parked, :idling], @matcher.filter([:parked, :idling])
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_should_generate_blacklist_matcher_after_subtraction
|
63
|
+
matcher = @matcher - [:parked, :idling]
|
64
|
+
assert_instance_of StateMachine::BlacklistMatcher, matcher
|
65
|
+
assert_equal [:parked, :idling], matcher.values
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_should_have_a_description
|
69
|
+
assert_equal 'all', @matcher.description
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class WhitelistMatcherTest < Test::Unit::TestCase
|
74
|
+
def setup
|
75
|
+
@matcher = StateMachine::WhitelistMatcher.new([:parked, :idling])
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_should_have_values
|
79
|
+
assert_equal [:parked, :idling], @matcher.values
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_should_filter_unknown_values
|
83
|
+
assert_equal [:parked, :idling], @matcher.filter([:parked, :idling, :first_gear])
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_should_match_known_values
|
87
|
+
assert @matcher.matches?(:parked)
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_should_not_match_unknown_values
|
91
|
+
assert !@matcher.matches?(:first_gear)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_should_have_a_description
|
95
|
+
assert_equal '[:parked, :idling]', @matcher.description
|
96
|
+
|
97
|
+
matcher = StateMachine::WhitelistMatcher.new([:parked])
|
98
|
+
assert_equal ':parked', matcher.description
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class BlacklistMatcherTest < Test::Unit::TestCase
|
103
|
+
def setup
|
104
|
+
@matcher = StateMachine::BlacklistMatcher.new([:parked, :idling])
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_should_have_values
|
108
|
+
assert_equal [:parked, :idling], @matcher.values
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_should_filter_known_values
|
112
|
+
assert_equal [:first_gear], @matcher.filter([:parked, :idling, :first_gear])
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_should_match_unknown_values
|
116
|
+
assert @matcher.matches?(:first_gear)
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_should_not_match_known_values
|
120
|
+
assert !@matcher.matches?(:parked)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_should_have_a_description
|
124
|
+
assert_equal 'all - [:parked, :idling]', @matcher.description
|
125
|
+
|
126
|
+
matcher = StateMachine::BlacklistMatcher.new([:parked])
|
127
|
+
assert_equal 'all - :parked', matcher.description
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
class LoopbackMatcherTest < Test::Unit::TestCase
|
132
|
+
def setup
|
133
|
+
@matcher = StateMachine::LoopbackMatcher.instance
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_should_have_no_values
|
137
|
+
assert_equal [], @matcher.values
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_should_filter_all_values
|
141
|
+
assert_equal [], @matcher.filter([:parked, :idling])
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_should_match_if_from_context_is_same
|
145
|
+
assert @matcher.matches?(:parked, :from => :parked)
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_should_not_match_if_from_context_is_different
|
149
|
+
assert !@matcher.matches?(:parked, :from => :idling)
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_should_have_a_description
|
153
|
+
assert_equal 'same', @matcher.description
|
154
|
+
end
|
155
|
+
end
|