aasm 3.0.24 → 3.0.25
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.
- checksums.yaml +4 -4
- data/.travis.yml +21 -3
- data/CHANGELOG.md +8 -0
- data/Gemfile +9 -1
- data/LICENSE +1 -1
- data/README.md +9 -8
- data/aasm.gemspec +4 -5
- data/gemfiles/rails_3.2.gemfile +11 -0
- data/gemfiles/rails_4.0.gemfile +10 -0
- data/lib/aasm.rb +0 -3
- data/lib/aasm/aasm.rb +31 -27
- data/lib/aasm/base.rb +14 -5
- data/lib/aasm/event.rb +16 -16
- data/lib/aasm/instance_base.rb +1 -1
- data/lib/aasm/persistence/active_record_persistence.rb +10 -8
- data/lib/aasm/persistence/base.rb +1 -1
- data/lib/aasm/persistence/mongoid_persistence.rb +10 -8
- data/lib/aasm/version.rb +1 -1
- data/spec/models/mongoid/no_scope_mongoid.rb +1 -1
- data/spec/models/mongoid/simple_mongoid.rb +5 -4
- data/spec/models/mongoid/simple_new_dsl_mongoid.rb +1 -1
- data/spec/models/not_auto_loaded/process.rb +10 -8
- data/spec/models/persistence.rb +5 -13
- data/spec/unit/callbacks_spec.rb +4 -20
- data/spec/unit/complex_example_spec.rb +4 -4
- data/spec/unit/event_spec.rb +49 -36
- data/spec/unit/initial_state_spec.rb +4 -5
- data/spec/unit/inspection_spec.rb +11 -24
- data/spec/unit/localizer_spec.rb +12 -12
- data/spec/unit/persistence/active_record_persistence_spec.rb +13 -31
- data/spec/unit/persistence/mongoid_persistance_spec.rb +102 -81
- data/spec/unit/simple_example_spec.rb +1 -2
- data/spec/unit/subclassing_spec.rb +7 -7
- data/spec/unit/transition_spec.rb +5 -5
- metadata +4 -75
- data/lib/aasm/deprecated/aasm.rb +0 -15
- data/spec/models/callback_old_dsl.rb +0 -41
@@ -35,7 +35,7 @@ module AASM
|
|
35
35
|
def aasm_read_state
|
36
36
|
state = send(self.class.aasm_column)
|
37
37
|
if new_record?
|
38
|
-
state.blank? ? aasm.determine_state_name(self.class.
|
38
|
+
state.blank? ? aasm.determine_state_name(self.class.aasm.initial_state) : state.to_sym
|
39
39
|
else
|
40
40
|
state.nil? ? nil : state.to_sym
|
41
41
|
end
|
@@ -36,6 +36,8 @@ module AASM
|
|
36
36
|
# Mongoid's Validatable gem dependency goes not have a before_validation_on_xxx hook yet.
|
37
37
|
# base.before_validation_on_create :aasm_ensure_initial_state
|
38
38
|
base.before_validation :aasm_ensure_initial_state
|
39
|
+
# ensure initial aasm state even when validations are skipped
|
40
|
+
base.before_create :aasm_ensure_initial_state
|
39
41
|
end
|
40
42
|
|
41
43
|
module ClassMethods
|
@@ -66,10 +68,10 @@ module AASM
|
|
66
68
|
# using update_attribute (which bypasses validation)
|
67
69
|
#
|
68
70
|
# foo = Foo.find(1)
|
69
|
-
# foo.
|
71
|
+
# foo.aasm.current_state # => :opened
|
70
72
|
# foo.close!
|
71
|
-
# foo.
|
72
|
-
# Foo.find(1).
|
73
|
+
# foo.aasm.current_state # => :closed
|
74
|
+
# Foo.find(1).aasm.current_state # => :closed
|
73
75
|
#
|
74
76
|
# NOTE: intended to be called from an event
|
75
77
|
def aasm_write_state(state)
|
@@ -87,13 +89,13 @@ module AASM
|
|
87
89
|
# Writes <tt>state</tt> to the state column, but does not persist it to the database
|
88
90
|
#
|
89
91
|
# foo = Foo.find(1)
|
90
|
-
# foo.
|
92
|
+
# foo.aasm.current_state # => :opened
|
91
93
|
# foo.close
|
92
|
-
# foo.
|
93
|
-
# Foo.find(1).
|
94
|
+
# foo.aasm.current_state # => :closed
|
95
|
+
# Foo.find(1).aasm.current_state # => :opened
|
94
96
|
# foo.save
|
95
|
-
# foo.
|
96
|
-
# Foo.find(1).
|
97
|
+
# foo.aasm.current_state # => :closed
|
98
|
+
# Foo.find(1).aasm.current_state # => :closed
|
97
99
|
#
|
98
100
|
# NOTE: intended to be called from an event
|
99
101
|
def aasm_write_state_without_persistence(state)
|
data/lib/aasm/version.rb
CHANGED
@@ -2,9 +2,10 @@ class SimpleMongoid
|
|
2
2
|
include Mongoid::Document
|
3
3
|
include AASM
|
4
4
|
|
5
|
-
field :status, type
|
5
|
+
field :status, :type => String
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
aasm column: :status do
|
8
|
+
state :unknown_scope
|
9
|
+
state :new
|
10
|
+
end
|
10
11
|
end
|
@@ -2,16 +2,18 @@ module Models
|
|
2
2
|
class Process
|
3
3
|
include AASM
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
aasm do
|
6
|
+
state :sleeping
|
7
|
+
state :running
|
8
|
+
state :suspended
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
event :start do
|
11
|
+
transitions :from => :sleeping, :to => :running
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
event :stop do
|
15
|
+
transitions :from => :running, :to => :suspended
|
16
|
+
end
|
15
17
|
end
|
16
18
|
|
17
19
|
end
|
data/spec/models/persistence.rb
CHANGED
@@ -36,13 +36,6 @@ class Transient < ActiveRecord::Base
|
|
36
36
|
include AASM
|
37
37
|
end
|
38
38
|
|
39
|
-
class Simple < ActiveRecord::Base
|
40
|
-
include AASM
|
41
|
-
aasm_column :status
|
42
|
-
aasm_state :unknown_scope
|
43
|
-
aasm_state :new
|
44
|
-
end
|
45
|
-
|
46
39
|
class SimpleNewDsl < ActiveRecord::Base
|
47
40
|
include AASM
|
48
41
|
aasm :column => :status
|
@@ -59,9 +52,6 @@ class NoScope < ActiveRecord::Base
|
|
59
52
|
end
|
60
53
|
end
|
61
54
|
|
62
|
-
class Derivate < Simple
|
63
|
-
end
|
64
|
-
|
65
55
|
class DerivateNewDsl < SimpleNewDsl
|
66
56
|
end
|
67
57
|
|
@@ -72,8 +62,10 @@ class Thief < ActiveRecord::Base
|
|
72
62
|
set_table_name "thieves"
|
73
63
|
end
|
74
64
|
include AASM
|
75
|
-
|
76
|
-
|
77
|
-
|
65
|
+
aasm do
|
66
|
+
state :rich
|
67
|
+
state :jailed
|
68
|
+
initial_state Proc.new {|thief| thief.skilled ? :rich : :jailed }
|
69
|
+
end
|
78
70
|
attr_accessor :skilled, :aasm_state
|
79
71
|
end
|
data/spec/unit/callbacks_spec.rb
CHANGED
@@ -1,23 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe 'callbacks for the old DSL' do
|
4
|
-
let(:callback) {CallbackOldDsl.new}
|
5
|
-
|
6
|
-
it "should get close callbacks" do
|
7
|
-
callback.should_receive(:exit_open).once.ordered
|
8
|
-
callback.should_receive(:before).once.ordered
|
9
|
-
callback.should_receive(:before_exit_open).once.ordered # these should be before the state changes
|
10
|
-
callback.should_receive(:before_enter_closed).once.ordered
|
11
|
-
callback.should_receive(:enter_closed).once.ordered
|
12
|
-
callback.should_receive(:aasm_write_state).once.ordered.and_return(true) # this is when the state changes
|
13
|
-
callback.should_receive(:after_exit_open).once.ordered # these should be after the state changes
|
14
|
-
callback.should_receive(:after_enter_closed).once.ordered
|
15
|
-
callback.should_receive(:after).once.ordered
|
16
|
-
|
17
|
-
callback.close!
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
3
|
describe 'callbacks for the new DSL' do
|
22
4
|
let(:callback) {CallbackNewDsl.new}
|
23
5
|
|
@@ -40,8 +22,10 @@ describe 'event callbacks' do
|
|
40
22
|
describe "with an error callback defined" do
|
41
23
|
before do
|
42
24
|
class Foo
|
43
|
-
|
44
|
-
|
25
|
+
aasm do
|
26
|
+
event :safe_close, :success => :success_callback, :error => :error_callback do
|
27
|
+
transitions :to => :closed, :from => [:open]
|
28
|
+
end
|
45
29
|
end
|
46
30
|
end
|
47
31
|
|
@@ -4,7 +4,7 @@ describe 'on initialization' do
|
|
4
4
|
let(:auth) {AuthMachine.new}
|
5
5
|
|
6
6
|
it 'should be in the pending state' do
|
7
|
-
auth.
|
7
|
+
auth.aasm.current_state.should == :pending
|
8
8
|
end
|
9
9
|
|
10
10
|
it 'should have an activation code' do
|
@@ -55,14 +55,14 @@ describe 'when being unsuspended' do
|
|
55
55
|
auth.suspend!
|
56
56
|
auth.unsuspend!
|
57
57
|
|
58
|
-
auth.
|
58
|
+
auth.aasm.current_state.should == :active
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'should be pending if not previously activated, but an activation code is present' do
|
62
62
|
auth.suspend!
|
63
63
|
auth.unsuspend!
|
64
64
|
|
65
|
-
auth.
|
65
|
+
auth.aasm.current_state.should == :pending
|
66
66
|
end
|
67
67
|
|
68
68
|
it 'should be passive if not previously activated and there is no activation code' do
|
@@ -70,6 +70,6 @@ describe 'when being unsuspended' do
|
|
70
70
|
auth.suspend!
|
71
71
|
auth.unsuspend!
|
72
72
|
|
73
|
-
auth.
|
73
|
+
auth.aasm.current_state.should == :passive
|
74
74
|
end
|
75
75
|
end
|
data/spec/unit/event_spec.rb
CHANGED
@@ -26,7 +26,7 @@ describe 'adding an event' do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'should create transitions' do
|
29
|
-
transitions = event.
|
29
|
+
transitions = event.transitions
|
30
30
|
transitions[0].from.should == :open
|
31
31
|
transitions[0].to.should == :closed
|
32
32
|
transitions[1].from.should == :received
|
@@ -60,8 +60,7 @@ end
|
|
60
60
|
|
61
61
|
describe 'firing an event' do
|
62
62
|
it 'should return nil if the transitions are empty' do
|
63
|
-
obj = double('object')
|
64
|
-
obj.stub(:aasm_current_state)
|
63
|
+
obj = double('object', :aasm => double('aasm', :current_state => 'open'))
|
65
64
|
|
66
65
|
event = AASM::Event.new(:event)
|
67
66
|
event.fire(obj).should be_nil
|
@@ -72,8 +71,7 @@ describe 'firing an event' do
|
|
72
71
|
transitions :to => :closed, :from => [:open, :received]
|
73
72
|
end
|
74
73
|
|
75
|
-
obj = double('object')
|
76
|
-
obj.stub(:aasm_current_state).and_return(:open)
|
74
|
+
obj = double('object', :aasm => double('aasm', :current_state => :open))
|
77
75
|
|
78
76
|
event.fire(obj).should == :closed
|
79
77
|
end
|
@@ -83,8 +81,7 @@ describe 'firing an event' do
|
|
83
81
|
transitions :to => :closed, :from => [:open, :received], :guard => :guard_fn
|
84
82
|
end
|
85
83
|
|
86
|
-
obj = double('object')
|
87
|
-
obj.stub(:aasm_current_state).and_return(:open)
|
84
|
+
obj = double('object', :aasm => double('aasm', :current_state => :open))
|
88
85
|
obj.should_receive(:guard_fn).with('arg1', 'arg2').and_return(true)
|
89
86
|
|
90
87
|
event.fire(obj, nil, 'arg1', 'arg2').should == :closed
|
@@ -96,8 +93,10 @@ describe 'should fire callbacks' do
|
|
96
93
|
describe 'success' do
|
97
94
|
it "if it's a symbol" do
|
98
95
|
ThisNameBetterNotBeInUse.instance_eval {
|
99
|
-
|
100
|
-
|
96
|
+
aasm do
|
97
|
+
event :with_symbol, :success => :symbol_success_callback do
|
98
|
+
transitions :to => :symbol, :from => [:initial]
|
99
|
+
end
|
101
100
|
end
|
102
101
|
}
|
103
102
|
|
@@ -108,8 +107,10 @@ describe 'should fire callbacks' do
|
|
108
107
|
|
109
108
|
it "if it's a string" do
|
110
109
|
ThisNameBetterNotBeInUse.instance_eval {
|
111
|
-
|
112
|
-
|
110
|
+
aasm do
|
111
|
+
event :with_string, :success => 'string_success_callback' do
|
112
|
+
transitions :to => :string, :from => [:initial]
|
113
|
+
end
|
113
114
|
end
|
114
115
|
}
|
115
116
|
|
@@ -120,8 +121,10 @@ describe 'should fire callbacks' do
|
|
120
121
|
|
121
122
|
it "if passed an array of strings and/or symbols" do
|
122
123
|
ThisNameBetterNotBeInUse.instance_eval {
|
123
|
-
|
124
|
-
|
124
|
+
aasm do
|
125
|
+
event :with_array, :success => [:success_callback1, 'success_callback2'] do
|
126
|
+
transitions :to => :array, :from => [:initial]
|
127
|
+
end
|
125
128
|
end
|
126
129
|
}
|
127
130
|
|
@@ -133,8 +136,10 @@ describe 'should fire callbacks' do
|
|
133
136
|
|
134
137
|
it "if passed an array of strings and/or symbols and/or procs" do
|
135
138
|
ThisNameBetterNotBeInUse.instance_eval {
|
136
|
-
|
137
|
-
|
139
|
+
aasm do
|
140
|
+
event :with_array_including_procs, :success => [:success_callback1, 'success_callback2', lambda { proc_success_callback }] do
|
141
|
+
transitions :to => :array, :from => [:initial]
|
142
|
+
end
|
138
143
|
end
|
139
144
|
}
|
140
145
|
|
@@ -147,8 +152,10 @@ describe 'should fire callbacks' do
|
|
147
152
|
|
148
153
|
it "if it's a proc" do
|
149
154
|
ThisNameBetterNotBeInUse.instance_eval {
|
150
|
-
|
151
|
-
|
155
|
+
aasm do
|
156
|
+
event :with_proc, :success => lambda { proc_success_callback } do
|
157
|
+
transitions :to => :proc, :from => [:initial]
|
158
|
+
end
|
152
159
|
end
|
153
160
|
}
|
154
161
|
|
@@ -161,14 +168,16 @@ describe 'should fire callbacks' do
|
|
161
168
|
describe 'after' do
|
162
169
|
it "if they set different ways" do
|
163
170
|
ThisNameBetterNotBeInUse.instance_eval do
|
164
|
-
|
165
|
-
after do
|
166
|
-
|
171
|
+
aasm do
|
172
|
+
event :with_afters, :after => :do_one_thing_after do
|
173
|
+
after do
|
174
|
+
do_another_thing_after_too
|
175
|
+
end
|
176
|
+
after do
|
177
|
+
do_third_thing_at_last
|
178
|
+
end
|
179
|
+
transitions :to => :proc, :from => [:initial]
|
167
180
|
end
|
168
|
-
after do
|
169
|
-
do_third_thing_at_last
|
170
|
-
end
|
171
|
-
transitions :to => :proc, :from => [:initial]
|
172
181
|
end
|
173
182
|
end
|
174
183
|
|
@@ -183,11 +192,13 @@ describe 'should fire callbacks' do
|
|
183
192
|
describe 'before' do
|
184
193
|
it "if it's a proc" do
|
185
194
|
ThisNameBetterNotBeInUse.instance_eval do
|
186
|
-
|
187
|
-
|
188
|
-
|
195
|
+
aasm do
|
196
|
+
event :before_as_proc do
|
197
|
+
before do
|
198
|
+
do_something_before
|
199
|
+
end
|
200
|
+
transitions :to => :proc, :from => [:initial]
|
189
201
|
end
|
190
|
-
transitions :to => :proc, :from => [:initial]
|
191
202
|
end
|
192
203
|
end
|
193
204
|
|
@@ -199,11 +210,13 @@ describe 'should fire callbacks' do
|
|
199
210
|
|
200
211
|
it 'in right order' do
|
201
212
|
ThisNameBetterNotBeInUse.instance_eval do
|
202
|
-
|
203
|
-
|
204
|
-
|
213
|
+
aasm do
|
214
|
+
event :in_right_order, :after => :do_something_after do
|
215
|
+
before do
|
216
|
+
do_something_before
|
217
|
+
end
|
218
|
+
transitions :to => :proc, :from => [:initial]
|
205
219
|
end
|
206
|
-
transitions :to => :proc, :from => [:initial]
|
207
220
|
end
|
208
221
|
end
|
209
222
|
|
@@ -219,22 +232,22 @@ describe 'parametrised events' do
|
|
219
232
|
|
220
233
|
it 'should transition to specified next state (sleeping to showering)' do
|
221
234
|
pe.wakeup!(:showering)
|
222
|
-
pe.
|
235
|
+
pe.aasm.current_state.should == :showering
|
223
236
|
end
|
224
237
|
|
225
238
|
it 'should transition to specified next state (sleeping to working)' do
|
226
239
|
pe.wakeup!(:working)
|
227
|
-
pe.
|
240
|
+
pe.aasm.current_state.should == :working
|
228
241
|
end
|
229
242
|
|
230
243
|
it 'should transition to default (first or showering) state' do
|
231
244
|
pe.wakeup!
|
232
|
-
pe.
|
245
|
+
pe.aasm.current_state.should == :showering
|
233
246
|
end
|
234
247
|
|
235
248
|
it 'should transition to default state when on_transition invoked' do
|
236
249
|
pe.dress!(nil, 'purple', 'dressy')
|
237
|
-
pe.
|
250
|
+
pe.aasm.current_state.should == :working
|
238
251
|
end
|
239
252
|
|
240
253
|
it 'should call on_transition method with args' do
|
@@ -5,8 +5,8 @@ class Banker
|
|
5
5
|
aasm do
|
6
6
|
state :retired
|
7
7
|
state :selling_bad_mortgages
|
8
|
+
initial_state Proc.new { |banker| banker.rich? ? :retired : :selling_bad_mortgages }
|
8
9
|
end
|
9
|
-
aasm_initial_state Proc.new { |banker| banker.rich? ? :retired : :selling_bad_mortgages }
|
10
10
|
RICH = 1_000_000
|
11
11
|
attr_accessor :balance
|
12
12
|
def initialize(balance = 0); self.balance = balance; end
|
@@ -17,12 +17,11 @@ describe 'initial states' do
|
|
17
17
|
let(:bar) {Bar.new}
|
18
18
|
|
19
19
|
it 'should use the first state defined if no initial state is given' do
|
20
|
-
bar.
|
21
|
-
# bar.aasm.current_state.should == :read # not yet supported
|
20
|
+
bar.aasm.current_state.should == :read
|
22
21
|
end
|
23
22
|
|
24
23
|
it 'should determine initial state from the Proc results' do
|
25
|
-
Banker.new(Banker::RICH - 1).
|
26
|
-
Banker.new(Banker::RICH + 1).
|
24
|
+
Banker.new(Banker::RICH - 1).aasm.current_state.should == :selling_bad_mortgages
|
25
|
+
Banker.new(Banker::RICH + 1).aasm.current_state.should == :retired
|
27
26
|
end
|
28
27
|
end
|
@@ -1,19 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'inspection for common cases' do
|
4
|
-
it 'should support the old DSL' do
|
5
|
-
Foo.should respond_to(:aasm_states)
|
6
|
-
Foo.aasm_states.should include(:open)
|
7
|
-
Foo.aasm_states.should include(:closed)
|
8
|
-
|
9
|
-
Foo.should respond_to(:aasm_initial_state)
|
10
|
-
Foo.aasm_initial_state.should == :open
|
11
|
-
|
12
|
-
Foo.should respond_to(:aasm_events)
|
13
|
-
Foo.aasm_events.should include(:close)
|
14
|
-
Foo.aasm_events.should include(:null)
|
15
|
-
end
|
16
|
-
|
17
4
|
it 'should support the new DSL' do
|
18
5
|
Foo.aasm.should respond_to(:states)
|
19
6
|
Foo.aasm.states.should include(:open)
|
@@ -74,35 +61,35 @@ end
|
|
74
61
|
|
75
62
|
describe "special cases" do
|
76
63
|
it "should support valid a state name" do
|
77
|
-
Argument.
|
78
|
-
Argument.
|
64
|
+
Argument.aasm.states.should include(:invalid)
|
65
|
+
Argument.aasm.states.should include(:valid)
|
79
66
|
|
80
67
|
argument = Argument.new
|
81
68
|
argument.invalid?.should be_true
|
82
|
-
argument.
|
69
|
+
argument.aasm.current_state.should == :invalid
|
83
70
|
|
84
71
|
argument.valid!
|
85
72
|
argument.valid?.should be_true
|
86
|
-
argument.
|
73
|
+
argument.aasm.current_state.should == :valid
|
87
74
|
end
|
88
75
|
end
|
89
76
|
|
90
|
-
describe
|
77
|
+
describe 'aasm.states_for_select' do
|
91
78
|
it "should return a select friendly array of states" do
|
92
|
-
Foo.should respond_to(:
|
93
|
-
Foo.
|
79
|
+
Foo.aasm.should respond_to(:states_for_select)
|
80
|
+
Foo.aasm.states_for_select.should == [['Open', 'open'], ['Closed', 'closed']]
|
94
81
|
end
|
95
82
|
end
|
96
83
|
|
97
|
-
describe
|
84
|
+
describe 'aasm.from_states_for_state' do
|
98
85
|
it "should return all from states for a state" do
|
99
|
-
AuthMachine.should respond_to(:
|
100
|
-
froms = AuthMachine.
|
86
|
+
AuthMachine.aasm.should respond_to(:from_states_for_state)
|
87
|
+
froms = AuthMachine.aasm.from_states_for_state(:active)
|
101
88
|
[:pending, :passive, :suspended].each {|from| froms.should include(from)}
|
102
89
|
end
|
103
90
|
|
104
91
|
it "should return from states for a state for a particular transition only" do
|
105
|
-
froms = AuthMachine.
|
92
|
+
froms = AuthMachine.aasm.from_states_for_state(:active, :transition => :unsuspend)
|
106
93
|
[:suspended].each {|from| froms.should include(from)}
|
107
94
|
end
|
108
95
|
end
|