statemachine 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGES CHANGED
@@ -1,5 +1,15 @@
1
1
  = Statemachine Changelog
2
2
 
3
+ == Version 0.4.0
4
+
5
+ Feature enhancements
6
+ * enabled nested superstate history
7
+ * TransitionMissingException's are raised when the statemachine can't respond to an event
8
+ * Statmachine overrides respond_to? to respond to valid events.
9
+
10
+ Behavior Fixes
11
+ * fixed default transition so that superstate transitions have priority over default
12
+
3
13
  == Version 0.3.0
4
14
 
5
15
  Feature enhancements
data/TODO CHANGED
@@ -1,4 +1,4 @@
1
-
1
+ Specific Exceptions... so missing events can be identified.
2
2
 
3
3
  Maybe:
4
4
  Implement superstate endstate with automatic transition
@@ -22,8 +22,8 @@ module Statemachine
22
22
 
23
23
  def transition_for(event)
24
24
  transition = @transitions[event]
25
+ transition = @superstate.transition_for(event) if @superstate and not transition
25
26
  transition = @default_transition if not transition
26
- transition = @superstate.transition_for(event) if @superstate and not transition
27
27
  return transition
28
28
  end
29
29
 
@@ -3,6 +3,9 @@ module Statemachine
3
3
  class StatemachineException < Exception
4
4
  end
5
5
 
6
+ class TransitionMissingException < Exception
7
+ end
8
+
6
9
  # Used at runtime to execute the behavior of the statemachine.
7
10
  # Should be created by using the Statemachine.build method.
8
11
  #
@@ -86,7 +89,7 @@ module Statemachine
86
89
  if transition
87
90
  transition.invoke(@state, self, args)
88
91
  else
89
- raise StatemachineException.new("#{@state} does not respond to the '#{event}' event.")
92
+ raise TransitionMissingException.new("#{@state} does not respond to the '#{event}' event.")
90
93
  end
91
94
  else
92
95
  raise StatemachineException.new("The state machine isn't in any state while processing the '#{event}' event.")
@@ -104,8 +107,7 @@ module Statemachine
104
107
  superstate_id = base_id(id)
105
108
  superstate = @states[superstate_id]
106
109
  raise StatemachineException.new("No history exists for #{superstate} since it is not a super state.") if superstate.is_concrete?
107
- raise StatemachineException.new("#{superstate} doesn't have any history yet.") if not superstate.history
108
- return superstate.history
110
+ return load_history(superstate)
109
111
  else
110
112
  state = State.new(id, @root, self)
111
113
  @states[id] = state
@@ -125,13 +127,24 @@ module Statemachine
125
127
  end
126
128
  end
127
129
 
130
+ def respond_to?(message)
131
+ return true if super(message)
132
+ return true if @state.transition_for(message)
133
+ return false
134
+ end
135
+
128
136
  def method_missing(message, *args) #:nodoc:
129
137
  if @state and @state.transition_for(message)
130
- method = self.method(:process_event)
131
- params = [message.to_sym].concat(args)
132
- method.call(*params)
138
+ process_event(message.to_sym, *args)
139
+ # method = self.method(:process_event)
140
+ # params = [message.to_sym].concat(args)
141
+ # method.call(*params)
133
142
  else
134
- super(message, args)
143
+ begin
144
+ super(message, args)
145
+ rescue NoMethodError
146
+ process_event(message.to_sym, *args)
147
+ end
135
148
  end
136
149
  end
137
150
 
@@ -145,6 +158,18 @@ module Statemachine
145
158
  return history_id.to_s[0...-2].to_sym
146
159
  end
147
160
 
161
+ def load_history(superstate)
162
+ 100.times do
163
+ history = superstate.history
164
+ raise StatemachineException.new("#{superstate} doesn't have any history yet.") if not history
165
+ if history.is_concrete?
166
+ return history
167
+ else
168
+ superstate = history
169
+ end
170
+ end
171
+ raise StatemachineException.new("No history found within 100 levels of nested superstates.")
172
+ end
173
+
148
174
  end
149
-
150
175
  end
@@ -2,7 +2,7 @@ module Statemachine
2
2
  module VERSION #:nodoc:
3
3
  unless defined? MAJOR
4
4
  MAJOR = 0
5
- MINOR = 3
5
+ MINOR = 4
6
6
  TINY = 0
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY].join('.')
@@ -19,13 +19,13 @@ class Noodle
19
19
 
20
20
  end
21
21
 
22
- context "Action Invokation" do
22
+ describe "Action Invokation" do
23
23
 
24
- setup do
24
+ before(:each) do
25
25
  @noodle = Noodle.new
26
26
  end
27
27
 
28
- specify "Proc actions" do
28
+ it "Proc actions" do
29
29
  sm = Statemachine.build do |smb|
30
30
  smb.trans :cold, :fire, :hot, Proc.new { @cooked = true }
31
31
  end
@@ -33,10 +33,10 @@ context "Action Invokation" do
33
33
  sm.context = @noodle
34
34
  sm.fire
35
35
 
36
- @noodle.cooked.should_be true
36
+ @noodle.cooked.should equal(true)
37
37
  end
38
38
 
39
- specify "Symbol actions" do
39
+ it "Symbol actions" do
40
40
  sm = Statemachine.build do |smb|
41
41
  smb.trans :cold, :fire, :hot, :cook
42
42
  smb.trans :hot, :mold, :changed, :transform
@@ -45,22 +45,22 @@ context "Action Invokation" do
45
45
  sm.context = @noodle
46
46
  sm.fire
47
47
 
48
- @noodle.cooked.should_be true
48
+ @noodle.cooked.should equal(true)
49
49
 
50
50
  sm.mold "capellini"
51
51
 
