simplificator-fsm 0.3.5 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.sw?
2
+ .DS_Store
3
+ **/.DS_Store
4
+ coverage
5
+ rdoc
6
+ pkg
7
+ *.sqlite3
8
+ **/*.sqlite3
data/README.markdown CHANGED
@@ -27,7 +27,7 @@ for suggestions!
27
27
  transition(:cool_down, [:gas, :liquid], :liquid, :event => :on_cool)
28
28
 
29
29
  # define the attribute which is used to store the state (defaults to :state)
30
- state(:state_of_material)
30
+ state_attribute(:state_of_material)
31
31
 
32
32
  # define the initial state (defaults to the first state defined - :gas in this sample)
33
33
  initial(:liquid)
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ require 'rake'
4
4
  begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
- gem.name = "fsm"
7
+ gem.name = "simplificator-fsm"
8
8
  gem.summary = %Q{A simple finite state machine (FSM) gem.}
9
9
  gem.email = "info@simplificator.com"
10
10
  gem.homepage = "http://github.com/simplificator/fsm"
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 5
3
- :major: 0
4
2
  :minor: 3
3
+ :patch: 7
4
+ :major: 0
data/lib/fsm/builder.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module FSM
2
- # Builder exposees 'only' (well there are some other methods exposed) the methods that are required to build the configuration
2
+ # Builder exposes 'only' (well there are some other methods exposed) the methods that are required to build the configuration
3
3
  class Builder
4
4
 
5
5
  # Blank Slate
data/lib/fsm/dot.rb ADDED
@@ -0,0 +1,61 @@
1
+ module FSM
2
+ module Dot
3
+ def self.included(includer)
4
+ FSM::Machine.class_eval do
5
+ include(MachineInstanceMethods)
6
+ end
7
+ FSM::State.class_eval do
8
+ include(StateInstanceMethods)
9
+ end
10
+ end
11
+
12
+ module MachineInstanceMethods
13
+ # Convert this state machine to the dot format of graphviz
14
+ def to_dot(options = {})
15
+ s = self.states.map do |state|
16
+ " #{state.to_dot(options)};"
17
+ end
18
+ t = self.transitions.map do |transition|
19
+ " #{transition.to_dot(options)};"
20
+ end
21
+ "digraph FSM_#{@target_class.name} {\n#{s.join("\n")}\n\n#{t.join("\n")}\n}"
22
+ end
23
+
24
+ #
25
+ def draw_graph(options = {})
26
+ format = options[:format] || :png
27
+ extension = options[:extension] || format
28
+ file_name = options[:outfile] || "#{@target_class.name.downcase}.#{extension}"
29
+ cmd = "dot -T#{format} -o#{file_name}"
30
+ IO.popen cmd, 'w' do |io|
31
+ io.write to_dot
32
+ end
33
+ raise 'dot failed' unless $?.success?
34
+ end
35
+ end
36
+
37
+ module StateInstanceMethods
38
+ def to_dot(options = {})
39
+ if initial?
40
+ attrs = "style=bold, label=\"#{self.name}\\n(initial)\""
41
+ elsif final?
42
+ attrs = "style=bold"
43
+ else
44
+ attrs = ""
45
+ end
46
+ "#{self.name}[#{attrs}]"
47
+ end
48
+
49
+
50
+ # Is this state final?
51
+ def final?
52
+ @transitions.empty?
53
+ end
54
+
55
+ # Is this the initial state
56
+ def initial?
57
+ Machine[@target_class].initial_state_name == self.name
58
+ end
59
+ end
60
+ end
61
+ end
data/lib/fsm/machine.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module FSM
2
2
  class Machine
3
+ include FSM::Dot
3
4
  attr_accessor(:initial_state_name, :current_state_attribute_name, :states, :transitions)
4
5
 
5
6
  def initialize(target_class)
@@ -79,28 +80,6 @@ module FSM
79
80
  state
80
81
  end
81
82
 
82
- # Convert this state machine to the dot format of graphviz
83
- def to_dot(options = {})
84
- s = self.states.map do |state|
85
- " #{state.to_dot(options)};"
86
- end
87
- t = self.transitions.map do |transition|
88
- " #{transition.to_dot(options)};"
89
- end
90
- "digraph FSM_#{@target_class.name} {\n#{s.join("\n")}\n\n#{t.join("\n")}\n}"
91
- end
92
-
93
- #
94
- def draw_graph(options = {})
95
- format = options[:format] || :png
96
- extension = options[:extension] || format
97
- file_name = options[:outfile] || "#{@target_class.name.downcase}.#{extension}"
98
- cmd = "dot -T#{format} -o#{file_name}"
99
- IO.popen cmd, 'w' do |io|
100
- io.write to_dot
101
- end
102
- raise 'dot failed' unless $?.success?
103
- end
104
83
 
105
84
  private
106
85
 
data/lib/fsm/state.rb CHANGED
@@ -41,27 +41,10 @@ module FSM
41
41
  def to_states
42
42
  @transitions.map { |to_name, transition| transition.to}
43
43
  end
44
- def final?
45
- @transitions.empty?
46
- end
47
-
48
- def initial?
49
- Machine[@target_class].initial_state_name == self.name
50
- end
51
44
 
52
45
  def to_s
53
46
  "State '#{self.name}' is "
54
47
  end
55
48
 
56
- def to_dot(options = {})
57
- if initial?
58
- attrs = "style=bold, label=\"#{self.name}\\n(initial)\""
59
- elsif final?
60
- attrs = "style=bold"
61
- else
62
- attrs = ""
63
- end
64
- "#{self.name}[#{attrs}]"
65
- end
66
49
  end
67
50
  end
@@ -27,7 +27,8 @@ module FSM
27
27
  def self.bar(klass)
28
28
  klass.instance_eval() do
29
29
  define_method(Machine[klass].current_state_attribute_name) do
30
- value = read_attribute(Machine[self.class].current_state_attribute_name) || Machine[self.class].initial_state_name
30
+ value = read_attribute(Machine[self.class].current_state_attribute_name)
31
+ value = Machine[self.class].initial_state_name if value.blank?
31
32
  value.is_a?(String) ? value.intern : value
32
33
  end
33
34
  end
data/lib/fsm.rb CHANGED
@@ -1,4 +1,4 @@
1
- %w[options errors machine state transition executable builder state_attribute_interceptor].each do |item|
1
+ %w[dot options state errors machine transition executable builder state_attribute_interceptor].each do |item|
2
2
  require File.join(File.dirname(__FILE__), 'fsm', item)
3
3
  end
4
4
 
@@ -13,14 +13,12 @@ module FSM
13
13
  # TODO: other checks? islands?
14
14
 
15
15
  # create alias for state attribute method to intercept it
16
- # intercept
17
16
  FSM::StateAttributeInterceptor.add_interceptor(self)
18
17
  end
19
18
 
20
- def draw_graph(options = {})
21
- machine = Machine[self]
22
- raise 'No FSM defined. Call define_fsm first' unless machine
23
- machine.draw_graph(options)
19
+ def fsm_draw_graph(options = {})
20
+ raise 'No FSM defined. Call define_fsm first' unless Machine[self]
21
+ Machine[self].draw_graph(options)
24
22
  end
25
23
 
26
24
  end
@@ -28,13 +26,23 @@ module FSM
28
26
  module InstanceMethods
29
27
  #
30
28
  # Which states are reachable from the current state
31
- def reachable_state_names
29
+ def fsm_next_state_names
32
30
  Machine[self.class].reachable_states(self).map() {|item| item.name}
33
31
  end
34
32
 
35
- def available_transition_names
33
+ def fsm_state_names
34
+ Machine[self.class].states.map() {|item| item.name}
35
+ end
36
+
37
+ #
38
+ # What are the next transitions
39
+ def fsm_next_transition_names
36
40
  Machine[self.class].available_transitions(self).map() {|item| item.name}
37
41
  end
42
+
43
+ def fsm_transition_names
44
+ Machine[self.class].transitions.map() {|item| item.name}
45
+ end
38
46
  end
39
47
 
40
48
  def self.included(receiver)
Binary file
@@ -0,0 +1,472 @@
1
+ %!PS-Adobe-3.0
2
+ %%Creator: graphviz version 2.22.2 (20090313.1817)
3
+ %%Title: FSM_Ticket
4
+ %%Pages: (atend)
5
+ %%BoundingBox: (atend)
6
+ %%EndComments
7
+ save
8
+ %%BeginProlog
9
+ /DotDict 200 dict def
10
+ DotDict begin
11
+
12
+ /setupLatin1 {
13
+ mark
14
+ /EncodingVector 256 array def
15
+ EncodingVector 0
16
+
17
+ ISOLatin1Encoding 0 255 getinterval putinterval
18
+ EncodingVector 45 /hyphen put
19
+
20
+ % Set up ISO Latin 1 character encoding
21
+ /starnetISO {
22
+ dup dup findfont dup length dict begin
23
+ { 1 index /FID ne { def }{ pop pop } ifelse
24
+ } forall
25
+ /Encoding EncodingVector def
26
+ currentdict end definefont
27
+ } def
28
+ /Times-Roman starnetISO def
29
+ /Times-Italic starnetISO def
30
+ /Times-Bold starnetISO def
31
+ /Times-BoldItalic starnetISO def
32
+ /Helvetica starnetISO def
33
+ /Helvetica-Oblique starnetISO def
34
+ /Helvetica-Bold starnetISO def
35
+ /Helvetica-BoldOblique starnetISO def
36
+ /Courier starnetISO def
37
+ /Courier-Oblique starnetISO def
38
+ /Courier-Bold starnetISO def
39
+ /Courier-BoldOblique starnetISO def
40
+ cleartomark
41
+ } bind def
42
+
43
+ %%BeginResource: procset graphviz 0 0
44
+ /coord-font-family /Times-Roman def
45
+ /default-font-family /Times-Roman def
46
+ /coordfont coord-font-family findfont 8 scalefont def
47
+
48
+ /InvScaleFactor 1.0 def
49
+ /set_scale {
50
+ dup 1 exch div /InvScaleFactor exch def
51
+ scale
52
+ } bind def
53
+
54
+ % styles
55
+ /solid { [] 0 setdash } bind def
56
+ /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
57
+ /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
58
+ /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
59
+ /bold { 2 setlinewidth } bind def
60
+ /filled { } bind def
61
+ /unfilled { } bind def
62
+ /rounded { } bind def
63
+ /diagonals { } bind def
64
+
65
+ % hooks for setting color
66
+ /nodecolor { sethsbcolor } bind def
67
+ /edgecolor { sethsbcolor } bind def
68
+ /graphcolor { sethsbcolor } bind def
69
+ /nopcolor {pop pop pop} bind def
70
+
71
+ /beginpage { % i j npages
72
+ /npages exch def
73
+ /j exch def
74
+ /i exch def
75
+ /str 10 string def
76
+ npages 1 gt {
77
+ gsave
78
+ coordfont setfont
79
+ 0 0 moveto
80
+ (\() show i str cvs show (,) show j str cvs show (\)) show
81
+ grestore
82
+ } if
83
+ } bind def
84
+
85
+ /set_font {
86
+ findfont exch
87
+ scalefont setfont
88
+ } def
89
+
90
+ % draw text fitted to its expected width
91
+ /alignedtext { % width text
92
+ /text exch def
93
+ /width exch def
94
+ gsave
95
+ width 0 gt {
96
+ [] 0 setdash
97
+ text stringwidth pop width exch sub text length div 0 text ashow
98
+ } if
99
+ grestore
100
+ } def
101
+
102
+ /boxprim { % xcorner ycorner xsize ysize
103
+ 4 2 roll
104
+ moveto
105
+ 2 copy
106
+ exch 0 rlineto
107
+ 0 exch rlineto
108
+ pop neg 0 rlineto
109
+ closepath
110
+ } bind def
111
+
112
+ /ellipse_path {
113
+ /ry exch def
114
+ /rx exch def
115
+ /y exch def
116
+ /x exch def
117
+ matrix currentmatrix
118
+ newpath
119
+ x y translate
120
+ rx ry scale
121
+ 0 0 1 0 360 arc
122
+ setmatrix
123
+ } bind def
124
+
125
+ /endpage { showpage } bind def
126
+ /showpage { } def
127
+
128
+ /layercolorseq
129
+ [ % layer color sequence - darkest to lightest
130
+ [0 0 0]
131
+ [.2 .8 .8]
132
+ [.4 .8 .8]
133
+ [.6 .8 .8]
134
+ [.8 .8 .8]
135
+ ]
136
+ def
137
+
138
+ /layerlen layercolorseq length def
139
+
140
+ /setlayer {/maxlayer exch def /curlayer exch def
141
+ layercolorseq curlayer 1 sub layerlen mod get
142
+ aload pop sethsbcolor
143
+ /nodecolor {nopcolor} def
144
+ /edgecolor {nopcolor} def
145
+ /graphcolor {nopcolor} def
146
+ } bind def
147
+
148
+ /onlayer { curlayer ne {invis} if } def
149
+
150
+ /onlayers {
151
+ /myupper exch def
152
+ /mylower exch def
153
+ curlayer mylower lt
154
+ curlayer myupper gt
155
+ or
156
+ {invis} if
157
+ } def
158
+
159
+ /curlayer 0 def
160
+
161
+ %%EndResource
162
+ %%EndProlog
163
+ %%BeginSetup
164
+ 14 default-font-family set_font
165
+ 1 setmiterlimit
166
+ % /arrowlength 10 def
167
+ % /arrowwidth 5 def
168
+
169
+ % make sure pdfmark is harmless for PS-interpreters other than Distiller
170
+ /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
171
+ % make '<<' and '>>' safe on PS Level 1 devices
172
+ /languagelevel where {pop languagelevel}{1} ifelse
173
+ 2 lt {
174
+ userdict (<<) cvn ([) cvn load put
175
+ userdict (>>) cvn ([) cvn load put
176
+ } if
177
+
178
+ %%EndSetup
179
+ setupLatin1
180
+ %%Page: 1 1
181
+ %%PageBoundingBox: 36 36 358 526
182
+ %%PageOrientation: Portrait
183
+ 0 0 1 beginpage
184
+ gsave
185
+ 36 36 322 490 boxprim clip newpath
186
+ 1 1 set_scale 0 rotate 40 41 translate
187
+ % created
188
+ gsave
189
+ 2 setlinewidth
190
+ bold
191
+ 0 0 0 nodecolor
192
+ 221.51 456 41.93 25.46 ellipse_path stroke
193
+ 0 0 0 nodecolor
194
+ 14 /Times-Roman set_font
195
+ 200.51 457.4 moveto 42 (created) alignedtext
196
+ 0 0 0 nodecolor
197
+ 14 /Times-Roman set_font
198
+ 199.51 443.4 moveto 44 (\(initial\)) alignedtext
199
+ grestore
200
+ % reserved
201
+ gsave
202
+ 1 setlinewidth
203
+ 0 0 0 nodecolor
204
+ 171.51 362 41.06 18 ellipse_path stroke
205
+ 0 0 0 nodecolor
206
+ 14 /Times-Roman set_font
207
+ 147.01 356.4 moveto 49 (reserved) alignedtext
208
+ grestore
209
+ % created->reserved
210
+ gsave
211
+ 1 setlinewidth
212
+ 0 0 0 edgecolor
213
+ newpath 208.37 431.3 moveto
214
+ 201.43 418.26 192.91 402.23 185.8 388.88 curveto
215
+ stroke
216
+ 0 0 0 edgecolor
217
+ newpath 188.71 386.89 moveto
218
+ 180.93 379.7 lineto
219
+ 182.53 390.18 lineto
220
+ closepath fill
221
+ 1 setlinewidth
222
+ solid
223
+ 0 0 0 edgecolor
224
+ newpath 188.71 386.89 moveto
225
+ 180.93 379.7 lineto
226
+ 182.53 390.18 lineto
227
+ closepath stroke
228
+ 0 0 0 edgecolor
229
+ 14 /Times-Roman set_font
230
+ 197.51 399.4 moveto 41 (reserve) alignedtext
231
+ grestore
232
+ % invalid
233
+ gsave
234
+ 2 setlinewidth
235
+ bold
236
+ 0 0 0 nodecolor
237
+ 135.51 18 36.01 18 ellipse_path stroke
238
+ 0 0 0 nodecolor
239
+ 14 /Times-Roman set_font
240
+ 115.01 12.4 moveto 41 (invalid) alignedtext
241
+ grestore
242
+ % created->invalid
243
+ gsave
244
+ 1 setlinewidth
245
+ 0 0 0 edgecolor
246
+ newpath 235.95 431.78 moveto
247
+ 245.59 413.31 256.51 386.9 256.51 362 curveto
248
+ 256.51 362 256.51 362 256.51 104 curveto
249
+ 256.51 64.19 212.45 41.11 177.5 29.06 curveto
250
+ stroke
251
+ 0 0 0 edgecolor
252
+ newpath 178.53 25.72 moveto
253
+ 167.93 25.96 lineto
254
+ 176.36 32.37 lineto
255
+ closepath fill
256
+ 1 setlinewidth
257
+ solid
258
+ 0 0 0 edgecolor
259
+ newpath 178.53 25.72 moveto
260
+ 167.93 25.96 lineto
261
+ 176.36 32.37 lineto
262
+ closepath stroke
263
+ 0 0 0 edgecolor
264
+ 14 /Times-Roman set_font
265
+ 256.51 227.4 moveto 57 (invalidate) alignedtext
266
+ grestore
267
+ % sold
268
+ gsave
269
+ 1 setlinewidth
270
+ 0 0 0 nodecolor
271
+ 105.51 276 27 18 ellipse_path stroke
272
+ 0 0 0 nodecolor
273
+ 14 /Times-Roman set_font
274
+ 93.01 270.4 moveto 25 (sold) alignedtext
275
+ grestore
276
+ % reserved->sold
277
+ gsave
278
+ 1 setlinewidth
279
+ 0 0 0 edgecolor
280
+ newpath 153.98 345.48 moveto
281
+ 148.13 339.59 141.77 332.73 136.51 326 curveto
282
+ 130.66 318.51 124.97 309.87 120.09 301.89 curveto
283
+ stroke
284
+ 0 0 0 edgecolor
285
+ newpath 123.09 300.08 moveto
286
+ 114.97 293.27 lineto
287
+ 117.07 303.66 lineto
288
+ closepath fill
289
+ 1 setlinewidth
290
+ solid
291
+ 0 0 0 edgecolor
292
+ newpath 123.09 300.08 moveto
293
+ 114.97 293.27 lineto
294
+ 117.07 303.66 lineto
295
+ closepath stroke
296
+ 0 0 0 edgecolor
297
+ 14 /Times-Roman set_font
298
+ 136.51 313.4 moveto 21 (buy) alignedtext
299
+ grestore
300
+ % reserved->invalid
301
+ gsave
302
+ 1 setlinewidth
303
+ 0 0 0 edgecolor
304
+ newpath 171.51 343.88 moveto
305
+ 171.51 326.48 171.51 299.44 171.51 276 curveto
306
+ 171.51 276 171.51 276 171.51 104 curveto
307
+ 171.51 82.76 162.05 60.69 152.82 44.23 curveto
308
+ stroke
309
+ 0 0 0 edgecolor
310
+ newpath 155.6 42.06 moveto
311
+ 147.5 35.24 lineto
312
+ 149.58 45.62 lineto
313
+ closepath fill
314
+ 1 setlinewidth
315
+ solid
316
+ 0 0 0 edgecolor
317
+ newpath 155.6 42.06 moveto
318
+ 147.5 35.24 lineto
319
+ 149.58 45.62 lineto
320
+ closepath stroke
321
+ 0 0 0 edgecolor
322
+ 14 /Times-Roman set_font
323
+ 171.51 184.4 moveto 57 (invalidate) alignedtext
324
+ grestore
325
+ % inside
326
+ gsave
327
+ 1 setlinewidth
328
+ 0 0 0 nodecolor
329
+ 77.51 190 32.22 18 ellipse_path stroke
330
+ 0 0 0 nodecolor
331
+ 14 /Times-Roman set_font
332
+ 60.01 184.4 moveto 35 (inside) alignedtext
333
+ grestore
334
+ % sold->inside
335
+ gsave
336
+ 1 setlinewidth
337
+ 0 0 0 edgecolor
338
+ newpath 99.71 258.18 moveto
339
+ 95.88 246.42 90.78 230.78 86.44 217.44 curveto
340
+ stroke
341
+ 0 0 0 edgecolor
342
+ newpath 89.73 216.22 moveto
343
+ 83.3 207.8 lineto
344
+ 83.07 218.39 lineto
345
+ closepath fill
346
+ 1 setlinewidth
347
+ solid
348
+ 0 0 0 edgecolor
349
+ newpath 89.73 216.22 moveto
350
+ 83.3 207.8 lineto
351
+ 83.07 218.39 lineto
352
+ closepath stroke
353
+ 0 0 0 edgecolor
354
+ 14 /Times-Roman set_font
355
+ 92.51 227.4 moveto 29 (enter) alignedtext
356
+ grestore
357
+ % inside->invalid
358
+ gsave
359
+ 1 setlinewidth
360
+ 0 0 0 edgecolor
361
+ newpath 55.89 176.23 moveto
362
+ 27.98 156.66 -14.74 119.44 5.51 86 curveto
363
+ 24.23 55.07 62.16 37.53 92.24 28.05 curveto
364
+ stroke
365
+ 0 0 0 edgecolor
366
+ newpath 93.51 31.32 moveto
367
+ 102.1 25.13 lineto
368
+ 91.52 24.61 lineto
369
+ closepath fill
370
+ 1 setlinewidth
371
+ solid
372
+ 0 0 0 edgecolor
373
+ newpath 93.51 31.32 moveto
374
+ 102.1 25.13 lineto
375
+ 91.52 24.61 lineto
376
+ closepath stroke
377
+ 0 0 0 edgecolor
378
+ 14 /Times-Roman set_font
379
+ 5.51 98.4 moveto 57 (invalidate) alignedtext
380
+ grestore
381
+ % outside
382
+ gsave
383
+ 1 setlinewidth
384
+ 0 0 0 nodecolor
385
+ 107.51 104 36.14 18 ellipse_path stroke
386
+ 0 0 0 nodecolor
387
+ 14 /Times-Roman set_font
388
+ 86.51 98.4 moveto 42 (outside) alignedtext
389
+ grestore
390
+ % inside->outside
391
+ gsave
392
+ 1 setlinewidth
393
+ 0 0 0 edgecolor
394
+ newpath 70.03 172.29 moveto
395
+ 67 162.45 65.13 150.18 69.51 140 curveto
396
+ 71.71 134.89 75.03 130.16 78.81 125.93 curveto
397
+ stroke
398
+ 0 0 0 edgecolor
399
+ newpath 81.31 128.38 moveto
400
+ 85.97 118.86 lineto
401
+ 76.39 123.39 lineto
402
+ closepath fill
403
+ 1 setlinewidth
404
+ solid
405
+ 0 0 0 edgecolor
406
+ newpath 81.31 128.38 moveto
407
+ 85.97 118.86 lineto
408
+ 76.39 123.39 lineto
409
+ closepath stroke
410
+ 0 0 0 edgecolor
411
+ 14 /Times-Roman set_font
412
+ 69.51 141.4 moveto 22 (exit) alignedtext
413
+ grestore
414
+ % outside->invalid
415
+ gsave
416
+ 1 setlinewidth
417
+ 0 0 0 edgecolor
418
+ newpath 100.58 85.86 moveto
419
+ 97.93 76.12 96.42 64.07 100.51 54 curveto
420
+ 102.47 49.18 105.41 44.64 108.79 40.53 curveto
421
+ stroke
422
+ 0 0 0 edgecolor
423
+ newpath 111.39 42.87 moveto
424
+ 115.64 33.17 lineto
425
+ 106.26 38.1 lineto
426
+ closepath fill
427
+ 1 setlinewidth
428
+ solid
429
+ 0 0 0 edgecolor
430
+ newpath 111.39 42.87 moveto
431
+ 115.64 33.17 lineto
432
+ 106.26 38.1 lineto
433
+ closepath stroke
434
+ 0 0 0 edgecolor
435
+ 14 /Times-Roman set_font
436
+ 100.51 55.4 moveto 57 (invalidate) alignedtext
437
+ grestore
438
+ % outside->inside
439
+ gsave
440
+ 1 setlinewidth
441
+ 0 0 0 edgecolor
442
+ newpath 104.15 122.35 moveto
443
+ 102.14 131.93 99.24 143.77 95.51 154 curveto
444
+ 94.36 157.15 93.01 160.39 91.57 163.56 curveto
445
+ stroke
446
+ 0 0 0 edgecolor
447
+ newpath 88.32 162.25 moveto
448
+ 87.12 172.78 lineto
449
+ 94.62 165.29 lineto
450
+ closepath fill
451
+ 1 setlinewidth
452
+ solid
453
+ 0 0 0 edgecolor
454
+ newpath 88.32 162.25 moveto
455
+ 87.12 172.78 lineto
456
+ 94.62 165.29 lineto
457
+ closepath stroke
458
+ 0 0 0 edgecolor
459
+ 14 /Times-Roman set_font
460
+ 99.51 141.4 moveto 29 (enter) alignedtext
461
+ grestore
462
+ endpage
463
+ showpage
464
+ grestore
465
+ %%PageTrailer
466
+ %%EndPage: 1
467
+ %%Trailer
468
+ %%Pages: 1
469
+ %%BoundingBox: 36 36 358 526
470
+ end
471
+ restore
472
+ %%EOF
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../../lib/fsm'
2
+ class Ticket
3
+ attr_accessor(:state)
4
+ include FSM
5
+ define_fsm do
6
+ states(:created, :reserved, :sold, :invalid, :inside, :outside)
7
+
8
+ transition(:reserve, :created, :reserved)
9
+ transition(:buy, :reserved, :sold)
10
+
11
+ transition(:enter, :sold, :inside)
12
+ transition(:enter, :outside, :inside)
13
+ transition(:exit, :inside, :outside)
14
+
15
+ transition(:invalidate, [:created, :reserved, :inside, :outside], :invalid)
16
+ end
17
+
18
+ end
19
+
20
+ t = Ticket.fsm_draw_graph(:format => 'png')
data/test/ar_test.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'test_helper_ar'
2
2
  class ArTest < Test::Unit::TestCase
3
+
3
4
  context 'AR' do
4
5
 
5
6
  should 'set the state' do
@@ -11,16 +12,21 @@ class ArTest < Test::Unit::TestCase
11
12
  assert_equal :open, o2.state
12
13
  end
13
14
 
15
+ should 'return initial state when state is empty string' do
16
+ o1 = Order.new(:state => '')
17
+ assert_equal :open, o1.state
18
+ end
19
+
14
20
  should 'make transition' do
15
- o = Order.new
16
- assert_equal :open, o.state
17
- o.deliver
18
- assert_equal :delivered, o.state
19
- o.save!
20
- o.reload
21
- o = Order.find(o.id)
22
- assert_equal :delivered, o.state
23
- end
24
-
21
+ o = Order.new
22
+ assert_equal :open, o.state
23
+ o.deliver
24
+ assert_equal :delivered, o.state
25
+ o.save!
26
+ assert_equal :delivered, o.state
27
+ o.reload
28
+ o = Order.find(o.id)
29
+ assert_equal :delivered, o.state
30
+ end
25
31
  end
26
32
  end
@@ -27,11 +27,12 @@ class Invoice
27
27
  end
28
28
 
29
29
  class InvoiceSampleTest < Test::Unit::TestCase
30
- context 'Invoice' do
31
-
30
+ context 'an Invoice' do
31
+ setup do
32
+ @invoice = Invoice.new
33
+ end
32
34
  should 'Initial State is the first state defined unless no initial() call was made' do
33
- invoice = Invoice.new
34
- assert_equal(:open, invoice.state)
35
+ assert_equal(:open, @invoice.state)
35
36
  end
36
37
 
37
38
  should 'Accept an initial state from outside' do
@@ -40,28 +41,46 @@ class InvoiceSampleTest < Test::Unit::TestCase
40
41
  end
41
42
 
42
43
  should 'Trasition to paid and then refunded' do
43
- invoice = Invoice.new
44
- assert_equal(:open, invoice.state)
44
+ assert_equal(:open, @invoice.state)
45
45
 
46
- invoice.pay(1000)
47
- assert_equal(:paid, invoice.state)
46
+ @invoice.pay(1000)
47
+ assert_equal(:paid, @invoice.state)
48
48
 
49
- invoice.refund
50
- assert_equal(:refunded, invoice.state)
49
+ @invoice.refund
50
+ assert_equal(:refunded, @invoice.state)
51
51
  end
52
52
 
53
53
  should 'Raise on illegal transition' do
54
- invoice = Invoice.new
55
54
  assert_raise(FSM::InvalidStateTransition) do
56
- invoice.refund
55
+ @invoice.refund
57
56
  end
58
57
  end
59
58
 
60
59
  should 'Pass the arguments to the event handler' do
61
- invoice = Invoice.new
62
- invoice.pay(1000)
63
- assert_equal(0, invoice.amount)
60
+ @invoice.pay(1000)
61
+ assert_equal(0, @invoice.amount)
62
+ end
63
+
64
+ should 'List all states' do
65
+ assert_equal_symbols [:paid, :refunded, :open], @invoice.fsm_state_names
66
+ end
67
+ should 'List all transitions' do
68
+ assert_equal_symbols [:pay, :refund], @invoice.fsm_transition_names
64
69
  end
65
70
 
71
+ should 'List next states' do
72
+ assert_equal_symbols :paid, @invoice.fsm_next_state_names
73
+ @invoice.pay(1000)
74
+ assert_equal_symbols :refunded, @invoice.fsm_next_state_names
75
+ end
76
+
77
+ should 'List next transitions' do
78
+ assert_equal_symbols :pay, @invoice.fsm_next_transition_names
79
+ @invoice.pay(1000)
80
+ assert_equal_symbols :refund, @invoice.fsm_next_transition_names
81
+ end
82
+
83
+
84
+
66
85
  end
67
86
  end
data/test/test_helper.rb CHANGED
@@ -5,3 +5,11 @@ require 'shoulda'
5
5
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
6
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
7
  require 'fsm'
8
+
9
+
10
+ class Test::Unit::TestCase
11
+ def assert_equal_symbols(a1, a2)
12
+ assert_equal Array(a1).map() {|item| item.to_s}.sort,
13
+ Array(a2).map() {|item| item.to_s}.sort
14
+ end
15
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simplificator-fsm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - simplificator
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-30 00:00:00 -07:00
12
+ date: 2009-12-07 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -23,12 +23,15 @@ extra_rdoc_files:
23
23
  - LICENSE
24
24
  - README.markdown
25
25
  files:
26
+ - .document
27
+ - .gitignore
26
28
  - LICENSE
27
29
  - README.markdown
28
30
  - Rakefile
29
31
  - VERSION.yml
30
32
  - lib/fsm.rb
31
33
  - lib/fsm/builder.rb
34
+ - lib/fsm/dot.rb
32
35
  - lib/fsm/errors.rb
33
36
  - lib/fsm/executable.rb
34
37
  - lib/fsm/machine.rb
@@ -36,6 +39,9 @@ files:
36
39
  - lib/fsm/state.rb
37
40
  - lib/fsm/state_attribute_interceptor.rb
38
41
  - lib/fsm/transition.rb
42
+ - samples/ticket/ticket.png
43
+ - samples/ticket/ticket.ps
44
+ - samples/ticket/ticket_sample.rb
39
45
  - test/ar_test.rb
40
46
  - test/executable_test.rb
41
47
  - test/invoice_sample_test.rb
@@ -47,6 +53,8 @@ files:
47
53
  - test/water_sample_test.rb
48
54
  has_rdoc: true
49
55
  homepage: http://github.com/simplificator/fsm
56
+ licenses: []
57
+
50
58
  post_install_message:
51
59
  rdoc_options:
52
60
  - --charset=UTF-8
@@ -67,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
75
  requirements: []
68
76
 
69
77
  rubyforge_project:
70
- rubygems_version: 1.2.0
78
+ rubygems_version: 1.3.5
71
79
  signing_key:
72
80
  specification_version: 3
73
81
  summary: A simple finite state machine (FSM) gem.