state_machine 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +26 -0
- data/README.rdoc +254 -46
- data/Rakefile +29 -3
- data/examples/AutoShop_state.png +0 -0
- data/examples/Car_state.jpg +0 -0
- data/examples/Vehicle_state.png +0 -0
- data/lib/state_machine.rb +161 -116
- data/lib/state_machine/assertions.rb +21 -0
- data/lib/state_machine/callback.rb +168 -0
- data/lib/state_machine/eval_helpers.rb +67 -0
- data/lib/state_machine/event.rb +135 -101
- data/lib/state_machine/extensions.rb +83 -0
- data/lib/state_machine/guard.rb +115 -0
- data/lib/state_machine/integrations/active_record.rb +242 -0
- data/lib/state_machine/integrations/data_mapper.rb +198 -0
- data/lib/state_machine/integrations/data_mapper/observer.rb +153 -0
- data/lib/state_machine/integrations/sequel.rb +169 -0
- data/lib/state_machine/machine.rb +746 -352
- data/lib/state_machine/transition.rb +104 -212
- data/test/active_record.log +34865 -0
- data/test/classes/switch.rb +11 -0
- data/test/data_mapper.log +14015 -0
- data/test/functional/state_machine_test.rb +249 -15
- data/test/sequel.log +3835 -0
- data/test/test_helper.rb +3 -12
- data/test/unit/assertions_test.rb +13 -0
- data/test/unit/callback_test.rb +189 -0
- data/test/unit/eval_helpers_test.rb +92 -0
- data/test/unit/event_test.rb +247 -113
- data/test/unit/guard_test.rb +420 -0
- data/test/unit/integrations/active_record_test.rb +515 -0
- data/test/unit/integrations/data_mapper_test.rb +407 -0
- data/test/unit/integrations/sequel_test.rb +244 -0
- data/test/unit/invalid_transition_test.rb +1 -1
- data/test/unit/machine_test.rb +1056 -98
- data/test/unit/state_machine_test.rb +14 -113
- data/test/unit/transition_test.rb +269 -495
- metadata +44 -30
- data/test/app_root/app/models/auto_shop.rb +0 -34
- data/test/app_root/app/models/car.rb +0 -19
- data/test/app_root/app/models/highway.rb +0 -3
- data/test/app_root/app/models/motorcycle.rb +0 -3
- data/test/app_root/app/models/switch.rb +0 -23
- data/test/app_root/app/models/switch_observer.rb +0 -20
- data/test/app_root/app/models/toggle_switch.rb +0 -2
- data/test/app_root/app/models/vehicle.rb +0 -78
- data/test/app_root/config/environment.rb +0 -7
- data/test/app_root/db/migrate/001_create_switches.rb +0 -12
- data/test/app_root/db/migrate/002_create_auto_shops.rb +0 -13
- data/test/app_root/db/migrate/003_create_highways.rb +0 -11
- data/test/app_root/db/migrate/004_create_vehicles.rb +0 -16
- data/test/factory.rb +0 -77
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
== master
|
2
2
|
|
3
|
+
== 0.4.0 / 2008-12-14
|
4
|
+
|
5
|
+
* Remove the PluginAWeek namespace
|
6
|
+
* Add generic attribute predicate (e.g. "#{attribute}?(state_name)") and state predicates (e.g. "#{state}?")
|
7
|
+
* Add Sequel support
|
8
|
+
* Fix aliasing :initialize on ActiveRecord models causing warnings when the environment is reloaded
|
9
|
+
* Fix ActiveRecord state machines trying to query the database on unmigrated models
|
10
|
+
* Fix initial states not getting set when the current value is an empty string [Aaron Gibralter]
|
11
|
+
* Add rake tasks for generating graphviz files for state machines [Nate Murray]
|
12
|
+
* Fix initial state not being included in list of known states
|
13
|
+
* Add other_states directive for defining additional states not referenced in transitions or callbacks [Pete Forde]
|
14
|
+
* Add next_#{event}_transition for getting the next transition that would be performed if the event were invoked
|
15
|
+
* Add the ability to override the pluralized name of an attribute for creating scopes
|
16
|
+
* Add the ability to halt callback chains by: throw :halt
|
17
|
+
* Add support for dynamic to states in transitions (e.g. :to => lambda {Time.now})
|
18
|
+
* Add support for using real blocks in before_transition/after_transition calls instead of using the :do option
|
19
|
+
* Add DataMapper support
|
20
|
+
* Include states referenced in transition callbacks in the list of a machine's known states
|
21
|
+
* Only generate the known states for a machine on demand, rather than calculating beforehand
|
22
|
+
* Add the ability to skip state change actions during a transition (e.g. vehicle.ignite(false))
|
23
|
+
* Add the ability for the state change action (e.g. +save+ for ActiveRecord) to be configurable
|
24
|
+
* Allow state machines to be defined on *any* Ruby class, not just ActiveRecord (removes all external dependencies)
|
25
|
+
* Refactor transitions, guards, and callbacks for better organization/design
|
26
|
+
* Use a class containing the transition context in callbacks, rather than an ordered list of each individual attribute
|
27
|
+
* Add without_#{attribute} named scopes (opposite of the existing with_#{attribute} named scopes) [Sean O'Brien]
|
28
|
+
|
3
29
|
== 0.3.1 / 2008-10-26
|
4
30
|
|
5
31
|
* Fix the initial state not getting set when the state attribute is mass-assigned but protected
|
data/README.rdoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
== state_machine
|
2
2
|
|
3
|
-
+state_machine+ adds support for creating state machines for attributes
|
4
|
-
|
3
|
+
+state_machine+ adds support for creating state machines for attributes on any
|
4
|
+
Ruby class.
|
5
5
|
|
6
6
|
== Resources
|
7
7
|
|
@@ -23,16 +23,29 @@ Source
|
|
23
23
|
|
24
24
|
== Description
|
25
25
|
|
26
|
-
State machines make it dead-simple to manage the behavior of a
|
27
|
-
the status of
|
28
|
-
|
29
|
-
|
30
|
-
increase.
|
26
|
+
State machines make it dead-simple to manage the behavior of a class. Too often,
|
27
|
+
the status of an object is kept by creating multiple boolean attributes and
|
28
|
+
deciding how to behave based on the values. This can become cumbersome and
|
29
|
+
difficult to maintain when the complexity of your class starts to increase.
|
31
30
|
|
32
31
|
+state_machine+ simplifies this design by introducing the various parts of a real
|
33
|
-
state machine, including states, events, and
|
34
|
-
designed to be
|
35
|
-
|
32
|
+
state machine, including states, events, transitions, and callbacks. However,
|
33
|
+
the api is designed to be so simple you don't even need to know what a
|
34
|
+
state machine is :)
|
35
|
+
|
36
|
+
Some brief, high-level features include:
|
37
|
+
* Defining state machines on any Ruby class
|
38
|
+
* Multiple state machines on a single class
|
39
|
+
* before/after transition hooks with explicit transition requirements
|
40
|
+
* ActiveRecord integration
|
41
|
+
* DataMapper integration
|
42
|
+
* Sequel integration
|
43
|
+
* States of any data type
|
44
|
+
* State predicates
|
45
|
+
* GraphViz visualization creator
|
46
|
+
|
47
|
+
Examples of the usage patterns for some of the above features are shown below.
|
48
|
+
You can find more detailed documentation in the actual API.
|
36
49
|
|
37
50
|
== Usage
|
38
51
|
|
@@ -43,12 +56,16 @@ Below is an example of many of the features offered by this plugin, including
|
|
43
56
|
* Transition callbacks
|
44
57
|
* Conditional transitions
|
45
58
|
|
46
|
-
class Vehicle
|
59
|
+
class Vehicle
|
60
|
+
attr_accessor :seatbelt_on
|
61
|
+
|
47
62
|
state_machine :state, :initial => 'parked' do
|
48
63
|
before_transition :from => %w(parked idling), :do => :put_on_seatbelt
|
49
|
-
after_transition :
|
50
|
-
after_transition :on => '
|
51
|
-
after_transition :
|
64
|
+
after_transition :on => 'crash', :do => :tow
|
65
|
+
after_transition :on => 'repair', :do => :fix
|
66
|
+
after_transition :to => 'parked' do |vehicle, transition|
|
67
|
+
vehicle.seatbelt_on = false
|
68
|
+
end
|
52
69
|
|
53
70
|
event :park do
|
54
71
|
transition :to => 'parked', :from => %w(idling first_gear)
|
@@ -83,44 +100,112 @@ Below is an example of many of the features offered by this plugin, including
|
|
83
100
|
end
|
84
101
|
end
|
85
102
|
|
86
|
-
def
|
87
|
-
|
103
|
+
def initialize
|
104
|
+
@seatbelt_on = false
|
88
105
|
end
|
89
106
|
|
90
|
-
def
|
91
|
-
|
107
|
+
def put_on_seatbelt
|
108
|
+
@seatbelt_on = true
|
92
109
|
end
|
93
110
|
|
94
111
|
def auto_shop_busy?
|
95
112
|
false
|
96
113
|
end
|
114
|
+
|
115
|
+
def tow
|
116
|
+
# tow the vehicle
|
117
|
+
end
|
118
|
+
|
119
|
+
def fix
|
120
|
+
# get the vehicle fixed by a mechanic
|
121
|
+
end
|
97
122
|
end
|
98
123
|
|
99
|
-
Using the above
|
124
|
+
Using the above class as an example, you can interact with the state machine
|
100
125
|
like so:
|
101
126
|
|
102
|
-
vehicle = Vehicle.
|
103
|
-
vehicle.
|
104
|
-
vehicle
|
105
|
-
vehicle.
|
106
|
-
vehicle
|
107
|
-
vehicle.
|
108
|
-
vehicle
|
127
|
+
vehicle = Vehicle.new # => #<Vehicle:0xb7cf4eac @state="parked", @seatbelt_on=false>
|
128
|
+
vehicle.parked? # => true
|
129
|
+
vehicle.can_ignite? # => true
|
130
|
+
vehicle.next_ignite_transition # => #<StateMachine::Transition:0xb7c34cec ...>
|
131
|
+
vehicle.ignite # => true
|
132
|
+
vehicle.parked? # => false
|
133
|
+
vehicle.idling? # => true
|
134
|
+
vehicle # => #<Vehicle:0xb7cf4eac @state="idling", @seatbelt_on=true>
|
135
|
+
vehicle.shift_up # => true
|
136
|
+
vehicle # => #<Vehicle:0xb7cf4eac @state="first_gear", @seatbelt_on=true>
|
137
|
+
vehicle.shift_up # => true
|
138
|
+
vehicle # => #<Vehicle:0xb7cf4eac @state="second_gear", @seatbelt_on=true>
|
109
139
|
|
110
140
|
# The bang (!) operator can raise exceptions if the event fails
|
111
|
-
vehicle.park!
|
141
|
+
vehicle.park! # => StateMachine::InvalidTransition: Cannot transition via :park from "second_gear"
|
142
|
+
|
143
|
+
# Generic state predicates can raise exceptions if the value does not exist
|
144
|
+
vehicle.state?('parked') # => true
|
145
|
+
vehicle.state?('invalid') # => ArgumentError: "parked" is not a known state value
|
146
|
+
|
147
|
+
== Integrations
|
148
|
+
|
149
|
+
In addition to being able to define state machines on all Ruby classes, a set of
|
150
|
+
out-of-the-box integrations are available for some of the more popular Ruby
|
151
|
+
libraries. These integrations add library-specific behavior, allowing for state
|
152
|
+
machines to work more tightly with the conventions defined by those libraries.
|
153
|
+
|
154
|
+
The integrations currently available include:
|
155
|
+
* ActiveRecord models
|
156
|
+
* DataMapper resources
|
157
|
+
* Sequel models
|
158
|
+
|
159
|
+
A brief overview of these integrations is described below.
|
160
|
+
|
161
|
+
=== ActiveRecord
|
162
|
+
|
163
|
+
The ActiveRecord integration adds support for database transactions, automatically
|
164
|
+
saving the record, named scopes, and observers. For example,
|
165
|
+
|
166
|
+
class Vehicle < ActiveRecord::Base
|
167
|
+
state_machine :initial => 'parked' do
|
168
|
+
before_transition :to => 'idling', :do => :put_on_seatbelt
|
169
|
+
after_transition :to => 'parked' do |vehicle, transition|
|
170
|
+
vehicle.seatbelt = 'off'
|
171
|
+
end
|
172
|
+
|
173
|
+
event :ignite do
|
174
|
+
transition :to => 'idling', :from => 'parked'
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def put_on_seatbelt
|
179
|
+
...
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
class VehicleObserver < ActiveRecord::Observer
|
184
|
+
# Callback for :ignite event *before* the transition is performed
|
185
|
+
def before_ignite(vehicle, transition)
|
186
|
+
# log message
|
187
|
+
end
|
188
|
+
|
189
|
+
# Generic transition callback *before* the transition is performed
|
190
|
+
def after_transition(vehicle, transition)
|
191
|
+
Audit.log(vehicle, transition)
|
192
|
+
end
|
193
|
+
end
|
112
194
|
|
113
|
-
|
195
|
+
For more information about the various behaviors added for ActiveRecord state
|
196
|
+
machines, see StateMachine::Integrations::ActiveRecord.
|
197
|
+
|
198
|
+
==== With enumerations
|
114
199
|
|
115
200
|
Using the acts_as_enumeration[http://github.com/pluginaweek/acts_as_enumeration] plugin
|
116
|
-
states can be transparently stored using
|
201
|
+
with an ActiveRecord integration, states can be transparently stored using
|
202
|
+
record ids in the database like so:
|
117
203
|
|
118
204
|
class VehicleState < ActiveRecord::Base
|
119
205
|
acts_as_enumeration
|
120
206
|
|
121
207
|
create :id => 1, :name => 'parked'
|
122
208
|
create :id => 2, :name => 'idling'
|
123
|
-
create :id => 3, :name => 'first_gear'
|
124
209
|
...
|
125
210
|
end
|
126
211
|
|
@@ -133,31 +218,151 @@ states can be transparently stored using record ids in the database like so:
|
|
133
218
|
event :park do
|
134
219
|
transition :to => 'parked', :from => %w(idling first_gear)
|
135
220
|
end
|
136
|
-
|
137
|
-
event :ignite do
|
138
|
-
transition :to => 'stalled', :from => 'stalled'
|
139
|
-
transition :to => 'idling', :from => 'parked'
|
140
|
-
end
|
141
221
|
end
|
142
222
|
|
143
223
|
...
|
144
224
|
end
|
145
225
|
|
146
|
-
Notice
|
147
|
-
|
148
|
-
|
226
|
+
Notice that the state machine definition remains *exactly* the same. However,
|
227
|
+
when interacting with the records, the actual state will be stored using the
|
228
|
+
identifiers defined for the enumeration:
|
149
229
|
|
150
230
|
vehicle = Vehicle.create # => #<Vehicle id: 1, seatbelt_on: false, state_id: 1>
|
151
231
|
vehicle.ignite # => true
|
152
232
|
vehicle # => #<Vehicle id: 1, seatbelt_on: true, state_id: 2>
|
153
|
-
vehicle.shift_up # => true
|
154
|
-
vehicle # => #<Vehicle id: 1, seatbelt_on: true, state_id: 3>
|
155
233
|
|
156
234
|
This allows states to take on more complex functionality other than just being
|
157
235
|
a string value.
|
158
236
|
|
237
|
+
=== DataMapper
|
238
|
+
|
239
|
+
Like the ActiveRecord integration, the DataMapper integration adds support for
|
240
|
+
database transactions, automatically saving the record, named scopes, Extlib-like
|
241
|
+
callbacks, and observers. For example,
|
242
|
+
|
243
|
+
class Vehicle
|
244
|
+
include DataMapper::Resource
|
245
|
+
|
246
|
+
property :id, Serial
|
247
|
+
property :state, String
|
248
|
+
|
249
|
+
state_machine :initial => 'parked' do
|
250
|
+
before_transition :to => 'idling', :do => :put_on_seatbelt
|
251
|
+
after_transition :to => 'parked' do |transition|
|
252
|
+
self.seatbelt = 'off' # self is the record
|
253
|
+
end
|
254
|
+
|
255
|
+
event :ignite do
|
256
|
+
transition :to => 'idling', :from => 'parked'
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def put_on_seatbelt
|
261
|
+
...
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
class VehicleObserver
|
266
|
+
include DataMapper::Observer
|
267
|
+
|
268
|
+
observe Vehicle
|
269
|
+
|
270
|
+
# Callback for :ignite event *before* the transition is performed
|
271
|
+
before_transition :on => :ignite do |transition|
|
272
|
+
# log message (self is the record)
|
273
|
+
end
|
274
|
+
|
275
|
+
# Generic transition callback *before* the transition is performed
|
276
|
+
after_transition do |transition, saved|
|
277
|
+
Audit.log(self, transition) if saved # self is the record
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
For more information about the various behaviors added for DataMapper state
|
282
|
+
machines, see StateMachine::Integrations::DataMapper.
|
283
|
+
|
284
|
+
=== Sequel
|
285
|
+
|
286
|
+
Like the ActiveRecord integration, the Sequel integration adds support for
|
287
|
+
database transactions, automatically saving the record, named scopes, and
|
288
|
+
callbacks. For example,
|
289
|
+
|
290
|
+
class Vehicle < Sequel::Model
|
291
|
+
state_machine :initial => 'parked' do
|
292
|
+
before_transition :to => 'idling', :do => :put_on_seatbelt
|
293
|
+
after_transition :to => 'parked' do |transition|
|
294
|
+
self.seatbelt = 'off' # self is the record
|
295
|
+
end
|
296
|
+
|
297
|
+
event :ignite do
|
298
|
+
transition :to => 'idling', :from => 'parked'
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
def put_on_seatbelt
|
303
|
+
...
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
For more information about the various behaviors added for Sequel state
|
308
|
+
machines, see StateMachine::Integrations::Sequel.
|
309
|
+
|
159
310
|
== Tools
|
160
311
|
|
312
|
+
=== Generating graphs
|
313
|
+
|
314
|
+
This library comes with built-in support for generating di-graphs based on the
|
315
|
+
events, states, and transitions defined for a state machine using GraphViz[http://www.graphviz.org].
|
316
|
+
This requires that both the <tt>ruby-graphviz</tt> gem and graphviz library be
|
317
|
+
installed on the system.
|
318
|
+
|
319
|
+
==== Examples
|
320
|
+
|
321
|
+
To generate a graph for a specific file / class:
|
322
|
+
|
323
|
+
rake state_machine:draw FILE=vehicle.rb CLASS=Vehicle
|
324
|
+
|
325
|
+
To save files to a specific path:
|
326
|
+
|
327
|
+
rake state_machine:draw FILE=vehicle.rb CLASS=Vehicle TARGET=files
|
328
|
+
|
329
|
+
To customize the image format:
|
330
|
+
|
331
|
+
rake state_machine:draw FILE=vehicle.rb CLASS=Vehicle FORMAT=jpg
|
332
|
+
|
333
|
+
To generate multiple state machine graphs:
|
334
|
+
|
335
|
+
rake state_machine:draw FILE=vehicle.rb,car.rb CLASS=Vehicle,Car
|
336
|
+
|
337
|
+
*Note* that this will generate a different file for every state machine defined
|
338
|
+
in the class. The generates files will an output filename of the format #{class_name}_#{attribute}.#{format}.
|
339
|
+
|
340
|
+
For examples of actual images generated using this task, see those under the
|
341
|
+
test/examples folder.
|
342
|
+
|
343
|
+
==== Ruby on Rails Integration
|
344
|
+
|
345
|
+
There is a special integration Rake task for generating state machines for
|
346
|
+
classes used in a Ruby on Rails application. This task will load the application
|
347
|
+
environment, meaning that it's unnecessary to specify the actual file to load.
|
348
|
+
|
349
|
+
For example,
|
350
|
+
|
351
|
+
rake state_machine:draw:rails CLASS=Vehicle
|
352
|
+
|
353
|
+
==== Merb Integration
|
354
|
+
|
355
|
+
Like Ruby on Rails, there is a special integration Rake task for generating
|
356
|
+
state machines for classes used in a Merb application. This task will load the
|
357
|
+
application environment, meaning that it's unnecessary to specify the actual
|
358
|
+
files to load.
|
359
|
+
|
360
|
+
For example,
|
361
|
+
|
362
|
+
rake state_machine:draw:merb CLASS=Vehicle
|
363
|
+
|
364
|
+
=== Interactive graphs
|
365
|
+
|
161
366
|
Jean Bovet - {Visual Automata Simulator}[http://www.cs.usfca.edu/~jbovet/vas.html].
|
162
367
|
This is a great tool for "simulating, visualizing and transforming finite state
|
163
368
|
automata and Turing Machines". This tool can help in the creation of states and
|
@@ -165,16 +370,19 @@ events for your models. It is cross-platform, written in Java.
|
|
165
370
|
|
166
371
|
== Testing
|
167
372
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
To run against a specific version of Rails:
|
373
|
+
To run the entire test suite (will test ActiveRecord, DataMapper, and Sequel
|
374
|
+
integrations if available):
|
172
375
|
|
173
|
-
rake test
|
376
|
+
rake test
|
174
377
|
|
175
378
|
== Dependencies
|
176
379
|
|
177
|
-
|
380
|
+
By default, there are no dependencies. If using specific integrations, those
|
381
|
+
dependencies are listed below.
|
382
|
+
|
383
|
+
* ActiveRecord[http://rubyonrails.org] integration: 2.1.0 or later
|
384
|
+
* DataMapper[http://datamapper.org] integration: 0.9.0 or later
|
385
|
+
* Sequel[http://sequel.rubyforge.org] integration: 2.8.0 or later
|
178
386
|
|
179
387
|
== References
|
180
388
|
|
data/Rakefile
CHANGED
@@ -5,11 +5,11 @@ require 'rake/contrib/sshpublisher'
|
|
5
5
|
|
6
6
|
spec = Gem::Specification.new do |s|
|
7
7
|
s.name = 'state_machine'
|
8
|
-
s.version = '0.
|
8
|
+
s.version = '0.4.0'
|
9
9
|
s.platform = Gem::Platform::RUBY
|
10
|
-
s.summary = 'Adds support for creating state machines for attributes
|
10
|
+
s.summary = 'Adds support for creating state machines for attributes on any Ruby class'
|
11
11
|
|
12
|
-
s.files = FileList['{lib,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc) - FileList['test/app_root/{log,log/*,script,script/*}']
|
12
|
+
s.files = FileList['{examples,lib,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc) - FileList['test/app_root/{log,log/*,script,script/*}']
|
13
13
|
s.require_path = 'lib'
|
14
14
|
s.has_rdoc = true
|
15
15
|
s.test_files = Dir['test/**/*_test.rb']
|
@@ -86,3 +86,29 @@ task :release => [:gem, :package] do
|
|
86
86
|
ruby_forge.add_release(spec.rubyforge_project, spec.name, spec.version, file)
|
87
87
|
end
|
88
88
|
end
|
89
|
+
|
90
|
+
namespace :state_machine do
|
91
|
+
desc 'Draws a set of state machines using GraphViz. Target files to load with FILE=x,y,z; Machine class with CLASS=x,y,z; Font name with FONT=x; Image format with FORMAT=x'
|
92
|
+
task :draw do
|
93
|
+
# Load the library
|
94
|
+
$:.unshift(File.dirname(__FILE__) + '/lib')
|
95
|
+
require 'state_machine'
|
96
|
+
|
97
|
+
# Build drawing options
|
98
|
+
options = {}
|
99
|
+
options[:file] = ENV['FILE'] if ENV['FILE']
|
100
|
+
options[:path] = ENV['TARGET'] if ENV['TARGET']
|
101
|
+
options[:format] = ENV['FORMAT'] if ENV['FORMAT']
|
102
|
+
options[:font] = ENV['FONT'] if ENV['FONT']
|
103
|
+
|
104
|
+
StateMachine::Machine.draw(ENV['CLASS'], options)
|
105
|
+
end
|
106
|
+
|
107
|
+
namespace :draw do
|
108
|
+
desc 'Draws a set of state machines using GraphViz for a Ruby on Rails application. Target class with CLASS=x,y,z; Font name with FONT=x; Image format with FORMAT=x'
|
109
|
+
task :rails => [:environment, 'state_machine:draw']
|
110
|
+
|
111
|
+
desc 'Draws a set of state machines using GraphViz for a Merb application. Target class with CLASS=x,y,z; Font name with FONT=x; Image format with FORMAT=x'
|
112
|
+
task :merb => [:merb_env, 'state_machine:draw']
|
113
|
+
end
|
114
|
+
end
|