52
- @noodle.shape.should_eql "capellini"
52
+ @noodle.shape.should eql("capellini")
53
53
  end
54
54
 
55
- specify "String actions" do
55
+ it "String actions" do
56
56
  sm = Statemachine.build do |smb|
57
57
  smb.trans :cold, :fire, :hot, "@shape = 'fettucini'; @cooked = true"
58
58
  end
59
59
  sm.context = @noodle
60
60
 
61
61
  sm.fire
62
- @noodle.shape.should_eql "fettucini"
63
- @noodle.cooked.should_be true
62
+ @noodle.shape.should eql("fettucini")
63
+ @noodle.cooked.should equal(true)
64
64
  end
65
65
 
66
66
 
data/spec/builder_spec.rb CHANGED
@@ -1,24 +1,24 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- context "Builder" do
3
+ describe "Builder" do
4
4
 
5
- setup do
5
+ before(:each) do
6
6
  @log = []
7
7
  end
8
8
 
9
9
  def check_switch(sm)
10
- sm.state.should_be :off
10
+ sm.state.should equal(:off)
11
11
 
12
12
  sm.toggle
13
- @log[0].should_eql "toggle on"
14
- sm.state.should_be :on
13
+ @log[0].should eql("toggle on")
14
+ sm.state.should equal(:on)
15
15
 
16
16
  sm.toggle
17
- @log[1].should_eql "toggle off"
18
- sm.state.should_be :off
17
+ @log[1].should eql("toggle off")
18
+ sm.state.should equal(:off)
19
19
  end
20
20
 
21
- specify "Building a the switch, relaxed" do
21
+ it "Building a the switch, relaxed" do
22
22
  sm = Statemachine.build do
23
23
  trans :off, :toggle, :on, Proc.new { @log << "toggle on" }
24
24
  trans :on, :toggle, :off, Proc.new { @log << "toggle off" }
@@ -28,7 +28,7 @@ context "Builder" do
28
28
  check_switch sm
29
29
  end
30
30
 
31
- specify "Building a the switch, strict" do
31
+ it "Building a the switch, strict" do
32
32
  sm = Statemachine.build do
33
33
  state(:off) { |s| s.event :toggle, :on, Proc.new { @log << "toggle on" } }
34
34
  state(:on) { |s| s.event :toggle, :off, Proc.new { @log << "toggle off" } }
@@ -38,7 +38,7 @@ context "Builder" do
38
38
  check_switch sm
39
39
  end
40
40
 
41
- specify "Adding a superstate to the switch" do
41
+ it "Adding a superstate to the switch" do
42
42
  the_context = self
43
43
  sm = Statemachine.build do
44
44
  superstate :operation do
@@ -52,16 +52,16 @@ context "Builder" do
52
52
  context the_context
53
53
  end
54
54
 
55
- sm.state.should_be :off
55
+ sm.state.should equal(:off)
56
56
  sm.toggle
57
57
  sm.admin
58
- sm.state.should_be :testing
58
+ sm.state.should equal(:testing)
59
59
  sm.resume
60
- sm.state.should_be :on
61
- @log.join(",").should_eql "toggle on,testing,resuming"
60
+ sm.state.should equal(:on)
61
+ @log.join(",").should eql("toggle on,testing,resuming")
62
62
  end
63
63
 
64
- specify "entry exit actions" do
64
+ it "entry exit actions" do
65
65
  the_context = self
66
66
  sm = Statemachine.build do
67
67
  state :off do
@@ -74,14 +74,14 @@ context "Builder" do
74
74
  end
75
75
 
76
76
  sm.toggle
77
- sm.state.should_be :on
77
+ sm.state.should equal(:on)
78
78
  sm.toggle
79
- sm.state.should_be :off
79
+ sm.state.should equal(:off)
80
80
 
81
- @log.join(",").should_eql "enter off,exit off,toggle on,toggle off,enter off"
81
+ @log.join(",").should eql("enter off,exit off,toggle on,toggle off,enter off")
82
82
  end
83
83
 
84
- specify "History state" do
84
+ it "History state" do
85
85
  the_context = self
86
86
  sm = Statemachine.build do
87
87
  superstate :operation do
@@ -100,12 +100,12 @@ context "Builder" do
100
100
 
101
101
  sm.admin
102
102
  sm.resume
103
- sm.state.should_be :off
103
+ sm.state.should equal(:off)
104
104
 
105
- @log.join(",").should_eql "enter off,testing,resuming,enter off"
105
+ @log.join(",").should eql("enter off,testing,resuming,enter off")
106
106
  end
107
107
 
108
- specify "entry and exit action created from superstate builder" do
108
+ it "entry and exit action created from superstate builder" do
109
109
  the_context = self
110
110
  sm = Statemachine.build do
111
111
  trans :off, :toggle, :on, Proc.new { @log << "toggle on" }
@@ -118,11 +118,11 @@ context "Builder" do
118
118
  sm.toggle
119
119
  sm.toggle
120
120
 
121
- @log.join(",").should_eql "entering off,toggle on,exiting on,toggle off,entering off"
121
+ @log.join(",").should eql("entering off,toggle on,exiting on,toggle off,entering off")
122
122
 
123
123
  end
124
124
 
125
- specify "superstate as startstate" do
125
+ it "superstate as startstate" do
126
126
 
127
127
  lambda do
128
128
  sm = Statemachine.build do
@@ -131,11 +131,11 @@ context "Builder" do
131
131
  end
132
132
  end
133
133
 
134
- sm.state.should_be :luigi
135
- end.should_not_raise(Exception)
134
+ sm.state.should equal(:luigi)
135
+ end.should_not raise_error(Exception)
136
136
  end
137
137
 
