statemachine 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -14,7 +14,7 @@ Where to start:
14
14
  == Documentation
15
15
 
16
16
  Some documentation is available here in this RDOC documentation.
17
- You may also find useful documentation on the Statemachine website: http://statemachine.rubyforge.org
17
+ You may also find useful documentation on the Statemachine website: http://slagyr.github.com/statemachine
18
18
 
19
19
  A detailed tutorial and overview of Finite State Machines and this library can be found
20
20
  at http://blog.8thlight.com/articles/2006/11/17/understanding-statemachines-part-1-states-and-transitions.
@@ -261,6 +261,20 @@ module Statemachine
261
261
  @statemachine.context = a_context
262
262
  a_context.statemachine = @statemachine if a_context.respond_to?(:statemachine=)
263
263
  end
264
+
265
+ # Stubs the context. This makes statemachine immediately useable, even if functionless.
266
+ # The stub will print all the actions called so it's nice for trial runs.
267
+ #
268
+ # sm = Statemachine.build do
269
+ # ...
270
+ # stub_context :verbose => true
271
+ # end
272
+ #
273
+ # Statemachine.context may also be used.
274
+ def stub_context(options={})
275
+ require 'statemachine/stub_context'
276
+ context StubContext.new(options)
277
+ end
264
278
  end
265
279
 
266
280
  end
@@ -42,8 +42,6 @@ module Statemachine
42
42
  private ###########################################
43
43
 
44
44
  def explore_sm
45
- @state_names = @sm.states.keys.reject{|k| k.nil? }.map { |id| id.to_s.camalized }.sort
46
-
47
45
  events = []
48
46
  actions = []
49
47
  @sm.states.values.each do |state|
@@ -59,6 +57,8 @@ module Statemachine
59
57
  add_action(actions, state.exit_action)
60
58
  end
61
59
  @action_names = actions.uniq.map {|e| e.to_s.camalized(:lower)}.sort
60
+
61
+ @startstate = @sm.get_state(@sm.startstate).resolve_startstate
62
62
  end
63
63
 
64
64
  def add_action(actions, action)
@@ -72,7 +72,8 @@ module Statemachine
72
72
  src << "public class #{@classname}" << endl
73
73
  begin_scope(src)
74
74
 
75
- add_state_instances(src)
75
+ add_instance_variables(src)
76
+ add_constructor(src)
76
77
  add_statemachine_boilerplate_code(src)
77
78
  add_event_delegation(src)
78
79
  add_statemachine_exception(src)
@@ -83,20 +84,42 @@ module Statemachine
83
84
  return src.to_s
84
85
  end
85
86
 
86
- def add_state_instances(src)
87
- src << "// State instances" << endl
88
- @state_names.each do |state|
89
- src << "public final State #{state.upcase} = new #{state}State(this);" << endl
87
+ def add_instance_variables (src)
88
+ src << "// Instance variables" << endl
89
+ concrete_states = @sm.states.values.reject { |state| state.id.nil? || !state.concrete? }.sort { |a, b| a.id <=> b.id }
90
+ concrete_states.each do |state|
91
+ name = state.id.to_s.camalized
92
+ src << "public final State #{name.upcase} = new #{name}State(this);" << endl
90
93
  end
91
- src << "private State state = #{default_state_name};" << endl
94
+ superstates = @sm.states.values.reject { |state| state.concrete? }.sort { |a, b| a.id <=> b.id }
95
+ superstates.each do |superstate|
96
+ startstate = superstate.resolve_startstate
97
+ src << "public final State #{superstate.id.to_s.upcase} = #{startstate.id.to_s.upcase};" << endl
98
+ end
99
+ src << "private State state = #{@startstate.id.to_s.upcase};" << endl
100
+ src << endl
101
+ src << "private #{@context_classname} context;" << endl
92
102
  src << endl
93
103
  end
94
104
 
105
+ def add_constructor(src)
106
+ src << "// Statemachine constructor" << endl
107
+ add_method(src, nil, @classname, "#{@context_classname} context") do
108
+ src << "this.context = context;" << endl
109
+ entered_states = []
110
+ entry_state = @startstate
111
+ while entry_state != @sm.root
112
+ entered_states << entry_state
113
+ entry_state = entry_state.superstate
114
+ end
115
+ entered_states.reverse.each do |state|
116
+ src << "context.#{state.entry_action.to_s.camalized(:lower)}();" << endl if state.entry_action
117
+ end
118
+ end
119
+ end
120
+
95
121
  def add_statemachine_boilerplate_code(src)
