stator 0.4.0 → 0.9.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +28 -0
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/Appraisals +23 -0
- data/Gemfile +4 -3
- data/gemfiles/activerecord_5.1.gemfile +12 -0
- data/gemfiles/activerecord_5.1.gemfile.lock +74 -0
- data/gemfiles/activerecord_5.2.gemfile +12 -0
- data/gemfiles/activerecord_5.2.gemfile.lock +74 -0
- data/gemfiles/activerecord_5.gemfile +12 -0
- data/gemfiles/activerecord_5.gemfile.lock +74 -0
- data/gemfiles/activerecord_6.0.gemfile +12 -0
- data/gemfiles/activerecord_6.0.gemfile.lock +74 -0
- data/gemfiles/activerecord_6.1.gemfile +12 -0
- data/gemfiles/activerecord_6.1.gemfile.lock +73 -0
- data/gemfiles/activerecord_7.0.gemfile +12 -0
- data/gemfiles/activerecord_7.0.gemfile.lock +71 -0
- data/lib/stator/alias.rb +51 -30
- data/lib/stator/integration.rb +42 -49
- data/lib/stator/machine.rb +59 -58
- data/lib/stator/model.rb +78 -73
- data/lib/stator/transition.rb +61 -60
- data/lib/stator/version.rb +3 -5
- data/lib/stator.rb +13 -0
- data/spec/model_spec.rb +206 -207
- data/spec/spec_helper.rb +6 -3
- data/spec/support/models.rb +26 -32
- data/spec/support/schema.rb +42 -42
- data/stator.gemspec +1 -0
- metadata +33 -10
- data/.travis.yml +0 -41
- data/gemfiles/ar40.gemfile +0 -10
- data/gemfiles/ar41.gemfile +0 -10
- data/gemfiles/ar42.gemfile +0 -10
- data/gemfiles/ar52.gemfile +0 -10
data/spec/model_spec.rb
CHANGED
@@ -1,203 +1,201 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Stator::Model do
|
6
|
-
it "should set the default state after initialization" do
|
7
|
-
u = User.new
|
8
|
-
u.state.should eql("pending")
|
9
|
-
end
|
10
6
|
|
11
|
-
|
12
|
-
u = User.new
|
13
|
-
u.state = "activated"
|
14
|
-
u.state_was.should eql("pending")
|
15
|
-
end
|
7
|
+
let(:u) { User.new }
|
16
8
|
|
17
|
-
|
18
|
-
u = User.new
|
19
|
-
u.should_not be_valid
|
20
|
-
u.errors[:email].grep(/length/).should_not be_empty
|
21
|
-
end
|
9
|
+
describe "basic operations" do
|
22
10
|
|
23
|
-
|
24
|
-
|
25
|
-
|
11
|
+
it 'should set the default state after initialization' do
|
12
|
+
u.state.to_sym.should eql(:pending)
|
13
|
+
end
|
26
14
|
|
27
|
-
|
28
|
-
|
29
|
-
|
15
|
+
it 'should see the initial setting of the state as a change with the initial state as the previous value' do
|
16
|
+
u.state = :activated
|
17
|
+
u.state_was.to_sym.should eql(:pending)
|
18
|
+
end
|
30
19
|
|
31
|
-
|
32
|
-
|
33
|
-
|
20
|
+
it 'should not obstruct normal validations' do
|
21
|
+
u.should_not be_valid
|
22
|
+
u.errors[:email].grep(/length/).should_not be_empty
|
23
|
+
end
|
34
24
|
|
35
|
-
|
36
|
-
|
25
|
+
it 'should ensure a valid state transition when given a bogus state' do
|
26
|
+
u.state = :anythingelse
|
37
27
|
|
38
|
-
|
39
|
-
|
28
|
+
u.should_not be_valid
|
29
|
+
u.errors[:state].should eql(['is not a valid state'])
|
30
|
+
end
|
40
31
|
|
41
|
-
allow
|
32
|
+
it 'should allow creation at any state' do
|
33
|
+
u.email = 'doug@example.com'
|
34
|
+
u.state = :hyperactivated
|
42
35
|
|
43
|
-
|
36
|
+
u.should be_valid
|
37
|
+
end
|
44
38
|
|
45
|
-
|
46
|
-
|
47
|
-
end
|
39
|
+
it 'should ensure a valid state transition when given an illegal state based on the current state' do
|
40
|
+
allow(u).to receive(:new_record?).and_return(false)
|
48
41
|
|
49
|
-
|
50
|
-
u = User.new(email: "fred@example.com")
|
51
|
-
u.activate!
|
52
|
-
u.hyperactivate!
|
42
|
+
u.state = 'hyperactivated'
|
53
43
|
|
54
|
-
|
44
|
+
u.should_not be_valid
|
45
|
+
u.errors[:state].should_not be_empty
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should not allow a transition that is currently in a `to` state' do
|
49
|
+
u.email = 'fred@example.com'
|
50
|
+
u.activate!
|
55
51
|
u.hyperactivate!
|
56
|
-
}.should raise_error(/cannot transition to \"hyperactivated\" from \"hyperactivated\"/)
|
57
|
-
end
|
58
52
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
53
|
+
lambda {
|
54
|
+
u.hyperactivate!
|
55
|
+
}.should raise_error(/cannot transition to hyperactivated from hyperactivated/)
|
56
|
+
end
|
63
57
|
|
64
|
-
|
65
|
-
|
66
|
-
|
58
|
+
it 'should run conditional validations' do
|
59
|
+
u.state = 'semiactivated'
|
60
|
+
u.should_not be_valid
|
67
61
|
|
68
|
-
|
69
|
-
|
70
|
-
|
62
|
+
u.errors[:state].should be_empty
|
63
|
+
u.errors[:email].should_not be_empty
|
64
|
+
end
|
71
65
|
|
72
|
-
|
66
|
+
it 'should invoke callbacks' do
|
67
|
+
u.assign_attributes(activated: true, email: 'doug@example.com', name: 'doug')
|
68
|
+
u.activated.should == true
|
73
69
|
|
74
|
-
|
75
|
-
u.state.should eql("deactivated")
|
76
|
-
u.activated_state_at.should be_nil
|
77
|
-
u.should be_persisted
|
78
|
-
end
|
70
|
+
u.deactivate
|
79
71
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
u.
|
84
|
-
|
85
|
-
end
|
72
|
+
u.activated.should == false
|
73
|
+
u.state.should eql :deactivated
|
74
|
+
u.activated_state_at.should be_nil
|
75
|
+
u.should be_persisted
|
76
|
+
end
|
86
77
|
|
87
|
-
|
88
|
-
|
89
|
-
|
78
|
+
it 'should blow up if the record is invalid and a bang method is used' do
|
79
|
+
u.assign_attributes(email: 'doug@other.com', name: 'doug')
|
80
|
+
-> { u.activate! }.should raise_error(ActiveRecord::RecordInvalid)
|
81
|
+
end
|
90
82
|
|
91
|
-
|
92
|
-
|
83
|
+
it 'should allow for other fields to be used other than state' do
|
84
|
+
a = Animal.new
|
85
|
+
a.should be_valid
|
93
86
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
87
|
+
a.birth!
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should create implicit transitions for state declarations' do
|
91
|
+
a = Animal.new
|
92
|
+
a.should_not be_grown_up
|
93
|
+
a.status = 'grown_up'
|
94
|
+
a.save
|
95
|
+
end
|
100
96
|
|
101
|
-
|
102
|
-
|
103
|
-
f.should be_dirty
|
104
|
-
f.should be_house_dirty
|
97
|
+
it 'should allow multiple machines in the same model' do
|
98
|
+
f = Farm.new
|
105
99
|
|
106
|
-
|
100
|
+
f.should be_dirty
|
101
|
+
f.should be_house_dirty
|
107
102
|
|
108
|
-
|
109
|
-
f.should be_house_dirty
|
103
|
+
f.cleanup
|
110
104
|
|
111
|
-
|
105
|
+
f.should_not be_dirty
|
106
|
+
f.should be_house_dirty
|
112
107
|
|
113
|
-
|
114
|
-
end
|
108
|
+
f.house_cleanup # the house namespace
|
115
109
|
|
116
|
-
|
117
|
-
|
118
|
-
|
110
|
+
f.should_not be_dirty
|
111
|
+
f.should_not be_house_dirty
|
112
|
+
end
|
119
113
|
|
120
|
-
|
121
|
-
|
114
|
+
it 'should allow saving to be skipped' do
|
115
|
+
f = Farm.new
|
116
|
+
f.cleanup(false)
|
122
117
|
|
123
|
-
|
124
|
-
|
125
|
-
f.state.should be_nil
|
118
|
+
f.should_not be_persisted
|
119
|
+
end
|
126
120
|
|
127
|
-
|
121
|
+
it 'should allow no initial state' do
|
122
|
+
f = Factory.new
|
123
|
+
f.state.should be_nil
|
128
124
|
|
129
|
-
|
130
|
-
|
125
|
+
f.construct.should eql(true)
|
126
|
+
|
127
|
+
f.state.should eql(:constructed)
|
128
|
+
end
|
131
129
|
|
132
|
-
|
133
|
-
|
134
|
-
u.email = "doug@example.com"
|
130
|
+
it 'should allow any transition if validations are opted out of' do
|
131
|
+
u.email = 'doug@example.com'
|
135
132
|
|
136
|
-
|
137
|
-
|
133
|
+
u.can_hyperactivate?.should eql(false)
|
134
|
+
u.hyperactivate.should eql(false)
|
138
135
|
|
139
|
-
|
136
|
+
u.current_state.should eql :pending
|
140
137
|
|
141
|
-
|
142
|
-
|
143
|
-
|
138
|
+
u.without_state_transition_validations do
|
139
|
+
u.can_hyperactivate?.should eql(true)
|
140
|
+
u.hyperactivate.should eql(true)
|
141
|
+
end
|
144
142
|
end
|
145
|
-
end
|
146
143
|
|
147
|
-
|
148
|
-
|
149
|
-
u.email = "doug@example.com"
|
144
|
+
it 'should skip tracking timestamps if opted out of' do
|
145
|
+
u.email = 'doug@example.com'
|
150
146
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
147
|
+
u.without_state_transition_tracking do
|
148
|
+
u.semiactivate!
|
149
|
+
u.state.should eql :semiactivated
|
150
|
+
u.semiactivated_state_at.should be_nil
|
151
|
+
end
|
152
|
+
|
153
|
+
# Make sure that tracking is ensured back to
|
154
|
+
# original value
|
155
|
+
u.activate!
|
156
|
+
u.activated_state_at.should_not be_nil
|
155
157
|
end
|
156
158
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
end
|
159
|
+
it 'should skip tracking timestamps if opted out of with thread safety' do
|
160
|
+
threads = []
|
161
|
+
skip = User.new(email: 'skip@example.com', state: :pending)
|
162
|
+
nope = User.new(email: 'nope@example.com', state: :pending)
|
162
163
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
164
|
+
threads << Thread.new do
|
165
|
+
sleep 0.5
|
166
|
+
nope.semiactivate!
|
167
|
+
end
|
167
168
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
skip.without_state_transition_tracking do
|
174
|
-
sleep 1
|
175
|
-
skip.semiactivate!
|
169
|
+
threads << Thread.new do
|
170
|
+
skip.without_state_transition_tracking do
|
171
|
+
sleep 1
|
172
|
+
skip.semiactivate!
|
173
|
+
end
|
176
174
|
end
|
177
|
-
end
|
178
175
|
|
179
|
-
|
176
|
+
threads.each(&:join)
|
180
177
|
|
181
|
-
|
182
|
-
|
183
|
-
|
178
|
+
nope.semiactivated_state_at.should_not be_nil
|
179
|
+
skip.semiactivated_state_at.should be_nil
|
180
|
+
end
|
184
181
|
|
185
|
-
|
186
|
-
|
187
|
-
|
182
|
+
it 'should not inherit _integration cache on dup' do
|
183
|
+
u.email = 'user@example.com'
|
184
|
+
u.save!
|
188
185
|
|
189
|
-
|
186
|
+
u_duped = u.dup
|
190
187
|
|
191
|
-
|
188
|
+
u.semiactivate!
|
192
189
|
|
193
|
-
|
190
|
+
u_duped_integration = u_duped.send(:_stator_integration)
|
194
191
|
|
195
|
-
|
196
|
-
|
192
|
+
u_duped_integration.state.should_not eql(u.state)
|
193
|
+
u_duped_integration.instance_values['record'].should eq(u_duped)
|
194
|
+
end
|
197
195
|
end
|
198
196
|
|
199
|
-
describe
|
200
|
-
it
|
197
|
+
describe 'helper methods' do
|
198
|
+
it 'should answer the question of whether the state is currently the one invoked' do
|
201
199
|
a = Animal.new
|
202
200
|
a.should be_unborn
|
203
201
|
a.should_not be_born
|
@@ -208,7 +206,7 @@ describe Stator::Model do
|
|
208
206
|
a.should_not be_unborn
|
209
207
|
end
|
210
208
|
|
211
|
-
it
|
209
|
+
it 'should determine if it can validly execute a transition' do
|
212
210
|
a = Animal.new
|
213
211
|
a.can_birth?.should eql(true)
|
214
212
|
|
@@ -218,18 +216,18 @@ describe Stator::Model do
|
|
218
216
|
end
|
219
217
|
end
|
220
218
|
|
221
|
-
describe
|
219
|
+
describe 'tracker methods' do
|
222
220
|
before do
|
223
|
-
Time.zone =
|
221
|
+
Time.zone = 'Eastern Time (US & Canada)'
|
224
222
|
end
|
225
223
|
|
226
|
-
it
|
224
|
+
it 'should store the initial state timestamp when the record is created' do
|
227
225
|
a = Animal.new
|
228
226
|
a.save
|
229
227
|
a.unborn_status_at.should be_within(1).of(Time.zone.now)
|
230
228
|
end
|
231
229
|
|
232
|
-
it
|
230
|
+
it 'should store when a record changed state for the first time' do
|
233
231
|
a = Animal.new
|
234
232
|
a.unborn_status_at.should be_nil
|
235
233
|
a.born_status_at.should be_nil
|
@@ -238,7 +236,7 @@ describe Stator::Model do
|
|
238
236
|
a.born_status_at.should be_within(1).of(Time.zone.now)
|
239
237
|
end
|
240
238
|
|
241
|
-
it
|
239
|
+
it 'should store when a record change states' do
|
242
240
|
a = Animal.new
|
243
241
|
a.status_changed_at.should be_nil
|
244
242
|
|
@@ -248,15 +246,14 @@ describe Stator::Model do
|
|
248
246
|
|
249
247
|
previous_status_changed_at = a.status_changed_at
|
250
248
|
|
251
|
-
a.name =
|
249
|
+
a.name = 'new name'
|
252
250
|
a.save
|
253
251
|
|
254
252
|
a.status_changed_at.should eql(previous_status_changed_at)
|
255
253
|
end
|
256
254
|
|
257
|
-
it
|
258
|
-
u =
|
259
|
-
u.email = "doug@example.com"
|
255
|
+
it 'should prepend the setting of the timestamp so other callbacks can use it' do
|
256
|
+
u.email = 'doug@example.com'
|
260
257
|
|
261
258
|
u.tagged_at.should be_nil
|
262
259
|
u.semiactivate!
|
@@ -265,35 +262,34 @@ describe Stator::Model do
|
|
265
262
|
u.tagged_at.should_not be_nil
|
266
263
|
end
|
267
264
|
|
268
|
-
it
|
269
|
-
t = Time.at(Time.now.to_i - 3600)
|
265
|
+
it 'should respect the timestamp if explicitly provided' do
|
266
|
+
t = Time.zone.at(Time.now.to_i - 3600)
|
270
267
|
|
271
|
-
u =
|
272
|
-
u.
|
273
|
-
u.state = "semiactivated"
|
268
|
+
u.email = 'doug@example.com'
|
269
|
+
u.state = 'semiactivated'
|
274
270
|
u.semiactivated_state_at = t
|
275
271
|
u.save!
|
276
272
|
|
277
|
-
u.state.should eql(
|
273
|
+
u.state.should eql('semiactivated')
|
278
274
|
u.semiactivated_state_at.should eql(t)
|
279
275
|
end
|
280
276
|
|
281
|
-
it
|
282
|
-
t = Time.at(Time.now.to_i - 3600)
|
277
|
+
it 'should respect the timestamp if explicitly provided via create' do
|
278
|
+
t = Time.zone.at(Time.now.to_i - 3600)
|
283
279
|
|
284
280
|
u = User.create!(
|
285
|
-
email:
|
286
|
-
state:
|
281
|
+
email: 'doug@example.com',
|
282
|
+
state: 'semiactivated',
|
287
283
|
semiactivated_state_at: t
|
288
284
|
)
|
289
285
|
|
290
|
-
u.state.should eql(
|
286
|
+
u.state.should eql('semiactivated')
|
291
287
|
u.semiactivated_state_at.should eql(t)
|
292
288
|
end
|
293
289
|
|
294
|
-
it
|
295
|
-
z = ZooKeeper.new(name:
|
296
|
-
z.employment_state.should eql(
|
290
|
+
it 'should allow opting into track by namespace' do
|
291
|
+
z = ZooKeeper.new(name: 'Doug')
|
292
|
+
z.employment_state.should eql('hired')
|
297
293
|
z.employment_fire!
|
298
294
|
z.fired_employment_state_at.should_not be_nil
|
299
295
|
|
@@ -306,52 +302,53 @@ describe Stator::Model do
|
|
306
302
|
z.ended_working_state_at.should be_nil
|
307
303
|
end
|
308
304
|
|
309
|
-
describe
|
310
|
-
it
|
311
|
-
t = Time.now
|
312
|
-
u = User.create!(
|
313
|
-
u.state_by?(:activated, Time.at(t.to_i + 1)).should be true
|
314
|
-
u.activated_state_by?(Time.at(t.to_i + 1)).should be true
|
305
|
+
describe '#state_by?' do
|
306
|
+
it 'should be true when the transition is earlier' do
|
307
|
+
t = Time.zone.now
|
308
|
+
u = User.create!(email: 'doug@example.com', activated_state_at: t)
|
309
|
+
u.state_by?(:activated, Time.zone.at(t.to_i + 1)).should be true
|
310
|
+
u.activated_state_by?(Time.zone.at(t.to_i + 1)).should be true
|
315
311
|
end
|
316
312
|
|
317
|
-
it
|
318
|
-
t = Time.now
|
319
|
-
u = User.create!(
|
313
|
+
it 'should be true when the transition is at the same time' do
|
314
|
+
t = Time.zone.now
|
315
|
+
u = User.create!(email: 'doug@example.com', activated_state_at: t)
|
320
316
|
u.state_by?(:activated, t).should be true
|
321
317
|
u.activated_state_by?(t).should be true
|
322
318
|
end
|
323
319
|
|
324
|
-
it
|
325
|
-
t = Time.now
|
326
|
-
u = User.create!(
|
327
|
-
u.state_by?(:activated, Time.at(t.to_i - 1)).should be false
|
328
|
-
u.activated_state_by?(Time.at(t.to_i - 1)).should be false
|
320
|
+
it 'should be false when the transition is later' do
|
321
|
+
t = Time.zone.now
|
322
|
+
u = User.create!(email: 'doug@example.com', activated_state_at: t)
|
323
|
+
u.state_by?(:activated, Time.zone.at(t.to_i - 1)).should be false
|
324
|
+
u.activated_state_by?(Time.zone.at(t.to_i - 1)).should be false
|
329
325
|
end
|
330
326
|
|
331
|
-
it
|
332
|
-
t = Time.now
|
333
|
-
u = User.create!(
|
327
|
+
it 'should be false when the transition is nil' do
|
328
|
+
t = Time.zone.now
|
329
|
+
u = User.create!(email: 'doug@example.com', activated_state_at: nil)
|
334
330
|
u.state_by?(:activated, t).should be false
|
335
331
|
u.activated_state_by?(t).should be false
|
336
332
|
end
|
337
333
|
|
338
|
-
it
|
339
|
-
u = User.create!(
|
334
|
+
it 'should be true when the transition is not nil and the time is nil' do
|
335
|
+
u = User.create!(email: 'doug@example.com', activated_state_at: Time.zone.now)
|
340
336
|
u.state_by?(:activated, nil).should be true
|
341
337
|
u.activated_state_by?(nil).should be true
|
342
338
|
end
|
343
339
|
|
344
|
-
it
|
345
|
-
u = User.create!(email:
|
340
|
+
it 'should be false when both are nil' do
|
341
|
+
u = User.create!(email: 'doug@example.com', activated_state_at: nil)
|
346
342
|
u.state_by?(:activated, nil).should be false
|
347
343
|
u.activated_state_by?(nil).should be false
|
348
344
|
end
|
349
345
|
end
|
350
346
|
end
|
351
347
|
|
352
|
-
describe
|
353
|
-
it
|
354
|
-
u = User.new(email:
|
348
|
+
describe 'aliasing' do
|
349
|
+
it 'should allow aliasing within the dsl' do
|
350
|
+
u = User.new(email: 'doug@example.com')
|
351
|
+
|
355
352
|
u.should respond_to(:active?)
|
356
353
|
u.should respond_to(:inactive?)
|
357
354
|
|
@@ -368,26 +365,28 @@ describe Stator::Model do
|
|
368
365
|
u.should be_active
|
369
366
|
u.should_not be_inactive
|
370
367
|
|
371
|
-
User::ACTIVE_STATES.should eql(%
|
372
|
-
User::INACTIVE_STATES.should eql(%
|
368
|
+
User::ACTIVE_STATES.should eql(%i[activated hyperactivated])
|
369
|
+
User::INACTIVE_STATES.should eql(%i[pending deactivated semiactivated])
|
373
370
|
|
374
|
-
User.active.to_sql.gsub(
|
375
|
-
|
371
|
+
User.active.to_sql.gsub(' ',
|
372
|
+
' ').should eq("SELECT users.* FROM users WHERE users.state IN ('activated', 'hyperactivated')")
|
373
|
+
User.inactive.to_sql.gsub(' ',
|
374
|
+
' ').should eq("SELECT users.* FROM users WHERE users.state IN ('pending', 'deactivated', 'semiactivated')")
|
376
375
|
end
|
377
376
|
|
378
|
-
it
|
377
|
+
it 'should evaluate inverses correctly' do
|
379
378
|
f = Farm.new
|
380
|
-
f.house_state =
|
379
|
+
f.house_state = 'dirty'
|
381
380
|
f.should_not be_house_cleaned
|
382
381
|
|
383
|
-
f.house_state =
|
382
|
+
f.house_state = 'disgusting'
|
384
383
|
f.should_not be_house_cleaned
|
385
384
|
|
386
|
-
f.house_state =
|
385
|
+
f.house_state = 'clean'
|
387
386
|
f.should be_house_cleaned
|
388
387
|
end
|
389
388
|
|
390
|
-
it
|
389
|
+
it 'should namespace aliases just like everything else' do
|
391
390
|
f = Farm.new
|
392
391
|
f.should respond_to(:house_cleaned?)
|
393
392
|
|
@@ -397,23 +396,23 @@ describe Stator::Model do
|
|
397
396
|
f.should be_house_cleaned
|
398
397
|
end
|
399
398
|
|
400
|
-
it
|
399
|
+
it 'should allow for explicit constant and scope names to be provided' do
|
401
400
|
User.should respond_to(:luke_warmers)
|
402
|
-
(
|
401
|
+
(!defined?(User::LUKE_WARMERS).nil?).should eql(true)
|
403
402
|
u = User.new
|
404
403
|
u.should respond_to(:luke_warm?)
|
405
404
|
end
|
406
405
|
|
407
|
-
it
|
406
|
+
it 'should not create constants or scopes by default' do
|
408
407
|
u = User.new
|
409
408
|
u.should respond_to(:iced_tea?)
|
410
|
-
(
|
409
|
+
(!defined?(User::ICED_TEA_STATES).nil?).should eql(false)
|
411
410
|
User.should_not respond_to(:iced_tea)
|
412
411
|
end
|
413
412
|
|
414
|
-
it
|
415
|
-
states = User._stator(
|
416
|
-
states.should eql(%
|
413
|
+
it 'should determine the full list of states correctly' do
|
414
|
+
states = User._stator('').states
|
415
|
+
states.should eql(%i[pending activated deactivated semiactivated hyperactivated])
|
417
416
|
end
|
418
417
|
end
|
419
418
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
4
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
5
|
# Require this file using `require "spec_helper"` to ensure that it is only
|
@@ -11,18 +13,19 @@ require 'active_support/core_ext'
|
|
11
13
|
require 'stator'
|
12
14
|
|
13
15
|
RSpec.configure do |config|
|
14
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
16
|
config.expect_with(:rspec) { |c| c.syntax = :should }
|
16
17
|
config.run_all_when_everything_filtered = true
|
17
18
|
config.filter_run :focus
|
18
19
|
|
20
|
+
config.raise_errors_for_deprecations!
|
21
|
+
|
19
22
|
NullDB.configure do |c|
|
20
23
|
c.project_root = File.dirname(__FILE__)
|
21
24
|
end
|
22
25
|
|
23
26
|
ActiveRecord::Base.establish_connection(
|
24
|
-
:
|
25
|
-
:
|
27
|
+
adapter: :nulldb,
|
28
|
+
schema: 'support/schema.rb'
|
26
29
|
)
|
27
30
|
|
28
31
|
require 'support/models'
|