138
- specify "setting the start state before any other states declared" do
138
+ it "setting the start state before any other states declared" do
139
139
 
140
140
  sm = Statemachine.build do
141
141
  startstate :right
@@ -144,12 +144,12 @@ context "Builder" do
144
144
  trans :right, :pull, :middle
145
145
  end
146
146
 
147
- sm.state.should_be :right
147
+ sm.state.should equal(:right)
148
148
  sm.pull
149
- sm.state.should_be :middle
149
+ sm.state.should equal(:middle)
150
150
  end
151
151
 
152
- specify "setting start state which is in a super state" do
152
+ it "setting start state which is in a super state" do
153
153
  sm = Statemachine.build do
154
154
  startstate :right
155
155
  superstate :table do
@@ -161,16 +161,16 @@ context "Builder" do
161
161
  state :floor
162
162
  end
163
163
 
164
- sm.state.should_be :right
164
+ sm.state.should equal(:right)
165
165
  sm.pull
166
- sm.state.should_be :middle
166
+ sm.state.should equal(:middle)
167
167
  sm.push
168
- sm.state.should_be :right
168
+ sm.state.should equal(:right)
169
169
  sm.tilt
170
- sm.state.should_be :floor
170
+ sm.state.should equal(:floor)
171
171
  end
172
172
 
173
- specify "can set context" do
173
+ it "can set context" do
174
174
  widget = Object.new
175
175
  sm = Statemachine.build do
176
176
  context widget
@@ -179,7 +179,7 @@ context "Builder" do
179
179
  sm.context.should be(widget)
180
180
  end
181
181
 
182
- specify "statemachine will be set on context if possible" do
182
+ it "statemachine will be set on context if possible" do
183
183
  class Widget
184
184
  attr_accessor :statemachine
185
185
  end
@@ -1,8 +1,8 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- context "Default Transition" do
3
+ describe "Default Transition" do
4
4
 
5
- setup do
5
+ before(:each) do
6
6
  @sm = Statemachine.build do
7
7
  trans :default_state, :start, :test_state
8
8
 
@@ -12,20 +12,20 @@ context "Default Transition" do
12
12
  end
13
13
  end
14
14
 
15
- specify "the default transition is set" do
15
+ it "the default transition is set" do
16
16
  test_state = @sm.get_state(:test_state)
17
17
  test_state.default_transition.should_not be(nil)
18
18
  test_state.transition_for(:fake_event).should_not be(nil)
19
19
  end
20
20
 
21
- specify "Should go to the default_state with any event" do
21
+ it "Should go to the default_state with any event" do
22
22
  @sm.start
23
23
  @sm.fake_event
24
24
 
25
25
  @sm.state.should eql(:default_state)
26
26
  end
27
27
 
28
- specify "default transition can have actions" do
28
+ it "default transition can have actions" do
29
29
  me = self
30
30
  @sm = Statemachine.build do
31
31
  trans :default_state, :start, :test_state
@@ -47,7 +47,7 @@ context "Default Transition" do
47
47
  @hi = true
48
48
  end
49
49
 
50
- specify "superstate supports the default" do
50
+ it "superstate supports the default" do
51
51
  @sm = Statemachine.build do
52
52
  superstate :test_superstate do
53
53
  default :default_state
@@ -62,4 +62,26 @@ context "Default Transition" do
62
62
  @sm.blah
63
63
  @sm.state.should eql(:default_state)
64
64
  end
65
+
66
+ it "superstate transitions do not go to the default state" do
67
+ @sm = Statemachine.build do
68
+ superstate :test_superstate do
69
+ event :not_default, :not_default_state
70
+
71
+ state :start_state do
72
+ default :default_state
73
+ end
74
+
75
+ state :default_state
76
+ end
77
+
78
+ startstate :start_state
79
+ end
80
+
81
+ @sm.state = :start_state
82
+ @sm.not_default
83
+ @sm.state.should eql(:not_default_state)
84
+ end
85
+
86
+
65
87
  end
data/spec/history_spec.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- context "History States" do
3
+ describe "History States" do
4
4
 
5
- setup do
5
+ before(:each) do
6
6
  @sm = Statemachine.build do
7
7
  superstate :operate do
8
8
  trans :on, :toggle, :off
@@ -16,19 +16,19 @@ context "History States" do
16
16
  end
17
17
  end
18
18
 
19
- specify "no history allowed for concrete states" do
19
+ it "no history allowed for concrete states" do
20
20
  lambda {
21
21
  @sm.dream
22
- }.should_raise(Statemachine::StatemachineException, "No history exists for 'on' state since it is not a super state.")
22
+ }.should raise_error(Statemachine::StatemachineException, "No history exists for 'on' state since it is not a super state.")
23
23
  end
24
24
 
25
- specify "error when trying to use history that doesn't exist yet" do
25
+ it "error when trying to use history that doesn't exist yet" do
26
26
  lambda {
27
27
  @sm.fiddle
28
- }.should_raise(Statemachine::StatemachineException, "'operate' superstate doesn't have any history yet.")
28
+ }.should raise_error(Statemachine::StatemachineException, "'operate' superstate doesn't have any history yet.")
29
29
  end
30
30
 
31
- specify "reseting the statemachine resets history" do
31
+ it "reseting the statemachine resets history" do
32
32
  @sm.faddle
33
33
  @sm.fiddle
34
34
  @sm.get_state(:operate).history.id.should eql(:on)
@@ -39,9 +39,9 @@ context "History States" do
39
39
 
40
40
  end
41
41
 
42
- context "History Default" do
42
+ describe "History Default" do
43
43
 
44
- setup do
44
+ before(:each) do
45
45
  @sm = Statemachine.build do
46
46
  superstate :operate do
47
47
  trans :on, :toggle, :off
