statemachine 0.5.0 → 0.5.1

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