workflow 1.2.0 → 2.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,107 +0,0 @@
1
- require 'test_helper'
2
-
3
- $VERBOSE = false
4
- require 'active_record'
5
- require 'logger'
6
- require 'sqlite3'
7
- require 'workflow'
8
- require 'mocha/setup'
9
- require 'stringio'
10
- require 'protected_attributes' if ActiveRecord::VERSION::MAJOR >= 4
11
-
12
- ActiveRecord::Migration.verbose = false
13
-
14
- class AttrProtectedTestOrder < ActiveRecord::Base
15
- include Workflow
16
-
17
- workflow do
18
- state :submitted do
19
- event :accept, :transitions_to => :accepted, :meta => {:doc_weight => 8} do |reviewer, args|
20
- end
21
- end
22
- state :accepted do
23
- event :ship, :transitions_to => :shipped
24
- end
25
- state :shipped
26
- end
27
-
28
- attr_accessible :title # protecting all the other attributes
29
-
30
- end
31
-
32
- AttrProtectedTestOrder.logger = Logger.new(STDOUT) # active_record 2.3 expects a logger instance
33
- AttrProtectedTestOrder.logger.level = Logger::WARN # switch to Logger::DEBUG to see the SQL statements
34
-
35
- class AttrProtectedTest < ActiveRecordTestCase
36
-
37
- def setup
38
- super
39
-
40
- ActiveRecord::Schema.define do
41
- create_table :attr_protected_test_orders do |t|
42
- t.string :title, :null => false
43
- t.string :workflow_state
44
- end
45
- end
46
-
47
- exec "INSERT INTO attr_protected_test_orders(title, workflow_state) VALUES('order1', 'submitted')"
48
- exec "INSERT INTO attr_protected_test_orders(title, workflow_state) VALUES('order2', 'accepted')"
49
- exec "INSERT INTO attr_protected_test_orders(title, workflow_state) VALUES('order3', 'accepted')"
50
- exec "INSERT INTO attr_protected_test_orders(title, workflow_state) VALUES('order4', 'accepted')"
51
- exec "INSERT INTO attr_protected_test_orders(title, workflow_state) VALUES('order5', 'accepted')"
52
- exec "INSERT INTO attr_protected_test_orders(title, workflow_state) VALUES('protected order', 'submitted')"
53
- end
54
-
55
- def assert_state(title, expected_state, klass = AttrProtectedTestOrder)
56
- o = klass.find_by_title(title)
57
- assert_equal expected_state, o.read_attribute(klass.workflow_column)
58
- o
59
- end
60
-
61
- test 'cannot mass-assign workflow_state if attr_protected' do
62
- o = AttrProtectedTestOrder.find_by_title('order1')
63
- assert_equal 'submitted', o.read_attribute(:workflow_state)
64
- AttrProtectedTestOrder.logger.level = Logger::ERROR # ignore warnings
65
- o.update_attributes :workflow_state => 'some_bad_value'
66
- AttrProtectedTestOrder.logger.level = Logger::WARN
67
- assert_equal 'submitted', o.read_attribute(:workflow_state)
68
- o.update_attribute :workflow_state, 'some_overridden_value'
69
- assert_equal 'some_overridden_value', o.read_attribute(:workflow_state)
70
- end
71
-
72
- test 'immediately save the new workflow_state on state machine transition' do
73
- o = assert_state 'order2', 'accepted'
74
- assert o.ship!
75
- assert_state 'order2', 'shipped'
76
- end
77
-
78
- test 'persist workflow_state in the db and reload' do
79
- o = assert_state 'order3', 'accepted'
80
- assert_equal :accepted, o.current_state.name
81
- o.ship! # should save in the database, no `o.save!` needed
82
-
83
- assert_state 'order3', 'shipped'
84
-
85
- o.reload
86
- assert_equal 'shipped', o.read_attribute(:workflow_state)
87
- end
88
-
89
- test 'default workflow column should be workflow_state' do
90
- o = assert_state 'order4', 'accepted'
91
- assert_equal :workflow_state, o.class.workflow_column
92
- end
93
-
94
- test 'access workflow specification' do
95
- assert_equal 3, AttrProtectedTestOrder.workflow_spec.states.length
96
- assert_equal ['submitted', 'accepted', 'shipped'].sort,
97
- AttrProtectedTestOrder.workflow_spec.state_names.map{|n| n.to_s}.sort
98
- end
99
-
100
- test 'current state object' do
101
- o = assert_state 'order5', 'accepted'
102
- assert_equal 'accepted', o.current_state.to_s
103
- assert_equal 1, o.current_state.events.length
104
- end
105
-
106
- end
107
-
@@ -1,36 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_helper')
2
- require 'workflow'
3
-
4
- class BeforeTransitionTest < Test::Unit::TestCase
5
- class MyFlow
6
- attr_reader :history
7
- def initialize
8
- @history = []
9
- end
10
-
11
- include Workflow
12
- workflow do
13
- state :first do
14
- event :forward, :transitions_to => :second do
15
- @history << 'forward'
16
- end
17
- end
18
- state :second do
19
- event :back, :transitions_to => :first do
20
- @history << 'back'
21
- end
22
- end
23
-
24
- before_transition { @history << 'before' }
25
- after_transition { @history << 'after' }
26
- on_transition { @history << 'on' }
27
- end
28
- end
29
-
30
- test 'that before_transition is run before the action' do
31
- flow = MyFlow.new
32
- flow.forward!
33
- flow.back!
34
- assert flow.history == ['before', 'forward', 'on', 'after', 'before', 'back', 'on', 'after']
35
- end
36
- end
@@ -1,46 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_helper')
2
- require 'couchtiny'
3
- require 'couchtiny/document'
4
- require 'workflow'
5
-
6
- class User < CouchTiny::Document
7
- include Workflow
8
- workflow do
9
- state :submitted do
10
- event :activate_via_link, :transitions_to => :proved_email
11
- end
12
- state :proved_email
13
- end
14
-
15
- def load_workflow_state
16
- self[:workflow_state]
17
- end
18
-
19
- def persist_workflow_state(new_value)
20
- self[:workflow_state] = new_value
21
- save!
22
- end
23
- end
24
-
25
-
26
- class CouchtinyExample < Test::Unit::TestCase
27
-
28
- def setup
29
- db = CouchTiny::Database.url("http://127.0.0.1:5984/test-workflow")
30
- db.delete_database! rescue nil
31
- db.create_database!
32
- User.use_database db
33
- end
34
-
35
- test 'CouchDB persistence' do
36
- user = User.new :email => 'manya@example.com'
37
- user.save!
38
- assert user.submitted?
39
- user.activate_via_link!
40
- assert user.proved_email?
41
-
42
- reloaded_user = User.get user.id
43
- puts reloaded_user.inspect
44
- assert reloaded_user.proved_email?, 'Reloaded user should have the desired workflow state'
45
- end
46
- end
@@ -1,60 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_helper')
2
- require 'workflow'
3
- class InheritanceTest < ActiveRecordTestCase
4
-
5
- test '#69 inheritance' do
6
- class Animal
7
- include Workflow
8
-
9
- workflow do
10
-
11
- state :conceived do
12
- event :birth, :transition_to => :born
13
- end
14
-
15
- state :born do
16
-
17
- end
18
- end
19
- end
20
-
21
- class Cat < Animal
22
- include Workflow
23
- workflow do
24
-
25
- state :upset do
26
- event :scratch, :transition_to => :hiding
27
- end
28
-
29
- state :hiding do
30
-
31
- end
32
- end
33
- end
34
-
35
- assert_equal [:born, :conceived] , sort_sym_array(Animal.workflow_spec.states.keys)
36
- assert_equal [:hiding, :upset], sort_sym_array(Cat.workflow_spec.states.keys), "Workflow definitions are not inherited"
37
-
38
- animal = Animal.new
39
- cat = Cat.new
40
-
41
- animal.birth!
42
-
43
- assert_raise NoMethodError, 'Methods defined by the old workflow spec should have be gone away' do
44
- cat.birth!
45
- end
46
-
47
- assert_equal [:birth!, :halt!, :process_event!], bang_methods(animal)
48
- assert_equal [:halt!, :process_event!, :scratch!], bang_methods(cat)
49
- end
50
-
51
- def sort_sym_array(a)
52
- a.sort { |a, b| a.to_s <=> b.to_s } # workaround for Ruby 1.8.7
53
- end
54
-
55
- def bang_methods(obj)
56
- non_trivial_methods = obj.public_methods-Object.public_methods
57
- methods_with_bang = non_trivial_methods.select {|m| m =~ /!$/}
58
- sort_sym_array(methods_with_bang).map {|m| m.to_sym}
59
- end
60
- end
@@ -1,584 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_helper')
2
-
3
- $VERBOSE = false
4
- require 'active_record'
5
- require 'sqlite3'
6
- require 'workflow'
7
- require 'mocha/setup'
8
- require 'stringio'
9
- #require 'ruby-debug'
10
-
11
- ActiveRecord::Migration.verbose = false
12
-
13
- class Order < ActiveRecord::Base
14
- include Workflow
15
- workflow do
16
- state :submitted do
17
- event :accept, :transitions_to => :accepted, :meta => {:weight => 8} do |reviewer, args|
18
- end
19
- end
20
- state :accepted do
21
- event :ship, :transitions_to => :shipped
22
- end
23
- state :shipped
24
- end
25
- end
26
-
27
- class LegacyOrder < ActiveRecord::Base
28
- include Workflow
29
-
30
- workflow_column :foo_bar # use this legacy database column for persistence
31
-
32
- workflow do
33
- state :submitted do
34
- event :accept, :transitions_to => :accepted, :meta => {:weight => 8} do |reviewer, args|
35
- end
36
- end
37
- state :accepted do
38
- event :ship, :transitions_to => :shipped
39
- end
40
- state :shipped
41
- end
42
- end
43
-
44
- class Image < ActiveRecord::Base
45
- include Workflow
46
-
47
- workflow_column :status
48
-
49
- workflow do
50
- state :unconverted do
51
- event :convert, :transitions_to => :converted
52
- end
53
- state :converted
54
- end
55
- end
56
-
57
- class SmallImage < Image
58
- end
59
-
60
- class SpecialSmallImage < SmallImage
61
- end
62
-
63
- class MainTest < ActiveRecordTestCase
64
-
65
- def setup
66
- super
67
-
68
- ActiveRecord::Schema.define do
69
- create_table :orders do |t|
70
- t.string :title, :null => false
71
- t.string :workflow_state
72
- end
73
- end
74
-
75
- exec "INSERT INTO orders(title, workflow_state) VALUES('some order', 'accepted')"
76
-
77
- ActiveRecord::Schema.define do
78
- create_table :legacy_orders do |t|
79
- t.string :title, :null => false
80
- t.string :foo_bar
81
- end
82
- end
83
-
84
- exec "INSERT INTO legacy_orders(title, foo_bar) VALUES('some order', 'accepted')"
85
-
86
- ActiveRecord::Schema.define do
87
- create_table :images do |t|
88
- t.string :title, :null => false
89
- t.string :state
90
- t.string :type
91
- end
92
- end
93
- end
94
-
95
- def assert_state(title, expected_state, klass = Order)
96
- o = klass.find_by_title(title)
97
- assert_equal expected_state, o.read_attribute(klass.workflow_column)
98
- o
99
- end
100
-
101
- test 'immediately save the new workflow_state on state machine transition' do
102
- o = assert_state 'some order', 'accepted'
103
- assert o.ship!
104
- assert_state 'some order', 'shipped'
105
- end
106
-
107
- test 'immediately save the new workflow_state on state machine transition with custom column name' do
108
- o = assert_state 'some order', 'accepted', LegacyOrder
109
- assert o.ship!
110
- assert_state 'some order', 'shipped', LegacyOrder
111
- end
112
-
113
- test 'persist workflow_state in the db and reload' do
114
- o = assert_state 'some order', 'accepted'
115
- assert_equal :accepted, o.current_state.name
116
- o.ship!
117
- o.save!
118
-
119
- assert_state 'some order', 'shipped'
120
-
121
- o.reload
122
- assert_equal 'shipped', o.read_attribute(:workflow_state)
123
- end
124
-
125
- test 'persist workflow_state in the db with_custom_name and reload' do
126
- o = assert_state 'some order', 'accepted', LegacyOrder
127
- assert_equal :accepted, o.current_state.name
128
- o.ship!
129
- o.save!
130
-
131
- assert_state 'some order', 'shipped', LegacyOrder
132
-
133
- o.reload
134
- assert_equal 'shipped', o.read_attribute(:foo_bar)
135
- end
136
-
137
- test 'default workflow column should be workflow_state' do
138
- o = assert_state 'some order', 'accepted'
139
- assert_equal :workflow_state, o.class.workflow_column
140
- end
141
-
142
- test 'custom workflow column should be foo_bar' do
143
- o = assert_state 'some order', 'accepted', LegacyOrder
144
- assert_equal :foo_bar, o.class.workflow_column
145
- end
146
-
147
- test 'access workflow specification' do
148
- assert_equal 3, Order.workflow_spec.states.length
149
- assert_equal ['submitted', 'accepted', 'shipped'].sort,
150
- Order.workflow_spec.state_names.map{|n| n.to_s}.sort
151
- end
152
-
153
- test 'current state object' do
154
- o = assert_state 'some order', 'accepted'
155
- assert_equal 'accepted', o.current_state.to_s
156
- assert_equal 1, o.current_state.events.length
157
- end
158
-
159
- test 'on_entry and on_exit invoked' do
160
- c = Class.new
161
- callbacks = mock()
162
- callbacks.expects(:my_on_exit_new).once
163
- callbacks.expects(:my_on_entry_old).once
164
- c.class_eval do
165
- include Workflow
166
- workflow do
167
- state :new do
168
- event :age, :transitions_to => :old
169
- end
170
- on_exit do
171
- callbacks.my_on_exit_new
172
- end
173
- state :old
174
- on_entry do
175
- callbacks.my_on_entry_old
176
- end
177
- on_exit do
178
- fail "wrong on_exit executed"
179
- end
180
- end
181
- end
182
-
183
- o = c.new
184
- assert_equal 'new', o.current_state.to_s
185
- o.age!
186
- end
187
-
188
- test 'on_transition invoked' do
189
- callbacks = mock()
190
- callbacks.expects(:on_tran).once # this is validated at the end
191
- c = Class.new
192
- c.class_eval do
193
- include Workflow
194
- workflow do
195
- state :one do
196
- event :increment, :transitions_to => :two
197
- end
198
- state :two
199
- on_transition do |from, to, triggering_event, *event_args|
200
- callbacks.on_tran
201
- end
202
- end
203
- end
204
- assert_not_nil c.workflow_spec.on_transition_proc
205
- c.new.increment!
206
- end
207
-
208
- test 'access event meta information' do
209
- c = Class.new
210
- c.class_eval do
211
- include Workflow
212
- workflow do
213
- state :main, :meta => {:importance => 8}
214
- state :supplemental, :meta => {:importance => 1}
215
- end
216
- end
217
- assert_equal 1, c.workflow_spec.states[:supplemental].meta[:importance]
218
- end
219
-
220
- test 'initial state' do
221
- c = Class.new
222
- c.class_eval do
223
- include Workflow
224
- workflow { state :one; state :two }
225
- end
226
- assert_equal 'one', c.new.current_state.to_s
227
- end
228
-
229
- test 'nil as initial state' do
230
- exec "INSERT INTO orders(title, workflow_state) VALUES('nil state', NULL)"
231
- o = Order.find_by_title('nil state')
232
- assert o.submitted?, 'if workflow_state is nil, the initial state should be assumed'
233
- assert !o.shipped?
234
- end
235
-
236
- test 'initial state immediately set as ActiveRecord attribute for new objects' do
237
- o = Order.create(:title => 'new object')
238
- assert_equal 'submitted', o.read_attribute(:workflow_state)
239
- end
240
-
241
- test 'question methods for state' do
242
- o = assert_state 'some order', 'accepted'
243
- assert o.accepted?
244
- assert !o.shipped?
245
- end
246
-
247
- test 'correct exception for event, that is not allowed in current state' do
248
- o = assert_state 'some order', 'accepted'
249
- assert_raise Workflow::NoTransitionAllowed do
250
- o.accept!
251
- end
252
- end
253
-
254
- test 'multiple events with the same name and different arguments lists from different states'
255
-
256
- test 'implicit transition callback' do
257
- args = mock()
258
- args.expects(:my_tran).once # this is validated at the end
259
- c = Class.new
260
- c.class_eval do
261
- include Workflow
262
- def my_transition(args)
263
- args.my_tran
264
- end
265
- workflow do
266
- state :one do
267
- event :my_transition, :transitions_to => :two
268
- end
269
- state :two
270
- end
271
-
272
- private
273
- def another_transition(args)
274
- args.another_tran
275
- end
276
- end
277
- a = c.new
278
- a.my_transition!(args)
279
- end
280
-
281
- test '#53 Support for non public transition callbacks' do
282
- args = mock()
283
- args.expects(:log).with('in private callback').once
284
- args.expects(:log).with('in protected callback in the base class').once
285
- args.expects(:log).with('in protected callback `on_assigned_entry`').once
286
-
287
- b = Class.new # the base class with a protected callback
288
- b.class_eval do
289
- protected
290
- def assign_old(args)
291
- args.log('in protected callback in the base class')
292
- end
293
-
294
- end
295
-
296
- c = Class.new(b) # inheriting class with an additional protected callback
297
- c.class_eval do
298
- include Workflow
299
- workflow do
300
- state :new do
301
- event :assign, :transitions_to => :assigned
302
- event :assign_old, :transitions_to => :assigned_old
303
- end
304
- state :assigned
305
- state :assigned_old
306
- end
307
-
308
- protected
309
- def on_assigned_entry(prev_state, event, args)
310
- args.log('in protected callback `on_assigned_entry`')
311
- end
312
-
313
- private
314
- def assign(args)
315
- args.log('in private callback')
316
- end
317
- end
318
-
319
- a = c.new
320
- a.assign!(args)
321
-
322
- a2 = c.new
323
- a2.assign_old!(args)
324
- end
325
-
326
- test '#58 Limited private transition callback lookup' do
327
- args = mock()
328
- c = Class.new
329
- c.class_eval do
330
- include Workflow
331
- workflow do
332
- state :new do
333
- event :fail, :transitions_to => :failed
334
- end
335
- state :failed
336
- end
337
- end
338
- a = c.new
339
- a.fail!(args)
340
- end
341
-
342
- test 'Single table inheritance (STI)' do
343
- class BigOrder < Order
344
- end
345
-
346
- bo = BigOrder.new
347
- assert bo.submitted?
348
- assert !bo.accepted?
349
- end
350
-
351
- test 'STI when parent changed the workflow_state column' do
352
- assert_equal 'status', Image.workflow_column.to_s
353
- assert_equal 'status', SmallImage.workflow_column.to_s
354
- assert_equal 'status', SpecialSmallImage.workflow_column.to_s
355
- end
356
-
357
- test 'Two-level inheritance' do
358
- class BigOrder < Order
359
- end
360
-
361
- class EvenBiggerOrder < BigOrder
362
- end
363
-
364
- assert EvenBiggerOrder.new.submitted?
365
- end
366
-
367
- test 'Iheritance with workflow definition override' do
368
- class BigOrder < Order
369
- end
370
-
371
- class SpecialBigOrder < BigOrder
372
- workflow do
373
- state :start_big
374
- end
375
- end
376
-
377
- special = SpecialBigOrder.new
378
- assert_equal 'start_big', special.current_state.to_s
379
- end
380
-
381
- test 'Better error message for missing target state' do
382
- class Problem
383
- include Workflow
384
- workflow do
385
- state :initial do
386
- event :solve, :transitions_to => :solved
387
- end
388
- end
389
- end
390
- assert_raise Workflow::WorkflowError do
391
- Problem.new.solve!
392
- end
393
- end
394
-
395
- # Intermixing of transition graph definition (states, transitions)
396
- # on the one side and implementation of the actions on the other side
397
- # for a bigger state machine can introduce clutter.
398
- #
399
- # To reduce this clutter it is now possible to use state entry- and
400
- # exit- hooks defined through a naming convention. For example, if there
401
- # is a state :pending, then you can hook in by defining method
402
- # `def on_pending_exit(new_state, event, *args)` instead of using a
403
- # block:
404
- #
405
- # state :pending do
406
- # on_entry do
407
- # # your implementation here
408
- # end
409
- # end
410
- #
411
- # If both a function with a name according to naming convention and the
412
- # on_entry/on_exit block are given, then only on_entry/on_exit block is used.
413
- test 'on_entry and on_exit hooks in separate methods' do
414
- c = Class.new
415
- c.class_eval do
416
- include Workflow
417
- attr_reader :history
418
- def initialize
419
- @history = []
420
- end
421
- workflow do
422
- state :new do
423
- event :next, :transitions_to => :next_state
424
- end
425
- state :next_state
426
- end
427
-
428
- def on_next_state_entry(prior_state, event, *args)
429
- @history << "on_next_state_entry #{event} #{prior_state} ->"
430
- end
431
-
432
- def on_new_exit(new_state, event, *args)
433
- @history << "on_new_exit #{event} -> #{new_state}"
434
- end
435
- end
436
-
437
- o = c.new
438
- assert_equal 'new', o.current_state.to_s
439
- assert_equal [], o.history
440
- o.next!
441
- assert_equal ['on_new_exit next -> next_state', 'on_next_state_entry next new ->'], o.history
442
-
443
- end
444
-
445
- test 'diagram generation' do
446
- begin
447
- $stdout = StringIO.new('', 'w')
448
- require 'workflow/draw'
449
- Workflow::Draw::workflow_diagram(Order, :path => '/tmp')
450
- assert_match(/run the following/, $stdout.string,
451
- 'PDF should be generate and a hint be given to the user.')
452
- ensure
453
- $stdout = STDOUT
454
- end
455
- end
456
-
457
- test 'halt stops the transition' do
458
- c = Class.new do
459
- include Workflow
460
- workflow do
461
- state :young do
462
- event :age, :transitions_to => :old
463
- end
464
- state :old
465
- end
466
-
467
- def age(by=1)
468
- halt 'too fast' if by > 100
469
- end
470
- end
471
-
472
- joe = c.new
473
- assert joe.young?
474
- joe.age! 120
475
- assert joe.young?, 'Transition should have been halted'
476
- assert_equal 'too fast', joe.halted_because
477
- end
478
-
479
- test 'halt! raises exception immediately' do
480
- article_class = Class.new do
481
- include Workflow
482
- attr_accessor :too_far
483
- workflow do
484
- state :new do
485
- event :reject, :transitions_to => :rejected
486
- end
487
- state :rejected
488
- end
489
-
490
- def reject(reason)
491
- halt! 'We do not reject articles unless the reason is important' \
492
- unless reason =~ /important/i
493
- self.too_far = "This line should not be executed"
494
- end
495
- end
496
-
497
- article = article_class.new
498
- assert article.new?
499
- assert_raise Workflow::TransitionHalted do
500
- article.reject! 'Too funny'
501
- end
502
- assert_nil article.too_far
503
- assert article.new?, 'Transition should have been halted'
504
- article.reject! 'Important: too short'
505
- assert article.rejected?, 'Transition should happen now'
506
- end
507
-
508
- test 'can fire event?' do
509
- c = Class.new do
510
- include Workflow
511
- workflow do
512
- state :newborn do
513
- event :go_to_school, :transitions_to => :schoolboy
514
- end
515
- state :schoolboy do
516
- event :go_to_college, :transitions_to => :student
517
- end
518
- state :student
519
- state :street
520
- end
521
- end
522
-
523
- human = c.new
524
- assert human.can_go_to_school?
525
- assert_equal false, human.can_go_to_college?
526
- end
527
-
528
- test 'can_<fire_event>? with conditions' do
529
- c = Class.new do
530
- include Workflow
531
- workflow do
532
- state :off do
533
- event :turn_on, :transitions_to => :on, :if => proc { |obj| obj.battery > 10 }
534
- event :turn_on, :transitions_to => :low_battery, :if => proc { |obj| obj.battery > 0 }
535
- end
536
- state :on
537
- state :low_battery
538
- end
539
- attr_reader :battery
540
- def initialize(battery)
541
- @battery = battery
542
- end
543
- end
544
-
545
- device = c.new 0
546
- assert_equal false, device.can_turn_on?
547
-
548
- device = c.new 5
549
- assert device.can_turn_on?
550
- device.turn_on!
551
- assert device.low_battery?
552
- assert_equal false, device.on?
553
-
554
- device = c.new 50
555
- assert device.can_turn_on?
556
- device.turn_on!
557
- assert device.on?
558
- end
559
-
560
- test 'workflow graph generation' do
561
- Dir.chdir('/tmp') do
562
- capture_streams do
563
- Workflow::Draw::workflow_diagram(Order, :path => '/tmp')
564
- end
565
- end
566
- end
567
-
568
- test 'workflow graph generation in a path with spaces' do
569
- `mkdir -p '/tmp/Workflow test'`
570
- capture_streams do
571
- Workflow::Draw::workflow_diagram(Order, :path => '/tmp/Workflow test')
572
- end
573
- end
574
-
575
- def capture_streams
576
- old_stdout = $stdout
577
- $stdout = captured_stdout = StringIO.new
578
- yield
579
- $stdout = old_stdout
580
- captured_stdout
581
- end
582
-
583
- end
584
-