@@ -55,12 +55,12 @@ context "History Default" do
55
55
  end
56
56
  end
57
57
 
58
- specify "default history" do
58
+ it "default history" do
59
59
  @sm.fiddle
60
60
  @sm.state.should eql(:on)
61
61
  end
62
62
 
63
- specify "reseting the statemachine resets history" do
63
+ it "reseting the statemachine resets history" do
64
64
  @sm.faddle
65
65
  @sm.toggle
66
66
  @sm.fiddle
@@ -72,3 +72,36 @@ context "History Default" do
72
72
 
73
73
  end
74
74
 
75
+ describe "Nested Superstates" do
76
+
77
+ before(:each) do
78
+ @sm = Statemachine.build do
79
+
80
+ superstate :grandpa do
81
+ trans :start, :go, :daughter
82
+ event :sister, :great_auntie
83
+
84
+ superstate :papa do
85
+ state :son
86
+ state :daughter
87
+ end
88
+ end
89
+
90
+ state :great_auntie do
91
+ event :foo, :grandpa_H
92
+ end
93
+
94
+ end
95
+ end
96
+
97
+ it "should use history of sub superstates when transitioning itto it's own history" do
98
+ @sm.go
99
+ @sm.sister
100
+ @sm.foo
101
+
102
+ @sm.state.should eql(:daughter)
103
+ end
104
+
105
+ end
106
+
107
+
@@ -1,99 +1,99 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- context "State Machine Odds And Ends" do
3
+ describe "State Machine Odds And Ends" do
4
4
  include SwitchStatemachine
5
5
 
6
- setup do
6
+ before(:each) do
7
7
  create_switch
8
8
  end
9
9
 
10
- specify "action with one parameter" do
10
+ it "action with one parameter" do
11
11
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |value| @status = value } }
12
12
  @sm.set "blue"
13
- @status.should_eql "blue"
14
- @sm.state.should_be :on
13
+ @status.should eql("blue")
14
+ @sm.state.should equal(:on)
15
15
  end
16
16
 
17
- specify "action with two parameters" do
17
+ it "action with two parameters" do
18
18
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |a, b| @status = [a, b].join(",") } }
19
19
  @sm.set "blue", "green"
20
- @status.should_eql "blue,green"
21
- @sm.state.should_be :on
20
+ @status.should eql("blue,green")
21
+ @sm.state.should equal(:on)
22
22
  end
23
23
 
24
- specify "action with three parameters" do
24
+ it "action with three parameters" do
25
25
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |a, b, c| @status = [a, b, c].join(",") } }
26
26
  @sm.set "blue", "green", "red"
27
- @status.should_eql "blue,green,red"
28
- @sm.state.should_be :on
27
+ @status.should eql("blue,green,red")
28
+ @sm.state.should equal(:on)
29
29
  end
30
30
 
31
- specify "action with four parameters" do
31
+ it "action with four parameters" do
32
32
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |a, b, c, d| @status = [a, b, c, d].join(",") } }
33
33
  @sm.set "blue", "green", "red", "orange"
34
- @status.should_eql "blue,green,red,orange"
35
- @sm.state.should_be :on
34
+ @status.should eql("blue,green,red,orange")
35
+ @sm.state.should equal(:on)
36
36
  end
37
37
 
38
- specify "action with five parameters" do
38
+ it "action with five parameters" do
39
39
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |a, b, c, d, e| @status = [a, b, c, d, e].join(",") } }
40
40
  @sm.set "blue", "green", "red", "orange", "yellow"
41
- @status.should_eql "blue,green,red,orange,yellow"
42
- @sm.state.should_be :on
41
+ @status.should eql("blue,green,red,orange,yellow")
42
+ @sm.state.should equal(:on)
43
43
  end
44
44
 
45
- specify "action with six parameters" do
45
+ it "action with six parameters" do
46
46
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |a, b, c, d, e, f| @status = [a, b, c, d, e, f].join(",") } }
47
47
  @sm.set "blue", "green", "red", "orange", "yellow", "indigo"
48
- @status.should_eql "blue,green,red,orange,yellow,indigo"
49
- @sm.state.should_be :on
48
+ @status.should eql("blue,green,red,orange,yellow,indigo")
49
+ @sm.state.should equal(:on)
50
50
  end
51
51
 
52
- specify "action with seven parameters" do
52
+ it "action with seven parameters" do
53
53
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |a, b, c, d, e, f, g| @status = [a, b, c, d, e, f, g].join(",") } }
54
54
  @sm.set "blue", "green", "red", "orange", "yellow", "indigo", "violet"
55
- @status.should_eql "blue,green,red,orange,yellow,indigo,violet"
56
- @sm.state.should_be :on
55
+ @status.should eql("blue,green,red,orange,yellow,indigo,violet")
56
+ @sm.state.should equal(:on)
57
57
  end
58
58
 
59
- specify "action with eight parameters" do
59
+ it "action with eight parameters" do
60
60
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |a, b, c, d, e, f, g, h| @status = [a, b, c, d, e, f, g, h].join(",") } }
61
61
  @sm.set "blue", "green", "red", "orange", "yellow", "indigo", "violet", "ultra-violet"
62
- @status.should_eql "blue,green,red,orange,yellow,indigo,violet,ultra-violet"
63
- @sm.state.should_be :on
62
+ @status.should eql("blue,green,red,orange,yellow,indigo,violet,ultra-violet")
63
+ @sm.state.should equal(:on)
64
64
  end
65
65
 
66
- specify "calling process_event with parameters" do
66
+ it "calling process_event with parameters" do
67
67
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |a, b, c| @status = [a, b, c].join(",") } }
68
68
  @sm.process_event(:set, "blue", "green", "red")
