state_machines 0.0.1 → 0.0.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -2
  3. data/README.md +25 -0
  4. data/Rakefile +10 -1
  5. data/lib/state_machines/branch.rb +0 -4
  6. data/lib/state_machines/core.rb +23 -5
  7. data/lib/state_machines/error.rb +81 -2
  8. data/lib/state_machines/event.rb +2 -20
  9. data/lib/state_machines/event_collection.rb +25 -27
  10. data/lib/state_machines/extensions.rb +34 -34
  11. data/lib/state_machines/integrations.rb +98 -90
  12. data/lib/state_machines/integrations/base.rb +11 -60
  13. data/lib/state_machines/matcher.rb +0 -2
  14. data/lib/state_machines/node_collection.rb +0 -2
  15. data/lib/state_machines/path_collection.rb +0 -2
  16. data/lib/state_machines/state.rb +0 -3
  17. data/lib/state_machines/state_collection.rb +17 -19
  18. data/lib/state_machines/state_context.rb +1 -6
  19. data/lib/state_machines/transition.rb +0 -56
  20. data/lib/state_machines/version.rb +1 -1
  21. data/spec/spec_helper.rb +1 -0
  22. data/spec/state_machines/assertions_spec.rb +31 -0
  23. data/spec/state_machines/branch_spec.rb +827 -0
  24. data/spec/state_machines/callbacks_spec.rb +706 -0
  25. data/spec/state_machines/errors_spec.rb +1 -0
  26. data/spec/state_machines/event_collection_spec.rb +401 -0
  27. data/spec/state_machines/event_spec.rb +1140 -0
  28. data/spec/{helpers → state_machines}/helper_spec.rb +0 -0
  29. data/spec/state_machines/integration_base_spec.rb +12 -0
  30. data/spec/state_machines/integration_spec.rb +132 -0
  31. data/spec/state_machines/invalid_event_spec.rb +19 -0
  32. data/spec/state_machines/invalid_parallel_transition_spec.rb +18 -0
  33. data/spec/state_machines/invalid_transition_spec.rb +114 -0
  34. data/spec/state_machines/machine_collection_spec.rb +606 -0
  35. data/spec/{machine_spec.rb → state_machines/machine_spec.rb} +11 -2
  36. data/spec/{matcher_helpers_spec.rb → state_machines/matcher_helpers_spec.rb} +0 -0
  37. data/spec/{matcher_spec.rb → state_machines/matcher_spec.rb} +0 -0
  38. data/spec/{node_collection_spec.rb → state_machines/node_collection_spec.rb} +0 -0
  39. data/spec/{path_collection_spec.rb → state_machines/path_collection_spec.rb} +0 -0
  40. data/spec/{path_spec.rb → state_machines/path_spec.rb} +0 -0
  41. data/spec/{state_collection_spec.rb → state_machines/state_collection_spec.rb} +0 -0
  42. data/spec/{state_context_spec.rb → state_machines/state_context_spec.rb} +0 -0
  43. data/spec/{state_machine_spec.rb → state_machines/state_machine_spec.rb} +0 -0
  44. data/spec/{state_spec.rb → state_machines/state_spec.rb} +0 -0
  45. data/spec/{transition_collection_spec.rb → state_machines/transition_collection_spec.rb} +0 -0
  46. data/spec/{transition_spec.rb → state_machines/transition_spec.rb} +0 -0
  47. data/spec/support/migration_helpers.rb +9 -0
  48. data/state_machines.gemspec +3 -1
  49. metadata +68 -45
  50. data/lib/state_machines/yard.rb +0 -8
  51. data/spec/errors/default_spec.rb +0 -14
  52. data/spec/errors/with_message_spec.rb +0 -39
@@ -1,3 +1,3 @@
1
1
  module StateMachines
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
@@ -1,3 +1,4 @@
1
+ require 'rspec/its'
1
2
  require 'state_machines'
2
3
  require 'stringio'
3
4
  Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ context 'AssertValidKeys' do