96
122
  src << "// The following is boiler plate code standard to all statemachines" << endl
97
- src << "private #{@context_classname} context;" << endl
98
- src << endl
99
- add_one_liner(src, nil, @classname, "#{@context_classname} context", "this.context = context")
100
123
  add_one_liner(src, @context_classname, "getContext", nil, "return context")
101
124
  add_one_liner(src, "State", "getState", nil, "return state")
102
125
  add_one_liner(src, "void", "setState", "State newState", "state = newState")
@@ -115,7 +138,7 @@ module Statemachine
115
138
  begin_scope(src)
116
139
  src << "public StatemachineException(State state, String event)" << endl
117
140
  begin_scope(src)
118
- src << "super(\"Missing transition from the '\" + state.getClass().getName() + \"' state with the '\" + event + \"' event.\");" << endl
141
+ src << "super(\"Missing transition from '\" + state.getClass().getSimpleName() + \"' with the '\" + event + \"' event.\");" << endl
119
142
  end_scope(src)
120
143
  end_scope(src)
121
144
  src << endl
@@ -137,34 +160,41 @@ module Statemachine
137
160
 
138
161
  def add_state_implementations(src)
139
162
  src << "// State implementations" << endl
140
- @sm.states.keys.sort.each do |state_id|
141
- add_state_class(src, state_id) if state_id
163
+ @sm.states.keys.reject{|k| k.nil? }.sort.each do |state_id|
164
+ state = @sm.states[state_id]
165
+ state_name = state.id.to_s.camalized
166
+ base_class = state.superstate == @sm.root ? "State" : state.superstate.id.to_s.camalized
167
+
168
+ add_concrete_state_class(src, state, state_name, base_class) if state_id
142
169
  end
143
170
  end
144
171
 
145
- def add_state_class(src, state_id)
146
- state = @sm.states[state_id]
147
- state_name = state_id.to_s.camalized
172
+ def add_concrete_state_class(src, state, state_name, base_class)
148
173
  src << "public static class #{state_name}State extends State" << endl
149
174
  src << "{" << endl
150
175
  src.indent!
151
176
  add_one_liner(src, nil, "#{state_name}State", "#{@classname} statemachine", "super(statemachine)")
152
177
  state.transitions.keys.sort.each do |event_id|
153
- add_state_event_handler(event_id, src, state)
178
+ transition = state.transitions[event_id]
179
+ add_state_event_handler(transition, src)
154
180
  end
155
181
  src.undent!
156
182
  src << "}" << endl
157
183
  src << endl
158
184
  end
159
185
 
160
- def add_state_event_handler(event_id, src, state)
161
- transition = state.transitions[event_id]
162
- event_name = event_id.to_s.camalized(:lower)
186
+ def add_state_event_handler(transition, src)
187
+ event_name = transition.event.to_s.camalized(:lower)
188
+ exits, entries = transition.exits_and_entries(@sm.get_state(transition.origin_id), @sm.get_state(transition.destination_id))
163
189
  add_method(src, "void", event_name, nil) do
164
- if transition.action
165
- src << "statemachine.getContext().#{transition.action.to_s.camalized(:lower)}();" << endl
190
+ exits.each do |exit|
191
+ src << "statemachine.getContext().#{exit.exit_action.to_s.camalized(:lower)}();" << endl if exit.exit_action
166
192
  end
193
+ src << "statemachine.getContext().#{transition.action.to_s.camalized(:lower)}();" << endl if transition.action
167
194
  src << "statemachine.setState(statemachine.#{transition.destination_id.to_s.upcase});" << endl
195
+ entries.each do |entry|
196
+ src << "statemachine.getContext().#{entry.entry_action.to_s.camalized(:lower)}();" << endl if entry.entry_action
197
+ end
168
198
  end
169
199
  end
170
200
 
@@ -175,7 +205,7 @@ module Statemachine
175
205
  end
176
206
 
177
207
  def add_method(src, return_type, name, params)
178
- src << "public #{return_type} #{name}(#{params})".sub(' ', ' ') << endl
208
+ src << "public #{return_type} #{name}(#{params})".sub(' ' * 2, ' ') << endl
179
209
  begin_scope(src)
180
210
  yield
181
211
  end_scope(src)