69
- @status.should_eql "blue,green,red"
70
- @sm.state.should_be :on
69
+ @status.should eql("blue,green,red")
70
+ @sm.state.should equal(:on)
71
71
  end
72
72
 
73
- specify "Insufficient params" do
73
+ it "Insufficient params" do
74
74
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |a, b, c| @status = [a, b, c].join(",") } }
75
- lambda { @sm.set "blue", "green" }.should_raise(Statemachine::StatemachineException,
75
+ lambda { @sm.set "blue", "green" }.should raise_error(Statemachine::StatemachineException,
76
76
  "Insufficient parameters. (transition action from 'off' state invoked by 'set' event)")
77
77
  end
78
78
 
79
- specify "infinate args" do
79
+ it "infinate args" do
80
80
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |*a| @status = a.join(",") } }
81
81
  @sm.set(1, 2, 3)
82
- @status.should_eql "1,2,3"
82
+ @status.should eql("1,2,3")
83
83
 
84
84
  @sm.state = :off
85
85
  @sm.set(1, 2, 3, 4, 5, 6)
86
- @status.should_eql "1,2,3,4,5,6"
86
+ @status.should eql("1,2,3,4,5,6")
87
87
  end
88
88
 
89
- specify "Insufficient params when params are infinate" do
89
+ it "Insufficient params when params are infinate" do
90
90
  Statemachine.build(@sm) { |s| s.trans :off, :set, :on, Proc.new { |a, *b| @status = a.to_s + ":" + b.join(",") } }
91
91
  @sm.set(1, 2, 3)
92
- @status.should_eql "1:2,3"
92
+ @status.should eql("1:2,3")
93
93
 
94
94
  @sm.state = :off
95
95
 
