state_machines 0.0.1 → 0.0.2

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