edge-state-machine 0.0.1 → 0.0.2
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/lib/edge-state-machine.rb +4 -2
- data/lib/edge-state-machine/event.rb +1 -1
- data/lib/edge-state-machine/{state_transition.rb → transition.rb} +1 -1
- data/lib/edge-state-machine/version.rb +1 -1
- data/spec/{active_record_helper.rb → active_record/active_record_helper.rb} +2 -2
- data/spec/{active_record_spec.rb → active_record/active_record_spec.rb} +1 -1
- data/spec/{migrations → active_record/migrations}/create_orders.rb +0 -0
- data/spec/{migrations → active_record/migrations}/create_traffic_lights.rb +0 -0
- data/spec/event_spec.rb +3 -3
- data/spec/{mongoid_helper.rb → mongoid/mongoid_helper.rb} +0 -0
- data/spec/{mongoid_spec.rb → mongoid/mongoid_spec.rb} +1 -1
- data/spec/state_spec.rb +38 -133
- data/spec/transition_spec.rb +71 -0
- metadata +76 -106
data/lib/edge-state-machine.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "edge-state-machine/event"
|
2
2
|
require "edge-state-machine/machine"
|
3
3
|
require "edge-state-machine/state"
|
4
|
-
require "edge-state-machine/
|
4
|
+
require "edge-state-machine/transition"
|
5
5
|
require "edge-state-machine/version"
|
6
6
|
|
7
7
|
module EdgeStateMachine
|
@@ -35,7 +35,9 @@ module EdgeStateMachine
|
|
35
35
|
def define_state_query_method(state_name)
|
36
36
|
name = "#{state_name}?"
|
37
37
|
undef_method(name) if method_defined?(name)
|
38
|
-
|
38
|
+
define_method(name) do
|
39
|
+
current_state.to_s == state_name.to_s
|
40
|
+
end
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
@@ -100,7 +100,7 @@ module EdgeStateMachine
|
|
100
100
|
|
101
101
|
def transitions(trans_opts)
|
102
102
|
Array(trans_opts[:from]).each do |s|
|
103
|
-
@transitions <<
|
103
|
+
@transitions << Transition.new(trans_opts.merge({:from => s.to_sym}))
|
104
104
|
end
|
105
105
|
end
|
106
106
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'active_record'
|
3
3
|
require 'active_support/core_ext/module/aliasing'
|
4
|
-
require 'migrations/create_orders'
|
5
|
-
require 'migrations/create_traffic_lights'
|
4
|
+
require 'active_record/migrations/create_orders'
|
5
|
+
require 'active_record/migrations/create_traffic_lights'
|
6
6
|
|
7
7
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", 'lib'))
|
8
8
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
File without changes
|
File without changes
|
data/spec/event_spec.rb
CHANGED
@@ -42,9 +42,9 @@ describe EdgeStateMachine::Event do
|
|
42
42
|
@success.should == @event.success
|
43
43
|
end
|
44
44
|
|
45
|
-
it "should create
|
46
|
-
EdgeStateMachine::
|
47
|
-
EdgeStateMachine::
|
45
|
+
it "should create Transitions" do
|
46
|
+
EdgeStateMachine::Transition.should_receive(:new).with(:to => :closed, :from => :open)
|
47
|
+
EdgeStateMachine::Transition.should_receive(:new).with(:to => :closed, :from => :received)
|
48
48
|
new_event
|
49
49
|
end
|
50
50
|
|
File without changes
|
data/spec/state_spec.rb
CHANGED
@@ -38,154 +38,59 @@ end
|
|
38
38
|
|
39
39
|
describe EdgeStateMachine::State do
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
41
|
+
before do
|
42
|
+
@state_name = :astate
|
43
|
+
@machine = StateTestSubject.state_machine
|
44
|
+
@options = { :crazy_custom_key => "key", :machine => @machine }
|
97
45
|
end
|
98
46
|
|
99
|
-
|
100
|
-
|
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
|
47
|
+
it "should set the name" do
|
48
|
+
new_state.name.should == :astate
|
129
49
|
end
|
130
50
|
|
131
|
-
|
132
|
-
|
133
|
-
|
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
|
51
|
+
it "should set the display_name from name" do
|
52
|
+
new_state.display_name.should == "Astate"
|
53
|
+
end
|
147
54
|
|
148
|
-
|
149
|
-
|
150
|
-
@car.start_driving!
|
151
|
-
end
|
55
|
+
it "should set the display_name from options" do
|
56
|
+
new_state(:display => "A State").display_name.should == "A State"
|
152
57
|
end
|
153
58
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
st.perform(nil).should == true
|
159
|
-
end
|
59
|
+
it "should set the options and expose them as options" do
|
60
|
+
@options.delete(:machine)
|
61
|
+
new_state.options.should == @options
|
62
|
+
end
|
160
63
|
|
161
|
-
|
162
|
-
|
163
|
-
|
64
|
+
it "should be equal to a symbol of the same name" do
|
65
|
+
new_state.should == :astate
|
66
|
+
end
|
164
67
|
|
165
|
-
|
166
|
-
|
68
|
+
it "should be equal with a State with the same name" do
|
69
|
+
new_state.should == new_state
|
70
|
+
end
|
167
71
|
|
168
|
-
|
169
|
-
|
72
|
+
it "should send a message to the record for an action if the action is present as a symbol" do
|
73
|
+
state = new_state(:entering => :foo)
|
74
|
+
record = mock
|
75
|
+
record.should_receive(:foo)
|
76
|
+
state.call_action(:entering, record)
|
77
|
+
end
|
170
78
|
|
171
|
-
|
172
|
-
|
173
|
-
st = EdgeStateMachine::StateTransition.new(opts)
|
79
|
+
it "should send a message to the record for an action if the action is present as a string" do
|
80
|
+
state = new_state(:entering => "foo")
|
174
81
|
|
175
|
-
|
176
|
-
|
82
|
+
record = mock
|
83
|
+
record.should_receive(:foo)
|
177
84
|
|
178
|
-
|
179
|
-
|
85
|
+
state.call_action(:entering, record)
|
86
|
+
end
|
180
87
|
|
181
|
-
|
182
|
-
|
183
|
-
st = EdgeStateMachine::StateTransition.new(opts)
|
88
|
+
it "should call a proc, passing in the record for an action if the action is present" do
|
89
|
+
state = new_state(:entering => Proc.new {|r| r.foobar})
|
184
90
|
|
185
|
-
|
186
|
-
|
91
|
+
record = mock
|
92
|
+
record.should_receive(:foobar)
|
187
93
|
|
188
|
-
|
189
|
-
end
|
94
|
+
state.call_action(:entering, record)
|
190
95
|
end
|
191
96
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EdgeStateMachine::State do
|
4
|
+
it "should set from, to, and opts attr readers" do
|
5
|
+
opts = {:from => "foo", :to => "bar", :guard => "g"}
|
6
|
+
st = EdgeStateMachine::Transition.new(opts)
|
7
|
+
|
8
|
+
st.from.should == opts[:from]
|
9
|
+
st.to.should == opts[:to]
|
10
|
+
st.options.should == opts
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should pass equality check if from and to are the same" do
|
14
|
+
opts = {:from => "foo", :to => "bar", :guard => "g"}
|
15
|
+
st = EdgeStateMachine::Transition.new(opts)
|
16
|
+
obj = EdgeStateMachine::Transition.new(opts)
|
17
|
+
obj.should == st
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should fail equality check if from are not the same" do
|
21
|
+
opts = {:from => "foo", :to => "bar", :guard => "g"}
|
22
|
+
st = EdgeStateMachine::Transition.new(opts)
|
23
|
+
obj = EdgeStateMachine::Transition.new(opts.merge({:from => "blah"}))
|
24
|
+
obj.should_not == st
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should fail equality check if to are not the same" do
|
28
|
+
opts = {:from => "foo", :to => "bar", :guard => "g"}
|
29
|
+
st = EdgeStateMachine::Transition.new(opts)
|
30
|
+
obj = EdgeStateMachine::Transition.new(opts.merge({:to => "blah"}))
|
31
|
+
obj.should_not == st
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "state transition guard check" do
|
36
|
+
it "should return true of there is no guard" do
|
37
|
+
opts = {:from => "foo", :to => "bar"}
|
38
|
+
st = EdgeStateMachine::Transition.new(opts)
|
39
|
+
st.perform(nil).should == true
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should call the method on the object if guard is a symbol" do
|
43
|
+
opts = {:from => "foo", :to => "bar", :guard => :test_guard}
|
44
|
+
st = EdgeStateMachine::Transition.new(opts)
|
45
|
+
|
46
|
+
obj = mock
|
47
|
+
obj.should_receive(:test_guard)
|
48
|
+
|
49
|
+
st.perform(obj)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should call the method on the object if guard is a string" do
|
53
|
+
opts = {:from => "foo", :to => "bar", :guard => "test_guard"}
|
54
|
+
st = EdgeStateMachine::Transition.new(opts)
|
55
|
+
|
56
|
+
obj = mock
|
57
|
+
obj.should_receive(:test_guard)
|
58
|
+
|
59
|
+
st.perform(obj)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should call the proc passing the object if the guard is a proc" do
|
63
|
+
opts = {:from => "foo", :to => "bar", :guard => Proc.new {|o| o.test_guard}}
|
64
|
+
st = EdgeStateMachine::Transition.new(opts)
|
65
|
+
|
66
|
+
obj = mock
|
67
|
+
obj.should_receive(:test_guard)
|
68
|
+
|
69
|
+
st.perform(obj)
|
70
|
+
end
|
71
|
+
end
|
metadata
CHANGED
@@ -1,111 +1,89 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: edge-state-machine
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
version: 0.0.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Dan Persa
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-11-24 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: rspec
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &20230980 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
18
|
+
requirements:
|
26
19
|
- - ~>
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
- 2
|
30
|
-
- 6
|
31
|
-
version: "2.6"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.6'
|
32
22
|
type: :development
|
33
|
-
version_requirements: *id001
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
name: rake
|
36
23
|
prerelease: false
|
37
|
-
|
24
|
+
version_requirements: *20230980
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &20230400 !ruby/object:Gem::Requirement
|
38
28
|
none: false
|
39
|
-
requirements:
|
40
|
-
- -
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
|
43
|
-
- 0
|
44
|
-
version: "0"
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
45
33
|
type: :development
|
46
|
-
version_requirements: *id002
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: mongoid
|
49
34
|
prerelease: false
|
50
|
-
|
35
|
+
version_requirements: *20230400
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: mongoid
|
38
|
+
requirement: &20229600 !ruby/object:Gem::Requirement
|
51
39
|
none: false
|
52
|
-
requirements:
|
53
|
-
- -
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
|
56
|
-
- 0
|
57
|
-
version: "0"
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
58
44
|
type: :development
|
59
|
-
version_requirements: *id003
|
60
|
-
- !ruby/object:Gem::Dependency
|
61
|
-
name: bson_ext
|
62
45
|
prerelease: false
|
63
|
-
|
46
|
+
version_requirements: *20229600
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: bson_ext
|
49
|
+
requirement: &20228540 !ruby/object:Gem::Requirement
|
64
50
|
none: false
|
65
|
-
requirements:
|
66
|
-
- -
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
|
69
|
-
- 0
|
70
|
-
version: "0"
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
71
55
|
type: :development
|
72
|
-
version_requirements: *id004
|
73
|
-
- !ruby/object:Gem::Dependency
|
74
|
-
name: sqlite3-ruby
|
75
56
|
prerelease: false
|
76
|
-
|
57
|
+
version_requirements: *20228540
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: sqlite3-ruby
|
60
|
+
requirement: &20227760 !ruby/object:Gem::Requirement
|
77
61
|
none: false
|
78
|
-
requirements:
|
79
|
-
- -
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
|
82
|
-
- 0
|
83
|
-
version: "0"
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
84
66
|
type: :development
|
85
|
-
version_requirements: *id005
|
86
|
-
- !ruby/object:Gem::Dependency
|
87
|
-
name: activerecord
|
88
67
|
prerelease: false
|
89
|
-
|
68
|
+
version_requirements: *20227760
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activerecord
|
71
|
+
requirement: &20226340 !ruby/object:Gem::Requirement
|
90
72
|
none: false
|
91
|
-
requirements:
|
92
|
-
- -
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
|
95
|
-
- 0
|
96
|
-
version: "0"
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
97
77
|
type: :development
|
98
|
-
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *20226340
|
99
80
|
description: Lightweight state machine extracted from ActiveModel
|
100
|
-
email:
|
81
|
+
email:
|
101
82
|
- dan.persa@gmail.com
|
102
83
|
executables: []
|
103
|
-
|
104
84
|
extensions: []
|
105
|
-
|
106
85
|
extra_rdoc_files: []
|
107
|
-
|
108
|
-
files:
|
86
|
+
files:
|
109
87
|
- .gitignore
|
110
88
|
- .rspec
|
111
89
|
- .travis.yml
|
@@ -118,50 +96,42 @@ files:
|
|
118
96
|
- lib/edge-state-machine/event.rb
|
119
97
|
- lib/edge-state-machine/machine.rb
|
120
98
|
- lib/edge-state-machine/state.rb
|
121
|
-
- lib/edge-state-machine/
|
99
|
+
- lib/edge-state-machine/transition.rb
|
122
100
|
- lib/edge-state-machine/version.rb
|
123
101
|
- lib/mongoid/edge-state-machine.rb
|
124
|
-
- spec/active_record_helper.rb
|
125
|
-
- spec/active_record_spec.rb
|
102
|
+
- spec/active_record/active_record_helper.rb
|
103
|
+
- spec/active_record/active_record_spec.rb
|
104
|
+
- spec/active_record/migrations/create_orders.rb
|
105
|
+
- spec/active_record/migrations/create_traffic_lights.rb
|
126
106
|
- spec/event_spec.rb
|
127
107
|
- spec/machine_spec.rb
|
128
|
-
- spec/
|
129
|
-
- spec/
|
130
|
-
- spec/mongoid_helper.rb
|
131
|
-
- spec/mongoid_spec.rb
|
108
|
+
- spec/mongoid/mongoid_helper.rb
|
109
|
+
- spec/mongoid/mongoid_spec.rb
|
132
110
|
- spec/spec_helper.rb
|
133
111
|
- spec/state_spec.rb
|
134
|
-
|
112
|
+
- spec/transition_spec.rb
|
135
113
|
homepage: http://github.com/danpersa/edge-state-machine
|
136
114
|
licenses: []
|
137
|
-
|
138
115
|
post_install_message:
|
139
116
|
rdoc_options: []
|
140
|
-
|
141
|
-
require_paths:
|
117
|
+
require_paths:
|
142
118
|
- lib
|
143
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
120
|
none: false
|
145
|
-
requirements:
|
146
|
-
- -
|
147
|
-
- !ruby/object:Gem::Version
|
148
|
-
|
149
|
-
|
150
|
-
version: "0"
|
151
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
126
|
none: false
|
153
|
-
requirements:
|
154
|
-
- -
|
155
|
-
- !ruby/object:Gem::Version
|
156
|
-
|
157
|
-
- 0
|
158
|
-
version: "0"
|
127
|
+
requirements:
|
128
|
+
- - ! '>='
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
159
131
|
requirements: []
|
160
|
-
|
161
132
|
rubyforge_project: edge-state-machine
|
162
|
-
rubygems_version: 1.
|
133
|
+
rubygems_version: 1.8.10
|
163
134
|
signing_key:
|
164
135
|
specification_version: 3
|
165
136
|
summary: State machine extracted from ActiveModel
|
166
137
|
test_files: []
|
167
|
-
|