96
- lambda { @sm.set }.should_raise(Statemachine::StatemachineException,
96
+ lambda { @sm.set }.should raise_error(Statemachine::StatemachineException,
97
97
  "Insufficient parameters. (transition action from 'off' state invoked by 'set' event)")
98
98
  end
99
99
  end
@@ -1,8 +1,8 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- context "State Machine Entry and Exit Actions" do
3
+ describe "State Machine Entry and Exit Actions" do
4
4
 
5
- setup do
5
+ before(:each) do
6
6
  @log = []
7
7
  @sm = Statemachine.build do
8
8
  trans :off, :toggle, :on, Proc.new { @log << "on" }
@@ -11,50 +11,50 @@ context "State Machine Entry and Exit Actions" do
11
11
  @sm.context = self
12
12
  end
13
13
 
14
- specify "entry action" do
14
+ it "entry action" do
15
15
  @sm.get_state(:on).entry_action = Proc.new { @log << "entered_on" }
16
16
 
17
17
  @sm.toggle
18
18
 
19
- @log.join(",").should_eql "on,entered_on"
19
+ @log.join(",").should eql("on,entered_on")
20
20
  end
21
21
 
22
- specify "exit action" do
22
+ it "exit action" do
23
23
  @sm.get_state(:off).exit_action = Proc.new { @log << "exited_off" }
24
24
 
25
25
  @sm.toggle
26
26
 
27
- @log.join(",").should_eql "exited_off,on"
27
+ @log.join(",").should eql("exited_off,on")
28
28
  end
29
29
 
30
- specify "exit and entry" do
30
+ it "exit and entry" do
31
31
  @sm.get_state(:off).exit_action = Proc.new { @log << "exited_off" }
32
32
  @sm.get_state(:on).entry_action = Proc.new { @log << "entered_on" }
33
33
 
34
34
  @sm.toggle
35
35
 
36
- @log.join(",").should_eql "exited_off,on,entered_on"
36
+ @log.join(",").should eql("exited_off,on,entered_on")
37
37
  end
38
38
 
39
- specify "entry and exit actions may be parameterized" do
39
+ it "entry and exit actions may be parameterized" do
40
40
  @sm.get_state(:off).exit_action = Proc.new { |a| @log << "exited_off(#{a})" }
41
41
  @sm.get_state(:on).entry_action = Proc.new { |a, b| @log << "entered_on(#{a},#{b})" }
42
42
 
43
43
  @sm.toggle "one", "two"
44
44
 
45
- @log.join(",").should_eql "exited_off(one),on,entered_on(one,two)"
45
+ @log.join(",").should eql("exited_off(one),on,entered_on(one,two)")
46
46
  end
47
47
 
48
- specify "current state is set prior to exit and entry actions" do
48
+ it "current state is set prior to exit and entry actions" do
49
49
  @sm.get_state(:off).exit_action = Proc.new { @log << @sm.state }
50
50
  @sm.get_state(:on).entry_action = Proc.new { @log << @sm.state }
51
51
 
52
52
  @sm.toggle
53
53
 
54
- @log.join(",").should_eql "off,on,on"
54
+ @log.join(",").should eql("off,on,on")
55
55
  end
56
56
 
57
- specify "current state is set prior to exit and entry actions even with super states" do
57
+ it "current state is set prior to exit and entry actions even with super states" do
58
58
  @sm = Statemachine::Statemachine.new
59
59
  Statemachine.build(@sm) do
60
60
  superstate :off_super do
@@ -72,18 +72,18 @@ context "State Machine Entry and Exit Actions" do
72
72
  @sm.context = self
73
73
 
74
74
  @sm.toggle
75
- @log.join(",").should_eql "off,super_on,on"
75
+ @log.join(",").should eql("off,super_on,on")
76
76
  end
77
77
 
78
- specify "entry actions invokes another event" do
78
+ it "entry actions invokes another event" do
79
79
  @sm.get_state(:on).entry_action = Proc.new { @sm.toggle }
80
80
 
81
81
  @sm.toggle
82
- @log.join(",").should_eql "on,off"
83
- @sm.state.should_be :off
82
+ @log.join(",").should eql("on,off")
83
+ @sm.state.should equal(:off)
84
84
  end
85
85
 
86
- specify "startstate's entry action should be called when the statemachine starts" do
86
+ it "startstate's entry action should be called when the statemachine starts" do
87
87
  the_context = self
88
88
  @sm = Statemachine.build do
89
89
  trans :a, :b, :c
@@ -1,41 +1,58 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- context "State Machine Odds And Ends" do
3
+ describe "State Machine Odds And Ends" do
4
4
  include SwitchStatemachine
5
5
 
6
- setup do
6
+ before(:each) do
7
7
  create_switch
8
8
  end
9
9
 
10
- specify "method missing delegates to super in case of no event" do
11
- lambda { @sm.blah }.should_raise NoMethodError
10
+ it "method missing delegates to super in case of no event" do
11
+ $method_missing_called = false
12
+ module Blah
13
+ def method_missing(message, *args)
14
+ $method_missing_called = true
15
+ end
16
+ end
17
+ @sm.extend(Blah)
18
+ @sm.blah
19
+ $method_missing_called.should eql(true)
20
+ end
21
+
22
+ it "should raise TransistionMissingException when the state doesn't respond to the event" do
23
+ lambda { @sm.blah }.should raise_error(Statemachine::TransitionMissingException, "'off' state does not respond to the 'blah' event.")
24
+ end
25
+
26
+ it "should respond to valid events" do
27
+ @sm.respond_to?(:toggle).should eql(true)
28
+ @sm.respond_to?(:blah).should eql(false)
12
29
  end
13
30
 
14
- specify "set state with string" do
15
- @sm.state.should_be :off
31
+ it "set state with string" do
32
+ @sm.state.should equal(:off)
16
33
  @sm.state = "on"
17
- @sm.state.should_be :on
34
+ @sm.state.should equal(:on)
18
35
  end
19
36
 
20
- specify "set state with symbol" do
21
- @sm.state.should_be :off
37
+ it "set state with symbol" do
38
+ @sm.state.should equal(:off)
22
39
  @sm.state = :on
23
- @sm.state.should_be :on
40
+ @sm.state.should equal(:on)
24
41
  end
25
42
 
26
- specify "process event accepts strings" do
43
+ it "process event accepts strings" do
27
44
  @sm.process_event("toggle")
28
- @sm.state.should_be :on
45
+ @sm.state.should equal(:on)
29
46
  end
30
47
 
31
- specify "states without transitions are valid" do
48
+ it "states without transitions are valid" do
32
49
  @sm = Statemachine.build do
33
50
  trans :middle, :push, :stuck
34
51
  startstate :middle
35
52
  end
36
53
 
37
54
  @sm.push
38
- @sm.state.should_be :stuck
55
+ @sm.state.should equal(:stuck)
39
56
  end
40
57
 
41
58
  end
@@ -1,23 +1,23 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- context "simple cases:" do
4
- setup do
3
+ describe "simple cases:" do
4
+ before(:each) do
5
5
  @sm = Statemachine::Statemachine.new
6
6
  @sm.context = self
7
7
  @count = 0
8
8
  @proc = Proc.new {@count = @count + 1}
9
9
  end
10
10
 
11
- specify "reset" do
11
+ it "reset" do
12
12
  Statemachine.build(@sm) { |s| s.trans :start, :blah, :end, @proc }
13
13
  @sm.process_event(:blah)
14
14
 
15
15
  @sm.reset
16
16
 
17
- @sm.state.should_be :start
17
+ @sm.state.should equal(:start)
18
18
  end
19
19
 
20
- specify "no proc in transition" do
20
+ it "no proc in transition" do
21
21
  Statemachine.build(@sm) { |s| s.trans :on, :flip, :off }
22
22
 
23
23
  @sm.flip
@@ -1,9 +1,9 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- context "Turn Stile" do
3
+ describe "Turn Stile" do
4
4
  include TurnstileStatemachine
5
5
 
6
- setup do
6
+ before(:each) do
7
7
  create_turnstile
8
8
 
9
9
  @out_out_order = false
@@ -22,19 +22,19 @@ context "Turn Stile" do
22
22
  @sm.context = self
23
23
  end
24
24
 
25
- specify "substates respond to superstate transitions" do
25
+ it "substates respond to superstate transitions" do
26
26
  @sm.process_event(:maintain)
27
- @sm.state.should_be :maintenance
28
- @locked.should_be true
29
- @out_of_order.should_be true
27
+ @sm.state.should equal(:maintenance)
28
+ @locked.should equal(true)
29
+ @out_of_order.should equal(true)
30
30
  end
31
31
 
32
- specify "after transitions, substates respond to superstate transitions" do
32
+ it "after transitions, substates respond to superstate transitions" do
33
33
  @sm.coin
34
34
  @sm.maintain
35
- @sm.state.should_be :maintenance
36
- @locked.should_be false
37
- @out_of_order.should_be true
35
+ @sm.state.should equal(:maintenance)
36
+ @locked.should equal(false)
37
+ @out_of_order.should equal(true)
38
38
  end
39
39
 
40
40
  end
@@ -1,18 +1,18 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- context "Turn Stile" do
3
+ describe "Turn Stile" do
4
4
  include TurnstileStatemachine
5
5
 
6
- setup do
6
+ before(:each) do
7
7
  create_turnstile
8
8
  end
9
9
 
10
- specify "connections" do
10
+ it "connections" do
11
11
  locked_state = @sm.get_state(:locked)
12
12
  unlocked_state = @sm.get_state(:unlocked)
13
13
 
14
- locked_state.transitions.length.should_be 2
15
- unlocked_state.transitions.length.should_be 2
14
+ locked_state.transitions.length.should equal(2)
15
+ unlocked_state.transitions.length.should equal(2)
16
16
 
17
17
  check_transition(locked_state.transitions[:coin], :locked, :unlocked, :coin, @unlock)
18
18
  check_transition(locked_state.transitions[:pass], :locked, :locked, :pass, @alarm)
@@ -20,57 +20,57 @@ context "Turn Stile" do
20
20
  check_transition(unlocked_state.transitions[:coin], :unlocked, :locked, :coin, @thankyou)
21
21
  end
22
22
 
23
- specify "start state" do
23
+ it "start state" do
24
24
  @sm.reset
25
- @sm.startstate.should.be :locked
26
- @sm.state.should.be :locked
25
+ @sm.startstate.should equal(:locked)
26
+ @sm.state.should equal(:locked)
27
27
  end
28
28
 
29
- specify "bad event" do
29
+ it "bad event" do
30
30
  begin
31
31
  @sm.process_event(:blah)
32
32
  self.should.fail_with_message("Exception expected")
33
33
  rescue Exception => e
34
- e.class.should.be Statemachine::StatemachineException
35
- e.to_s.should_eql "'locked' state does not respond to the 'blah' event."
34
+ e.class.should equal(Statemachine::TransitionMissingException)
35
+ e.to_s.should eql("'locked' state does not respond to the 'blah' event.")
36
36
  end
37
37
  end
38
38
 
39
- specify "locked state with a coin" do
39
+ it "locked state with a coin" do
40
40
  @sm.process_event(:coin)
41
41
 
42
- @sm.state.should.be :unlocked
43
- @locked.should.be false
42
+ @sm.state.should equal(:unlocked)
43
+ @locked.should equal(false)
44
44
  end
45
45
 
46
- specify "locked state with pass event" do
46
+ it "locked state with pass event" do
47
47
  @sm.process_event(:pass)
48
48
 
49
- @sm.state.should.be :locked
50
- @locked.should.be true
51
- @alarm_status.should.be true
49
+ @sm.state.should equal(:locked)
50
+ @locked.should equal(true)
51
+ @alarm_status.should equal(true)
52
52
  end
53
53
 
54
- specify "unlocked state with coin" do
54
+ it "unlocked state with coin" do
55
55
  @sm.process_event(:coin)
56
56
  @sm.process_event(:coin)
57
57
 
58
- @sm.state.should.be :locked
59
- @thankyou_status.should.be true
58
+ @sm.state.should equal(:locked)
59
+ @thankyou_status.should equal(true)
60
60
  end
61
61
 
62
- specify "unlocked state with pass event" do
62
+ it "unlocked state with pass event" do
63
63
  @sm.process_event(:coin)
64
64
  @sm.process_event(:pass)
65
65
 
66
- @sm.state.should.be :locked
67
- @locked.should.be true
66
+ @sm.state.should equal(:locked)
67
+ @locked.should equal(true)
68
68
  end
69
69
 
70
- specify "events invoked via method_missing" do
70
+ it "events invoked via method_missing" do
71
71
  @sm.coin
72
- @sm.state.should.be :unlocked
72
+ @sm.state.should equal(:unlocked)
73
73
  @sm.pass
74
- @sm.state.should.be :locked
74
+ @sm.state.should equal(:locked)
75
75
  end
76
76
  end
data/spec/spec_helper.rb CHANGED
@@ -4,11 +4,11 @@ require 'spec'
4
4
  require 'statemachine'
5
5
 
6
6
  def check_transition(transition, origin_id, destination_id, event, action)
7
- transition.should_not_be nil
8
- transition.event.should_be event
9
- transition.origin_id.should_be origin_id
10
- transition.destination_id.should_be destination_id
11
- transition.action.should_eql action
7
+ transition.should_not equal(nil)
8
+ transition.event.should equal(event)
9
+ transition.origin_id.should equal(origin_id)
10
+ transition.destination_id.should equal(destination_id)
11
+ transition.action.should eql(action)
12
12
  end
13
13
 
14
14
  module SwitchStatemachine
@@ -1,107 +1,107 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- context "Transition Calculating Exits and Entries" do
3
+ describe "Transition Calculating Exits and Entries" do
4
4
 
5
- setup do
5
+ before(:each) do
6
6
  @transition = Statemachine::Transition.new(nil, nil, nil, nil)
7
7
  end
8
8
 
9
- specify "to nil" do
9
+ it "to nil" do
10
10
  @a = Statemachine::State.new("a", nil, nil)
11
11
  exits, entries = @transition.exits_and_entries(@a, nil)
12
- exits.to_s.should_eql [@a].to_s
13
- entries.to_s.should_eql [].to_s
14
- entries.length.should_be 0
12
+ exits.to_s.should eql([@a].to_s)
13
+ entries.to_s.should eql([].to_s)
14
+ entries.length.should equal(0)
15
15
  end
16
16
 
17
- specify "to itself" do
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.to_s.should eql([@a].to_s)
21
+ entries.to_s.should eql([@a].to_s)
22
22
  end
23
23
 
24
- specify "to friend" do
24
+ it "to friend" do
25
25
  @a = Statemachine::State.new("a", nil, nil)
26
26
  @b = Statemachine::State.new("b", nil, nil)
27
27
  exits, entries = @transition.exits_and_entries(@a, @b)
28
- exits.to_s.should_eql [@a].to_s
29
- entries.to_s.should_eql [@b].to_s
28
+ exits.to_s.should eql([@a].to_s)
29
+ entries.to_s.should eql([@b].to_s)
30
30
  end
31
31
 
32
- specify "to parent" do
32
+ it "to parent" do
33
33
  @b = Statemachine::State.new("b", nil, nil)
34
34
  @a = Statemachine::State.new("a", @b, nil)
35
35
  exits, entries = @transition.exits_and_entries(@a, @b)
36
- exits.to_s.should_eql [@a, @b].to_s
37
- entries.to_s.should_eql [@b].to_s
36
+ exits.to_s.should eql([@a, @b].to_s)
37
+ entries.to_s.should eql([@b].to_s)
38
38
  end
39
39
 
40
- specify "to uncle" do
40
+ it "to uncle" do
41
41
  @b = Statemachine::State.new("b", nil, nil)
42
42
  @a = Statemachine::State.new("a", @b, nil)
43
43
  @c = Statemachine::State.new("c", nil, nil)
44
44
  exits, entries = @transition.exits_and_entries(@a, @c)
45
- exits.to_s.should_eql [@a, @b].to_s
46
- entries.to_s.should_eql [@c].to_s
45
+ exits.to_s.should eql([@a, @b].to_s)
46
+ entries.to_s.should eql([@c].to_s)
47
47
  end
48
48
 
49
- specify "to cousin" do
49
+ it "to cousin" do
50
50
  @b = Statemachine::State.new("b", nil, nil)
51
51
  @d = Statemachine::State.new("d", nil, nil)
52
52
  @a = Statemachine::State.new("a", @b, nil)
53
53
  @c = Statemachine::State.new("c", @d, nil)
54
54
  exits, entries = @transition.exits_and_entries(@a, @c)
55
- exits.to_s.should_eql [@a, @b].to_s
56
- entries.to_s.should_eql [@d, @c].to_s
55
+ exits.to_s.should eql([@a, @b].to_s)
56
+ entries.to_s.should eql([@d, @c].to_s)
57
57
  end
58
58
 
59
- specify "to nephew" do
59
+ it "to nephew" do
60
60
  @b = Statemachine::State.new("b", nil, nil)
61
61
  @c = Statemachine::State.new("c", nil, nil)
62
62
  @a = Statemachine::State.new("a", @b, nil)
63
63
  exits, entries = @transition.exits_and_entries(@c, @a)
64
- exits.to_s.should_eql [@c].to_s
65
- entries.to_s.should_eql [@b,@a].to_s
64
+ exits.to_s.should eql([@c].to_s)
65
+ entries.to_s.should eql([@b,@a].to_s)
66
66
  end
67
67
 
68
- specify "to sister" do
68
+ it "to sister" do
69
69
  @c = Statemachine::State.new("c", nil, nil)
70
70
  @a = Statemachine::State.new("a", @c, nil)
71
71
  @b = Statemachine::State.new("b", @c, nil)
72
72
  exits, entries = @transition.exits_and_entries(@a, @b)
73
- exits.to_s.should_eql [@a].to_s
74
- entries.to_s.should_eql [@b].to_s
73
+ exits.to_s.should eql([@a].to_s)
74
+ entries.to_s.should eql([@b].to_s)
75
75
  end
76
76
 
77
- specify "to second cousin" do
77
+ it "to second cousin" do
78
78
  @c = Statemachine::State.new("c", nil, nil)
79
79
  @b = Statemachine::State.new("b", @c, nil)
80
80
  @a = Statemachine::State.new("a", @b, nil)
81
81
  @e = Statemachine::State.new("e", @c, nil)
82
82
  @d = Statemachine::State.new("d", @e, nil)
83
83
  exits, entries = @transition.exits_and_entries(@a, @d)
84
- exits.to_s.should_eql [@a, @b].to_s
85
- entries.to_s.should_eql [@e, @d].to_s
84
+ exits.to_s.should eql([@a, @b].to_s)
85
+ entries.to_s.should eql([@e, @d].to_s)
86
86
  end
87
87
 
88
- specify "to grandparent" do
88
+ it "to grandparent" do
89
89
  @c = Statemachine::State.new("c", nil, nil)
90
90
  @b = Statemachine::State.new("b", @c, nil)
91
91
  @a = Statemachine::State.new("a", @b, nil)
92
92
  exits, entries = @transition.exits_and_entries(@a, @c)
93
- exits.to_s.should_eql [@a, @b, @c].to_s
94
- entries.to_s.should_eql [@c].to_s
93
+ exits.to_s.should eql([@a, @b, @c].to_s)
94
+ entries.to_s.should eql([@c].to_s)
95
95
  end
96
96
 
97
- specify "to parent's grandchild" do
97
+ it "to parent's grandchild" do
98
98
  @c = Statemachine::State.new("c", nil, nil)
99
99
  @b = Statemachine::State.new("b", @c, nil)
100
100
  @a = Statemachine::State.new("a", @b, nil)
101
101
  @d = Statemachine::State.new("d", @c, nil)
102
102
  exits, entries = @transition.exits_and_entries(@d, @a)
103
- exits.to_s.should_eql [@d].to_s
104
- entries.to_s.should_eql [@b, @a].to_s
103
+ exits.to_s.should eql([@d].to_s)
104
+ entries.to_s.should eql([@b, @a].to_s)
105
105
  end
106
106
 
107
107
  end
metadata CHANGED
@@ -3,9 +3,9 @@ rubygems_version: 0.9.1
3
3
  specification_version: 1
4
4
  name: statemachine
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.3.0
7
- date: 2007-04-18 00:00:00 -05:00
8
- summary: Statemachine-0.3.0 - Statemachine Library for Ruby http://statemachine.rubyforge.org/
6
+ version: 0.4.0
7
+ date: 2007-05-17 00:00:00 -05:00
8
+ summary: Statemachine-0.4.0 - Statemachine Library for Ruby http://statemachine.rubyforge.org/
9
9
  require_paths:
10
10
  - lib
11
11
  email: statemachine-devel@rubyforge.org