statemachine 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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