simplificator-fsm 0.3.5 → 0.3.7

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/.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.