state_machine 0.4.1 → 0.4.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.
@@ -0,0 +1,583 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class StateByDefaultTest < Test::Unit::TestCase
4
+ def setup
5
+ @machine = StateMachine::Machine.new(Class.new)
6
+ @state = StateMachine::State.new(@machine, 'on')
7
+ end
8
+
9
+ def test_should_have_a_machine
10
+ assert_equal @machine, @state.machine
11
+ end
12
+
13
+ def test_should_have_a_value
14
+ assert_equal 'on', @state.value
15
+ end
16
+
17
+ def test_should_not_have_any_methods
18
+ expected = {}
19
+ assert_equal expected, @state.methods
20
+ end
21
+
22
+ def test_should_not_be_initial
23
+ assert !@state.initial
24
+ end
25
+ end
26
+
27
+ class StateTest < Test::Unit::TestCase
28
+ def setup
29
+ @machine = StateMachine::Machine.new(Class.new)
30
+ end
31
+
32
+ def test_should_raise_exception_if_invalid_option_specified
33
+ assert_raise(ArgumentError) {StateMachine::State.new(@machine, 'on', :invalid => true)}
34
+ end
35
+ end
36
+
37
+ class StateWithNilValueTest < Test::Unit::TestCase
38
+ def setup
39
+ @klass = Class.new
40
+ @machine = StateMachine::Machine.new(@klass)
41
+ @state = StateMachine::State.new(@machine, nil)
42
+ end
43
+
44
+ def test_should_be_nil_without_object
45
+ assert_nil @state.value
46
+ end
47
+
48
+ def test_should_be_nil_with_object
49
+ assert_nil @state.value(@klass.new)
50
+ end
51
+
52
+ def test_should_not_redefine_nil_predicate
53
+ object = @klass.new
54
+ assert !object.nil?
55
+ assert !object.respond_to?('?')
56
+ end
57
+ end
58
+
59
+ class StateWithStringValueTest < Test::Unit::TestCase
60
+ def setup
61
+ @klass = Class.new
62
+ @machine = StateMachine::Machine.new(@klass)
63
+ @state = StateMachine::State.new(@machine, 'on')
64
+ end
65
+
66
+ def test_should_use_original_value_without_object
67
+ assert_equal 'on', @state.value
68
+ end
69
+
70
+ def test_should_use_original_value_with_object
71
+ assert_equal 'on', @state.value(@klass.new)
72
+ end
73
+
74
+ def test_should_define_predicate
75
+ object = @klass.new
76
+ assert object.respond_to?(:on?)
77
+ end
78
+ end
79
+
80
+ class StateWithSymbolicValueTest < Test::Unit::TestCase
81
+ def setup
82
+ @klass = Class.new
83
+ @machine = StateMachine::Machine.new(@klass)
84
+ @state = StateMachine::State.new(@machine, :on)
85
+ end
86
+
87
+ def test_should_use_original_value_without_object
88
+ assert_equal :on, @state.value
89
+ end
90
+
91
+ def test_should_use_original_value_with_object
92
+ assert_equal :on, @state.value(@klass.new)
93
+ end
94
+
95
+ def test_should_define_predicate
96
+ object = @klass.new
97
+ assert object.respond_to?(:on?)
98
+ end
99
+ end
100
+
101
+ class StateWithIntegerValueTest < Test::Unit::TestCase
102
+ def setup
103
+ @klass = Class.new
104
+ @machine = StateMachine::Machine.new(@klass)
105
+ @state = StateMachine::State.new(@machine, 1)
106
+ end
107
+
108
+ def test_should_use_original_value_without_object
109
+ assert_equal 1, @state.value
110
+ end
111
+
112
+ def test_should_use_original_value_with_object
113
+ assert_equal 1, @state.value(@klass.new)
114
+ end
115
+
116
+ def test_should_not_define_predicate
117
+ object = @klass.new
118
+ assert !object.respond_to?('1?')
119
+ end
120
+ end
121
+
122
+ class StateWithObjectValueTest < Test::Unit::TestCase
123
+ def setup
124
+ @klass = Class.new
125
+ @machine = StateMachine::Machine.new(@klass)
126
+ @value = Object.new
127
+ @state = StateMachine::State.new(@machine, @value)
128
+ end
129
+
130
+ def test_should_use_original_value_without_object
131
+ assert_equal @value, @state.value
132
+ end
133
+
134
+ def test_should_use_original_value_with_object
135
+ assert_equal @value, @state.value(@klass.new)
136
+ end
137
+
138
+ def test_should_not_define_predicate
139
+ object = @klass.new
140
+ assert !object.respond_to?("#{@value.inspect}?")
141
+ end
142
+ end
143
+
144
+ class StateWithLambdaValueTest < Test::Unit::TestCase
145
+ def setup
146
+ @klass = Class.new
147
+ @args = nil
148
+ @machine = StateMachine::Machine.new(@klass)
149
+ @value = lambda {|*args| @args = args; 'on'}
150
+ @state = StateMachine::State.new(@machine, @value)
151
+ end
152
+
153
+ def test_should_use_original_value_without_object
154
+ assert_equal @value, @state.value
155
+ end
156
+
157
+ def test_should_use_evaluated_value_with_object
158
+ assert_equal 'on', @state.value(@klass.new)
159
+ end
160
+
161
+ def test_should_pass_object_in_when_evaluating_value
162
+ object = @klass.new
163
+ @state.value(object)
164
+
165
+ assert_equal [object], @args
166
+ end
167
+
168
+ def test_should_not_define_predicate
169
+ object = @klass.new
170
+ assert !object.respond_to?("#{@value.inspect}?")
171
+ end
172
+ end
173
+
174
+ class StateInitialTest < Test::Unit::TestCase
175
+ def setup
176
+ @machine = StateMachine::Machine.new(Class.new)
177
+ @state = StateMachine::State.new(@machine, 'on', :initial => true)
178
+ end
179
+
180
+ def test_should_be_initial
181
+ assert @state.initial
182
+ end
183
+ end
184
+
185
+ class StateNotInitialTest < Test::Unit::TestCase
186
+ def setup
187
+ @machine = StateMachine::Machine.new(Class.new)
188
+ @state = StateMachine::State.new(@machine, 'on', :initial => false)
189
+ end
190
+
191
+ def test_should_not_be_initial
192
+ assert !@state.initial
193
+ end
194
+ end
195
+
196
+ class StateWithConflictingPredicateTest < Test::Unit::TestCase
197
+ def setup
198
+ @klass = Class.new do
199
+ def on?
200
+ true
201
+ end
202
+ end
203
+ @machine = StateMachine::Machine.new(@klass)
204
+ @state = StateMachine::State.new(@machine, 'on')
205
+ @object = @klass.new
206
+ end
207
+
208
+ def test_should_not_define_state_predicate
209
+ assert @object.on?
210
+ end
211
+ end
212
+
213
+ class StateWithNamespaceTest < Test::Unit::TestCase
214
+ def setup
215
+ @klass = Class.new do
216
+ def on?
217
+ true
218
+ end
219
+ end
220
+ @machine = StateMachine::Machine.new(@klass, :namespace => 'switch')
221
+ @state = StateMachine::State.new(@machine, 'on')
222
+ @object = @klass.new
223
+ end
224
+
225
+ def test_should_namespace_predicate
226
+ assert @object.respond_to?(:switch_on?)
227
+ end
228
+ end
229
+
230
+ class StateAfterBeingCopiedTest < Test::Unit::TestCase
231
+ def setup
232
+ @machine = StateMachine::Machine.new(Class.new)
233
+ @state = StateMachine::State.new(@machine, 'on')
234
+ @copied_state = @state.dup
235
+ end
236
+
237
+ def test_should_not_have_the_same_collection_of_methods
238
+ assert_not_same @state.methods, @copied_state.methods
239
+ end
240
+ end
241
+
242
+ class StateWithContextTest < Test::Unit::TestCase
243
+ def setup
244
+ @klass = Class.new
245
+ @machine = StateMachine::Machine.new(@klass)
246
+ @ancestors = @klass.ancestors
247
+ @state = StateMachine::State.new(@machine, 'on')
248
+
249
+ color_method = nil
250
+ glow_method = nil
251
+ @state.context do
252
+ def color
253
+ 'green'
254
+ end
255
+ color_method = instance_method(:color)
256
+
257
+ def glow
258
+ 3
259
+ end
260
+ glow_method = instance_method(:glow)
261
+ end
262
+
263
+ @color_method = color_method
264
+ @glow_method = glow_method
265
+ end
266
+
267
+ def test_should_include_new_module_in_owner_class
268
+ assert_not_equal @ancestors, @klass.ancestors
269
+ assert_equal 1, @klass.ancestors.size - @ancestors.size
270
+ end
271
+
272
+ def test_should_define_each_context_method_in_owner_class
273
+ %w(color glow).each {|method| assert @klass.instance_methods.include?(method)}
274
+ end
275
+
276
+ def test_should_not_use_context_methods_as_owner_class_methods
277
+ assert_not_equal @color_method, @klass.instance_method(:color)
278
+ assert_not_equal @glow_method, @klass.instance_method(:glow)
279
+ end
280
+
281
+ def test_should_include_context_methods_in_state_methods
282
+ assert_equal @color_method, @state.methods['color']
283
+ assert_equal @glow_method, @state.methods['glow']
284
+ end
285
+ end
286
+
287
+ class StateWithMultipleContextsTest < Test::Unit::TestCase
288
+ def setup
289
+ @klass = Class.new
290
+ @machine = StateMachine::Machine.new(@klass)
291
+ @ancestors = @klass.ancestors
292
+ @state = StateMachine::State.new(@machine, 'on')
293
+
294
+ color_method = nil
295
+ @state.context do
296
+ def color
297
+ 'green'
298
+ end
299
+
300
+ color_method = instance_method(:color)
301
+ end
302
+ @color_method = color_method
303
+
304
+ glow_method = nil
305
+ @state.context do
306
+ def glow
307
+ 3
308
+ end
309
+
310
+ glow_method = instance_method(:glow)
311
+ end
312
+ @glow_method = glow_method
313
+ end
314
+
315
+ def test_should_include_new_module_in_owner_class
316
+ assert_not_equal @ancestors, @klass.ancestors
317
+ assert_equal 2, @klass.ancestors.size - @ancestors.size
318
+ end
319
+
320
+ def test_should_define_each_context_method_in_owner_class
321
+ %w(color glow).each {|method| assert @klass.instance_methods.include?(method)}
322
+ end
323
+
324
+ def test_should_not_use_context_methods_as_owner_class_methods
325
+ assert_not_equal @color_method, @klass.instance_method(:color)
326
+ assert_not_equal @glow_method, @klass.instance_method(:glow)
327
+ end
328
+
329
+ def test_should_include_context_methods_in_state_methods
330
+ assert_equal @color_method, @state.methods['color']
331
+ assert_equal @glow_method, @state.methods['glow']
332
+ end
333
+ end
334
+
335
+ class StateWithExistingContextMethodTest < Test::Unit::TestCase
336
+ def setup
337
+ @klass = Class.new do
338
+ def color
339
+ 'always green'
340
+ end
341
+ end
342
+ @original_color_method = @klass.instance_method(:color)
343
+
344
+ @machine = StateMachine::Machine.new(@klass)
345
+ @state = StateMachine::State.new(@machine, 'on')
346
+ @state.context do
347
+ def color
348
+ 'green'
349
+ end
350
+ end
351
+ end
352
+
353
+ def test_should_not_override_method
354
+ assert_equal @original_color_method, @klass.instance_method(:color)
355
+ end
356
+ end
357
+
358
+ class StateWithRedefinedContextMethodTest < Test::Unit::TestCase
359
+ def setup
360
+ @klass = Class.new
361
+ @machine = StateMachine::Machine.new(@klass)
362
+ @state = StateMachine::State.new(@machine, 'on')
363
+
364
+ old_color_method = nil
365
+ @state.context do
366
+ def color
367
+ 'green'
368
+ end
369
+ old_color_method = instance_method(:color)
370
+ end
371
+ @old_color_method = old_color_method
372
+
373
+ current_color_method = nil
374
+ @state.context do
375
+ def color
376
+ 'green'
377
+ end
378
+ current_color_method = instance_method(:color)
379
+ end
380
+ @current_color_method = current_color_method
381
+ end
382
+
383
+ def test_should_track_latest_defined_method
384
+ assert_equal @current_color_method, @state.methods['color']
385
+ end
386
+ end
387
+
388
+ class StateWithInvalidMethodCallTest < Test::Unit::TestCase
389
+ def setup
390
+ @klass = Class.new
391
+ @machine = StateMachine::Machine.new(@klass)
392
+ @ancestors = @klass.ancestors
393
+ @state = StateMachine::State.new(@machine, 'on')
394
+ @state.context do
395
+ def color
396
+ 'green'
397
+ end
398
+ end
399
+
400
+ @object = @klass.new
401
+ end
402
+
403
+ def test_should_raise_an_exception
404
+ assert_raise(NoMethodError) { @state.call(@object, :invalid) }
405
+ end
406
+ end
407
+
408
+ class StateWithValidMethodCallTest < Test::Unit::TestCase
409
+ def setup
410
+ @klass = Class.new
411
+ @machine = StateMachine::Machine.new(@klass)
412
+ @ancestors = @klass.ancestors
413
+ @state = StateMachine::State.new(@machine, 'on')
414
+ @state.context do
415
+ def color(arg = nil)
416
+ block_given? ? [arg, yield] : arg
417
+ end
418
+ end
419
+
420
+ @object = @klass.new
421
+ end
422
+
423
+ def test_should_not_raise_an_exception
424
+ assert_nothing_raised { @state.call(@object, :color) }
425
+ end
426
+
427
+ def test_should_pass_arguments_through
428
+ assert_equal 1, @state.call(@object, :color, 1)
429
+ end
430
+
431
+ def test_should_pass_blocks_through
432
+ assert_equal [nil, 1], @state.call(@object, :color) {1}
433
+ end
434
+
435
+ def test_should_pass_both_arguments_and_blocks_through
436
+ assert_equal [1, 2], @state.call(@object, :color, 1) {2}
437
+ end
438
+ end
439
+
440
+ class StateIdGeneratorTest < Test::Unit::TestCase
441
+ def test_should_use_nil_for_nil
442
+ assert_equal 'nil', StateMachine::State.id_for(nil)
443
+ end
444
+
445
+ def test_should_use_to_s_for_string
446
+ assert_equal 'on', StateMachine::State.id_for('on')
447
+ end
448
+
449
+ def test_should_use_to_s_for_symbol
450
+ assert_equal 'on', StateMachine::State.id_for(:on)
451
+ end
452
+
453
+ def test_should_use_to_s_for_number
454
+ assert_equal '1', StateMachine::State.id_for(1)
455
+ end
456
+
457
+ def test_should_use_to_s_for_object
458
+ class << (state = Object.new)
459
+ def to_s
460
+ 'on'
461
+ end
462
+ end
463
+
464
+ assert_equal 'on', StateMachine::State.id_for(state)
465
+ end
466
+
467
+ def test_should_use_lambda_id_for_proc
468
+ state = lambda {}
469
+
470
+ assert_equal "lambda#{state.object_id.abs}", StateMachine::State.id_for(state)
471
+ end
472
+ end
473
+
474
+ begin
475
+ # Load library
476
+ require 'rubygems'
477
+ require 'graphviz'
478
+
479
+ class StateDrawingTest < Test::Unit::TestCase
480
+ def setup
481
+ @machine = StateMachine::Machine.new(Class.new)
482
+ @state = StateMachine::State.new(@machine, 'on')
483
+
484
+ graph = GraphViz.new('G')
485
+ @node = @state.draw(graph)
486
+ end
487
+
488
+ def test_should_use_circle_shape
489
+ assert_equal 'circle', @node['shape']
490
+ end
491
+
492
+ def test_should_enabled_fixedsize
493
+ assert_equal 'true', @node['fixedsize']
494
+ end
495
+
496
+ def test_should_set_width_to_one
497
+ assert_equal '1', @node['width']
498
+ end
499
+
500
+ def test_should_set_height_to_one
501
+ assert_equal '1', @node['height']
502
+ end
503
+
504
+ def test_should_use_value_as_name
505
+ assert_equal 'on', @node.name
506
+ end
507
+
508
+ def test_should_use_stringified_value_as_label
509
+ assert_equal 'on', @node['label']
510
+ end
511
+ end
512
+
513
+ class StateDrawingInitialTest < Test::Unit::TestCase
514
+ def setup
515
+ @machine = StateMachine::Machine.new(Class.new)
516
+ @state = StateMachine::State.new(@machine, 'on', :initial => true)
517
+
518
+ graph = GraphViz.new('G')
519
+ @node = @state.draw(graph)
520
+ end
521
+
522
+ def test_should_use_doublecircle_as_shape
523
+ assert_equal 'doublecircle', @node['shape']
524
+ end
525
+ end
526
+
527
+ class StateDrawingNilTest < Test::Unit::TestCase
528
+ def setup
529
+ @machine = StateMachine::Machine.new(Class.new)
530
+ @state = StateMachine::State.new(@machine, nil)
531
+
532
+ graph = GraphViz.new('G')
533
+ @node = @state.draw(graph)
534
+ end
535
+
536
+ def test_should_use_value_as_name
537
+ assert_equal 'nil', @node.name
538
+ end
539
+
540
+ def test_should_use_stringified_value_as_label
541
+ assert_equal 'nil', @node['label']
542
+ end
543
+ end
544
+
545
+ class StateDrawingProcTest < Test::Unit::TestCase
546
+ def setup
547
+ @machine = StateMachine::Machine.new(Class.new)
548
+ @value = lambda {}
549
+ @state = StateMachine::State.new(@machine, @value)
550
+
551
+ graph = GraphViz.new('G')
552
+ @node = @state.draw(graph)
553
+ end
554
+
555
+ def test_should_use_lambda_id_as_name
556
+ assert_equal "lambda#{@value.object_id.abs}", @node.name
557
+ end
558
+
559
+ def test_should_use_asterisk_as_label
560
+ assert_equal '*', @node['label']
561
+ end
562
+ end
563
+
564
+ class StateDrawingSymbolTest < Test::Unit::TestCase
565
+ def setup
566
+ @machine = StateMachine::Machine.new(Class.new)
567
+ @state = StateMachine::State.new(@machine, :on)
568
+
569
+ graph = GraphViz.new('G')
570
+ @node = @state.draw(graph)
571
+ end
572
+
573
+ def test_should_use_stringified_value_as_name
574
+ assert_equal 'on', @node.name
575
+ end
576
+
577
+ def test_should_use_stringified_value_as_label
578
+ assert_equal 'on', @node['label']
579
+ end
580
+ end
581
+ rescue LoadError
582
+ $stderr.puts 'Skipping GraphViz StateMachine::State tests. `gem install ruby-graphviz` and try again.'
583
+ end