@@ -191,10 +221,6 @@ module Statemachine
191
221
  src.undent! << "}" << endl
192
222
  end
193
223
 
194
- def default_state_name
195
- @sm.startstate.nil? ? "null" : @sm.startstate.to_s.upcase
196
- end
197
-
198
224
  def build_context_src
199
225
  src = begin_src
200
226
  src << "public interface #{@context_classname}" << endl
@@ -54,9 +54,13 @@ module Statemachine
54
54
  @statemachine.state = self
55
55
  end
56
56
 
57
- def is_concrete?
57
+ def concrete?
58
58
  return true
59
59
  end
60
+
61
+ def resolve_startstate
62
+ return self
63
+ end
60
64
 
61
65
  def reset
62
66
  end
@@ -50,7 +50,7 @@ module Statemachine
50
50
  # Resets the statemachine back to its starting state.
51
51
  def reset
52
52
  @state = get_state(@root.startstate_id)
53
- while @state and not @state.is_concrete?
53
+ while @state and not @state.concrete?
54
54
  @state = get_state(@state.startstate_id)
55
55
  end
56
56
  raise StatemachineException.new("The state machine doesn't know where to start. Try setting the startstate.") if @state == nil
@@ -106,7 +106,7 @@ module Statemachine
106
106
  elsif(is_history_state_id?(id))
107
107
  superstate_id = base_id(id)
108
108
  superstate = @states[superstate_id]
109
- raise StatemachineException.new("No history exists for #{superstate} since it is not a super state.") if superstate.is_concrete?
109
+ raise StatemachineException.new("No history exists for #{superstate} since it is not a super state.") if superstate.concrete?
110
110
  return load_history(superstate)
111
111
  else
112
112
  state = State.new(id, @root, self)
@@ -162,7 +162,7 @@ module Statemachine
162
162
  100.times do
163
163
  history = superstate.history_id ? get_state(superstate.history_id) : nil
164
164
  raise StatemachineException.new("#{superstate} doesn't have any history yet.") if not history
165
- if history.is_concrete?
165
+ if history.concrete?
166
166
  return history
167
167
  else
168
168
  superstate = history
@@ -0,0 +1,24 @@
1
+ module Statemachine
2
+
3
+ class StubContext
4
+
5
+ def initialize(options = {})
6
+ @verbose = options[:verbose]
7
+ end
8
+
9
+ attr_accessor :statemachine
10
+
11
+ def method(name)
12
+ super(name)
13
+ rescue
14
+ self.class.class_eval "def #{name}(*args, &block); __generic_method(:#{name}, *args, &block); end"
15
+ return super(name)
16
+ end
17
+
18
+ def __generic_method(name, *args)
19
+ puts "action invoked: #{name}(#{args.join(", ")}) #{block_given? ? "with block" : ""}" if @verbose
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -11,10 +11,18 @@ module Statemachine
11
11
  @history_id = nil
12
12
  end
13
13
 
14
- def is_concrete?
14
+ def concrete?
15
15
  return false
16
16
  end
17
-
17
+
18
+ def startstate
19
+ return @statemachine.get_state(@startstate_id)
20
+ end
21
+
22
+ def resolve_startstate
23
+ return startstate.resolve_startstate
24
+ end
25
+
18
26
  def substate_exiting(substate)
19
27
  @history_id = substate.id
20
28
  end
@@ -19,20 +19,16 @@ module Statemachine
19
19
 
20
20
  origin.statemachine.invoke_action(@action, args, "transition action from #{origin} invoked by '#{@event}' event") if @action
21
21
 
22
- terminal_state = destination
23
- while terminal_state and not terminal_state.is_concrete?
24
- terminal_state = statemachine.get_state(terminal_state.startstate_id)
25
- entries << terminal_state
26
- end
22
+ terminal_state = entries.last
27
23
  terminal_state.activate if terminal_state
28
24
 
29
25
  entries.each { |entered_state| entered_state.enter(args) }
30
26
  end
31
27
 
32
28
  def exits_and_entries(origin, destination)
29
+ return [], [] if origin == destination
33
30
  exits = []
34
31
  entries = exits_and_entries_helper(exits, origin, destination)
35
-
36
32
  return exits, entries.reverse
37
33
  end
38
34
 
@@ -52,8 +48,9 @@ module Statemachine
52
48
  end
53
49
 
54
50
  def entries_to_destination(exit_state, destination)
