stator 0.8.0 → 0.9.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/lib/stator/integration.rb +1 -1
- data/lib/stator/version.rb +1 -1
- data/stator.gemspec +6 -2
- metadata +6 -36
- data/.github/CODEOWNERS +0 -1
- data/.github/dependabot.yml +0 -24
- data/.github/workflows/build.yml +0 -23
- data/.gitignore +0 -17
- data/.rspec +0 -2
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/Appraisals +0 -26
- data/Gemfile +0 -10
- data/LICENSE.txt +0 -22
- data/README.md +0 -230
- data/Rakefile +0 -9
- data/gemfiles/activerecord_6.0.gemfile +0 -12
- data/gemfiles/activerecord_6.0.gemfile.lock +0 -102
- data/gemfiles/activerecord_6.1.gemfile +0 -12
- data/gemfiles/activerecord_6.1.gemfile.lock +0 -100
- data/gemfiles/activerecord_7.0.gemfile +0 -12
- data/gemfiles/activerecord_7.0.gemfile.lock +0 -97
- data/gemfiles/activerecord_7.1.gemfile +0 -11
- data/gemfiles/activerecord_7.1.gemfile.lock +0 -114
- data/gemfiles/activerecord_7.2.gemfile +0 -11
- data/gemfiles/activerecord_7.2.gemfile.lock +0 -113
- data/gemfiles/activerecord_8.0.gemfile +0 -11
- data/gemfiles/activerecord_8.0.gemfile.lock +0 -116
- data/spec/model_spec.rb +0 -533
- data/spec/spec_helper.rb +0 -34
- data/spec/support/models.rb +0 -226
- data/spec/support/schema.rb +0 -55
data/spec/model_spec.rb
DELETED
@@ -1,533 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
describe Stator::Model do
|
6
|
-
|
7
|
-
it "should set the default state after initialization" do
|
8
|
-
u = User.new
|
9
|
-
u.state.should eql("pending")
|
10
|
-
end
|
11
|
-
|
12
|
-
it "should see the initial setting of the state as a change with the initial state as the previous value" do
|
13
|
-
u = User.new
|
14
|
-
u.state = "activated"
|
15
|
-
u.state_in_database.should eql("pending")
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should not obstruct normal validations" do
|
19
|
-
u = User.new
|
20
|
-
u.should_not be_valid
|
21
|
-
u.errors[:email].grep(/length/).should_not be_empty
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should ensure a valid state transition when given a bogus state" do
|
25
|
-
u = User.new
|
26
|
-
u.state = "anythingelse"
|
27
|
-
|
28
|
-
u.should_not be_valid
|
29
|
-
u.errors[:state].should eql(["is not a valid state"])
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should allow creation at any state" do
|
33
|
-
u = User.new(email: "doug@example.com")
|
34
|
-
u.state = "hyperactivated"
|
35
|
-
|
36
|
-
u.should be_valid
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should work normally with active_record dirty methods" do
|
40
|
-
u = User.new(email: "doug@example.com")
|
41
|
-
|
42
|
-
u.will_save_change_to_state?.should_not be true
|
43
|
-
u.state_in_database.should eq("pending")
|
44
|
-
u.state_before_last_save.should be nil
|
45
|
-
|
46
|
-
u.state = "hyperactivated"
|
47
|
-
|
48
|
-
u.will_save_change_to_state?.should be true
|
49
|
-
u.state_in_database.should eq("pending")
|
50
|
-
u.state_before_last_save.should be nil
|
51
|
-
|
52
|
-
u.save!
|
53
|
-
|
54
|
-
u.will_save_change_to_state?.should_not be true
|
55
|
-
u.state_in_database.should eq("hyperactivated")
|
56
|
-
u.state_before_last_save.should eq("pending")
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should ensure a valid state transition when given an illegal state based on the current state" do
|
60
|
-
u = User.new
|
61
|
-
|
62
|
-
allow(u).to receive(:new_record?).and_return(false)
|
63
|
-
|
64
|
-
u.state = "hyperactivated"
|
65
|
-
|
66
|
-
u.should_not be_valid
|
67
|
-
u.errors[:state].should_not be_empty
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should not allow a transition that is currently in a `to` state" do
|
71
|
-
u = User.new(email: "fred@example.com")
|
72
|
-
u.activate!
|
73
|
-
u.hyperactivate!
|
74
|
-
|
75
|
-
lambda {
|
76
|
-
u.hyperactivate!
|
77
|
-
}.should raise_error(/cannot transition to \"hyperactivated\" from \"hyperactivated\"/)
|
78
|
-
end
|
79
|
-
|
80
|
-
it "should run conditional validations" do
|
81
|
-
u = User.new
|
82
|
-
u.state = "semiactivated"
|
83
|
-
u.should_not be_valid
|
84
|
-
|
85
|
-
u.errors[:state].should be_empty
|
86
|
-
u.errors[:email].grep(/format/).should_not be_empty
|
87
|
-
end
|
88
|
-
|
89
|
-
it "should invoke callbacks" do
|
90
|
-
u = User.new(activated: true, email: "doug@example.com", name: "doug")
|
91
|
-
u.activated.should == true
|
92
|
-
|
93
|
-
u.deactivate
|
94
|
-
|
95
|
-
u.activated.should == false
|
96
|
-
u.state.should eql("deactivated")
|
97
|
-
u.activated_state_at.should be_nil
|
98
|
-
u.should be_persisted
|
99
|
-
end
|
100
|
-
|
101
|
-
it "should conditionally invoke after_save callbacks when use_previous is true" do
|
102
|
-
u = User.new
|
103
|
-
u.email = "doug@example.com"
|
104
|
-
|
105
|
-
u.semiactivate!
|
106
|
-
|
107
|
-
u.state.should eql("semiactivated")
|
108
|
-
u.activation_notification_published.should_not be true
|
109
|
-
|
110
|
-
u.activate!
|
111
|
-
|
112
|
-
u.state.should eql("activated")
|
113
|
-
u.activation_notification_published.should be true
|
114
|
-
end
|
115
|
-
|
116
|
-
it "should blow up if the record is invalid and a bang method is used" do
|
117
|
-
u = User.new(email: "doug@other.com", name: "doug")
|
118
|
-
lambda {
|
119
|
-
u.activate!
|
120
|
-
}.should raise_error(ActiveRecord::RecordInvalid)
|
121
|
-
end
|
122
|
-
|
123
|
-
it "should allow for other fields to be used other than state" do
|
124
|
-
a = Animal.new
|
125
|
-
a.should be_valid
|
126
|
-
|
127
|
-
a.birth!
|
128
|
-
end
|
129
|
-
|
130
|
-
it "should create implicit transitions for state declarations" do
|
131
|
-
a = Animal.new
|
132
|
-
a.should_not be_grown_up
|
133
|
-
a.status = "grown_up"
|
134
|
-
a.save
|
135
|
-
end
|
136
|
-
|
137
|
-
it "should allow multiple machines in the same model" do
|
138
|
-
f = Farm.new
|
139
|
-
f.should be_dirty
|
140
|
-
f.should be_house_dirty
|
141
|
-
|
142
|
-
f.cleanup
|
143
|
-
|
144
|
-
f.should_not be_dirty
|
145
|
-
f.should be_house_dirty
|
146
|
-
|
147
|
-
f.house_cleanup
|
148
|
-
|
149
|
-
f.should_not be_house_dirty
|
150
|
-
end
|
151
|
-
|
152
|
-
it "should allow saving to be skipped" do
|
153
|
-
f = Farm.new
|
154
|
-
f.cleanup(false)
|
155
|
-
|
156
|
-
f.should_not be_persisted
|
157
|
-
end
|
158
|
-
|
159
|
-
it "should allow no initial state" do
|
160
|
-
f = Factory.new
|
161
|
-
f.state.should be_nil
|
162
|
-
|
163
|
-
f.construct.should eql(true)
|
164
|
-
|
165
|
-
f.state.should eql("constructed")
|
166
|
-
end
|
167
|
-
|
168
|
-
it "should allow any transition if validations are opted out of" do
|
169
|
-
u = User.new
|
170
|
-
u.email = "doug@example.com"
|
171
|
-
|
172
|
-
u.can_hyperactivate?.should eql(false)
|
173
|
-
u.hyperactivate.should eql(false)
|
174
|
-
|
175
|
-
u.state.should eql("pending")
|
176
|
-
|
177
|
-
u.without_state_transition_validations do
|
178
|
-
u.can_hyperactivate?.should eql(true)
|
179
|
-
u.hyperactivate.should eql(true)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should skip tracking timestamps if opted out of" do
|
184
|
-
u = User.new
|
185
|
-
u.email = "doug@example.com"
|
186
|
-
|
187
|
-
u.without_state_transition_tracking do
|
188
|
-
u.semiactivate!
|
189
|
-
u.state.should eql("semiactivated")
|
190
|
-
u.semiactivated_state_at.should be_nil
|
191
|
-
end
|
192
|
-
|
193
|
-
# Make sure that tracking is ensured back to
|
194
|
-
# original value
|
195
|
-
u.activate!
|
196
|
-
u.activated_state_at.should_not be_nil
|
197
|
-
end
|
198
|
-
|
199
|
-
it "should skip tracking timestamps if opted out of with thread safety" do
|
200
|
-
threads = []
|
201
|
-
skip = User.new(email: "skip@example.com")
|
202
|
-
nope = User.new(email: "nope@example.com")
|
203
|
-
|
204
|
-
threads << Thread.new do
|
205
|
-
sleep 0.5
|
206
|
-
nope.semiactivate!
|
207
|
-
end
|
208
|
-
threads << Thread.new do
|
209
|
-
skip.without_state_transition_tracking do
|
210
|
-
sleep 1
|
211
|
-
skip.semiactivate!
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
threads.each(&:join)
|
216
|
-
|
217
|
-
nope.semiactivated_state_at.should_not be_nil
|
218
|
-
skip.semiactivated_state_at.should be_nil
|
219
|
-
end
|
220
|
-
|
221
|
-
it "should not inherit _integration cache on dup" do
|
222
|
-
u = User.new(email: "user@example.com")
|
223
|
-
u.save!
|
224
|
-
|
225
|
-
u_duped = u.dup
|
226
|
-
|
227
|
-
u.semiactivate!
|
228
|
-
|
229
|
-
u_duped_integration = u_duped.send(:_integration)
|
230
|
-
|
231
|
-
u_duped_integration.state.should_not eql(u.state)
|
232
|
-
u_duped_integration.instance_values["record"].should eq(u_duped)
|
233
|
-
end
|
234
|
-
|
235
|
-
describe "helper methods" do
|
236
|
-
it "should answer the question of whether the state is currently the one invoked" do
|
237
|
-
a = Animal.new
|
238
|
-
a.should be_unborn
|
239
|
-
a.should_not be_born
|
240
|
-
|
241
|
-
a.birth
|
242
|
-
|
243
|
-
a.should be_born
|
244
|
-
a.should_not be_unborn
|
245
|
-
end
|
246
|
-
|
247
|
-
it "should determine if it can validly execute a transition" do
|
248
|
-
a = Animal.new
|
249
|
-
a.can_birth?.should eql(true)
|
250
|
-
|
251
|
-
a.birth
|
252
|
-
|
253
|
-
a.can_birth?.should eql(false)
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
it "should validate state transitions using the db state after a transaction rollback" do
|
258
|
-
is_active_record_6_or_higher = Gem::Requirement.new(">= 6.0").satisfied_by?(ActiveRecord.version)
|
259
|
-
|
260
|
-
u = User.create!(email: 'doug@example.com')
|
261
|
-
u.state.should eql('pending')
|
262
|
-
|
263
|
-
lambda {
|
264
|
-
ActiveRecord::Base.transaction do
|
265
|
-
# The state change will be applied to the model object in memory.
|
266
|
-
# An UPDATE query will be sent to the db, but it will be rolled back
|
267
|
-
# when the error is raised below.
|
268
|
-
u.activate!
|
269
|
-
raise "Some error"
|
270
|
-
end
|
271
|
-
}.should raise_error("Some error")
|
272
|
-
|
273
|
-
u.state.should eql("activated")
|
274
|
-
|
275
|
-
# Rails 6.0 fixed a bug where a model's dirty state would be incorrect
|
276
|
-
# in a scenario like this one, where a model is updated within a transaction,
|
277
|
-
# and the transaction is then rolled back:
|
278
|
-
#
|
279
|
-
# https://github.com/rails/rails/pull/35987
|
280
|
-
#
|
281
|
-
# We show this dirty behavior change in Rails 6.0 below to clarify why stator itself
|
282
|
-
# behaves differently starting in Rails 6.0.
|
283
|
-
if is_active_record_6_or_higher
|
284
|
-
# On Rails 6.0 or higher, attribute_in_database is "pending" — which is correct,
|
285
|
-
# because the db transaction was rolled back.
|
286
|
-
u.attribute_in_database("state").should eql("pending")
|
287
|
-
|
288
|
-
# Attempting a state change to "hyperactivated" fails, which is correct,
|
289
|
-
# because the previous state change to "activated" did not succeed.
|
290
|
-
lambda {
|
291
|
-
u.hyperactivate!
|
292
|
-
}.should raise_error(ActiveRecord::RecordInvalid, 'Validation failed: State cannot transition to "hyperactivated" from "pending"')
|
293
|
-
else
|
294
|
-
# On Rails < 6.0, attribute_in_database is "activated" — which is incorrect,
|
295
|
-
# because the db transaction was rolled back.
|
296
|
-
u.attribute_in_database("state").should eql("activated")
|
297
|
-
|
298
|
-
# On Rails < 6.0, stator incorrectly allows the state change to "hyperactivated"
|
299
|
-
# because it incorrectly thinks the state has been successfully updated to "activated".
|
300
|
-
lambda {
|
301
|
-
u.hyperactivate!
|
302
|
-
}.should_not raise_error
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
|
-
it "should not support multiple state changes made between saves" do
|
307
|
-
u = User.create!(email: "doug@example.com")
|
308
|
-
u.state.should eql("pending")
|
309
|
-
|
310
|
-
u.activate(false) # change state, but do not save to db
|
311
|
-
u.state.should eql("activated")
|
312
|
-
|
313
|
-
lambda {
|
314
|
-
# Fails because the db state is still "pending", and
|
315
|
-
# the db state is what stator uses for the "previous" state
|
316
|
-
# to check that the state transition is valid.
|
317
|
-
u.hyperactivate!
|
318
|
-
}.should raise_error(ActiveRecord::RecordInvalid, 'Validation failed: State cannot transition to "hyperactivated" from "pending"')
|
319
|
-
|
320
|
-
# The model is updated in-memory with the new state value,
|
321
|
-
# but remains invalid.
|
322
|
-
u.state.should eql("hyperactivated")
|
323
|
-
u.valid?.should be false
|
324
|
-
end
|
325
|
-
|
326
|
-
describe "tracker methods" do
|
327
|
-
before do
|
328
|
-
Time.zone = "Eastern Time (US & Canada)"
|
329
|
-
end
|
330
|
-
|
331
|
-
it "should store the initial state timestamp when the record is created" do
|
332
|
-
a = Animal.new
|
333
|
-
a.save
|
334
|
-
a.unborn_status_at.should be_within(1).of(Time.zone.now)
|
335
|
-
end
|
336
|
-
|
337
|
-
it "should store when a record changed state for the first time" do
|
338
|
-
a = Animal.new
|
339
|
-
a.unborn_status_at.should be_nil
|
340
|
-
a.born_status_at.should be_nil
|
341
|
-
a.birth
|
342
|
-
a.unborn_status_at.should be_nil
|
343
|
-
a.born_status_at.should be_within(1).of(Time.zone.now)
|
344
|
-
end
|
345
|
-
|
346
|
-
it "should store when a record change states" do
|
347
|
-
a = Animal.new
|
348
|
-
a.status_changed_at.should be_nil
|
349
|
-
|
350
|
-
a.birth
|
351
|
-
|
352
|
-
a.status_changed_at.should be_within(1).of(Time.zone.now)
|
353
|
-
|
354
|
-
previous_status_changed_at = a.status_changed_at
|
355
|
-
|
356
|
-
a.name = "new name"
|
357
|
-
a.save
|
358
|
-
|
359
|
-
a.status_changed_at.should eql(previous_status_changed_at)
|
360
|
-
end
|
361
|
-
|
362
|
-
it "should prepend the setting of the timestamp so other callbacks can use it" do
|
363
|
-
u = User.new
|
364
|
-
u.email = "doug@example.com"
|
365
|
-
|
366
|
-
u.tagged_at.should be_nil
|
367
|
-
u.semiactivate!
|
368
|
-
|
369
|
-
u.semiactivated_state_at.should_not be_nil
|
370
|
-
u.tagged_at.should_not be_nil
|
371
|
-
end
|
372
|
-
|
373
|
-
it "should respect the timestamp if explicitly provided" do
|
374
|
-
t = Time.at(Time.now.to_i - 3600)
|
375
|
-
|
376
|
-
u = User.new
|
377
|
-
u.email = "doug@example.com"
|
378
|
-
u.state = "semiactivated"
|
379
|
-
u.semiactivated_state_at = t
|
380
|
-
u.save!
|
381
|
-
|
382
|
-
u.state.should eql("semiactivated")
|
383
|
-
u.semiactivated_state_at.should eql(t)
|
384
|
-
end
|
385
|
-
|
386
|
-
it "should respect the timestamp if explicitly provided via create" do
|
387
|
-
t = Time.at(Time.now.to_i - 3600)
|
388
|
-
|
389
|
-
u = User.create!(
|
390
|
-
email: "doug@example.com",
|
391
|
-
state: "semiactivated",
|
392
|
-
semiactivated_state_at: t
|
393
|
-
)
|
394
|
-
|
395
|
-
u.state.should eql("semiactivated")
|
396
|
-
u.semiactivated_state_at.should eql(t)
|
397
|
-
end
|
398
|
-
|
399
|
-
it "should allow opting into track by namespace" do
|
400
|
-
z = ZooKeeper.new(name: "Doug")
|
401
|
-
z.employment_state.should eql("hired")
|
402
|
-
z.employment_fire!
|
403
|
-
z.fired_employment_state_at.should_not be_nil
|
404
|
-
|
405
|
-
z.employment_hire!
|
406
|
-
z.hired_employment_state_at.should_not be_nil
|
407
|
-
|
408
|
-
z.working_start!
|
409
|
-
z.started_working_state_at.should be_nil
|
410
|
-
z.working_end!
|
411
|
-
z.ended_working_state_at.should be_nil
|
412
|
-
end
|
413
|
-
|
414
|
-
describe "#state_by?" do
|
415
|
-
it "should be true when the transition is earlier" do
|
416
|
-
t = Time.now
|
417
|
-
u = User.create!( email: "doug@example.com", activated_state_at: t)
|
418
|
-
u.state_by?(:activated, Time.at(t.to_i + 1)).should be true
|
419
|
-
u.activated_state_by?(Time.at(t.to_i + 1)).should be true
|
420
|
-
end
|
421
|
-
|
422
|
-
it "should be true when the transition is at the same time" do
|
423
|
-
t = Time.now
|
424
|
-
u = User.create!( email: "doug@example.com", activated_state_at: t)
|
425
|
-
u.state_by?(:activated, t).should be true
|
426
|
-
u.activated_state_by?(t).should be true
|
427
|
-
end
|
428
|
-
|
429
|
-
it "should be false when the transition is later" do
|
430
|
-
t = Time.now
|
431
|
-
u = User.create!( email: "doug@example.com", activated_state_at: t)
|
432
|
-
u.state_by?(:activated, Time.at(t.to_i - 1)).should be false
|
433
|
-
u.activated_state_by?(Time.at(t.to_i - 1)).should be false
|
434
|
-
end
|
435
|
-
|
436
|
-
it "should be false when the transition is nil" do
|
437
|
-
t = Time.now
|
438
|
-
u = User.create!( email: "doug@example.com", activated_state_at: nil)
|
439
|
-
u.state_by?(:activated, t).should be false
|
440
|
-
u.activated_state_by?(t).should be false
|
441
|
-
end
|
442
|
-
|
443
|
-
it "should be true when the transition is not nil and the time is nil" do
|
444
|
-
u = User.create!( email: "doug@example.com", activated_state_at: Time.now)
|
445
|
-
u.state_by?(:activated, nil).should be true
|
446
|
-
u.activated_state_by?(nil).should be true
|
447
|
-
end
|
448
|
-
|
449
|
-
it "should be false when both are nil" do
|
450
|
-
u = User.create!(email: "doug@example.com", activated_state_at: nil)
|
451
|
-
u.state_by?(:activated, nil).should be false
|
452
|
-
u.activated_state_by?(nil).should be false
|
453
|
-
end
|
454
|
-
end
|
455
|
-
end
|
456
|
-
|
457
|
-
describe "aliasing" do
|
458
|
-
it "should allow aliasing within the dsl" do
|
459
|
-
u = User.new(email: "doug@example.com")
|
460
|
-
u.should respond_to(:active?)
|
461
|
-
u.should respond_to(:inactive?)
|
462
|
-
|
463
|
-
u.should_not be_active
|
464
|
-
|
465
|
-
u.inactive?
|
466
|
-
u.should be_inactive
|
467
|
-
|
468
|
-
u.activate!
|
469
|
-
u.should be_active
|
470
|
-
u.should_not be_inactive
|
471
|
-
|
472
|
-
u.hyperactivate!
|
473
|
-
u.should be_active
|
474
|
-
u.should_not be_inactive
|
475
|
-
|
476
|
-
User::ACTIVE_STATES.should eql(%w[activated hyperactivated])
|
477
|
-
User::INACTIVE_STATES.should eql(%w[pending deactivated semiactivated])
|
478
|
-
|
479
|
-
is_active_record_72_or_higher = Gem::Requirement.new(">= 7.2").satisfied_by?(ActiveRecord.version)
|
480
|
-
|
481
|
-
if (is_active_record_72_or_higher)
|
482
|
-
User.active.to_sql.gsub(" ", " ").should eq("SELECT 'users'.* FROM 'users' WHERE 'users'.'state' IN ('activated', 'hyperactivated')")
|
483
|
-
User.inactive.to_sql.gsub(" ", " ").should eq("SELECT 'users'.* FROM 'users' WHERE 'users'.'state' IN ('pending', 'deactivated', 'semiactivated')")
|
484
|
-
else
|
485
|
-
User.active.to_sql.gsub(" ", " ").should eq("SELECT users.* FROM users WHERE users.state IN ('activated', 'hyperactivated')")
|
486
|
-
User.inactive.to_sql.gsub(" ", " ").should eq("SELECT users.* FROM users WHERE users.state IN ('pending', 'deactivated', 'semiactivated')")
|
487
|
-
end
|
488
|
-
|
489
|
-
end
|
490
|
-
|
491
|
-
it "should evaluate inverses correctly" do
|
492
|
-
f = Farm.new
|
493
|
-
f.house_state = "dirty"
|
494
|
-
f.should_not be_house_cleaned
|
495
|
-
|
496
|
-
f.house_state = "disgusting"
|
497
|
-
f.should_not be_house_cleaned
|
498
|
-
|
499
|
-
f.house_state = "clean"
|
500
|
-
f.should be_house_cleaned
|
501
|
-
end
|
502
|
-
|
503
|
-
it "should namespace aliases just like everything else" do
|
504
|
-
f = Farm.new
|
505
|
-
f.should respond_to(:house_cleaned?)
|
506
|
-
|
507
|
-
f.should_not be_house_cleaned
|
508
|
-
f.house_cleanup!
|
509
|
-
|
510
|
-
f.should be_house_cleaned
|
511
|
-
end
|
512
|
-
|
513
|
-
it "should allow for explicit constant and scope names to be provided" do
|
514
|
-
User.should respond_to(:luke_warmers)
|
515
|
-
(!!defined?(User::LUKE_WARMERS)).should eql(true)
|
516
|
-
u = User.new
|
517
|
-
u.should respond_to(:luke_warm?)
|
518
|
-
end
|
519
|
-
|
520
|
-
it "should not create constants or scopes by default" do
|
521
|
-
u = User.new
|
522
|
-
u.should respond_to(:iced_tea?)
|
523
|
-
(!!defined?(User::ICED_TEA_STATES)).should eql(false)
|
524
|
-
User.should_not respond_to(:iced_tea)
|
525
|
-
end
|
526
|
-
|
527
|
-
it "should determine the full list of states correctly" do
|
528
|
-
states = User._stator("").states
|
529
|
-
states.should eql(%w[pending activated deactivated semiactivated hyperactivated])
|
530
|
-
end
|
531
|
-
end
|
532
|
-
|
533
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
-
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
-
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
-
# loaded once.
|
5
|
-
#
|
6
|
-
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
-
|
8
|
-
require 'active_record'
|
9
|
-
require 'nulldb/core'
|
10
|
-
require 'active_support/core_ext'
|
11
|
-
require 'stator'
|
12
|
-
|
13
|
-
RSpec.configure do |config|
|
14
|
-
config.expect_with(:rspec) { |c| c.syntax = :should }
|
15
|
-
config.run_all_when_everything_filtered = true
|
16
|
-
config.filter_run :focus
|
17
|
-
|
18
|
-
NullDB.configure do |c|
|
19
|
-
c.project_root = File.dirname(__FILE__)
|
20
|
-
end
|
21
|
-
|
22
|
-
ActiveRecord::Base.establish_connection(
|
23
|
-
:adapter => :nulldb,
|
24
|
-
:schema => 'support/schema.rb'
|
25
|
-
)
|
26
|
-
|
27
|
-
require 'support/models'
|
28
|
-
|
29
|
-
# Run specs in random order to surface order dependencies. If you find an
|
30
|
-
# order dependency and want to debug it, you can fix the order by providing
|
31
|
-
# the seed, which is printed after each run.
|
32
|
-
# --seed 1234
|
33
|
-
config.order = 'random'
|
34
|
-
end
|