aasm 3.0.24 → 3.1.0
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/.gitignore +3 -0
- data/.travis.yml +23 -4
- data/CHANGELOG.md +20 -0
- data/Gemfile +9 -1
- data/LICENSE +1 -1
- data/README.md +65 -12
- data/aasm.gemspec +5 -6
- data/gemfiles/rails_3.2.gemfile +12 -0
- data/gemfiles/rails_4.0.gemfile +11 -0
- data/gemfiles/rails_4.1.gemfile +11 -0
- data/lib/aasm/aasm.rb +31 -27
- data/lib/aasm/base.rb +35 -20
- data/lib/aasm/event.rb +27 -16
- data/lib/aasm/instance_base.rb +3 -1
- data/lib/aasm/persistence/active_record_persistence.rb +27 -9
- data/lib/aasm/persistence/base.rb +1 -1
- data/lib/aasm/persistence/mongoid_persistence.rb +10 -8
- data/lib/aasm/state.rb +1 -0
- data/lib/aasm/transition.rb +13 -6
- data/lib/aasm/version.rb +1 -1
- data/lib/aasm.rb +0 -3
- data/spec/database.rb +33 -0
- data/spec/models/guardian.rb +48 -0
- 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/spec_helper.rb +1 -1
- data/spec/unit/api_spec.rb +12 -12
- data/spec/unit/callbacks_spec.rb +29 -45
- data/spec/unit/complex_example_spec.rb +15 -15
- data/spec/unit/event_spec.rb +89 -76
- data/spec/unit/guard_spec.rb +60 -0
- data/spec/unit/initial_state_spec.rb +4 -5
- data/spec/unit/inspection_spec.rb +40 -53
- data/spec/unit/localizer_spec.rb +22 -18
- data/spec/unit/new_dsl_spec.rb +2 -2
- data/spec/unit/persistence/active_record_persistence_spec.rb +111 -89
- data/spec/unit/persistence/mongoid_persistance_spec.rb +102 -81
- data/spec/unit/simple_example_spec.rb +20 -21
- data/spec/unit/state_spec.rb +16 -16
- data/spec/unit/subclassing_spec.rb +8 -8
- data/spec/unit/transition_spec.rb +59 -44
- metadata +28 -94
- data/lib/aasm/deprecated/aasm.rb +0 -15
- data/spec/models/callback_old_dsl.rb +0 -41
- data/spec/schema.rb +0 -35
|
@@ -4,12 +4,12 @@ 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
|
+
expect(auth.aasm.current_state).to eq(:pending)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
it 'should have an activation code' do
|
|
11
|
-
auth.has_activation_code
|
|
12
|
-
auth.activation_code.
|
|
11
|
+
expect(auth.has_activation_code?).to be_true
|
|
12
|
+
expect(auth.activation_code).not_to be_nil
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -19,26 +19,26 @@ describe 'when being unsuspended' do
|
|
|
19
19
|
it 'should be able to be unsuspended' do
|
|
20
20
|
auth.activate!
|
|
21
21
|
auth.suspend!
|
|
22
|
-
auth.may_unsuspend
|
|
22
|
+
expect(auth.may_unsuspend?).to be_true
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
it 'should not be able to be unsuspended into active' do
|
|
26
26
|
auth.suspend!
|
|
27
|
-
auth.may_unsuspend?(:active).
|
|
27
|
+
expect(auth.may_unsuspend?(:active)).not_to be_true
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
it 'should be able to be unsuspended into active if polite' do
|
|
31
31
|
auth.suspend!
|
|
32
|
-
auth.may_wait?(:waiting, :please).
|
|
32
|
+
expect(auth.may_wait?(:waiting, :please)).to be_true
|
|
33
33
|
auth.wait!(nil, :please)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
it 'should not be able to be unsuspended into active if not polite' do
|
|
37
37
|
auth.suspend!
|
|
38
|
-
auth.may_wait?(:waiting).
|
|
39
|
-
auth.may_wait?(:waiting, :rude).
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
expect(auth.may_wait?(:waiting)).not_to be_true
|
|
39
|
+
expect(auth.may_wait?(:waiting, :rude)).not_to be_true
|
|
40
|
+
expect {auth.wait!(nil, :rude)}.to raise_error(AASM::InvalidTransition)
|
|
41
|
+
expect {auth.wait!}.to raise_error(AASM::InvalidTransition)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
it 'should not be able to be unpassified' do
|
|
@@ -46,8 +46,8 @@ describe 'when being unsuspended' do
|
|
|
46
46
|
auth.suspend!
|
|
47
47
|
auth.unsuspend!
|
|
48
48
|
|
|
49
|
-
auth.may_unpassify
|
|
50
|
-
|
|
49
|
+
expect(auth.may_unpassify?).not_to be_true
|
|
50
|
+
expect {auth.unpassify!}.to raise_error(AASM::InvalidTransition)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it 'should be active if previously activated' do
|
|
@@ -55,14 +55,14 @@ describe 'when being unsuspended' do
|
|
|
55
55
|
auth.suspend!
|
|
56
56
|
auth.unsuspend!
|
|
57
57
|
|
|
58
|
-
auth.
|
|
58
|
+
expect(auth.aasm.current_state).to eq(: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
|
+
expect(auth.aasm.current_state).to eq(: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
|
+
expect(auth.aasm.current_state).to eq(:passive)
|
|
74
74
|
end
|
|
75
75
|
end
|
data/spec/unit/event_spec.rb
CHANGED
|
@@ -10,27 +10,27 @@ describe 'adding an event' do
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
it 'should set the name' do
|
|
13
|
-
event.name.
|
|
13
|
+
expect(event.name).to eq(:close_order)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it 'should set the success callback' do
|
|
17
|
-
event.options[:success].
|
|
17
|
+
expect(event.options[:success]).to eq(:success_callback)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it 'should set the after callback' do
|
|
21
|
-
event.options[:after].
|
|
21
|
+
expect(event.options[:after]).to eq([:after_callback])
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it 'should set the before callback' do
|
|
25
|
-
event.options[:before].
|
|
25
|
+
expect(event.options[:before]).to eq([:before_callback])
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
it 'should create transitions' do
|
|
29
|
-
transitions = event.
|
|
30
|
-
transitions[0].from.
|
|
31
|
-
transitions[0].to.
|
|
32
|
-
transitions[1].from.
|
|
33
|
-
transitions[1].to.
|
|
29
|
+
transitions = event.transitions
|
|
30
|
+
expect(transitions[0].from).to eq(:open)
|
|
31
|
+
expect(transitions[0].to).to eq(:closed)
|
|
32
|
+
expect(transitions[1].from).to eq(:received)
|
|
33
|
+
expect(transitions[1].to).to eq(:closed)
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -42,29 +42,28 @@ describe 'transition inspection' do
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
it 'should support inspecting transitions from other states' do
|
|
45
|
-
event.transitions_from_state(:sleeping).map(&:to).
|
|
46
|
-
event.transitions_from_state?(:sleeping).
|
|
45
|
+
expect(event.transitions_from_state(:sleeping).map(&:to)).to eq([:running])
|
|
46
|
+
expect(event.transitions_from_state?(:sleeping)).to be_true
|
|
47
47
|
|
|
48
|
-
event.transitions_from_state(:cleaning).map(&:to).
|
|
49
|
-
event.transitions_from_state?(:cleaning).
|
|
48
|
+
expect(event.transitions_from_state(:cleaning).map(&:to)).to eq([])
|
|
49
|
+
expect(event.transitions_from_state?(:cleaning)).to be_false
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
it 'should support inspecting transitions to other states' do
|
|
53
|
-
event.transitions_to_state(:running).map(&:from).
|
|
54
|
-
event.transitions_to_state?(:running).
|
|
53
|
+
expect(event.transitions_to_state(:running).map(&:from)).to eq([:sleeping])
|
|
54
|
+
expect(event.transitions_to_state?(:running)).to be_true
|
|
55
55
|
|
|
56
|
-
event.transitions_to_state(:cleaning).map(&:to).
|
|
57
|
-
event.transitions_to_state?(:cleaning).
|
|
56
|
+
expect(event.transitions_to_state(:cleaning).map(&:to)).to eq([])
|
|
57
|
+
expect(event.transitions_to_state?(:cleaning)).to be_false
|
|
58
58
|
end
|
|
59
59
|
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
|
-
event.fire(obj).
|
|
66
|
+
expect(event.fire(obj)).to be_nil
|
|
68
67
|
end
|
|
69
68
|
|
|
70
69
|
it 'should return the state of the first matching transition it finds' do
|
|
@@ -72,10 +71,9 @@ 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
|
-
event.fire(obj).
|
|
76
|
+
expect(event.fire(obj)).to eq(:closed)
|
|
79
77
|
end
|
|
80
78
|
|
|
81
79
|
it 'should call the guard with the params passed in' do
|
|
@@ -83,11 +81,10 @@ 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.
|
|
88
|
-
obj.should_receive(:guard_fn).with('arg1', 'arg2').and_return(true)
|
|
84
|
+
obj = double('object', :aasm => double('aasm', :current_state => :open))
|
|
85
|
+
expect(obj).to receive(:guard_fn).with('arg1', 'arg2').and_return(true)
|
|
89
86
|
|
|
90
|
-
event.fire(obj, nil, 'arg1', 'arg2').
|
|
87
|
+
expect(event.fire(obj, nil, 'arg1', 'arg2')).to eq(:closed)
|
|
91
88
|
end
|
|
92
89
|
|
|
93
90
|
end
|
|
@@ -96,64 +93,74 @@ 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
|
|
|
104
103
|
model = ThisNameBetterNotBeInUse.new
|
|
105
|
-
model.
|
|
104
|
+
expect(model).to receive(:symbol_success_callback)
|
|
106
105
|
model.with_symbol!
|
|
107
106
|
end
|
|
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
|
|
|
116
117
|
model = ThisNameBetterNotBeInUse.new
|
|
117
|
-
model.
|
|
118
|
+
expect(model).to receive(:string_success_callback)
|
|
118
119
|
model.with_string!
|
|
119
120
|
end
|
|
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
|
|
|
128
131
|
model = ThisNameBetterNotBeInUse.new
|
|
129
|
-
model.
|
|
130
|
-
model.
|
|
132
|
+
expect(model).to receive(:success_callback1)
|
|
133
|
+
expect(model).to receive(:success_callback2)
|
|
131
134
|
model.with_array!
|
|
132
135
|
end
|
|
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
|
|
|
141
146
|
model = ThisNameBetterNotBeInUse.new
|
|
142
|
-
model.
|
|
143
|
-
model.
|
|
144
|
-
model.
|
|
147
|
+
expect(model).to receive(:success_callback1)
|
|
148
|
+
expect(model).to receive(:success_callback2)
|
|
149
|
+
expect(model).to receive(:proc_success_callback)
|
|
145
150
|
model.with_array_including_procs!
|
|
146
151
|
end
|
|
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
|
|
|
155
162
|
model = ThisNameBetterNotBeInUse.new
|
|
156
|
-
model.
|
|
163
|
+
expect(model).to receive(:proc_success_callback)
|
|
157
164
|
model.with_proc!
|
|
158
165
|
end
|
|
159
166
|
end
|
|
@@ -161,21 +168,23 @@ 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
|
|
|
175
184
|
model = ThisNameBetterNotBeInUse.new
|
|
176
|
-
model.
|
|
177
|
-
model.
|
|
178
|
-
model.
|
|
185
|
+
expect(model).to receive(:do_one_thing_after).once.ordered
|
|
186
|
+
expect(model).to receive(:do_another_thing_after_too).once.ordered
|
|
187
|
+
expect(model).to receive(:do_third_thing_at_last).once.ordered
|
|
179
188
|
model.with_afters!
|
|
180
189
|
end
|
|
181
190
|
end
|
|
@@ -183,33 +192,37 @@ 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
|
|
|
194
205
|
model = ThisNameBetterNotBeInUse.new
|
|
195
|
-
model.
|
|
206
|
+
expect(model).to receive(:do_something_before).once
|
|
196
207
|
model.before_as_proc!
|
|
197
208
|
end
|
|
198
209
|
end
|
|
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
|
|
|
210
223
|
model = ThisNameBetterNotBeInUse.new
|
|
211
|
-
model.
|
|
212
|
-
model.
|
|
224
|
+
expect(model).to receive(:do_something_before).once.ordered
|
|
225
|
+
expect(model).to receive(:do_something_after).once.ordered
|
|
213
226
|
model.in_right_order!
|
|
214
227
|
end
|
|
215
228
|
end
|
|
@@ -219,40 +232,40 @@ 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
|
+
expect(pe.aasm.current_state).to eq(: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
|
+
expect(pe.aasm.current_state).to eq(: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
|
+
expect(pe.aasm.current_state).to eq(: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
|
+
expect(pe.aasm.current_state).to eq(:working)
|
|
238
251
|
end
|
|
239
252
|
|
|
240
253
|
it 'should call on_transition method with args' do
|
|
241
254
|
pe.wakeup!(:showering)
|
|
242
|
-
pe.
|
|
255
|
+
expect(pe).to receive(:wear_clothes).with('blue', 'jeans')
|
|
243
256
|
pe.dress!(:working, 'blue', 'jeans')
|
|
244
257
|
end
|
|
245
258
|
|
|
246
259
|
it 'should call on_transition proc' do
|
|
247
260
|
pe.wakeup!(:showering)
|
|
248
|
-
pe.
|
|
261
|
+
expect(pe).to receive(:wear_clothes).with('purple', 'slacks')
|
|
249
262
|
pe.dress!(:dating, 'purple', 'slacks')
|
|
250
263
|
end
|
|
251
264
|
|
|
252
265
|
it 'should call on_transition with an array of methods' do
|
|
253
266
|
pe.wakeup!(:showering)
|
|
254
|
-
pe.
|
|
255
|
-
pe.
|
|
267
|
+
expect(pe).to receive(:condition_hair)
|
|
268
|
+
expect(pe).to receive(:fix_hair)
|
|
256
269
|
pe.dress!(:prettying_up)
|
|
257
270
|
end
|
|
258
271
|
end
|
|
@@ -261,9 +274,9 @@ describe 'event firing without persistence' do
|
|
|
261
274
|
it 'should attempt to persist if aasm_write_state is defined' do
|
|
262
275
|
foo = Foo.new
|
|
263
276
|
def foo.aasm_write_state; end
|
|
264
|
-
foo.
|
|
277
|
+
expect(foo).to be_open
|
|
265
278
|
|
|
266
|
-
foo.
|
|
279
|
+
expect(foo).to receive(:aasm_write_state_without_persistence)
|
|
267
280
|
foo.close
|
|
268
281
|
end
|
|
269
282
|
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "per-transition guards" do
|
|
4
|
+
let(:guardian) { Guardian.new }
|
|
5
|
+
|
|
6
|
+
it "allows the transition if the guard succeeds" do
|
|
7
|
+
expect { guardian.use_one_guard_that_succeeds! }.to_not raise_error
|
|
8
|
+
expect(guardian).to be_beta
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "stops the transition if the guard fails" do
|
|
12
|
+
expect { guardian.use_one_guard_that_fails! }.to raise_error(AASM::InvalidTransition)
|
|
13
|
+
expect(guardian).to be_alpha
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "allows the transition if all guards succeeds" do
|
|
17
|
+
expect { guardian.use_guards_that_succeed! }.to_not raise_error
|
|
18
|
+
expect(guardian).to be_beta
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "stops the transition if the first guard fails" do
|
|
22
|
+
expect { guardian.use_guards_where_the_first_fails! }.to raise_error(AASM::InvalidTransition)
|
|
23
|
+
expect(guardian).to be_alpha
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "stops the transition if the second guard fails" do
|
|
27
|
+
expect { guardian.use_guards_where_the_second_fails! }.to raise_error(AASM::InvalidTransition)
|
|
28
|
+
expect(guardian).to be_alpha
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "event guards" do
|
|
33
|
+
let(:guardian) { Guardian.new }
|
|
34
|
+
|
|
35
|
+
it "allows the transition if the event guards succeed" do
|
|
36
|
+
expect { guardian.use_event_guards_that_succeed! }.to_not raise_error
|
|
37
|
+
expect(guardian).to be_beta
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "allows the transition if the event and transition guards succeed" do
|
|
41
|
+
expect { guardian.use_event_and_transition_guards_that_succeed! }.to_not raise_error
|
|
42
|
+
expect(guardian).to be_beta
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "stops the transition if the first event guard fails" do
|
|
46
|
+
expect { guardian.use_event_guards_where_the_first_fails! }.to raise_error(AASM::InvalidTransition)
|
|
47
|
+
expect(guardian).to be_alpha
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "stops the transition if the second event guard fails" do
|
|
51
|
+
expect { guardian.use_event_guards_where_the_second_fails! }.to raise_error(AASM::InvalidTransition)
|
|
52
|
+
expect(guardian).to be_alpha
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "stops the transition if the transition guard fails" do
|
|
56
|
+
expect { guardian.use_event_and_transition_guards_where_third_fails! }.to raise_error(AASM::InvalidTransition)
|
|
57
|
+
expect(guardian).to be_alpha
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
@@ -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
|
+
expect(bar.aasm.current_state).to eq(: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
|
+
expect(Banker.new(Banker::RICH - 1).aasm.current_state).to eq(:selling_bad_mortgages)
|
|
25
|
+
expect(Banker.new(Banker::RICH + 1).aasm.current_state).to eq(:retired)
|
|
27
26
|
end
|
|
28
27
|
end
|
|
@@ -1,30 +1,17 @@
|
|
|
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
|
-
Foo.aasm.
|
|
19
|
-
Foo.aasm.states.
|
|
20
|
-
Foo.aasm.states.
|
|
5
|
+
expect(Foo.aasm).to respond_to(:states)
|
|
6
|
+
expect(Foo.aasm.states).to include(:open)
|
|
7
|
+
expect(Foo.aasm.states).to include(:closed)
|
|
21
8
|
|
|
22
|
-
Foo.aasm.
|
|
23
|
-
Foo.aasm.initial_state.
|
|
9
|
+
expect(Foo.aasm).to respond_to(:initial_state)
|
|
10
|
+
expect(Foo.aasm.initial_state).to eq(:open)
|
|
24
11
|
|
|
25
|
-
Foo.aasm.
|
|
26
|
-
Foo.aasm.events.
|
|
27
|
-
Foo.aasm.events.
|
|
12
|
+
expect(Foo.aasm).to respond_to(:events)
|
|
13
|
+
expect(Foo.aasm.events).to include(:close)
|
|
14
|
+
expect(Foo.aasm.events).to include(:null)
|
|
28
15
|
end
|
|
29
16
|
|
|
30
17
|
context "instance level inspection" do
|
|
@@ -33,77 +20,77 @@ describe 'inspection for common cases' do
|
|
|
33
20
|
|
|
34
21
|
it "delivers all states" do
|
|
35
22
|
states = foo.aasm.states
|
|
36
|
-
states.
|
|
37
|
-
states.
|
|
23
|
+
expect(states).to include(:open)
|
|
24
|
+
expect(states).to include(:closed)
|
|
38
25
|
|
|
39
26
|
states = foo.aasm.states(:permissible => true)
|
|
40
|
-
states.
|
|
41
|
-
states.
|
|
27
|
+
expect(states).to include(:closed)
|
|
28
|
+
expect(states).not_to include(:open)
|
|
42
29
|
|
|
43
30
|
foo.close
|
|
44
|
-
foo.aasm.states(:permissible => true).
|
|
31
|
+
expect(foo.aasm.states(:permissible => true)).to be_empty
|
|
45
32
|
end
|
|
46
33
|
|
|
47
34
|
it "delivers all states for subclasses" do
|
|
48
35
|
states = two.aasm.states
|
|
49
|
-
states.
|
|
50
|
-
states.
|
|
51
|
-
states.
|
|
36
|
+
expect(states).to include(:open)
|
|
37
|
+
expect(states).to include(:closed)
|
|
38
|
+
expect(states).to include(:foo)
|
|
52
39
|
|
|
53
40
|
states = two.aasm.states(:permissible => true)
|
|
54
|
-
states.
|
|
55
|
-
states.
|
|
41
|
+
expect(states).to include(:closed)
|
|
42
|
+
expect(states).not_to include(:open)
|
|
56
43
|
|
|
57
44
|
two.close
|
|
58
|
-
two.aasm.states(:permissible => true).
|
|
45
|
+
expect(two.aasm.states(:permissible => true)).to be_empty
|
|
59
46
|
end
|
|
60
47
|
|
|
61
48
|
it "delivers all events" do
|
|
62
49
|
events = foo.aasm.events
|
|
63
|
-
events.
|
|
64
|
-
events.
|
|
50
|
+
expect(events).to include(:close)
|
|
51
|
+
expect(events).to include(:null)
|
|
65
52
|
foo.close
|
|
66
|
-
foo.aasm.events.
|
|
53
|
+
expect(foo.aasm.events).to be_empty
|
|
67
54
|
end
|
|
68
55
|
end
|
|
69
56
|
|
|
70
57
|
it 'should list states in the order they have been defined' do
|
|
71
|
-
Conversation.aasm.states.
|
|
58
|
+
expect(Conversation.aasm.states).to eq([:needs_attention, :read, :closed, :awaiting_response, :junk])
|
|
72
59
|
end
|
|
73
60
|
end
|
|
74
61
|
|
|
75
62
|
describe "special cases" do
|
|
76
63
|
it "should support valid a state name" do
|
|
77
|
-
Argument.
|
|
78
|
-
Argument.
|
|
64
|
+
expect(Argument.aasm.states).to include(:invalid)
|
|
65
|
+
expect(Argument.aasm.states).to include(:valid)
|
|
79
66
|
|
|
80
67
|
argument = Argument.new
|
|
81
|
-
argument.invalid
|
|
82
|
-
argument.
|
|
68
|
+
expect(argument.invalid?).to be_true
|
|
69
|
+
expect(argument.aasm.current_state).to eq(:invalid)
|
|
83
70
|
|
|
84
71
|
argument.valid!
|
|
85
|
-
argument.valid
|
|
86
|
-
argument.
|
|
72
|
+
expect(argument.valid?).to be_true
|
|
73
|
+
expect(argument.aasm.current_state).to eq(: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.
|
|
93
|
-
Foo.
|
|
79
|
+
expect(Foo.aasm).to respond_to(:states_for_select)
|
|
80
|
+
expect(Foo.aasm.states_for_select).to eq([['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.
|
|
100
|
-
froms = AuthMachine.
|
|
101
|
-
[:pending, :passive, :suspended].each {|from| froms.
|
|
86
|
+
expect(AuthMachine.aasm).to respond_to(:from_states_for_state)
|
|
87
|
+
froms = AuthMachine.aasm.from_states_for_state(:active)
|
|
88
|
+
[:pending, :passive, :suspended].each {|from| expect(froms).to 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.
|
|
106
|
-
[:suspended].each {|from| froms.
|
|
92
|
+
froms = AuthMachine.aasm.from_states_for_state(:active, :transition => :unsuspend)
|
|
93
|
+
[:suspended].each {|from| expect(froms).to include(from)}
|
|
107
94
|
end
|
|
108
95
|
end
|
|
109
96
|
|
|
@@ -111,7 +98,7 @@ describe 'permissible events' do
|
|
|
111
98
|
let(:foo) {Foo.new}
|
|
112
99
|
|
|
113
100
|
it 'work' do
|
|
114
|
-
foo.aasm.permissible_events.
|
|
115
|
-
foo.aasm.permissible_events.
|
|
101
|
+
expect(foo.aasm.permissible_events).to include(:close)
|
|
102
|
+
expect(foo.aasm.permissible_events).not_to include(:null)
|
|
116
103
|
end
|
|
117
104
|
end
|