stator 0.4.0 → 0.9.0.beta
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/.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'
|