edge-state-machine 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/.rspec +4 -0
- data/.travis.yml +1 -0
- data/Gemfile +4 -0
- data/README.rdoc +63 -0
- data/Rakefile +20 -0
- data/edge-state-machine.gemspec +31 -0
- data/lib/active_record/edge-state-machine.rb +34 -0
- data/lib/edge-state-machine/event.rb +107 -0
- data/lib/edge-state-machine/machine.rb +85 -0
- data/lib/edge-state-machine/state.rb +45 -0
- data/lib/edge-state-machine/state_transition.rb +47 -0
- data/lib/edge-state-machine/version.rb +3 -0
- data/lib/edge-state-machine.rb +71 -0
- data/lib/mongoid/edge-state-machine.rb +34 -0
- data/spec/active_record_helper.rb +10 -0
- data/spec/active_record_spec.rb +248 -0
- data/spec/event_spec.rb +76 -0
- data/spec/machine_spec.rb +44 -0
- data/spec/migrations/create_orders.rb +12 -0
- data/spec/migrations/create_traffic_lights.rb +8 -0
- data/spec/mongoid_helper.rb +12 -0
- data/spec/mongoid_spec.rb +251 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/state_spec.rb +191 -0
- metadata +167 -0
data/spec/state_spec.rb
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class StateTestSubject
|
4
|
+
include EdgeStateMachine
|
5
|
+
|
6
|
+
state_machine do
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Car
|
11
|
+
include EdgeStateMachine
|
12
|
+
|
13
|
+
state_machine do
|
14
|
+
state :parked
|
15
|
+
state :running
|
16
|
+
state :driving
|
17
|
+
|
18
|
+
event :turn_key do
|
19
|
+
transitions :from => :parked, :to => :running, :on_transition => :start_engine
|
20
|
+
end
|
21
|
+
|
22
|
+
event :start_driving do
|
23
|
+
transitions :from => :parked, :to => :driving, :on_transition => [:start_engine, :loosen_handbrake, :push_gas_pedal]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def event_fired(current_state, new_state, event)
|
28
|
+
end
|
29
|
+
|
30
|
+
%w!start_engine loosen_handbrake push_gas_pedal!.each do |m|
|
31
|
+
define_method(m){}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def new_state(options={})
|
36
|
+
EdgeStateMachine::State.new(@state_name, @options.merge(options))
|
37
|
+
end
|
38
|
+
|
39
|
+
describe EdgeStateMachine::State do
|
40
|
+
|
41
|
+
describe "general methods" do
|
42
|
+
before do
|
43
|
+
@state_name = :astate
|
44
|
+
@machine = StateTestSubject.state_machine
|
45
|
+
@options = { :crazy_custom_key => "key", :machine => @machine }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should set the name" do
|
49
|
+
new_state.name.should == :astate
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should set the display_name from name" do
|
53
|
+
new_state.display_name.should == "Astate"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should set the display_name from options" do
|
57
|
+
new_state(:display => "A State").display_name.should == "A State"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should set the options and expose them as options" do
|
61
|
+
@options.delete(:machine)
|
62
|
+
new_state.options.should == @options
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should be equal to a symbol of the same name" do
|
66
|
+
new_state.should == :astate
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should be equal with a State with the same name" do
|
70
|
+
new_state.should == new_state
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should send a message to the record for an action if the action is present as a symbol" do
|
74
|
+
state = new_state(:entering => :foo)
|
75
|
+
record = mock
|
76
|
+
record.should_receive(:foo)
|
77
|
+
state.call_action(:entering, record)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should send a message to the record for an action if the action is present as a string" do
|
81
|
+
state = new_state(:entering => "foo")
|
82
|
+
|
83
|
+
record = mock
|
84
|
+
record.should_receive(:foo)
|
85
|
+
|
86
|
+
state.call_action(:entering, record)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should call a proc, passing in the record for an action if the action is present" do
|
90
|
+
state = new_state(:entering => Proc.new {|r| r.foobar})
|
91
|
+
|
92
|
+
record = mock
|
93
|
+
record.should_receive(:foobar)
|
94
|
+
|
95
|
+
state.call_action(:entering, record)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "state transitions" do
|
100
|
+
it "should set from, to, and opts attr readers" do
|
101
|
+
opts = {:from => "foo", :to => "bar", :guard => "g"}
|
102
|
+
st = EdgeStateMachine::StateTransition.new(opts)
|
103
|
+
|
104
|
+
st.from.should == opts[:from]
|
105
|
+
st.to.should == opts[:to]
|
106
|
+
st.options.should == opts
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should pass equality check if from and to are the same" do
|
110
|
+
opts = {:from => "foo", :to => "bar", :guard => "g"}
|
111
|
+
st = EdgeStateMachine::StateTransition.new(opts)
|
112
|
+
obj = EdgeStateMachine::StateTransition.new(opts)
|
113
|
+
obj.should == st
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should fail equality check if from are not the same" do
|
117
|
+
opts = {:from => "foo", :to => "bar", :guard => "g"}
|
118
|
+
st = EdgeStateMachine::StateTransition.new(opts)
|
119
|
+
obj = EdgeStateMachine::StateTransition.new(opts.merge({:from => "blah"}))
|
120
|
+
obj.should_not == st
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should fail equality check if to are not the same" do
|
124
|
+
opts = {:from => "foo", :to => "bar", :guard => "g"}
|
125
|
+
st = EdgeStateMachine::StateTransition.new(opts)
|
126
|
+
obj = EdgeStateMachine::StateTransition.new(opts.merge({:to => "blah"}))
|
127
|
+
obj.should_not == st
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "state transition callbacks" do
|
132
|
+
before do
|
133
|
+
@car = Car.new
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should execute callback defined via 'on_transition'" do
|
137
|
+
@car.should_receive(:start_engine)
|
138
|
+
@car.turn_key!
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should execute multiple callbacks defined via 'on_transition' in the same order they were defined" do
|
142
|
+
@car.should_receive(:start_engine).ordered
|
143
|
+
@car.should_receive(:loosen_handbrake).ordered
|
144
|
+
@car.should_receive(:push_gas_pedal).ordered
|
145
|
+
@car.start_driving!
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should pass event when calling event_fired_callback" do
|
149
|
+
@car.should_receive(:event_fired).with(:parked, :driving, :start_driving)
|
150
|
+
@car.start_driving!
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "state transition guard check" do
|
155
|
+
it "should return true of there is no guard" do
|
156
|
+
opts = {:from => "foo", :to => "bar"}
|
157
|
+
st = EdgeStateMachine::StateTransition.new(opts)
|
158
|
+
st.perform(nil).should == true
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should call the method on the object if guard is a symbol" do
|
162
|
+
opts = {:from => "foo", :to => "bar", :guard => :test_guard}
|
163
|
+
st = EdgeStateMachine::StateTransition.new(opts)
|
164
|
+
|
165
|
+
obj = mock
|
166
|
+
obj.should_receive(:test_guard)
|
167
|
+
|
168
|
+
st.perform(obj)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should call the method on the object if guard is a string" do
|
172
|
+
opts = {:from => "foo", :to => "bar", :guard => "test_guard"}
|
173
|
+
st = EdgeStateMachine::StateTransition.new(opts)
|
174
|
+
|
175
|
+
obj = mock
|
176
|
+
obj.should_receive(:test_guard)
|
177
|
+
|
178
|
+
st.perform(obj)
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should call the proc passing the object if the guard is a proc" do
|
182
|
+
opts = {:from => "foo", :to => "bar", :guard => Proc.new {|o| o.test_guard}}
|
183
|
+
st = EdgeStateMachine::StateTransition.new(opts)
|
184
|
+
|
185
|
+
obj = mock
|
186
|
+
obj.should_receive(:test_guard)
|
187
|
+
|
188
|
+
st.perform(obj)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
metadata
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: edge-state-machine
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Dan Persa
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-11-23 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 6
|
31
|
+
version: "2.6"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rake
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
segments:
|
43
|
+
- 0
|
44
|
+
version: "0"
|
45
|
+
type: :development
|
46
|
+
version_requirements: *id002
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: mongoid
|
49
|
+
prerelease: false
|
50
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id003
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: bson_ext
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
version: "0"
|
71
|
+
type: :development
|
72
|
+
version_requirements: *id004
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: sqlite3-ruby
|
75
|
+
prerelease: false
|
76
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
84
|
+
type: :development
|
85
|
+
version_requirements: *id005
|
86
|
+
- !ruby/object:Gem::Dependency
|
87
|
+
name: activerecord
|
88
|
+
prerelease: false
|
89
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
version: "0"
|
97
|
+
type: :development
|
98
|
+
version_requirements: *id006
|
99
|
+
description: Lightweight state machine extracted from ActiveModel
|
100
|
+
email:
|
101
|
+
- dan.persa@gmail.com
|
102
|
+
executables: []
|
103
|
+
|
104
|
+
extensions: []
|
105
|
+
|
106
|
+
extra_rdoc_files: []
|
107
|
+
|
108
|
+
files:
|
109
|
+
- .gitignore
|
110
|
+
- .rspec
|
111
|
+
- .travis.yml
|
112
|
+
- Gemfile
|
113
|
+
- README.rdoc
|
114
|
+
- Rakefile
|
115
|
+
- edge-state-machine.gemspec
|
116
|
+
- lib/active_record/edge-state-machine.rb
|
117
|
+
- lib/edge-state-machine.rb
|
118
|
+
- lib/edge-state-machine/event.rb
|
119
|
+
- lib/edge-state-machine/machine.rb
|
120
|
+
- lib/edge-state-machine/state.rb
|
121
|
+
- lib/edge-state-machine/state_transition.rb
|
122
|
+
- lib/edge-state-machine/version.rb
|
123
|
+
- lib/mongoid/edge-state-machine.rb
|
124
|
+
- spec/active_record_helper.rb
|
125
|
+
- spec/active_record_spec.rb
|
126
|
+
- spec/event_spec.rb
|
127
|
+
- spec/machine_spec.rb
|
128
|
+
- spec/migrations/create_orders.rb
|
129
|
+
- spec/migrations/create_traffic_lights.rb
|
130
|
+
- spec/mongoid_helper.rb
|
131
|
+
- spec/mongoid_spec.rb
|
132
|
+
- spec/spec_helper.rb
|
133
|
+
- spec/state_spec.rb
|
134
|
+
has_rdoc: true
|
135
|
+
homepage: http://github.com/danpersa/edge-state-machine
|
136
|
+
licenses: []
|
137
|
+
|
138
|
+
post_install_message:
|
139
|
+
rdoc_options: []
|
140
|
+
|
141
|
+
require_paths:
|
142
|
+
- lib
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
none: false
|
145
|
+
requirements:
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
segments:
|
149
|
+
- 0
|
150
|
+
version: "0"
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
none: false
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
segments:
|
157
|
+
- 0
|
158
|
+
version: "0"
|
159
|
+
requirements: []
|
160
|
+
|
161
|
+
rubyforge_project: edge-state-machine
|
162
|
+
rubygems_version: 1.3.7
|
163
|
+
signing_key:
|
164
|
+
specification_version: 3
|
165
|
+
summary: State machine extracted from ActiveModel
|
166
|
+
test_files: []
|
167
|
+
|