stator 0.3.3 → 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 +46 -45
- data/lib/stator/machine.rb +61 -55
- data/lib/stator/model.rb +79 -70
- data/lib/stator/transition.rb +61 -60
- data/lib/stator/version.rb +4 -6
- data/lib/stator.rb +13 -0
- data/spec/model_spec.rb +227 -186
- 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
|
19
|
+
|
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
|
30
24
|
|
31
|
-
|
32
|
-
|
33
|
-
u.state = "hyperactivated"
|
25
|
+
it 'should ensure a valid state transition when given a bogus state' do
|
26
|
+
u.state = :anythingelse
|
34
27
|
|
35
|
-
|
36
|
-
|
28
|
+
u.should_not be_valid
|
29
|
+
u.errors[:state].should eql(['is not a valid state'])
|
30
|
+
end
|
37
31
|
|
38
|
-
|
39
|
-
|
32
|
+
it 'should allow creation at any state' do
|
33
|
+
u.email = 'doug@example.com'
|
34
|
+
u.state = :hyperactivated
|
40
35
|
|
41
|
-
|
36
|
+
u.should be_valid
|
37
|
+
end
|
42
38
|
|
43
|
-
|
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)
|
44
41
|
|
45
|
-
|
46
|
-
u.errors[:state].should_not be_empty
|
47
|
-
end
|
42
|
+
u.state = 'hyperactivated'
|
48
43
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
u.hyperactivate!
|
44
|
+
u.should_not be_valid
|
45
|
+
u.errors[:state].should_not be_empty
|
46
|
+
end
|
53
47
|
|
54
|
-
|
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
|
-
a.should_not be_grown_up
|
97
|
-
a.status = "grown_up"
|
98
|
-
a.save
|
99
|
-
end
|
87
|
+
a.birth!
|
88
|
+
end
|
100
89
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
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
|
105
96
|
|
106
|
-
|
97
|
+
it 'should allow multiple machines in the same model' do
|
98
|
+
f = Farm.new
|
107
99
|
|
108
|
-
|
109
|
-
|
100
|
+
f.should be_dirty
|
101
|
+
f.should be_house_dirty
|
110
102
|
|
111
|
-
|
103
|
+
f.cleanup
|
112
104
|
|
113
|
-
|
114
|
-
|
105
|
+
f.should_not be_dirty
|
106
|
+
f.should be_house_dirty
|
115
107
|
|
116
|
-
|
117
|
-
f = Farm.new
|
118
|
-
f.cleanup(false)
|
108
|
+
f.house_cleanup # the house namespace
|
119
109
|
|
120
|
-
|
121
|
-
|
110
|
+
f.should_not be_dirty
|
111
|
+
f.should_not be_house_dirty
|
112
|
+
end
|
122
113
|
|
123
|
-
|
124
|
-
|
125
|
-
|
114
|
+
it 'should allow saving to be skipped' do
|
115
|
+
f = Farm.new
|
116
|
+
f.cleanup(false)
|
126
117
|
|
127
|
-
|
118
|
+
f.should_not be_persisted
|
119
|
+
end
|
128
120
|
|
129
|
-
|
130
|
-
|
121
|
+
it 'should allow no initial state' do
|
122
|
+
f = Factory.new
|
123
|
+
f.state.should be_nil
|
131
124
|
|
132
|
-
|
133
|
-
u = User.new
|
134
|
-
u.email = "doug@example.com"
|
125
|
+
f.construct.should eql(true)
|
135
126
|
|
136
|
-
|
137
|
-
|
127
|
+
f.state.should eql(:constructed)
|
128
|
+
end
|
138
129
|
|
139
|
-
|
130
|
+
it 'should allow any transition if validations are opted out of' do
|
131
|
+
u.email = 'doug@example.com'
|
140
132
|
|
141
|
-
|
142
|
-
u.
|
143
|
-
u.hyperactivate.should eql(true)
|
144
|
-
end
|
145
|
-
end
|
133
|
+
u.can_hyperactivate?.should eql(false)
|
134
|
+
u.hyperactivate.should eql(false)
|
146
135
|
|
147
|
-
|
148
|
-
u = User.new
|
149
|
-
u.email = "doug@example.com"
|
136
|
+
u.current_state.should eql :pending
|
150
137
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
138
|
+
u.without_state_transition_validations do
|
139
|
+
u.can_hyperactivate?.should eql(true)
|
140
|
+
u.hyperactivate.should eql(true)
|
141
|
+
end
|
155
142
|
end
|
156
143
|
|
157
|
-
|
158
|
-
|
159
|
-
u.activate!
|
160
|
-
u.activated_state_at.should_not be_nil
|
161
|
-
end
|
144
|
+
it 'should skip tracking timestamps if opted out of' do
|
145
|
+
u.email = 'doug@example.com'
|
162
146
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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
|
167
152
|
|
168
|
-
|
169
|
-
|
170
|
-
|
153
|
+
# Make sure that tracking is ensured back to
|
154
|
+
# original value
|
155
|
+
u.activate!
|
156
|
+
u.activated_state_at.should_not be_nil
|
171
157
|
end
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
158
|
+
|
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)
|
163
|
+
|
164
|
+
threads << Thread.new do
|
165
|
+
sleep 0.5
|
166
|
+
nope.semiactivate!
|
176
167
|
end
|
177
|
-
end
|
178
168
|
|
179
|
-
|
169
|
+
threads << Thread.new do
|
170
|
+
skip.without_state_transition_tracking do
|
171
|
+
sleep 1
|
172
|
+
skip.semiactivate!
|
173
|
+
end
|
174
|
+
end
|
180
175
|
|
181
|
-
|
182
|
-
skip.semiactivated_state_at.should be_nil
|
183
|
-
end
|
176
|
+
threads.each(&:join)
|
184
177
|
|
185
|
-
|
186
|
-
|
187
|
-
|
178
|
+
nope.semiactivated_state_at.should_not be_nil
|
179
|
+
skip.semiactivated_state_at.should be_nil
|
180
|
+
end
|
181
|
+
|
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
|
|
@@ -305,11 +301,54 @@ describe Stator::Model do
|
|
305
301
|
z.working_end!
|
306
302
|
z.ended_working_state_at.should be_nil
|
307
303
|
end
|
304
|
+
|
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
|
311
|
+
end
|
312
|
+
|
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)
|
316
|
+
u.state_by?(:activated, t).should be true
|
317
|
+
u.activated_state_by?(t).should be true
|
318
|
+
end
|
319
|
+
|
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
|
325
|
+
end
|
326
|
+
|
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)
|
330
|
+
u.state_by?(:activated, t).should be false
|
331
|
+
u.activated_state_by?(t).should be false
|
332
|
+
end
|
333
|
+
|
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)
|
336
|
+
u.state_by?(:activated, nil).should be true
|
337
|
+
u.activated_state_by?(nil).should be true
|
338
|
+
end
|
339
|
+
|
340
|
+
it 'should be false when both are nil' do
|
341
|
+
u = User.create!(email: 'doug@example.com', activated_state_at: nil)
|
342
|
+
u.state_by?(:activated, nil).should be false
|
343
|
+
u.activated_state_by?(nil).should be false
|
344
|
+
end
|
345
|
+
end
|
308
346
|
end
|
309
347
|
|
310
|
-
describe
|
311
|
-
it
|
312
|
-
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
|
+
|
313
352
|
u.should respond_to(:active?)
|
314
353
|
u.should respond_to(:inactive?)
|
315
354
|
|
@@ -326,26 +365,28 @@ describe Stator::Model do
|
|
326
365
|
u.should be_active
|
327
366
|
u.should_not be_inactive
|
328
367
|
|
329
|
-
User::ACTIVE_STATES.should eql(%
|
330
|
-
User::INACTIVE_STATES.should eql(%
|
368
|
+
User::ACTIVE_STATES.should eql(%i[activated hyperactivated])
|
369
|
+
User::INACTIVE_STATES.should eql(%i[pending deactivated semiactivated])
|
331
370
|
|
332
|
-
User.active.to_sql.gsub(
|
333
|
-
|
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')")
|
334
375
|
end
|
335
376
|
|
336
|
-
it
|
377
|
+
it 'should evaluate inverses correctly' do
|
337
378
|
f = Farm.new
|
338
|
-
f.house_state =
|
379
|
+
f.house_state = 'dirty'
|
339
380
|
f.should_not be_house_cleaned
|
340
381
|
|
341
|
-
f.house_state =
|
382
|
+
f.house_state = 'disgusting'
|
342
383
|
f.should_not be_house_cleaned
|
343
384
|
|
344
|
-
f.house_state =
|
385
|
+
f.house_state = 'clean'
|
345
386
|
f.should be_house_cleaned
|
346
387
|
end
|
347
388
|
|
348
|
-
it
|
389
|
+
it 'should namespace aliases just like everything else' do
|
349
390
|
f = Farm.new
|
350
391
|
f.should respond_to(:house_cleaned?)
|
351
392
|
|
@@ -355,23 +396,23 @@ describe Stator::Model do
|
|
355
396
|
f.should be_house_cleaned
|
356
397
|
end
|
357
398
|
|
358
|
-
it
|
399
|
+
it 'should allow for explicit constant and scope names to be provided' do
|
359
400
|
User.should respond_to(:luke_warmers)
|
360
|
-
(
|
401
|
+
(!defined?(User::LUKE_WARMERS).nil?).should eql(true)
|
361
402
|
u = User.new
|
362
403
|
u.should respond_to(:luke_warm?)
|
363
404
|
end
|
364
405
|
|
365
|
-
it
|
406
|
+
it 'should not create constants or scopes by default' do
|
366
407
|
u = User.new
|
367
408
|
u.should respond_to(:iced_tea?)
|
368
|
-
(
|
409
|
+
(!defined?(User::ICED_TEA_STATES).nil?).should eql(false)
|
369
410
|
User.should_not respond_to(:iced_tea)
|
370
411
|
end
|
371
412
|
|
372
|
-
it
|
373
|
-
states = User._stator(
|
374
|
-
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])
|
375
416
|
end
|
376
417
|
end
|
377
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'
|