5
+ it 'should_not_raise_exception_if_key_is_valid' do
6
+ assert_nothing_raised { {:name => 'foo', :value => 'bar'}.assert_valid_keys(:name, :value, :force) }
7
+ end
8
+
9
+ it 'should_raise_exception_if_key_is_invalid' do
10
+ assert_raise(ArgumentError) { {:name => 'foo', :value => 'bar', :invalid => true}.assert_valid_keys(:name, :value, :force) }
11
+ end
12
+ end
13
+
14
+ context 'AssertExclusiveKeys' do
15
+ it 'should_not_raise_exception_if_no_keys_found' do
16
+ assert_nothing_raised { {:on => :park}.assert_exclusive_keys(:only, :except) }
17
+ end
18
+
19
+ it 'should_not_raise_exception_if_one_key_found' do
20
+ assert_nothing_raised { {:only => :parked}.assert_exclusive_keys(:only, :except) }
21
+ assert_nothing_raised { {:except => :parked}.assert_exclusive_keys(:only, :except) }
22
+ end
23
+
24
+ it 'should_raise_exception_if_two_keys_found' do
25
+ assert_raise(ArgumentError) { {:only => :parked, :except => :parked}.assert_exclusive_keys(:only, :except) }
26
+ end
27
+
28
+ it 'should_raise_exception_if_multiple_keys_found' do
29
+ assert_raise(ArgumentError) { {:only => :parked, :except => :parked, :on => :park}.assert_exclusive_keys(:only, :except, :with) }
30
+ end
31
+ end
@@ -0,0 +1,827 @@
1
+ require 'spec_helper'
2
+ describe StateMachines::Branch do
3
+ context 'Default' do
4
+ before(:each) do
5
+ @branch = StateMachines::Branch.new(:from => :parked, :to => :idling)
6
+ end
7
+
8
+ it 'should_not_raise_exception_if_implicit_option_specified' do
9
+ assert_nothing_raised { StateMachines::Branch.new(:invalid => :valid) }
10
+ end
11
+
12
+ it 'should_not_have_an_if_condition' do
13
+ assert_nil @branch.if_condition
14
+ end
15
+
16
+ it 'should_not_have_an_unless_condition' do
17
+ assert_nil @branch.unless_condition
18
+ end
19
+
20
+ it 'should_have_a_state_requirement' do
21
+ assert_equal 1, @branch.state_requirements.length
22
+ end
23
+
24
+ it 'should_raise_an_exception_if_invalid_match_option_specified' do
25
+ assert_raise(ArgumentError) { @branch.match(Object.new, :invalid => true) }
26
+ end
27
+ end
28
+
29
+ context 'WithNoRequirements' do
30
+ before(:each) do
31
+ @object = Object.new
32
+ @branch = StateMachines::Branch.new
33
+ end
34
+
35
+ it 'should_use_all_matcher_for_event_requirement' do
36
+ assert_equal StateMachines::AllMatcher.instance, @branch.event_requirement
37
+ end
38
+
39
+ it 'should_use_all_matcher_for_from_state_requirement' do
40
+ assert_equal StateMachines::AllMatcher.instance, @branch.state_requirements.first[:from]
41
+ end
42
+
43
+ it 'should_use_all_matcher_for_to_state_requirement' do
44
+ assert_equal StateMachines::AllMatcher.instance, @branch.state_requirements.first[:to]
45
+ end
46
+
47
+ it 'should_match_empty_query' do
48
+ assert @branch.matches?(@object, {})
49
+ end
50
+
51
+ it 'should_match_non_empty_query' do
52
+ assert @branch.matches?(@object, :to => :idling, :from => :parked, :on => :ignite)
53
+ end
54
+
55
+ it 'should_include_all_requirements_in_match' do
56
+ match = @branch.match(@object, {})
57
+
58
+ assert_equal @branch.state_requirements.first[:from], match[:from]
59
+ assert_equal @branch.state_requirements.first[:to], match[:to]
60
+ assert_equal @branch.event_requirement, match[:on]
61
+ end
62
+ end
63
+
64
+ context 'WithFromRequirement' do
65
+ before(:each) do
66
+ @object = Object.new
67
+ @branch = StateMachines::Branch.new(:from => :parked)
68
+ end
69
+
70
+ it 'should_use_a_whitelist_matcher' do
71
+ assert_instance_of StateMachines::WhitelistMatcher, @branch.state_requirements.first[:from]
72
+ end
73
+
74
+ it 'should_match_if_not_specified' do
75
+ assert @branch.matches?(@object, :to => :idling)
76
+ end
77
+
78
+ it 'should_match_if_included' do
79
+ assert @branch.matches?(@object, :from => :parked)
80
+ end
81
+
82
+ it 'should_not_match_if_not_included' do
83
+ assert !@branch.matches?(@object, :from => :idling)
84
+ end
85
+
86
+ it 'should_not_match_if_nil' do
87
+ assert !@branch.matches?(@object, :from => nil)
88
+ end
89
+
90
+ it 'should_ignore_to' do
91
+ assert @branch.matches?(@object, :from => :parked, :to => :idling)
92
+ end
93
+
94
+ it 'should_ignore_on' do
95
+ assert @branch.matches?(@object, :from => :parked, :on => :ignite)
96
+ end
97
+
98
+ it 'should_be_included_in_known_states' do
99
+ assert_equal [:parked], @branch.known_states
100
+ end
101
+
102
+ it 'should_include_requirement_in_match' do
103
+ match = @branch.match(@object, :from => :parked)
104
+ assert_equal @branch.state_requirements.first[:from], match[:from]
105
+ end
106
+ end
107
+
108
+ context 'WithMultipleFromRequirements' do
109
+ before(:each) do
110
+ @object = Object.new
111
+ @branch = StateMachines::Branch.new(:from => [:idling, :parked])
112
+ end
113
+
114
+ it 'should_match_if_included' do
115
+ assert @branch.matches?(@object, :from => :idling)
116
+ end
117
+
118
+ it 'should_not_match_if_not_included' do
119
+ assert !@branch.matches?(@object, :from => :first_gear)
120
+ end
121
+
122
+ it 'should_be_included_in_known_states' do
123
+ assert_equal [:idling, :parked], @branch.known_states
124
+ end
125
+ end
126
+
127
+ context 'WithFromMatcherRequirement' do
128
+ before(:each) do
129
+ @object = Object.new
130
+ @branch = StateMachines::Branch.new(:from => StateMachines::BlacklistMatcher.new([:idling, :parked]))
131
+ end
132
+
133
+ it 'should_match_if_included' do
134
+ assert @branch.matches?(@object, :from => :first_gear)
135
+ end
136
+
137
+ it 'should_not_match_if_not_included' do
138
+ assert !@branch.matches?(@object, :from => :idling)
139
+ end
140
+
141
+ it 'include_values_in_known_states' do
142
+ assert_equal [:idling, :parked], @branch.known_states
143
+ end
144
+ end
145
+
146
+ context 'WithToRequirement' do
147
+ before(:each) do
148
+ @object = Object.new
149
+ @branch = StateMachines::Branch.new(:to => :idling)
150
+ end
151
+
152
+ it 'should_use_a_whitelist_matcher' do
153
+ assert_instance_of StateMachines::WhitelistMatcher, @branch.state_requirements.first[:to]
154
+ end
155
+
156
+ it 'should_match_if_not_specified' do
157
+ assert @branch.matches?(@object, :from => :parked)
158
+ end
159
+
160
+ it 'should_match_if_included' do
161
+ assert @branch.matches?(@object, :to => :idling)
162
+ end
163
+
164
+ it 'should_not_match_if_not_included' do
165
+ assert !@branch.matches?(@object, :to => :parked)
166
+ end
167
+
168
+ it 'should_not_match_if_nil' do
169
+ assert !@branch.matches?(@object, :to => nil)
170
+ end
171
+
172
+ it 'should_ignore_from' do
173
+ assert @branch.matches?(@object, :to => :idling, :from => :parked)
174
+ end
175
+
176
+ it 'should_ignore_on' do
177
+ assert @branch.matches?(@object, :to => :idling, :on => :ignite)
178
+ end
179
+
180
+ it 'should_be_included_in_known_states' do
181
+ assert_equal [:idling], @branch.known_states
182
+ end
183
+
184
+ it 'should_include_requirement_in_match' do
185
+ match = @branch.match(@object, :to => :idling)
186
+ assert_equal @branch.state_requirements.first[:to], match[:to]
187
+ end
188
+ end
189
+
190
+ context 'WithMultipleToRequirements' do
191
+ before(:each) do
192
+ @object = Object.new
193
+ @branch = StateMachines::Branch.new(:to => [:idling, :parked])
194
+ end
195
+
196
+ it 'should_match_if_included' do
197
+ assert @branch.matches?(@object, :to => :idling)
198
+ end
199
+
200
+ it 'should_not_match_if_not_included' do
201
+ assert !@branch.matches?(@object, :to => :first_gear)
202
+ end
203
+
204
+ it 'should_be_included_in_known_states' do
205
+ assert_equal [:idling, :parked], @branch.known_states
206
+ end
207
+ end
208
+
209
+ context 'WithToMatcherRequirement' do
210
+ before(:each) do
211
+ @object = Object.new
212
+ @branch = StateMachines::Branch.new(:to => StateMachines::BlacklistMatcher.new([:idling, :parked]))
213
+ end
214
+
215
+ it 'should_match_if_included' do
216
+ assert @branch.matches?(@object, :to => :first_gear)
217
+ end
218
+
219
+ it 'should_not_match_if_not_included' do
220
+ assert !@branch.matches?(@object, :to => :idling)
221
+ end
222
+
223
+ it 'include_values_in_known_states' do
224
+ assert_equal [:idling, :parked], @branch.known_states
225
+ end
226
+ end
227
+
228
+ context 'WithOnRequirement' do
229
+ before(:each) do
230
+ @object = Object.new
231
+ @branch = StateMachines::Branch.new(:on => :ignite)
232
+ end
233
+
234
+ it 'should_use_a_whitelist_matcher' do
235
+ assert_instance_of StateMachines::WhitelistMatcher, @branch.event_requirement
236
+ end
237
+
238
+ it 'should_match_if_not_specified' do
239
+ assert @branch.matches?(@object, :from => :parked)
240
+ end
241
+
242
+ it 'should_match_if_included' do
243
+ assert @branch.matches?(@object, :on => :ignite)
244
+ end
245
+
246
+ it 'should_not_match_if_not_included' do
247
+ assert !@branch.matches?(@object, :on => :park)
248
+ end
249
+
250
+ it 'should_not_match_if_nil' do
251
+ assert !@branch.matches?(@object, :on => nil)
252
+ end
253
+
254
+ it 'should_ignore_to' do
255
+ assert @branch.matches?(@object, :on => :ignite, :to => :parked)
256
+ end
257
+
258
+ it 'should_ignore_from' do
259
+ assert @branch.matches?(@object, :on => :ignite, :from => :parked)
260
+ end
261
+
262
+ it 'should_not_be_included_in_known_states' do
263
+ assert_equal [], @branch.known_states
264
+ end
265
+
266
+ it 'should_include_requirement_in_match' do
267
+ match = @branch.match(@object, :on => :ignite)
268
+ assert_equal @branch.event_requirement, match[:on]
269
+ end
270
+ end
271
+
272
+ context 'WithMultipleOnRequirements' do
273
+ before(:each) do
274
+ @object = Object.new
275
+ @branch = StateMachines::Branch.new(:on => [:ignite, :park])
276
+ end
277
+
278
+ it 'should_match_if_included' do
279
+ assert @branch.matches?(@object, :on => :ignite)
280
+ end
281
+
282
+ it 'should_not_match_if_not_included' do
283
+ assert !@branch.matches?(@object, :on => :shift_up)
284
+ end
285
+ end
286
+
287
+ context 'WithOnMatcherRequirement' do
288
+ before(:each) do
289
+ @object = Object.new
290
+ @branch = StateMachines::Branch.new(:on => StateMachines::BlacklistMatcher.new([:ignite, :park]))
291
+ end
292
+
293
+ it 'should_match_if_included' do
294
+ assert @branch.matches?(@object, :on => :shift_up)
295
+ end
296
+
297
+ it 'should_not_match_if_not_included' do
298
+ assert !@branch.matches?(@object, :on => :ignite)
299
+ end
300
+ end
301
+
302
+ context 'WithExceptFromRequirement' do
303
+ before(:each) do
304
+ @object = Object.new
305
+ @branch = StateMachines::Branch.new(:except_from => :parked)
306
+ end
307
+
308
+ it 'should_use_a_blacklist_matcher' do
309
+ assert_instance_of StateMachines::BlacklistMatcher, @branch.state_requirements.first[:from]
310
+ end
311
+
312
+ it 'should_match_if_not_included' do
313
+ assert @branch.matches?(@object, :from => :idling)
314
+ end
315
+
316
+ it 'should_not_match_if_included' do
317
+ assert !@branch.matches?(@object, :from => :parked)
318
+ end
319
+
320
+ it 'should_match_if_nil' do
321
+ assert @branch.matches?(@object, :from => nil)
322
+ end
323
+
324
+ it 'should_ignore_to' do
325
+ assert @branch.matches?(@object, :from => :idling, :to => :parked)
326
+ end
327
+
328
+ it 'should_ignore_on' do
329
+ assert @branch.matches?(@object, :from => :idling, :on => :ignite)
330
+ end
331
+
332
+ it 'should_be_included_in_known_states' do
333
+ assert_equal [:parked], @branch.known_states
334
+ end
335
+ end
336
+
337
+ context 'WithMultipleExceptFromRequirements' do
338
+ before(:each) do
339
+ @object = Object.new
340
+ @branch = StateMachines::Branch.new(:except_from => [:idling, :parked])
341
+ end
342
+
343
+ it 'should_match_if_not_included' do
344
+ assert @branch.matches?(@object, :from => :first_gear)
345
+ end
346
+
347
+ it 'should_not_match_if_included' do
348
+ assert !@branch.matches?(@object, :from => :idling)
349
+ end
350
+
351
+ it 'should_be_included_in_known_states' do
352
+ assert_equal [:idling, :parked], @branch.known_states
353
+ end
354
+ end
355
+
356
+ context 'WithExceptFromMatcherRequirement' do
357
+ it 'should_raise_an_exception' do
358
+ assert_raise(ArgumentError) { StateMachines::Branch.new(:except_from => StateMachines::AllMatcher.instance) }
359
+ end
360
+ end
361
+
362
+ context 'WithExceptToRequirement' do
363
+ before(:each) do
364
+ @object = Object.new
365
+ @branch = StateMachines::Branch.new(:except_to => :idling)
366
+ end
367
+
368
+ it 'should_use_a_blacklist_matcher' do
369
+ assert_instance_of StateMachines::BlacklistMatcher, @branch.state_requirements.first[:to]
370
+ end
371
+
372
+ it 'should_match_if_not_included' do
373
+ assert @branch.matches?(@object, :to => :parked)
374
+ end
375
+
376
+ it 'should_not_match_if_included' do
377
+ assert !@branch.matches?(@object, :to => :idling)
378
+ end
379
+
380
+ it 'should_match_if_nil' do
381
+ assert @branch.matches?(@object, :to => nil)
382
+ end
383
+
384
+ it 'should_ignore_from' do
385
+ assert @branch.matches?(@object, :to => :parked, :from => :idling)
386
+ end
387
+
388
+ it 'should_ignore_on' do
389
+ assert @branch.matches?(@object, :to => :parked, :on => :ignite)
390
+ end
391
+
392
+ it 'should_be_included_in_known_states' do
393
+ assert_equal [:idling], @branch.known_states
394
+ end
395
+ end
396
+
397
+ context 'WithMultipleExceptToRequirements' do
398
+ before(:each) do
399
+ @object = Object.new
400
+ @branch = StateMachines::Branch.new(:except_to => [:idling, :parked])
401
+ end
402
+
403
+ it 'should_match_if_not_included' do
404
+ assert @branch.matches?(@object, :to => :first_gear)
405
+ end
406
+
407
+ it 'should_not_match_if_included' do
408
+ assert !@branch.matches?(@object, :to => :idling)
409
+ end
410
+
411
+ it 'should_be_included_in_known_states' do
412
+ assert_equal [:idling, :parked], @branch.known_states
413
+ end
414
+ end
415
+
416
+ context 'WithExceptToMatcherRequirement' do
417
+ it 'should_raise_an_exception' do
418
+ assert_raise(ArgumentError) { StateMachines::Branch.new(:except_to => StateMachines::AllMatcher.instance) }
419
+ end
420
+ end
421
+
422
+ context 'WithExceptOnRequirement' do
423
+ before(:each) do
424
+ @object = Object.new
425
+ @branch = StateMachines::Branch.new(:except_on => :ignite)
426
+ end
427
+
428
+ it 'should_use_a_blacklist_matcher' do
429
+ assert_instance_of StateMachines::BlacklistMatcher, @branch.event_requirement
430
+ end
431
+
432
+ it 'should_match_if_not_included' do
433
+ assert @branch.matches?(@object, :on => :park)
434
+ end
435
+
436
+ it 'should_not_match_if_included' do
437
+ assert !@branch.matches?(@object, :on => :ignite)
438
+ end
439
+
440
+ it 'should_match_if_nil' do
441
+ assert @branch.matches?(@object, :on => nil)
442
+ end
443
+
444
+ it 'should_ignore_to' do
445
+ assert @branch.matches?(@object, :on => :park, :to => :idling)
446
+ end
447
+
448
+ it 'should_ignore_from' do
449
+ assert @branch.matches?(@object, :on => :park, :from => :parked)
450
+ end
451
+
452
+ it 'should_not_be_included_in_known_states' do
453
+ assert_equal [], @branch.known_states
454
+ end
455
+ end
456
+
457
+ context 'WithExceptOnMatcherRequirement' do
458
+ it 'should_raise_an_exception' do
459
+ assert_raise(ArgumentError) { StateMachines::Branch.new(:except_on => StateMachines::AllMatcher.instance) }
460
+ end
461
+ end
462
+
463
+ context 'WithMultipleExceptOnRequirements' do
464
+ before(:each) do
465
+ @object = Object.new
466
+ @branch = StateMachines::Branch.new(:except_on => [:ignite, :park])
467
+ end
468
+
469
+ it 'should_match_if_not_included' do
470
+ assert @branch.matches?(@object, :on => :shift_up)
471
+ end
472
+
473
+ it 'should_not_match_if_included' do
474
+ assert !@branch.matches?(@object, :on => :ignite)
475
+ end
476
+ end
477
+
478
+ context 'WithConflictingFromRequirements' do
479
+ it 'should_raise_an_exception' do
480
+ assert_raise(ArgumentError) { StateMachines::Branch.new(:from => :parked, :except_from => :parked) }
481
+ end
482
+ end
483
+
484
+ context 'WithConflictingToRequirements' do
485
+ it 'should_raise_an_exception' do
486
+ assert_raise(ArgumentError) { StateMachines::Branch.new(:to => :idling, :except_to => :idling) }
487
+ end
488
+ end
489
+
490
+ context 'WithConflictingOnRequirements' do
491
+ it 'should_raise_an_exception' do
492
+ assert_raise(ArgumentError) { StateMachines::Branch.new(:on => :ignite, :except_on => :ignite) }
493
+ end
494
+ end
495
+
496
+ context 'WithDifferentRequirements' do
497
+ before(:each) do
498
+ @object = Object.new
499
+ @branch = StateMachines::Branch.new(:from => :parked, :to => :idling, :on => :ignite)
500
+ end
501
+
502
+ it 'should_match_empty_query' do
503
+ assert @branch.matches?(@object)
504
+ end
505
+
506
+ it 'should_match_if_all_requirements_match' do
507
+ assert @branch.matches?(@object, :from => :parked, :to => :idling, :on => :ignite)
508
+ end
509
+
510
+ it 'should_not_match_if_from_not_included' do
511
+ assert !@branch.matches?(@object, :from => :idling)
512
+ end
513
+
514
+ it 'should_not_match_if_to_not_included' do
515
+ assert !@branch.matches?(@object, :to => :parked)
516
+ end
517
+
518
+ it 'should_not_match_if_on_not_included' do
519
+ assert !@branch.matches?(@object, :on => :park)
520
+ end
521
+
522
+ it 'should_be_nil_if_unmatched' do
523
+ assert_nil @branch.match(@object, :from => :parked, :to => :idling, :on => :park)
524
+ end
525
+
526
+ it 'should_include_all_known_states' do
527
+ assert_equal [:parked, :idling], @branch.known_states
528
+ end
529
+
530
+ it 'should_not_duplicate_known_statse' do
531
+ branch = StateMachines::Branch.new(:except_from => :idling, :to => :idling, :on => :ignite)
532
+ assert_equal [:idling], branch.known_states
533
+ end
534
+ end
535
+
536
+ context 'WithNilRequirements' do
537
+ before(:each) do
538
+ @object = Object.new
539
+ @branch = StateMachines::Branch.new(:from => nil, :to => nil)
540
+ end
541
+
542
+ it 'should_match_empty_query' do
543
+ assert @branch.matches?(@object)
544
+ end
545
+
546
+ it 'should_match_if_all_requirements_match' do
547
+ assert @branch.matches?(@object, :from => nil, :to => nil)
548
+ end
549
+
550
+ it 'should_not_match_if_from_not_included' do
551
+ assert !@branch.matches?(@object, :from => :parked)
552
+ end
553
+
554
+ it 'should_not_match_if_to_not_included' do
555
+ assert !@branch.matches?(@object, :to => :idling)
556
+ end
557
+
558
+ it 'should_include_all_known_states' do
559
+ assert_equal [nil], @branch.known_states
560
+ end
561
+ end
562
+
563
+ context 'WithImplicitRequirement' do
564
+ before(:each) do
565
+ @branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
566
+ end
567
+
568
+ it 'should_create_an_event_requirement' do
569
+ assert_instance_of StateMachines::WhitelistMatcher, @branch.event_requirement
570
+ assert_equal [:ignite], @branch.event_requirement.values
571
+ end
572
+
573
+ it 'should_use_a_whitelist_from_matcher' do
574
+ assert_instance_of StateMachines::WhitelistMatcher, @branch.state_requirements.first[:from]
575
+ end
576
+
577
+ it 'should_use_a_whitelist_to_matcher' do
578
+ assert_instance_of StateMachines::WhitelistMatcher, @branch.state_requirements.first[:to]
579
+ end
580
+ end
581
+
582
+ context 'WithMultipleImplicitRequirements' do
583
+ before(:each) do
584
+ @object = Object.new
585
+ @branch = StateMachines::Branch.new(:parked => :idling, :idling => :first_gear, :on => :ignite)
586
+ end
587
+
588
+ it 'should_create_multiple_state_requirements' do
589
+ assert_equal 2, @branch.state_requirements.length
590
+ end
591
+
592
+ it 'should_not_match_event_as_state_requirement' do
593
+ assert !@branch.matches?(@object, :from => :on, :to => :ignite)
594
+ end
595
+
596
+ it 'should_match_if_from_included_in_any' do
597
+ assert @branch.matches?(@object, :from => :parked)
598
+ assert @branch.matches?(@object, :from => :idling)
599
+ end
600
+
601
+ it 'should_not_match_if_from_not_included_in_any' do
602
+ assert !@branch.matches?(@object, :from => :first_gear)
603
+ end
604
+
605
+ it 'should_match_if_to_included_in_any' do
606
+ assert @branch.matches?(@object, :to => :idling)
607
+ assert @branch.matches?(@object, :to => :first_gear)
608
+ end
609
+
610
+ it 'should_not_match_if_to_not_included_in_any' do
611
+ assert !@branch.matches?(@object, :to => :parked)
612
+ end
613
+
614
+ it 'should_match_if_all_options_match' do
615
+ assert @branch.matches?(@object, :from => :parked, :to => :idling, :on => :ignite)
616
+ assert @branch.matches?(@object, :from => :idling, :to => :first_gear, :on => :ignite)
617
+ end
618
+
619
+ it 'should_not_match_if_any_options_do_not_match' do
620
+ assert !@branch.matches?(@object, :from => :parked, :to => :idling, :on => :park)
621
+ assert !@branch.matches?(@object, :from => :parked, :to => :first_gear, :on => :park)
622
+ end
623
+
624
+ it 'should_include_all_known_states' do
625
+ assert_equal [:first_gear, :idling, :parked], @branch.known_states.sort_by { |state| state.to_s }
626
+ end
627
+
628
+ it 'should_not_duplicate_known_statse' do
629
+ branch = StateMachines::Branch.new(:parked => :idling, :first_gear => :idling)
630
+ assert_equal [:first_gear, :idling, :parked], branch.known_states.sort_by { |state| state.to_s }
631
+ end
632
+ end
633
+
634
+ context 'WithImplicitFromRequirementMatcher' do
635
+ before(:each) do
636
+ @matcher = StateMachines::BlacklistMatcher.new(:parked)
637
+ @branch = StateMachines::Branch.new(@matcher => :idling)
638
+ end
639
+
640
+ it 'should_not_convert_from_to_whitelist_matcher' do
641
+ assert_equal @matcher, @branch.state_requirements.first[:from]
642
+ end
643
+
644
+ it 'should_convert_to_to_whitelist_matcher' do
645
+ assert_instance_of StateMachines::WhitelistMatcher, @branch.state_requirements.first[:to]
646
+ end
647
+ end
648
+
649
+ context 'WithImplicitToRequirementMatcher' do
650
+ before(:each) do
651
+ @matcher = StateMachines::BlacklistMatcher.new(:idling)
652
+ @branch = StateMachines::Branch.new(:parked => @matcher)
653
+ end
654
+
655
+ it 'should_convert_from_to_whitelist_matcher' do
656
+ assert_instance_of StateMachines::WhitelistMatcher, @branch.state_requirements.first[:from]
657
+ end
658
+
659
+ it 'should_not_convert_to_to_whitelist_matcher' do
660
+ assert_equal @matcher, @branch.state_requirements.first[:to]
661
+ end
662
+ end
663
+
664
+ context 'WithImplicitAndExplicitRequirements' do
665
+ before(:each) do
666
+ @branch = StateMachines::Branch.new(:parked => :idling, :from => :parked)
667
+ end
668
+
669
+ it 'should_create_multiple_requirements' do
670
+ assert_equal 2, @branch.state_requirements.length
671
+ end
672
+
673
+ it 'should_create_implicit_requirements_for_implicit_options' do
674
+ assert(@branch.state_requirements.any? do |state_requirement|
675
+ state_requirement[:from].values == [:parked] && state_requirement[:to].values == [:idling]
676
+ end)
677
+ end
678
+
679
+ it 'should_create_implicit_requirements_for_explicit_options' do
680
+ assert(@branch.state_requirements.any? do |state_requirement|
681
+ state_requirement[:from].values == [:from] && state_requirement[:to].values == [:parked]
682
+ end)
683
+ end
684
+ end
685
+
686
+ context 'WithIfConditional' do
687
+ before(:each) do
688
+ @object = Object.new
689
+ end
690
+
691
+ it 'should_have_an_if_condition' do
692
+ branch = StateMachines::Branch.new(:if => lambda { true })
693
+ assert_not_nil branch.if_condition
694
+ end
695
+
696
+ it 'should_match_if_true' do
697
+ branch = StateMachines::Branch.new(:if => lambda { true })
698
+ assert branch.matches?(@object)
699
+ end
700
+
701
+ it 'should_not_match_if_false' do
702
+ branch = StateMachines::Branch.new(:if => lambda { false })
703
+ assert !branch.matches?(@object)
704
+ end
705
+
706
+ it 'should_be_nil_if_unmatched' do
707
+ branch = StateMachines::Branch.new(:if => lambda { false })
708
+ assert_nil branch.match(@object)
709
+ end
710
+ end
711
+
712
+ context 'WithMultipleIfConditionals' do
713
+ before(:each) do
714
+ @object = Object.new
715
+ end
716
+
717
+ it 'should_match_if_all_are_true' do
718
+ branch = StateMachines::Branch.new(:if => [lambda { true }, lambda { true }])
719
+ assert branch.match(@object)
720
+ end
721
+
722
+ it 'should_not_match_if_any_are_false' do
723
+ branch = StateMachines::Branch.new(:if => [lambda { true }, lambda { false }])
724
+ assert !branch.match(@object)
725
+
726
+ branch = StateMachines::Branch.new(:if => [lambda { false }, lambda { true }])
727
+ assert !branch.match(@object)
728
+ end
729
+ end
730
+
731
+ context 'WithUnlessConditional' do
732
+ before(:each) do
733
+ @object = Object.new
734
+ end
735
+
736
+ it 'should_have_an_unless_condition' do
737
+ branch = StateMachines::Branch.new(:unless => lambda { true })
738
+ assert_not_nil branch.unless_condition
739
+ end
740
+
741
+ it 'should_match_if_false' do
742
+ branch = StateMachines::Branch.new(:unless => lambda { false })
743
+ assert branch.matches?(@object)
744
+ end
745
+
746
+ it 'should_not_match_if_true' do
747
+ branch = StateMachines::Branch.new(:unless => lambda { true })
748
+ assert !branch.matches?(@object)
749
+ end
750
+
751
+ it 'should_be_nil_if_unmatched' do
752
+ branch = StateMachines::Branch.new(:unless => lambda { true })
753
+ assert_nil branch.match(@object)
754
+ end
755
+ end
756
+
757
+ context 'WithMultipleUnlessConditionals' do
758
+ before(:each) do
759
+ @object = Object.new
760
+ end
761
+
762
+ it 'should_match_if_all_are_false' do
763
+ branch = StateMachines::Branch.new(:unless => [lambda { false }, lambda { false }])
764
+ assert branch.match(@object)
765
+ end
766
+
767
+ it 'should_not_match_if_any_are_true' do
768
+ branch = StateMachines::Branch.new(:unless => [lambda { true }, lambda { false }])
769
+ assert !branch.match(@object)
770
+
771
+ branch = StateMachines::Branch.new(:unless => [lambda { false }, lambda { true }])
772
+ assert !branch.match(@object)
773
+ end
774
+ end
775
+
776
+ context 'WithConflictingConditionals' do
777
+ before(:each) do
778
+ @object = Object.new
779
+ end
780
+
781
+ it 'should_match_if_if_is_true_and_unless_is_false' do
782
+ branch = StateMachines::Branch.new(:if => lambda { true }, :unless => lambda { false })
783
+ assert branch.match(@object)
784
+ end
785
+
786
+ it 'should_not_match_if_if_is_false_and_unless_is_true' do
787
+ branch = StateMachines::Branch.new(:if => lambda { false }, :unless => lambda { true })
788
+ assert !branch.match(@object)
789
+ end
790
+
791
+ it 'should_not_match_if_if_is_false_and_unless_is_false' do
792
+ branch = StateMachines::Branch.new(:if => lambda { false }, :unless => lambda { false })
793
+ assert !branch.match(@object)
794
+ end
795
+
796
+ it 'should_not_match_if_if_is_true_and_unless_is_true' do
797
+ branch = StateMachines::Branch.new(:if => lambda { true }, :unless => lambda { true })
798
+ assert !branch.match(@object)
799
+ end
800
+ end
801
+
802
+ context 'WithoutGuards' do
803
+ before(:each) do
804
+ @object = Object.new
805
+ end
806
+
807
+ it 'should_match_if_if_is_false' do
808
+ branch = StateMachines::Branch.new(:if => lambda { false })
809
+ assert branch.matches?(@object, :guard => false)
810
+ end
811
+
812
+ it 'should_match_if_if_is_true' do
813
+ branch = StateMachines::Branch.new(:if => lambda { true })
814
+ assert branch.matches?(@object, :guard => false)
815
+ end
816
+
817
+ it 'should_match_if_unless_is_false' do
818
+ branch = StateMachines::Branch.new(:unless => lambda { false })
819
+ assert branch.matches?(@object, :guard => false)
820
+ end
821
+
822
+ it 'should_match_if_unless_is_true' do
823
+ branch = StateMachines::Branch.new(:unless => lambda { true })
824
+ assert branch.matches?(@object, :guard => false)
825
+ end
826
+ end
827
+ end