51
+ return nil if destination.nil?
55
52
  entries = []
56
- state = destination
53
+ state = destination.resolve_startstate
57
54
  while state
58
55
  entries << state
59
56
  return entries if exit_state == state.superstate
@@ -3,7 +3,7 @@ module Statemachine
3
3
  unless defined? MAJOR
4
4
  MAJOR = 0
5
5
  MINOR = 5
6
- TINY = 0
6
+ TINY = 1
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY].join('.')
9
9
  TAG = "REL_" + [MAJOR, MINOR, TINY].join('_')
@@ -20,26 +20,58 @@ describe Statemachine::Statemachine, "(Java)" do
20
20
  @sm.to_java(:output => @output, :name => "JavaTurnstile", :package => "test.turnstile")
21
21
  end
22
22
 
23
+ def generate_complex_turnstile_sm
24
+ @sm = Statemachine.build do
25
+ superstate :operational do
26
+ on_entry :operate
27
+ on_exit :beep
28
+ state :locked do
29
+ on_entry :lock
30
+ event :coin, :unlocked
31
+ event :pass, :locked, :alarm
32
+ end
33
+ state :unlocked do
34
+ on_entry :unlock
35
+ event :coin, :unlocked, :thanks
36
+ event :pass, :locked
37
+ end
38
+ event :diagnose, :diagnostics
39
+ end
40
+ state :diagnostics do
41
+ on_entry :disable
42
+ on_exit :beep
43
+ event :operate, :operational
44
+ end
45
+ stub_context :verbose => true
46
+ end
47
+
48
+ @sm.to_java(:output => @output, :name => "JavaTurnstile", :package => "test.turnstile")
49
+ end
50
+
51
+ def load_lines(*segs)
52
+ filename = File.join(*segs)
53
+ File.should exist( filename)
54
+ return IO.read(filename).split("\n")
55
+ end
56
+
23
57
  def empty_sm_lines
24
58
  @sm.to_java(:name => "JavaTest", :output => @output, :package => "test.blank")
25
- filename = File.join(@output, "test", "blank", "JavaTest.java")
26
- File.should exist( filename)
27
- lines = IO.read(filename).split("\n")
28
- return lines
59
+ return load_lines(@output, "test", "blank", "JavaTest.java")
29
60
  end
30
61
 
31
- def sm_lines
62
+ def turnstile_lines
32
63
  generate_turnstile_sm
33
- filename = File.join(@output, "test", "turnstile", "JavaTurnstile.java")
34
- File.should exist( filename)
35
- return IO.read(filename).split("\n")
64
+ return load_lines(@output, "test", "turnstile", "JavaTurnstile.java")
36
65
  end
37
66
 
38
- def context_lines
67
+ def turnstile_context_lines
39
68
  generate_turnstile_sm
40
- filename = File.join(@output, "test", "turnstile", "JavaTurnstileContext.java")
41
- File.should exist( filename)
42
- return IO.read(filename).split("\n")
69
+ return load_lines(@output, "test", "turnstile", "JavaTurnstileContext.java")
70
+ end
71
+
72
+ def complex_turnstile_lines
73
+ generate_complex_turnstile_sm
74
+ return load_lines(@output, "test", "turnstile", "JavaTurnstile.java")
43
75
  end
44
76
 
45
77
  def find_lines_after(lines, goose)
@@ -78,17 +110,19 @@ describe Statemachine::Statemachine, "(Java)" do
78
110
  lines.last.should == "}"
79
111
  end
80
112
 
81
- it "should generate sm boilerplate code" do
82
- lines = empty_sm_lines
83
- lines = find_lines_after(lines, "// The following is boiler plate code standard to all statemachines")
113
+ it "should generate the constructor" do
114
+ lines = find_lines_after(empty_sm_lines, "// Statemachine constructor")
84
115
 
85
- lines.shift.should == " private JavaTestContext context;"
86
- lines.shift.should == ""
87
116
  lines.shift.should == " public JavaTest(JavaTestContext context)"
88
117
  lines.shift.should == " {"
89
118
  lines.shift.should == " this.context = context;"
90
119
  lines.shift.should == " }"
91
120
  lines.shift.should == ""
121
+ end
122
+
123
+ it "should generate sm boilerplate code" do
124
+ lines = find_lines_after(empty_sm_lines, "// The following is boiler plate code standard to all statemachines")
125
+
92
126
  lines.shift.should == " public JavaTestContext getContext()"
