simple_state_machine 0.4.3 → 0.5.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +3 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +34 -0
- data/Rakefile +17 -34
- data/autotest/discover.rb +1 -0
- data/lib/simple_state_machine/active_record.rb +11 -6
- data/lib/simple_state_machine/simple_state_machine.rb +77 -27
- data/lib/simple_state_machine/version.rb +3 -0
- data/lib/simple_state_machine.rb +1 -1
- data/simple_state_machine.gemspec +13 -54
- data/spec/active_record_spec.rb +53 -24
- data/spec/decorator_spec.rb +179 -28
- data/spec/examples_spec.rb +1 -0
- data/spec/mountable_spec.rb +24 -0
- data/spec/simple_state_machine_spec.rb +73 -93
- data/spec/spec_helper.rb +0 -6
- data/spec/state_machine_definition_spec.rb +89 -0
- data/spec/state_machine_spec.rb +26 -0
- metadata +87 -24
- data/VERSION +0 -1
- data/spec/spec.opts +0 -3
data/spec/decorator_spec.rb
CHANGED
@@ -1,44 +1,195 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
|
4
|
-
extend SimpleStateMachine
|
3
|
+
describe SimpleStateMachine::Decorator do
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
context "given a class" do
|
6
|
+
before do
|
7
|
+
klass = Class.new do
|
8
|
+
# TODO remove the need for defining this method
|
9
|
+
def self.state_machine_definition
|
10
|
+
@state_machine_definition ||= SimpleStateMachine::StateMachineDefinition.new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
decorator = SimpleStateMachine::Decorator.new klass
|
14
|
+
decorator.decorate SimpleStateMachine::Transition.new(:event, :state1, :state2)
|
15
|
+
@instance = klass.new
|
16
|
+
@instance.state = 'state1'
|
17
|
+
end
|
12
18
|
|
13
|
-
|
14
|
-
|
19
|
+
describe "#initialize" do
|
20
|
+
it "defines a state_machine method" do
|
21
|
+
@instance.state_machine.should be_an(SimpleStateMachine::StateMachine)
|
22
|
+
end
|
15
23
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
24
|
+
it "defines a state getter method" do
|
25
|
+
@instance.should respond_to(:state)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "defines a state setter method" do
|
29
|
+
@instance.should respond_to(:state=)
|
30
|
+
end
|
31
|
+
end
|
20
32
|
|
21
|
-
|
22
|
-
|
33
|
+
describe "#decorate" do
|
34
|
+
it "defines state_helper_methods for both states" do
|
35
|
+
@instance.state1?.should == true
|
36
|
+
@instance.state2?.should == false
|
37
|
+
end
|
38
|
+
|
39
|
+
it "defines an event method" do
|
40
|
+
@instance.should respond_to(:event)
|
41
|
+
end
|
42
|
+
end
|
23
43
|
end
|
24
|
-
end
|
25
44
|
|
45
|
+
context "given a class with predefined public methods" do
|
46
|
+
before do
|
47
|
+
klass = Class.new do
|
48
|
+
# TODO remove the need for defining this method
|
49
|
+
def self.state_machine_definition
|
50
|
+
@state_machine_definition ||= SimpleStateMachine::StateMachineDefinition.new
|
51
|
+
end
|
52
|
+
# predefined methods
|
53
|
+
def state1?() "state1" end
|
54
|
+
def state2?() "state2" end
|
55
|
+
def event() "predefined method" end
|
56
|
+
end
|
57
|
+
transition = SimpleStateMachine::Transition.new(:event, :state1, :state2)
|
58
|
+
decorator = SimpleStateMachine::Decorator.new klass
|
59
|
+
decorator.decorate transition
|
60
|
+
klass.state_machine_definition.transitions << transition
|
61
|
+
@instance = klass.new
|
62
|
+
@instance.state = 'state1'
|
63
|
+
end
|
26
64
|
|
27
|
-
describe
|
65
|
+
describe "#initialize" do
|
66
|
+
it "defines a state_machine method" do
|
67
|
+
@instance.state_machine.should be_an(SimpleStateMachine::StateMachine)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "defines a state getter method" do
|
71
|
+
@instance.should respond_to(:state)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "defines a state setter method" do
|
75
|
+
@instance.should respond_to(:state=)
|
76
|
+
end
|
77
|
+
end
|
28
78
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
79
|
+
describe "#decorate" do
|
80
|
+
it "does not overwrite predefined state_helper_methods" do
|
81
|
+
@instance.state1?.should == "state1"
|
82
|
+
@instance.state2?.should == "state2"
|
83
|
+
end
|
84
|
+
|
85
|
+
it "does not overwrite predefined event method" do
|
86
|
+
@instance.event.should == "predefined method"
|
87
|
+
end
|
88
|
+
end
|
33
89
|
end
|
34
90
|
|
35
|
-
|
36
|
-
|
37
|
-
|
91
|
+
context "given a class with predefined protected methods" do
|
92
|
+
before do
|
93
|
+
klass = Class.new do
|
94
|
+
# TODO remove the need for defining this method
|
95
|
+
def self.state_machine_definition
|
96
|
+
@state_machine_definition ||= SimpleStateMachine::StateMachineDefinition.new
|
97
|
+
end
|
98
|
+
# predefined methods
|
99
|
+
protected
|
100
|
+
def state1?() "state1" end
|
101
|
+
def state2?() "state2" end
|
102
|
+
def event() "predefined method" end
|
103
|
+
end
|
104
|
+
transition = SimpleStateMachine::Transition.new(:event, :state1, :state2)
|
105
|
+
decorator = SimpleStateMachine::Decorator.new klass
|
106
|
+
decorator.decorate transition
|
107
|
+
klass.state_machine_definition.transitions << transition
|
108
|
+
@instance = klass.new
|
109
|
+
@instance.state = 'state1'
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#initialize" do
|
113
|
+
it "defines a state_machine method" do
|
114
|
+
@instance.state_machine.should be_an(SimpleStateMachine::StateMachine)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "defines a state getter method" do
|
118
|
+
@instance.should respond_to(:state)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "defines a state setter method" do
|
122
|
+
@instance.should respond_to(:state=)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "#decorate" do
|
127
|
+
it "does not overwrite predefined protected state_helper_methods" do
|
128
|
+
@instance.send(:state1?).should == "state1"
|
129
|
+
@instance.send(:state2?).should == "state2"
|
130
|
+
end
|
131
|
+
|
132
|
+
it "keeps predefined protected state_helper_methods protected" do
|
133
|
+
expect { @instance.state1? }.to raise_error(NoMethodError)
|
134
|
+
expect { @instance.state2? }.to raise_error(NoMethodError)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "does not overwrite predefined protected event method" do
|
138
|
+
@instance.event.should == "predefined method"
|
139
|
+
end
|
140
|
+
end
|
38
141
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
142
|
+
|
143
|
+
context "given a class with predefined private methods" do
|
144
|
+
before do
|
145
|
+
klass = Class.new do
|
146
|
+
# TODO the need for defining this method
|
147
|
+
def self.state_machine_definition
|
148
|
+
@state_machine_definition ||= SimpleStateMachine::StateMachineDefinition.new
|
149
|
+
end
|
150
|
+
# predefined methods
|
151
|
+
private
|
152
|
+
def state1?() "state1" end
|
153
|
+
def state2?() "state2" end
|
154
|
+
def event() "predefined method" end
|
155
|
+
end
|
156
|
+
transition = SimpleStateMachine::Transition.new(:event, :state1, :state2)
|
157
|
+
decorator = SimpleStateMachine::Decorator.new klass
|
158
|
+
decorator.decorate transition
|
159
|
+
klass.state_machine_definition.transitions << transition
|
160
|
+
@instance = klass.new
|
161
|
+
@instance.state = 'state1'
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "#initialize" do
|
165
|
+
it "defines a state_machine method" do
|
166
|
+
@instance.state_machine.should be_an(SimpleStateMachine::StateMachine)
|
167
|
+
end
|
168
|
+
|
169
|
+
it "defines a state getter method" do
|
170
|
+
@instance.should respond_to(:state)
|
171
|
+
end
|
172
|
+
|
173
|
+
it "defines a state setter method" do
|
174
|
+
@instance.should respond_to(:state=)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "#decorate" do
|
179
|
+
it "does not overwrite predefined private state_helper_methods" do
|
180
|
+
@instance.send(:state1?).should == "state1"
|
181
|
+
@instance.send(:state2?).should == "state2"
|
182
|
+
end
|
183
|
+
|
184
|
+
it "keeps predefined private state_helper_methods private" do
|
185
|
+
expect { @instance.state1? }.to raise_error(NoMethodError)
|
186
|
+
expect { @instance.state2? }.to raise_error(NoMethodError)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "does not overwrite predefined protected event method" do
|
190
|
+
@instance.event.should == "predefined method"
|
191
|
+
end
|
192
|
+
end
|
42
193
|
end
|
43
194
|
|
44
195
|
end
|
data/spec/examples_spec.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Mountable" do
|
4
|
+
before do
|
5
|
+
mountable_class = Class.new(SimpleStateMachine::StateMachineDefinition) do
|
6
|
+
def initialize(subject)
|
7
|
+
self.lazy_decorator = lambda { SimpleStateMachine::Decorator.new(subject) }
|
8
|
+
add_transition(:event, :state1, :state2)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
klass = Class.new do
|
12
|
+
extend SimpleStateMachine::Mountable
|
13
|
+
self.state_machine_definition = mountable_class.new self
|
14
|
+
end
|
15
|
+
@instance = klass.new
|
16
|
+
@instance.state = 'state1'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has state_helper methods" do
|
20
|
+
@instance.should be_state1
|
21
|
+
@instance.should_not be_state2
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -1,85 +1,81 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
class SimpleExample
|
4
|
-
extend SimpleStateMachine
|
5
|
-
attr_reader :event2_called
|
6
|
-
def initialize(state = 'state1')
|
7
|
-
@state = state
|
8
|
-
end
|
9
|
-
event :event1, :state1 => :state2, :state2 => :state3
|
10
|
-
def event2
|
11
|
-
@event2_called = true
|
12
|
-
'event2'
|
13
|
-
end
|
14
|
-
event :event2, :state2 => :state3
|
15
|
-
event :event_with_multiple_from, [:state1, :state2] => :state3
|
16
|
-
event :event_from_all, :all => :state3
|
17
|
-
end
|
18
|
-
|
19
|
-
class SimpleExampleWithCustomStateMethod
|
20
|
-
extend SimpleStateMachine
|
21
|
-
state_machine_definition.state_method = :ssm_state
|
22
|
-
|
23
|
-
def initialize(state = 'state1')
|
24
|
-
@ssm_state = state
|
25
|
-
end
|
26
|
-
event :event1, :state1 => :state2
|
27
|
-
event :event2, :state2 => :state3
|
28
|
-
end
|
2
|
+
require 'cgi'
|
29
3
|
|
30
4
|
describe SimpleStateMachine do
|
31
5
|
|
32
6
|
it "has an error that extends RuntimeError" do
|
33
|
-
SimpleStateMachine::
|
7
|
+
SimpleStateMachine::IllegalStateTransitionError.superclass.should == RuntimeError
|
34
8
|
end
|
35
9
|
|
36
|
-
|
37
|
-
SimpleExample.new.state.should == 'state1'
|
38
|
-
end
|
10
|
+
describe ".event" do
|
39
11
|
|
40
|
-
|
12
|
+
before do
|
13
|
+
@klass = Class.new do
|
14
|
+
extend SimpleStateMachine
|
15
|
+
def initialize(state = 'state1')
|
16
|
+
@state = state
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
41
20
|
|
42
21
|
it "changes state if event has multiple transitions" do
|
43
|
-
|
22
|
+
klass = Class.new(@klass)
|
23
|
+
klass.instance_eval do
|
24
|
+
event :event, :state1 => :state2, :state2 => :state3
|
25
|
+
end
|
26
|
+
example = klass.new
|
44
27
|
example.should be_state1
|
45
|
-
example.
|
28
|
+
example.event
|
46
29
|
example.should be_state2
|
47
|
-
example.
|
30
|
+
example.event
|
48
31
|
example.should be_state3
|
49
32
|
end
|
50
33
|
|
51
34
|
it "changes state if event has multiple froms" do
|
52
|
-
|
53
|
-
|
35
|
+
klass = Class.new(@klass)
|
36
|
+
klass.instance_eval do
|
37
|
+
event :event, [:state1, :state2] => :state3
|
38
|
+
end
|
39
|
+
example = klass.new
|
40
|
+
example.event
|
54
41
|
example.should be_state3
|
55
|
-
example =
|
42
|
+
example = klass.new 'state2'
|
56
43
|
example.should be_state2
|
57
|
-
example.
|
44
|
+
example.event
|
58
45
|
example.should be_state3
|
59
46
|
end
|
60
47
|
|
61
48
|
it "changes state if event has all as from" do
|
62
|
-
|
63
|
-
|
49
|
+
klass = Class.new(@klass)
|
50
|
+
klass.instance_eval do
|
51
|
+
event :other_event, :state1 => :state2
|
52
|
+
event :event, :all => :state3
|
53
|
+
end
|
54
|
+
example = klass.new
|
55
|
+
example.event
|
64
56
|
example.should be_state3
|
65
|
-
example =
|
57
|
+
example = klass.new 'state2'
|
66
58
|
example.should be_state2
|
67
|
-
example.
|
59
|
+
example.event
|
68
60
|
example.should be_state3
|
69
61
|
end
|
70
62
|
|
71
63
|
it "changes state when state is a symbol instead of a string" do
|
72
|
-
|
64
|
+
klass = Class.new(@klass)
|
65
|
+
klass.instance_eval do
|
66
|
+
event :event, :state1 => :state2
|
67
|
+
end
|
68
|
+
example = klass.new :state1
|
73
69
|
example.state.should == :state1
|
74
|
-
example.send(:
|
70
|
+
example.send(:event)
|
75
71
|
example.should be_state2
|
76
72
|
end
|
77
73
|
|
78
|
-
it "changes state to error_state when error
|
79
|
-
class_with_error = Class.new(
|
74
|
+
it "changes state to error_state when error can be caught" do
|
75
|
+
class_with_error = Class.new(@klass)
|
80
76
|
class_with_error.instance_eval do
|
81
77
|
define_method :raise_error do
|
82
|
-
raise
|
78
|
+
raise RuntimeError.new
|
83
79
|
end
|
84
80
|
event :raise_error, :state1 => :state2, RuntimeError => :failed
|
85
81
|
end
|
@@ -89,61 +85,45 @@ describe SimpleStateMachine do
|
|
89
85
|
example.should be_failed
|
90
86
|
end
|
91
87
|
|
92
|
-
it "
|
93
|
-
|
94
|
-
|
88
|
+
it "raises an error if an invalid state_transition is called" do
|
89
|
+
klass = Class.new(@klass)
|
90
|
+
klass.instance_eval do
|
91
|
+
event :event, :state1 => :state2
|
92
|
+
event :event2, :state2 => :state3
|
93
|
+
end
|
94
|
+
example = klass.new
|
95
|
+
lambda { example.event2 }.should raise_error(SimpleStateMachine::IllegalStateTransitionError, "You cannot 'event2' when state is 'state1'")
|
95
96
|
end
|
96
97
|
|
97
98
|
it "returns what the decorated method returns" do
|
98
|
-
|
99
|
+
klass = Class.new(@klass)
|
100
|
+
klass.instance_eval do
|
101
|
+
event :event1, :state1 => :state2
|
102
|
+
define_method :event2 do
|
103
|
+
'event2'
|
104
|
+
end
|
105
|
+
event :event2, :state2 => :state3
|
106
|
+
end
|
107
|
+
example = klass.new
|
99
108
|
example.event1.should == nil
|
100
109
|
example.event2.should == 'event2'
|
101
110
|
end
|
102
111
|
|
103
112
|
it "calls existing methods" do
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
example = SimpleExampleWithCustomStateMethod.new
|
116
|
-
example.should be_state1
|
117
|
-
example.event1
|
118
|
-
example.should be_state2
|
119
|
-
example.event2
|
120
|
-
example.should be_state3
|
121
|
-
end
|
122
|
-
|
123
|
-
it "raise an error if an invalid state_transition is called" do
|
124
|
-
example = SimpleExampleWithCustomStateMethod.new
|
125
|
-
lambda { example.event2 }.should raise_error(SimpleStateMachine::Error, "You cannot 'event2' when state is 'state1'")
|
126
|
-
end
|
127
|
-
|
128
|
-
end
|
129
|
-
|
130
|
-
describe "state_machine_definition" do
|
131
|
-
it "is inherited by subclasses" do
|
132
|
-
example = Class.new(SimpleExample).new
|
133
|
-
example.should be_state1
|
134
|
-
example.event1
|
135
|
-
example.should be_state2
|
136
|
-
example.event1
|
137
|
-
example.should be_state3
|
113
|
+
klass = Class.new(@klass)
|
114
|
+
klass.instance_eval do
|
115
|
+
attr_accessor :event_called
|
116
|
+
define_method :event do
|
117
|
+
@event_called = true
|
118
|
+
end
|
119
|
+
event :event, :state1 => :state2
|
120
|
+
end
|
121
|
+
example = klass.new
|
122
|
+
example.event
|
123
|
+
example.event_called.should == true
|
138
124
|
end
|
139
|
-
end
|
140
125
|
|
141
|
-
describe "state_machine" do
|
142
|
-
it "has a next_state method" do
|
143
|
-
example = SimpleExample.new
|
144
|
-
example.state_machine.next_state('event1').should == 'state2'
|
145
|
-
example.state_machine.next_state('event2').should be_nil
|
146
|
-
end
|
147
126
|
end
|
148
127
|
|
149
128
|
end
|
129
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,7 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
3
|
require 'simple_state_machine'
|
4
|
-
require 'spec'
|
5
|
-
require 'spec/autorun'
|
6
|
-
|
7
4
|
require 'examples/conversation'
|
8
5
|
require 'examples/lamp'
|
9
6
|
require 'examples/traffic_light'
|
10
7
|
|
11
|
-
Spec::Runner.configure do |config|
|
12
|
-
|
13
|
-
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe SimpleStateMachine::StateMachineDefinition do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@klass = Class.new do
|
7
|
+
extend SimpleStateMachine
|
8
|
+
def initialize(state = 'state1')
|
9
|
+
@state = state
|
10
|
+
end
|
11
|
+
event :event1, :state1 => :state2, :state2 => :state3
|
12
|
+
end
|
13
|
+
@smd = @klass.state_machine_definition
|
14
|
+
end
|
15
|
+
|
16
|
+
it "is inherited by subclasses" do
|
17
|
+
example = Class.new(@klass).new
|
18
|
+
example.should be_state1
|
19
|
+
example.event1
|
20
|
+
example.should be_state2
|
21
|
+
example.event1
|
22
|
+
example.should be_state3
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#state_method' do
|
26
|
+
subject do
|
27
|
+
klass = Class.new do
|
28
|
+
attr_reader :ssm_state
|
29
|
+
extend SimpleStateMachine
|
30
|
+
state_machine_definition.state_method = :ssm_state
|
31
|
+
|
32
|
+
def initialize(state = 'state1')
|
33
|
+
@ssm_state = state
|
34
|
+
end
|
35
|
+
event :event1, :state1 => :state2
|
36
|
+
event :event2, :state2 => :state3
|
37
|
+
end
|
38
|
+
klass.new
|
39
|
+
end
|
40
|
+
|
41
|
+
it "is used when changing state" do
|
42
|
+
subject.ssm_state.should == 'state1'
|
43
|
+
subject.event1
|
44
|
+
subject.ssm_state.should == 'state2'
|
45
|
+
subject.event2
|
46
|
+
subject.ssm_state.should == 'state3'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "works with state helper methods" do
|
50
|
+
subject.should be_state1
|
51
|
+
subject.event1
|
52
|
+
subject.should be_state2
|
53
|
+
subject.event2
|
54
|
+
subject.should be_state3
|
55
|
+
end
|
56
|
+
|
57
|
+
it "raise an error if an invalid state_transition is called" do
|
58
|
+
lambda { subject.event2 }.should raise_error(SimpleStateMachine::IllegalStateTransitionError, "You cannot 'event2' when state is 'state1'")
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#transitions" do
|
64
|
+
it "has a list of transitions" do
|
65
|
+
@smd.transitions.should be_a(Array)
|
66
|
+
@smd.transitions.first.should be_a(SimpleStateMachine::Transition)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#to_s" do
|
71
|
+
it "converts to readable string format" do
|
72
|
+
@smd.to_s.should =~ Regexp.new("state1.event1! => state2")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#to_graphiz_dot" do
|
77
|
+
it "converts to graphiz dot format" do
|
78
|
+
@smd.to_graphiz_dot.should == %("state1"->"state2"[label=event1];"state2"->"state3"[label=event1])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#google_chart_url" do
|
83
|
+
it "shows the state and event dependencies as a Google chart" do
|
84
|
+
puts "http://chart.googleapis.com/chart?cht=gv&chl=digraph{#{::CGI.escape @smd.to_graphiz_dot}}"
|
85
|
+
@smd.google_chart_url.should == "http://chart.googleapis.com/chart?cht=gv&chl=digraph{#{::CGI.escape @smd.to_graphiz_dot}}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe SimpleStateMachine::StateMachine do
|
4
|
+
|
5
|
+
describe "#next_state" do
|
6
|
+
subject do
|
7
|
+
klass = Class.new do
|
8
|
+
extend SimpleStateMachine
|
9
|
+
def initialize() @state = 'state1' end
|
10
|
+
event :event1, :state1 => :state2
|
11
|
+
event :event2, :state2 => :state3
|
12
|
+
end
|
13
|
+
klass.new.state_machine
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns the next state for the event and current state" do
|
17
|
+
subject.next_state('event1').should == 'state2'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns nil if no next state for the event and current state exists" do
|
21
|
+
subject.next_state('event2').should be_nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|