acts_as_paranoid 0.4.2 → 0.4.3.pre
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 +7 -0
- data/LICENSE +1 -1
- data/{README.markdown → README.md} +15 -11
- data/lib/acts_as_paranoid.rb +8 -15
- data/lib/acts_as_paranoid/core.rb +14 -6
- data/lib/acts_as_paranoid/relation.rb +2 -2
- data/lib/acts_as_paranoid/version.rb +3 -0
- data/test/test_associations.rb +222 -0
- data/test/test_core.rb +387 -0
- data/test/test_default_scopes.rb +52 -0
- data/test/test_helper.rb +442 -0
- data/test/test_inheritance.rb +14 -0
- data/test/test_observers.rb +16 -0
- data/test/test_relations.rb +117 -0
- data/test/test_validations.rb +42 -0
- metadata +92 -24
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class MultipleDefaultScopesTest < ParanoidBaseTest
|
4
|
+
def setup
|
5
|
+
setup_db
|
6
|
+
|
7
|
+
# Naturally, the default scope for humans is male. Sexism++
|
8
|
+
ParanoidHuman.create! :gender => 'male'
|
9
|
+
ParanoidHuman.create! :gender => 'male'
|
10
|
+
ParanoidHuman.create! :gender => 'male'
|
11
|
+
ParanoidHuman.create! :gender => 'female'
|
12
|
+
|
13
|
+
assert_equal 3, ParanoidHuman.count
|
14
|
+
assert_equal 4, ParanoidHuman.unscoped.count
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_fake_removal_with_multiple_default_scope
|
18
|
+
ParanoidHuman.first.destroy
|
19
|
+
assert_equal 2, ParanoidHuman.count
|
20
|
+
assert_equal 3, ParanoidHuman.with_deleted.count
|
21
|
+
assert_equal 1, ParanoidHuman.only_deleted.count
|
22
|
+
assert_equal 4, ParanoidHuman.unscoped.count
|
23
|
+
|
24
|
+
ParanoidHuman.destroy_all
|
25
|
+
assert_equal 0, ParanoidHuman.count
|
26
|
+
assert_equal 3, ParanoidHuman.with_deleted.count
|
27
|
+
assert_equal 3, ParanoidHuman.with_deleted.count
|
28
|
+
assert_equal 4, ParanoidHuman.unscoped.count
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_real_removal_with_multiple_default_scope
|
32
|
+
# two-step
|
33
|
+
ParanoidHuman.first.destroy
|
34
|
+
ParanoidHuman.only_deleted.first.destroy
|
35
|
+
assert_equal 2, ParanoidHuman.count
|
36
|
+
assert_equal 2, ParanoidHuman.with_deleted.count
|
37
|
+
assert_equal 0, ParanoidHuman.only_deleted.count
|
38
|
+
assert_equal 3, ParanoidHuman.unscoped.count
|
39
|
+
|
40
|
+
ParanoidHuman.first.destroy!
|
41
|
+
assert_equal 1, ParanoidHuman.count
|
42
|
+
assert_equal 1, ParanoidHuman.with_deleted.count
|
43
|
+
assert_equal 0, ParanoidHuman.only_deleted.count
|
44
|
+
assert_equal 2, ParanoidHuman.unscoped.count
|
45
|
+
|
46
|
+
ParanoidHuman.delete_all!
|
47
|
+
assert_equal 0, ParanoidHuman.count
|
48
|
+
assert_equal 0, ParanoidHuman.with_deleted.count
|
49
|
+
assert_equal 0, ParanoidHuman.only_deleted.count
|
50
|
+
assert_equal 1, ParanoidHuman.unscoped.count
|
51
|
+
end
|
52
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,442 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
begin
|
3
|
+
Bundler.require(:default, :development)
|
4
|
+
rescue Bundler::BundlerError => e
|
5
|
+
$stderr.puts e.message
|
6
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
7
|
+
exit e.status_code
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'acts_as_paranoid'
|
11
|
+
require 'minitest/autorun'
|
12
|
+
|
13
|
+
# Silence deprecation halfway through the test
|
14
|
+
I18n.enforce_available_locales = true
|
15
|
+
|
16
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
17
|
+
ActiveRecord::Schema.verbose = false
|
18
|
+
|
19
|
+
def setup_db
|
20
|
+
ActiveRecord::Schema.define(:version => 1) do
|
21
|
+
create_table :paranoid_times do |t|
|
22
|
+
t.string :name
|
23
|
+
t.datetime :deleted_at
|
24
|
+
t.integer :paranoid_belongs_dependant_id
|
25
|
+
t.integer :not_paranoid_id
|
26
|
+
|
27
|
+
t.timestamps
|
28
|
+
end
|
29
|
+
|
30
|
+
create_table :paranoid_booleans do |t|
|
31
|
+
t.string :name
|
32
|
+
t.boolean :is_deleted
|
33
|
+
t.integer :paranoid_time_id
|
34
|
+
|
35
|
+
t.timestamps
|
36
|
+
end
|
37
|
+
|
38
|
+
create_table :paranoid_strings do |t|
|
39
|
+
t.string :name
|
40
|
+
t.string :deleted
|
41
|
+
end
|
42
|
+
|
43
|
+
create_table :not_paranoids do |t|
|
44
|
+
t.string :name
|
45
|
+
t.integer :paranoid_time_id
|
46
|
+
|
47
|
+
t.timestamps
|
48
|
+
end
|
49
|
+
|
50
|
+
create_table :has_one_not_paranoids do |t|
|
51
|
+
t.string :name
|
52
|
+
t.integer :paranoid_time_id
|
53
|
+
|
54
|
+
t.timestamps
|
55
|
+
end
|
56
|
+
|
57
|
+
create_table :paranoid_has_many_dependants do |t|
|
58
|
+
t.string :name
|
59
|
+
t.datetime :deleted_at
|
60
|
+
t.integer :paranoid_time_id
|
61
|
+
t.string :paranoid_time_polymorphic_with_deleted_type
|
62
|
+
t.integer :paranoid_belongs_dependant_id
|
63
|
+
|
64
|
+
t.timestamps
|
65
|
+
end
|
66
|
+
|
67
|
+
create_table :paranoid_belongs_dependants do |t|
|
68
|
+
t.string :name
|
69
|
+
t.datetime :deleted_at
|
70
|
+
|
71
|
+
t.timestamps
|
72
|
+
end
|
73
|
+
|
74
|
+
create_table :paranoid_has_one_dependants do |t|
|
75
|
+
t.string :name
|
76
|
+
t.datetime :deleted_at
|
77
|
+
t.integer :paranoid_boolean_id
|
78
|
+
|
79
|
+
t.timestamps
|
80
|
+
end
|
81
|
+
|
82
|
+
create_table :paranoid_with_callbacks do |t|
|
83
|
+
t.string :name
|
84
|
+
t.datetime :deleted_at
|
85
|
+
|
86
|
+
t.timestamps
|
87
|
+
end
|
88
|
+
|
89
|
+
create_table :paranoid_destroy_companies do |t|
|
90
|
+
t.string :name
|
91
|
+
t.datetime :deleted_at
|
92
|
+
|
93
|
+
t.timestamps
|
94
|
+
end
|
95
|
+
|
96
|
+
create_table :paranoid_delete_companies do |t|
|
97
|
+
t.string :name
|
98
|
+
t.datetime :deleted_at
|
99
|
+
|
100
|
+
t.timestamps
|
101
|
+
end
|
102
|
+
|
103
|
+
create_table :paranoid_products do |t|
|
104
|
+
t.integer :paranoid_destroy_company_id
|
105
|
+
t.integer :paranoid_delete_company_id
|
106
|
+
t.string :name
|
107
|
+
t.datetime :deleted_at
|
108
|
+
|
109
|
+
t.timestamps
|
110
|
+
end
|
111
|
+
|
112
|
+
create_table :super_paranoids do |t|
|
113
|
+
t.string :type
|
114
|
+
t.references :has_many_inherited_super_paranoidz
|
115
|
+
t.datetime :deleted_at
|
116
|
+
|
117
|
+
t.timestamps
|
118
|
+
end
|
119
|
+
|
120
|
+
create_table :has_many_inherited_super_paranoidzs do |t|
|
121
|
+
t.references :super_paranoidz
|
122
|
+
t.datetime :deleted_at
|
123
|
+
|
124
|
+
t.timestamps
|
125
|
+
end
|
126
|
+
|
127
|
+
create_table :paranoid_many_many_parent_lefts do |t|
|
128
|
+
t.string :name
|
129
|
+
t.timestamps
|
130
|
+
end
|
131
|
+
|
132
|
+
create_table :paranoid_many_many_parent_rights do |t|
|
133
|
+
t.string :name
|
134
|
+
t.timestamps
|
135
|
+
end
|
136
|
+
|
137
|
+
create_table :paranoid_many_many_children do |t|
|
138
|
+
t.integer :paranoid_many_many_parent_left_id
|
139
|
+
t.integer :paranoid_many_many_parent_right_id
|
140
|
+
t.datetime :deleted_at
|
141
|
+
t.timestamps
|
142
|
+
end
|
143
|
+
|
144
|
+
create_table :paranoid_with_scoped_validations do |t|
|
145
|
+
t.string :name
|
146
|
+
t.string :category
|
147
|
+
t.datetime :deleted_at
|
148
|
+
t.timestamps
|
149
|
+
end
|
150
|
+
|
151
|
+
create_table :paranoid_forests do |t|
|
152
|
+
t.string :name
|
153
|
+
t.boolean :rainforest
|
154
|
+
t.datetime :deleted_at
|
155
|
+
|
156
|
+
t.timestamps
|
157
|
+
end
|
158
|
+
|
159
|
+
create_table :paranoid_trees do |t|
|
160
|
+
t.integer :paranoid_forest_id
|
161
|
+
t.string :name
|
162
|
+
t.datetime :deleted_at
|
163
|
+
|
164
|
+
t.timestamps
|
165
|
+
end
|
166
|
+
|
167
|
+
create_table :paranoid_humen do |t|
|
168
|
+
t.string :gender
|
169
|
+
t.datetime :deleted_at
|
170
|
+
|
171
|
+
t.timestamps
|
172
|
+
end
|
173
|
+
|
174
|
+
create_table :paranoid_androids do |t|
|
175
|
+
t.datetime :deleted_at
|
176
|
+
end
|
177
|
+
|
178
|
+
create_table :paranoid_sections do |t|
|
179
|
+
t.integer :paranoid_time_id
|
180
|
+
t.integer :paranoid_thing_id
|
181
|
+
t.string :paranoid_thing_type
|
182
|
+
t.datetime :deleted_at
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def teardown_db
|
188
|
+
ActiveRecord::Base.connection.tables.each do |table|
|
189
|
+
ActiveRecord::Base.connection.drop_table(table)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
class ParanoidTime < ActiveRecord::Base
|
194
|
+
acts_as_paranoid
|
195
|
+
|
196
|
+
validates_uniqueness_of :name
|
197
|
+
|
198
|
+
has_many :paranoid_has_many_dependants, :dependent => :destroy
|
199
|
+
has_many :paranoid_booleans, :dependent => :destroy
|
200
|
+
has_many :not_paranoids, :dependent => :delete_all
|
201
|
+
has_many :paranoid_sections, :dependent => :destroy
|
202
|
+
|
203
|
+
has_one :has_one_not_paranoid, :dependent => :destroy
|
204
|
+
|
205
|
+
belongs_to :not_paranoid, :dependent => :destroy
|
206
|
+
end
|
207
|
+
|
208
|
+
class ParanoidBoolean < ActiveRecord::Base
|
209
|
+
acts_as_paranoid :column_type => "boolean", :column => "is_deleted"
|
210
|
+
validates_as_paranoid
|
211
|
+
validates_uniqueness_of_without_deleted :name
|
212
|
+
|
213
|
+
belongs_to :paranoid_time
|
214
|
+
has_one :paranoid_has_one_dependant, :dependent => :destroy
|
215
|
+
end
|
216
|
+
|
217
|
+
class ParanoidString < ActiveRecord::Base
|
218
|
+
acts_as_paranoid :column_type => "string", :column => "deleted", :deleted_value => "dead"
|
219
|
+
end
|
220
|
+
|
221
|
+
class NotParanoid < ActiveRecord::Base
|
222
|
+
end
|
223
|
+
|
224
|
+
class HasOneNotParanoid < ActiveRecord::Base
|
225
|
+
belongs_to :paranoid_time, :with_deleted => true
|
226
|
+
end
|
227
|
+
|
228
|
+
class DoubleHasOneNotParanoid < HasOneNotParanoid
|
229
|
+
belongs_to :paranoid_time, :with_deleted => true
|
230
|
+
belongs_to :paranoid_time, :with_deleted => true
|
231
|
+
end
|
232
|
+
|
233
|
+
class ParanoidHasManyDependant < ActiveRecord::Base
|
234
|
+
acts_as_paranoid
|
235
|
+
belongs_to :paranoid_time
|
236
|
+
belongs_to :paranoid_time_with_deleted, :class_name => 'ParanoidTime', :foreign_key => :paranoid_time_id, :with_deleted => true
|
237
|
+
belongs_to :paranoid_time_polymorphic_with_deleted, :class_name => 'ParanoidTime', :foreign_key => :paranoid_time_id, :polymorphic => true, :with_deleted => true
|
238
|
+
|
239
|
+
belongs_to :paranoid_belongs_dependant, :dependent => :destroy
|
240
|
+
end
|
241
|
+
|
242
|
+
class ParanoidBelongsDependant < ActiveRecord::Base
|
243
|
+
acts_as_paranoid
|
244
|
+
|
245
|
+
has_many :paranoid_has_many_dependants
|
246
|
+
end
|
247
|
+
|
248
|
+
class ParanoidHasOneDependant < ActiveRecord::Base
|
249
|
+
acts_as_paranoid
|
250
|
+
|
251
|
+
belongs_to :paranoid_boolean
|
252
|
+
end
|
253
|
+
|
254
|
+
class ParanoidWithCallback < ActiveRecord::Base
|
255
|
+
acts_as_paranoid
|
256
|
+
|
257
|
+
attr_accessor :called_before_destroy, :called_after_destroy, :called_after_commit_on_destroy
|
258
|
+
attr_accessor :called_before_recover, :called_after_recover
|
259
|
+
|
260
|
+
before_destroy :call_me_before_destroy
|
261
|
+
after_destroy :call_me_after_destroy
|
262
|
+
|
263
|
+
after_commit :call_me_after_commit_on_destroy, :on => :destroy
|
264
|
+
|
265
|
+
before_recover :call_me_before_recover
|
266
|
+
after_recover :call_me_after_recover
|
267
|
+
|
268
|
+
def initialize(*attrs)
|
269
|
+
@called_before_destroy = @called_after_destroy = @called_after_commit_on_destroy = false
|
270
|
+
super(*attrs)
|
271
|
+
end
|
272
|
+
|
273
|
+
def call_me_before_destroy
|
274
|
+
@called_before_destroy = true
|
275
|
+
end
|
276
|
+
|
277
|
+
def call_me_after_destroy
|
278
|
+
@called_after_destroy = true
|
279
|
+
end
|
280
|
+
|
281
|
+
def call_me_after_commit_on_destroy
|
282
|
+
@called_after_commit_on_destroy = true
|
283
|
+
end
|
284
|
+
|
285
|
+
def call_me_before_recover
|
286
|
+
@called_before_recover = true
|
287
|
+
end
|
288
|
+
|
289
|
+
def call_me_after_recover
|
290
|
+
@called_after_recover = true
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
class ParanoidDestroyCompany < ActiveRecord::Base
|
295
|
+
acts_as_paranoid
|
296
|
+
validates :name, :presence => true
|
297
|
+
has_many :paranoid_products, :dependent => :destroy
|
298
|
+
end
|
299
|
+
|
300
|
+
class ParanoidDeleteCompany < ActiveRecord::Base
|
301
|
+
acts_as_paranoid
|
302
|
+
validates :name, :presence => true
|
303
|
+
has_many :paranoid_products, :dependent => :delete_all
|
304
|
+
end
|
305
|
+
|
306
|
+
class ParanoidProduct < ActiveRecord::Base
|
307
|
+
acts_as_paranoid
|
308
|
+
belongs_to :paranoid_destroy_company
|
309
|
+
belongs_to :paranoid_delete_company
|
310
|
+
validates_presence_of :name
|
311
|
+
end
|
312
|
+
|
313
|
+
class SuperParanoid < ActiveRecord::Base
|
314
|
+
acts_as_paranoid
|
315
|
+
belongs_to :has_many_inherited_super_paranoidz
|
316
|
+
end
|
317
|
+
|
318
|
+
class HasManyInheritedSuperParanoidz < ActiveRecord::Base
|
319
|
+
has_many :super_paranoidz, :class_name => "InheritedParanoid", :dependent => :destroy
|
320
|
+
end
|
321
|
+
|
322
|
+
class InheritedParanoid < SuperParanoid
|
323
|
+
acts_as_paranoid
|
324
|
+
end
|
325
|
+
|
326
|
+
class ParanoidObserver < ActiveRecord::Observer
|
327
|
+
observe :paranoid_with_callback
|
328
|
+
|
329
|
+
attr_accessor :called_before_recover, :called_after_recover
|
330
|
+
|
331
|
+
def before_recover(paranoid_object)
|
332
|
+
self.called_before_recover = paranoid_object
|
333
|
+
end
|
334
|
+
|
335
|
+
def after_recover(paranoid_object)
|
336
|
+
self.called_after_recover = paranoid_object
|
337
|
+
end
|
338
|
+
|
339
|
+
def reset
|
340
|
+
self.called_before_recover = nil
|
341
|
+
self.called_after_recover = nil
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
|
346
|
+
class ParanoidManyManyParentLeft < ActiveRecord::Base
|
347
|
+
has_many :paranoid_many_many_children
|
348
|
+
has_many :paranoid_many_many_parent_rights, :through => :paranoid_many_many_children
|
349
|
+
end
|
350
|
+
|
351
|
+
class ParanoidManyManyParentRight < ActiveRecord::Base
|
352
|
+
has_many :paranoid_many_many_children
|
353
|
+
has_many :paranoid_many_many_parent_lefts, :through => :paranoid_many_many_children
|
354
|
+
end
|
355
|
+
|
356
|
+
class ParanoidManyManyChild < ActiveRecord::Base
|
357
|
+
acts_as_paranoid
|
358
|
+
belongs_to :paranoid_many_many_parent_left
|
359
|
+
belongs_to :paranoid_many_many_parent_right
|
360
|
+
end
|
361
|
+
|
362
|
+
class ParanoidWithScopedValidation < ActiveRecord::Base
|
363
|
+
acts_as_paranoid
|
364
|
+
validates_uniqueness_of :name, :scope => :category
|
365
|
+
end
|
366
|
+
|
367
|
+
ParanoidWithCallback.add_observer(ParanoidObserver.instance)
|
368
|
+
|
369
|
+
class ParanoidBaseTest < ActiveSupport::TestCase
|
370
|
+
def setup
|
371
|
+
setup_db
|
372
|
+
|
373
|
+
["paranoid", "really paranoid", "extremely paranoid"].each do |name|
|
374
|
+
ParanoidTime.create! :name => name
|
375
|
+
ParanoidBoolean.create! :name => name
|
376
|
+
end
|
377
|
+
|
378
|
+
ParanoidString.create! :name => "strings can be paranoid"
|
379
|
+
NotParanoid.create! :name => "no paranoid goals"
|
380
|
+
ParanoidWithCallback.create! :name => "paranoid with callbacks"
|
381
|
+
|
382
|
+
ParanoidObserver.instance.reset
|
383
|
+
end
|
384
|
+
|
385
|
+
def teardown
|
386
|
+
teardown_db
|
387
|
+
end
|
388
|
+
|
389
|
+
def assert_empty(collection)
|
390
|
+
assert(collection.respond_to?(:empty?) && collection.empty?)
|
391
|
+
end
|
392
|
+
|
393
|
+
def assert_paranoid_deletion(model)
|
394
|
+
row = find_row(model)
|
395
|
+
assert_not_nil row, "#{model.class} entirely deleted"
|
396
|
+
assert_not_nil row["deleted_at"], "Deleted at not set"
|
397
|
+
end
|
398
|
+
|
399
|
+
def assert_non_paranoid_deletion(model)
|
400
|
+
row = find_row(model)
|
401
|
+
assert_nil row, "#{model.class} still exists"
|
402
|
+
end
|
403
|
+
|
404
|
+
def find_row(model)
|
405
|
+
sql = "select deleted_at from #{model.class.table_name} where id = #{model.id}"
|
406
|
+
# puts sql here if you want to debug
|
407
|
+
model.class.connection.select_one(sql)
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
class ParanoidForest < ActiveRecord::Base
|
412
|
+
acts_as_paranoid
|
413
|
+
|
414
|
+
# HACK: scope throws an error on 1.8.7 because the logger isn't initialized (see https://github.com/Casecommons/pg_search/issues/26)
|
415
|
+
require "active_support/core_ext/logger.rb"
|
416
|
+
ActiveRecord::Base.logger = Logger.new(StringIO.new)
|
417
|
+
|
418
|
+
scope :rainforest, where(:rainforest => true)
|
419
|
+
|
420
|
+
has_many :paranoid_trees, :dependent => :destroy
|
421
|
+
end
|
422
|
+
|
423
|
+
class ParanoidTree < ActiveRecord::Base
|
424
|
+
acts_as_paranoid
|
425
|
+
belongs_to :paranoid_forest
|
426
|
+
validates_presence_of :name
|
427
|
+
end
|
428
|
+
|
429
|
+
class ParanoidHuman < ActiveRecord::Base
|
430
|
+
acts_as_paranoid
|
431
|
+
default_scope where('gender = ?', 'male')
|
432
|
+
end
|
433
|
+
|
434
|
+
class ParanoidAndroid < ActiveRecord::Base
|
435
|
+
acts_as_paranoid
|
436
|
+
end
|
437
|
+
|
438
|
+
class ParanoidSection < ActiveRecord::Base
|
439
|
+
acts_as_paranoid
|
440
|
+
belongs_to :paranoid_time
|
441
|
+
belongs_to :paranoid_thing, :polymorphic => true, :dependent => :destroy
|
442
|
+
end
|