93
127
  lines.shift.should == " {"
94
128
  lines.shift.should == " return context;"
@@ -113,9 +147,9 @@ describe Statemachine::Statemachine, "(Java)" do
113
147
  lines.shift.should == " {"
114
148
  lines.shift.should == " public StatemachineException(State state, String event)"
115
149
  lines.shift.should == " {"
116
- lines.shift.should == " super(\"Missing transition from the '\" + state.getClass().getName() + \"' state with the '\" + event + \"' event.\");"
150
+ lines.shift.should == " super(\"Missing transition from '\" + state.getClass().getSimpleName() + \"' with the '\" + event + \"' event.\");"
117
151
  lines.shift.should == " }"
118
- lines.shift.should == " }"
152
+ lines.shift.should == " }"
119
153
  end
120
154
 
121
155
  it "should generate base state" do
@@ -136,7 +170,7 @@ describe Statemachine::Statemachine, "(Java)" do
136
170
 
137
171
  it "should generate the context" do
138
172
  @sm.to_java(:name => "JavaTest", :output => @output, :package => "com.blah")
139
-
173
+
140
174
  filename = File.join(@output, "com", "blah", "JavaTestContext.java")
141
175
  File.should exist(filename)
142
176
  lines = IO.read(filename).split("\n")
@@ -153,15 +187,17 @@ describe Statemachine::Statemachine, "(Java)" do
153
187
  end
154
188
 
155
189
  it "should generate the state instance variables" do
156
- lines = find_lines_after(sm_lines, "// State instances")
190
+ lines = find_lines_after(turnstile_lines, "// Instance variables")
157
191
 
158
192
  lines.shift.should == " public final State LOCKED = new LockedState(this);"
159
193
  lines.shift.should == " public final State UNLOCKED = new UnlockedState(this);"
160
194
  lines.shift.should == " private State state = LOCKED;"
195
+ lines.shift.should == ""
196
+ lines.shift.should == " private JavaTurnstileContext context;"
161
197
  end
162
198
 
163
199
  it "should generate all the sm event handlers" do
164
- lines = find_lines_after(sm_lines, "// Event delegation")
200
+ lines = find_lines_after(turnstile_lines, "// Event delegation")
165
201
 
166
202
  lines.shift.should == " public void coin()"
167
203
  lines.shift.should == " {"
@@ -176,7 +212,7 @@ describe Statemachine::Statemachine, "(Java)" do
176
212
  end
177
213
 
178
214
  it "should generate all the default event handlers" do
179
- lines = find_lines_after(sm_lines, "// The base state")
215
+ lines = find_lines_after(turnstile_lines, "// The base state")
180
216
 
181
217
  lines.shift.should == " public static abstract class State"
182
218
  lines.shift.should == " {"
@@ -201,7 +237,7 @@ describe Statemachine::Statemachine, "(Java)" do
201
237
  end
202
238
 
203
239
  it "should generate state classes" do
204
- lines = find_lines_after(sm_lines, "// State implementations")
240
+ lines = find_lines_after(turnstile_lines, "// State implementations")
205
241
 
206
242
  lines.shift.should == " public static class LockedState extends State"
207
243
  lines.shift.should == " {"
@@ -248,7 +284,7 @@ describe Statemachine::Statemachine, "(Java)" do
248
284
  end
249
285
 
250
286
  it "should generate all the context methods" do
251
- lines = find_lines_after(context_lines, "// Actions")
287
+ lines = find_lines_after(turnstile_context_lines, "// Actions")
252
288
 
253
289
  lines.shift.should == " void alarm();"
254
290
  lines.shift.should == " void lock();"
@@ -256,4 +292,57 @@ describe Statemachine::Statemachine, "(Java)" do
256
292
  lines.shift.should == " void unlock();"
257
293
  end
258
294
 
295
+ it "should generate complext state instances" do
296
+ lines = find_lines_after(complex_turnstile_lines, "// Instance variables")
297
+
298
+ lines.shift.should == " public final State DIAGNOSTICS = new DiagnosticsState(this);"
299
+ lines.shift.should == " public final State LOCKED = new LockedState(this);"
300
+ lines.shift.should == " public final State UNLOCKED = new UnlockedState(this);"
301
+ lines.shift.should == " public final State OPERATIONAL = LOCKED;"
302
+ lines.shift.should == " private State state = LOCKED;"
303
+ end
304
+
305
+ it "should generate entry actions on startup" do
306
+ lines = find_lines_after(complex_turnstile_lines, "// Statemachine constructor")
307
+
308
+ lines.shift.should == " public JavaTurnstile(JavaTurnstileContext context)"
309
+ lines.shift.should == " {"
310
+ lines.shift.should == " this.context = context;"
311
+ lines.shift.should == " context.operate();"
312
+ lines.shift.should == " context.lock();"
313
+ lines.shift.should == " }"
314
+ lines.shift.should == ""
315
+ end
316
+
317
+ it "should add entry/exit actions to each transition" do
318
+ lines = find_lines_after(complex_turnstile_lines, "public static class LockedState extends State")
319
+
320
+ lines.shift.should == " {"
321
+ lines.shift.should == " public LockedState(JavaTurnstile statemachine)"
322
+ lines.shift.should == " {"
323
+ lines.shift.should == " super(statemachine);"
324
+ lines.shift.should == " }"
325
+ lines.shift.should == ""
326
+ lines.shift.should == " public void coin()"
327
+ lines.shift.should == " {"
328
+ lines.shift.should == " statemachine.setState(statemachine.UNLOCKED);"
329
+ lines.shift.should == " statemachine.getContext().unlock();"
330
+ lines.shift.should == " }"
331
+ lines.shift.should == ""
332
+ lines.shift.should == " public void diagnose()"
333
+ lines.shift.should == " {"
334
+ lines.shift.should == " statemachine.getContext().beep();"
335
+ lines.shift.should == " statemachine.setState(statemachine.DIAGNOSTICS);"
336
+ lines.shift.should == " statemachine.getContext().disable();"
337
+ lines.shift.should == " }"
338
+ lines.shift.should == ""
339
+ lines.shift.should == " public void pass()"
340
+ lines.shift.should == " {"
341
+ lines.shift.should == " statemachine.getContext().alarm();"
342
+ lines.shift.should == " statemachine.setState(statemachine.LOCKED);"
343
+ lines.shift.should == " }"
344
+ lines.shift.should == ""
345
+ lines.shift.should == " }"
346
+ end
347
+
259
348
  end
@@ -17,8 +17,8 @@ describe "Transition Calculating Exits and Entries" do
17
17
  it "to itself" do
18
18
  @a = Statemachine::State.new("a", nil, nil)
19
19
  exits, entries = @transition.exits_and_entries(@a, @a)
20
- exits.to_s.should eql([@a].to_s)
21
- entries.to_s.should eql([@a].to_s)
20
+ exits.should == []
21
+ entries.should == []
22
22
  end
23
23
 
24
24
  it "to friend" do
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statemachine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 5
8
+ - 1
9
+ version: 0.5.1
5
10
  platform: ruby
6
11
  authors:
7
12
  - Micah Martin
@@ -9,7 +14,7 @@ autorequire: statemachine
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-03-24 00:00:00 -05:00
17
+ date: 2010-03-25 00:00:00 -05:00
13
18
  default_executable:
14
19
  dependencies: []
15
20
 
@@ -35,6 +40,7 @@ files:
35
40
  - lib/statemachine/generate/util.rb
36
41
  - lib/statemachine/state.rb
37
42
  - lib/statemachine/statemachine.rb
43
+ - lib/statemachine/stub_context.rb
38
44
  - lib/statemachine/superstate.rb
39
45
  - lib/statemachine/transition.rb
40
46
  - lib/statemachine/version.rb
@@ -65,21 +71,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
71
  requirements:
66
72
  - - ">="
67
73
  - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
68
76
  version: "0"
69
- version:
70
77
  required_rubygems_version: !ruby/object:Gem::Requirement
71
78
  requirements:
72
79
  - - ">="
73
80
  - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
74
83
  version: "0"
75
- version:
76
84
  requirements: []
77
85
 
78
86
  rubyforge_project: statemachine
79
- rubygems_version: 1.3.5
87
+ rubygems_version: 1.3.6
80
88
  signing_key:
81
89
  specification_version: 3
82
- summary: Statemachine-0.5.0 - Statemachine Library for Ruby http://slagyr.github.com/statemachine
90
+ summary: Statemachine-0.5.1 - Statemachine Library for Ruby http://slagyr.github.com/statemachine
83
91
  test_files:
84
92
  - spec/action_invokation_spec.rb
85
93
  - spec/builder_spec.rb