acts_as_paranoid 0.6.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActsAsParanoid
2
4
  module Relation
3
5
  def self.included(base)
@@ -28,6 +30,13 @@ module ActsAsParanoid
28
30
  end
29
31
 
30
32
  def destroy!(id_or_array)
33
+ destroy_fully! id_or_array
34
+ end
35
+
36
+ deprecate :destroy!,
37
+ deprecator: ActiveSupport::Deprecation.new("0.8.0", "ActsAsParanoid")
38
+
39
+ def destroy_fully!(id_or_array)
31
40
  where(primary_key => id_or_array).orig_delete_all
32
41
  end
33
42
  end
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/array/wrap'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/wrap"
2
4
 
3
5
  module ActsAsParanoid
4
6
  module Validations
@@ -6,85 +8,17 @@ module ActsAsParanoid
6
8
  base.extend ClassMethods
7
9
  end
8
10
 
9
- class UniquenessWithoutDeletedValidator
10
- def self.[](version)
11
- name = "V#{version.to_s.tr('.', '_')}"
12
- unless constants.include? name.to_sym
13
- raise "Unknown validator version #{name.inspect}; expected one of #{constants.sort.join(', ')}"
14
- end
15
- const_get name
16
- end
17
-
18
- class V5 < ActiveRecord::Validations::UniquenessValidator
19
- def validate_each(record, attribute, value)
20
- finder_class = find_finder_class_for(record)
21
- table = finder_class.arel_table
22
-
23
- relation = build_relation(finder_class, attribute, value)
24
- [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value|
25
- relation = relation.where(table[pk_key.to_sym].not_eq(pk_value))
26
- end if record.persisted?
27
-
28
- Array.wrap(options[:scope]).each do |scope_item|
29
- relation = relation.where(table[scope_item].eq(record.public_send(scope_item)))
30
- end
31
-
32
- if relation.where(finder_class.paranoid_default_scope).exists?(relation)
33
- record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
34
- end
35
- end
36
-
37
- protected
38
-
39
- def build_relation(klass, attribute, value)
40
- if ActiveRecord::VERSION::MINOR == 0 && ActiveRecord::VERSION::MAJOR == 5
41
- return super(klass, klass.arel_table, attribute, value)
42
- else
43
- super
44
- end
45
- end
46
- end
47
-
48
- class V4 < ActiveRecord::Validations::UniquenessValidator
49
- def validate_each(record, attribute, value)
50
- finder_class = find_finder_class_for(record)
51
- table = finder_class.arel_table
52
-
53
- # TODO: Use record.class.column_types[attribute.to_s].coder ?
54
- coder = record.class.column_types[attribute.to_s]
55
-
56
- if value && coder
57
- value = if coder.respond_to? :type_cast_for_database
58
- coder.type_cast_for_database value
59
- else
60
- coder.type_cast_for_write value
61
- end
62
- end
63
-
64
- relation = build_relation(finder_class, table, attribute, value)
65
- [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value|
66
- relation = relation.and(table[pk_key.to_sym].not_eq(pk_value))
67
- end if record.persisted?
68
-
69
- Array.wrap(options[:scope]).each do |scope_item|
70
- scope_value = record.send(scope_item)
71
- relation = relation.and(table[scope_item].eq(scope_value))
72
- end
73
-
74
- # Re-add ActsAsParanoid default scope conditions manually.
75
- if finder_class.unscoped.where(finder_class.paranoid_default_scope).where(relation).exists?
76
- record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
77
- end
78
- end
79
- end
11
+ class UniquenessWithoutDeletedValidator < ActiveRecord::Validations::UniquenessValidator
12
+ private
80
13
 
81
- class V6 < V5
14
+ def build_relation(klass, attribute, value)
15
+ super.where(klass.paranoid_default_scope)
82
16
  end
83
17
  end
84
18
 
85
19
  module ClassMethods
86
20
  def validates_uniqueness_of_without_deleted(*attr_names)
87
- validates_with UniquenessWithoutDeletedValidator[ActiveRecord::VERSION::MAJOR], _merge_attributes(attr_names)
21
+ validates_with UniquenessWithoutDeletedValidator, _merge_attributes(attr_names)
88
22
  end
89
23
  end
90
24
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActsAsParanoid
2
- VERSION = "0.6.2"
4
+ VERSION = "0.7.3"
3
5
  end
@@ -1,27 +1,34 @@
1
- require 'test_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
2
4
 
3
5
  class AssociationsTest < ParanoidBaseTest
4
- def test_removal_with_associations
5
- paranoid_company_1 = ParanoidDestroyCompany.create! :name => "ParanoidDestroyCompany #1"
6
- paranoid_company_2 = ParanoidDeleteCompany.create! :name => "ParanoidDestroyCompany #1"
7
- paranoid_company_1.paranoid_products.create! :name => "ParanoidProduct #1"
8
- paranoid_company_2.paranoid_products.create! :name => "ParanoidProduct #2"
6
+ def test_removal_with_destroy_associations
7
+ paranoid_company = ParanoidDestroyCompany.create! name: "ParanoidDestroyCompany #1"
8
+ paranoid_company.paranoid_products.create! name: "ParanoidProduct #1"
9
9
 
10
10
  assert_equal 1, ParanoidDestroyCompany.count
11
- assert_equal 1, ParanoidDeleteCompany.count
12
- assert_equal 2, ParanoidProduct.count
11
+ assert_equal 1, ParanoidProduct.count
13
12
 
14
13
  ParanoidDestroyCompany.first.destroy
15
14
  assert_equal 0, ParanoidDestroyCompany.count
16
- assert_equal 1, ParanoidProduct.count
15
+ assert_equal 0, ParanoidProduct.count
17
16
  assert_equal 1, ParanoidDestroyCompany.with_deleted.count
18
- assert_equal 2, ParanoidProduct.with_deleted.count
17
+ assert_equal 1, ParanoidProduct.with_deleted.count
19
18
 
20
19
  ParanoidDestroyCompany.with_deleted.first.destroy
21
20
  assert_equal 0, ParanoidDestroyCompany.count
22
- assert_equal 1, ParanoidProduct.count
21
+ assert_equal 0, ParanoidProduct.count
23
22
  assert_equal 0, ParanoidDestroyCompany.with_deleted.count
24
- assert_equal 1, ParanoidProduct.with_deleted.count
23
+ assert_equal 0, ParanoidProduct.with_deleted.count
24
+ end
25
+
26
+ def test_removal_with_delete_all_associations
27
+ paranoid_company = ParanoidDeleteCompany.create! name: "ParanoidDestroyCompany #1"
28
+ paranoid_company.paranoid_products.create! name: "ParanoidProduct #2"
29
+
30
+ assert_equal 1, ParanoidDeleteCompany.count
31
+ assert_equal 1, ParanoidProduct.count
25
32
 
26
33
  ParanoidDeleteCompany.first.destroy
27
34
  assert_equal 0, ParanoidDeleteCompany.count
@@ -38,17 +45,20 @@ class AssociationsTest < ParanoidBaseTest
38
45
 
39
46
  def test_belongs_to_with_scope_option
40
47
  paranoid_has_many_dependant = ParanoidHasManyDependant.new
41
- includes_values = ParanoidTime.includes(:not_paranoid).includes_values
42
48
 
43
- assert_equal includes_values, paranoid_has_many_dependant.association(:paranoid_time_with_scope).scope.includes_values
49
+ expected_includes_values = ParanoidTime.includes(:not_paranoid).includes_values
50
+ includes_values = paranoid_has_many_dependant
51
+ .association(:paranoid_time_with_scope).scope.includes_values
44
52
 
45
- paranoid_time = ParanoidTime.create(name: 'not-hello')
53
+ assert_equal expected_includes_values, includes_values
54
+
55
+ paranoid_time = ParanoidTime.create(name: "not-hello")
46
56
  paranoid_has_many_dependant.paranoid_time = paranoid_time
47
57
  paranoid_has_many_dependant.save!
48
58
 
49
59
  assert_nil paranoid_has_many_dependant.paranoid_time_with_scope
50
60
 
51
- paranoid_time.update(name: 'hello')
61
+ paranoid_time.update(name: "hello")
52
62
 
53
63
  paranoid_has_many_dependant.reload
54
64
 
@@ -68,26 +78,29 @@ class AssociationsTest < ParanoidBaseTest
68
78
  assert_equal includes_values, paranoid_has_many_dependant
69
79
  .association(:paranoid_time_with_scope_with_deleted).scope.includes_values
70
80
 
71
- paranoid_time = ParanoidTime.create(name: 'not-hello')
81
+ paranoid_time = ParanoidTime.create(name: "not-hello")
72
82
  paranoid_has_many_dependant.paranoid_time = paranoid_time
73
83
  paranoid_has_many_dependant.save!
74
84
 
75
85
  assert_nil paranoid_has_many_dependant.paranoid_time_with_scope_with_deleted
76
86
 
77
- paranoid_time.update(name: 'hello')
87
+ paranoid_time.update(name: "hello")
78
88
  paranoid_has_many_dependant.reload
79
89
 
80
- assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_scope_with_deleted
90
+ assert_equal paranoid_time, paranoid_has_many_dependant
91
+ .paranoid_time_with_scope_with_deleted
81
92
 
82
93
  paranoid_time.destroy
83
94
  paranoid_has_many_dependant.reload
84
95
 
85
- assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_scope_with_deleted
96
+ assert_equal paranoid_time, paranoid_has_many_dependant
97
+ .paranoid_time_with_scope_with_deleted
86
98
  end
87
99
 
88
100
  def test_belongs_to_with_deleted
89
101
  paranoid_time = ParanoidTime.first
90
- paranoid_has_many_dependant = paranoid_time.paranoid_has_many_dependants.create(:name => 'dependant!')
102
+ paranoid_has_many_dependant = paranoid_time.paranoid_has_many_dependants
103
+ .create(name: "dependant!")
91
104
 
92
105
  assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time
93
106
  assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_deleted
@@ -101,20 +114,25 @@ class AssociationsTest < ParanoidBaseTest
101
114
 
102
115
  def test_belongs_to_polymorphic_with_deleted
103
116
  paranoid_time = ParanoidTime.first
104
- paranoid_has_many_dependant = ParanoidHasManyDependant.create!(:name => 'dependant!', :paranoid_time_polymorphic_with_deleted => paranoid_time)
117
+ paranoid_has_many_dependant = ParanoidHasManyDependant
118
+ .create!(name: "dependant!", paranoid_time_polymorphic_with_deleted: paranoid_time)
105
119
 
106
120
  assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time
107
- assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted
121
+ assert_equal paranoid_time, paranoid_has_many_dependant
122
+ .paranoid_time_polymorphic_with_deleted
108
123
 
109
124
  paranoid_time.destroy
110
125
 
111
126
  assert_nil paranoid_has_many_dependant.reload.paranoid_time
112
- assert_equal paranoid_time, paranoid_has_many_dependant.reload.paranoid_time_polymorphic_with_deleted
127
+ assert_equal paranoid_time, paranoid_has_many_dependant
128
+ .reload.paranoid_time_polymorphic_with_deleted
113
129
  end
114
130
 
115
131
  def test_belongs_to_nil_polymorphic_with_deleted
116
132
  paranoid_time = ParanoidTime.first
117
- paranoid_has_many_dependant = ParanoidHasManyDependant.create!(:name => 'dependant!', :paranoid_time_polymorphic_with_deleted => nil)
133
+ paranoid_has_many_dependant =
134
+ ParanoidHasManyDependant.create!(name: "dependant!",
135
+ paranoid_time_polymorphic_with_deleted: nil)
118
136
 
119
137
  assert_nil paranoid_has_many_dependant.paranoid_time
120
138
  assert_nil paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted
@@ -126,19 +144,23 @@ class AssociationsTest < ParanoidBaseTest
126
144
  end
127
145
 
128
146
  def test_belongs_to_options
129
- paranoid_time = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time]
147
+ paranoid_time = ParanoidHasManyDependant.reflections
148
+ .with_indifferent_access[:paranoid_time]
130
149
  assert_equal :belongs_to, paranoid_time.macro
131
150
  assert_nil paranoid_time.options[:with_deleted]
132
151
  end
133
152
 
134
153
  def test_belongs_to_with_deleted_options
135
- paranoid_time_with_deleted = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time_with_deleted]
154
+ paranoid_time_with_deleted =
155
+ ParanoidHasManyDependant.reflections
156
+ .with_indifferent_access[:paranoid_time_with_deleted]
136
157
  assert_equal :belongs_to, paranoid_time_with_deleted.macro
137
158
  assert paranoid_time_with_deleted.options[:with_deleted]
138
159
  end
139
160
 
140
161
  def test_belongs_to_polymorphic_with_deleted_options
141
- paranoid_time_polymorphic_with_deleted = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time_polymorphic_with_deleted]
162
+ paranoid_time_polymorphic_with_deleted = ParanoidHasManyDependant.reflections
163
+ .with_indifferent_access[:paranoid_time_polymorphic_with_deleted]
142
164
  assert_equal :belongs_to, paranoid_time_polymorphic_with_deleted.macro
143
165
  assert paranoid_time_polymorphic_with_deleted.options[:with_deleted]
144
166
  end
@@ -161,6 +183,50 @@ class AssociationsTest < ParanoidBaseTest
161
183
  assert_equal [child], parent.paranoid_has_many_dependants.with_deleted.to_a
162
184
  end
163
185
 
186
+ def test_join_with_model_with_deleted
187
+ obj = ParanoidHasManyDependant.create(paranoid_time: ParanoidTime.create)
188
+ assert_not_nil obj.paranoid_time
189
+ assert_not_nil obj.paranoid_time_with_deleted
190
+
191
+ obj.paranoid_time.destroy
192
+ obj.reload
193
+
194
+ assert_nil obj.paranoid_time
195
+ assert_not_nil obj.paranoid_time_with_deleted
196
+
197
+ # Note that obj is destroyed because of dependent: :destroy in ParanoidTime
198
+ assert obj.destroyed?
199
+
200
+ assert_empty ParanoidHasManyDependant.with_deleted.joins(:paranoid_time)
201
+ assert_equal [obj],
202
+ ParanoidHasManyDependant.with_deleted.joins(:paranoid_time_with_deleted)
203
+ end
204
+
205
+ def test_includes_with_deleted
206
+ paranoid_time = ParanoidTime.first
207
+ paranoid_time.paranoid_has_many_dependants.create(name: "dependant!")
208
+
209
+ paranoid_time.destroy
210
+
211
+ ParanoidHasManyDependant.with_deleted
212
+ .includes(:paranoid_time_with_deleted).each do |hasmany|
213
+ assert_not_nil hasmany.paranoid_time_with_deleted
214
+ end
215
+ end
216
+
217
+ def test_includes_with_deleted_with_polymorphic_parent
218
+ not_paranoid_parent = NotParanoidHasManyAsParent.create(name: "not paranoid parent")
219
+ paranoid_parent = ParanoidHasManyAsParent.create(name: "paranoid parent")
220
+ ParanoidBelongsToPolymorphic.create(name: "belongs_to", parent: not_paranoid_parent)
221
+ ParanoidBelongsToPolymorphic.create(name: "belongs_to", parent: paranoid_parent)
222
+
223
+ paranoid_parent.destroy
224
+
225
+ ParanoidBelongsToPolymorphic.with_deleted.includes(:parent).each do |hasmany|
226
+ assert_not_nil hasmany.parent
227
+ end
228
+ end
229
+
164
230
  def test_cannot_find_a_paranoid_deleted_many_many_association
165
231
  left = ParanoidManyManyParentLeft.create
166
232
  right = ParanoidManyManyParentRight.create
@@ -171,8 +237,10 @@ class AssociationsTest < ParanoidBaseTest
171
237
  left.reload
172
238
 
173
239
  assert_equal [], left.paranoid_many_many_children, "Linking objects not deleted"
174
- assert_equal [], left.paranoid_many_many_parent_rights, "Associated objects not unlinked"
175
- assert_equal right, ParanoidManyManyParentRight.find(right.id), "Associated object deleted"
240
+ assert_equal [], left.paranoid_many_many_parent_rights,
241
+ "Associated objects not unlinked"
242
+ assert_equal right, ParanoidManyManyParentRight.find(right.id),
243
+ "Associated object deleted"
176
244
  end
177
245
 
178
246
  def test_cannot_find_a_paranoid_destroyed_many_many_association
@@ -185,11 +253,13 @@ class AssociationsTest < ParanoidBaseTest
185
253
  left.reload
186
254
 
187
255
  assert_equal [], left.paranoid_many_many_children, "Linking objects not deleted"
188
- assert_equal [], left.paranoid_many_many_parent_rights, "Associated objects not unlinked"
189
- assert_equal right, ParanoidManyManyParentRight.find(right.id), "Associated object deleted"
256
+ assert_equal [], left.paranoid_many_many_parent_rights,
257
+ "Associated objects not unlinked"
258
+ assert_equal right, ParanoidManyManyParentRight.find(right.id),
259
+ "Associated object deleted"
190
260
  end
191
261
 
192
- def test_cannot_find_a_has_many_through_object_when_its_linking_object_is_paranoid_destroyed
262
+ def test_cannot_find_a_has_many_through_object_when_its_linking_object_is_soft_destroyed
193
263
  left = ParanoidManyManyParentLeft.create
194
264
  right = ParanoidManyManyParentRight.create
195
265
  left.paranoid_many_many_parent_rights << right
@@ -218,8 +288,10 @@ class AssociationsTest < ParanoidBaseTest
218
288
  left.paranoid_many_many_parent_rights << right
219
289
 
220
290
  child = left.paranoid_many_many_children.first
221
- assert_equal left, child.paranoid_many_many_parent_left, "Child's left parent is incorrect"
222
- assert_equal right, child.paranoid_many_many_parent_right, "Child's right parent is incorrect"
291
+ assert_equal left, child.paranoid_many_many_parent_left,
292
+ "Child's left parent is incorrect"
293
+ assert_equal right, child.paranoid_many_many_parent_right,
294
+ "Child's right parent is incorrect"
223
295
 
224
296
  left.paranoid_many_many_parent_rights.clear
225
297
 
@@ -232,8 +304,10 @@ class AssociationsTest < ParanoidBaseTest
232
304
  left.paranoid_many_many_parent_rights << right
233
305
 
234
306
  child = left.paranoid_many_many_children.first
235
- assert_equal left, child.paranoid_many_many_parent_left, "Child's left parent is incorrect"
236
- assert_equal right, child.paranoid_many_many_parent_right, "Child's right parent is incorrect"
307
+ assert_equal left, child.paranoid_many_many_parent_left,
308
+ "Child's left parent is incorrect"
309
+ assert_equal right, child.paranoid_many_many_parent_right,
310
+ "Child's right parent is incorrect"
237
311
 
238
312
  left.paranoid_many_many_parent_rights.destroy(right)
239
313
 
@@ -246,8 +320,10 @@ class AssociationsTest < ParanoidBaseTest
246
320
  left.paranoid_many_many_parent_rights << right
247
321
 
248
322
  child = left.paranoid_many_many_children.first
249
- assert_equal left, child.paranoid_many_many_parent_left, "Child's left parent is incorrect"
250
- assert_equal right, child.paranoid_many_many_parent_right, "Child's right parent is incorrect"
323
+ assert_equal left, child.paranoid_many_many_parent_left,
324
+ "Child's left parent is incorrect"
325
+ assert_equal right, child.paranoid_many_many_parent_right,
326
+ "Child's right parent is incorrect"
251
327
 
252
328
  left.paranoid_many_many_parent_rights.delete(right)
253
329
 
@@ -270,13 +346,9 @@ class AssociationsTest < ParanoidBaseTest
270
346
  assert_not_nil not_paranoid.paranoid_time
271
347
  end
272
348
 
273
- def test_mass_assignment_of_paranoid_column_enabled
274
- if Gem.loaded_specs['activerecord'].version >= Gem::Version.new('5.2.0')
275
- skip 'Creation as deleted is not supported with Rails >= 5.2'
349
+ def test_mass_assignment_of_paranoid_column_disabled
350
+ assert_raises ActiveRecord::RecordNotSaved do
351
+ ParanoidTime.create! name: "Foo", deleted_at: Time.now
276
352
  end
277
- now = Time.now
278
- record = ParanoidTime.create! :name => 'Foo', :deleted_at => now
279
- assert_equal 'Foo', record.name
280
- assert_equal now, record.deleted_at
281
353
  end
282
354
  end
data/test/test_core.rb CHANGED
@@ -1,4 +1,6 @@
1
- require 'test_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
2
4
 
3
5
  class ParanoidTest < ParanoidBaseTest
4
6
  def test_paranoid?
@@ -69,6 +71,13 @@ class ParanoidTest < ParanoidBaseTest
69
71
  assert_not_nil pt.paranoid_value
70
72
  end
71
73
 
74
+ def test_non_persisted_delete
75
+ pt = ParanoidTime.new
76
+ assert_nil pt.paranoid_value
77
+ pt.delete
78
+ assert_not_nil pt.paranoid_value
79
+ end
80
+
72
81
  def test_non_persisted_destroy!
73
82
  pt = ParanoidTime.new
74
83
  assert_nil pt.paranoid_value
@@ -94,12 +103,69 @@ class ParanoidTest < ParanoidBaseTest
94
103
  assert_equal 1, ParanoidString.count
95
104
  end
96
105
 
106
+ def test_recovery!
107
+ ParanoidBoolean.first.destroy
108
+ ParanoidBoolean.create(name: "paranoid")
109
+
110
+ assert_raise do
111
+ ParanoidBoolean.only_deleted.first.recover!
112
+ end
113
+ end
114
+
115
+ def test_recover_has_one_association
116
+ parent = ParanoidBoolean.create(name: "parent")
117
+ child = parent.create_paranoid_has_one_dependant(name: "child")
118
+
119
+ parent.destroy
120
+ assert parent.paranoid_has_one_dependant.destroyed?
121
+
122
+ parent.recover
123
+ refute parent.paranoid_has_one_dependant.destroyed?
124
+
125
+ child.reload
126
+ refute child.destroyed?
127
+ end
128
+
129
+ def test_recover_has_many_association
130
+ parent = ParanoidTime.create(name: "parent")
131
+ child = parent.paranoid_has_many_dependants.create(name: "child")
132
+
133
+ parent.destroy
134
+ assert child.destroyed?
135
+
136
+ parent.recover
137
+ assert_equal 1, parent.paranoid_has_many_dependants.count
138
+
139
+ child.reload
140
+ refute child.destroyed?
141
+ end
142
+
143
+ # Rails does not allow saving deleted records
144
+ def test_no_save_after_destroy
145
+ paranoid = ParanoidString.first
146
+ paranoid.destroy
147
+ paranoid.name = "Let's update!"
148
+
149
+ assert_not paranoid.save
150
+ assert_raises ActiveRecord::RecordNotSaved do
151
+ paranoid.save!
152
+ end
153
+ end
154
+
155
+ def test_scope_chaining
156
+ assert_equal 3, ParanoidBoolean.unscoped.with_deleted.count
157
+ assert_equal 0, ParanoidBoolean.unscoped.only_deleted.count
158
+ assert_equal 0, ParanoidBoolean.with_deleted.only_deleted.count
159
+ assert_equal 3, ParanoidBoolean.with_deleted.with_deleted.count
160
+ end
161
+
97
162
  def setup_recursive_tests
98
163
  @paranoid_time_object = ParanoidTime.first
99
164
 
100
165
  # Create one extra ParanoidHasManyDependant record so that we can validate
101
166
  # the correct dependants are recovered.
102
- ParanoidTime.where('id <> ?', @paranoid_time_object.id).first.paranoid_has_many_dependants.create(:name => "should not be recovered").destroy
167
+ ParanoidTime.where("id <> ?", @paranoid_time_object.id).first
168
+ .paranoid_has_many_dependants.create(name: "should not be recovered").destroy
103
169
 
104
170
  @paranoid_boolean_count = ParanoidBoolean.count
105
171
 
@@ -108,20 +174,21 @@ class ParanoidTest < ParanoidBaseTest
108
174
  assert_equal 1, NotParanoid.count
109
175
 
110
176
  (1..3).each do |i|
111
- has_many_object = @paranoid_time_object.paranoid_has_many_dependants.create(:name => "has_many_#{i}")
112
- has_many_object.create_paranoid_belongs_dependant(:name => "belongs_to_#{i}")
177
+ has_many_object = @paranoid_time_object.paranoid_has_many_dependants
178
+ .create(name: "has_many_#{i}")
179
+ has_many_object.create_paranoid_belongs_dependant(name: "belongs_to_#{i}")
113
180
  has_many_object.save
114
181
 
115
- paranoid_boolean = @paranoid_time_object.paranoid_booleans.create(:name => "boolean_#{i}")
116
- paranoid_boolean.create_paranoid_has_one_dependant(:name => "has_one_#{i}")
182
+ paranoid_boolean = @paranoid_time_object.paranoid_booleans
183
+ .create(name: "boolean_#{i}")
184
+ paranoid_boolean.create_paranoid_has_one_dependant(name: "has_one_#{i}")
117
185
  paranoid_boolean.save
118
186
 
119
- @paranoid_time_object.not_paranoids.create(:name => "not_paranoid_a#{i}")
120
-
187
+ @paranoid_time_object.not_paranoids.create(name: "not_paranoid_a#{i}")
121
188
  end
122
189
 
123
- @paranoid_time_object.create_not_paranoid(:name => "not_paranoid_belongs_to")
124
- @paranoid_time_object.create_has_one_not_paranoid(:name => "has_one_not_paranoid")
190
+ @paranoid_time_object.create_not_paranoid(name: "not_paranoid_belongs_to")
191
+ @paranoid_time_object.create_has_one_not_paranoid(name: "has_one_not_paranoid")
125
192
 
126
193
  assert_equal 3, ParanoidTime.count
127
194
  assert_equal 3, ParanoidHasManyDependant.count
@@ -172,7 +239,7 @@ class ParanoidTest < ParanoidBaseTest
172
239
  @paranoid_time_object.destroy
173
240
  @paranoid_time_object.reload
174
241
 
175
- @paranoid_time_object.recover(:recursive => true)
242
+ @paranoid_time_object.recover(recursive: true)
176
243
 
177
244
  assert_equal 3, ParanoidTime.count
178
245
  assert_equal 3, ParanoidHasManyDependant.count
@@ -193,14 +260,14 @@ class ParanoidTest < ParanoidBaseTest
193
260
  @paranoid_time_object.paranoid_has_many_dependants.first.destroy
194
261
  end
195
262
  Time.stub :now, 1.hour.ago do
196
- @paranoid_time_object.paranoid_has_many_dependants.
197
- last.paranoid_belongs_dependant.
198
- destroy
263
+ @paranoid_time_object.paranoid_has_many_dependants
264
+ .last.paranoid_belongs_dependant
265
+ .destroy
199
266
  end
200
267
  @paranoid_time_object.destroy
201
268
  @paranoid_time_object.reload
202
269
 
203
- @paranoid_time_object.recover(:recursive => true)
270
+ @paranoid_time_object.recover(recursive: true)
204
271
 
205
272
  assert_equal 3, ParanoidTime.count
206
273
  assert_equal 2, ParanoidHasManyDependant.count
@@ -213,17 +280,17 @@ class ParanoidTest < ParanoidBaseTest
213
280
 
214
281
  def test_recursive_recovery_for_belongs_to_polymorphic
215
282
  child_1 = ParanoidAndroid.create
216
- section_1 = ParanoidSection.create(:paranoid_thing => child_1)
283
+ section_1 = ParanoidSection.create(paranoid_thing: child_1)
217
284
 
218
- child_2 = ParanoidPolygon.create(:sides => 3)
219
- section_2 = ParanoidSection.create(:paranoid_thing => child_2)
285
+ child_2 = ParanoidPolygon.create(sides: 3)
286
+ section_2 = ParanoidSection.create(paranoid_thing: child_2)
220
287
 
221
288
  assert_equal section_1.paranoid_thing, child_1
222
289
  assert_equal section_1.paranoid_thing.class, ParanoidAndroid
223
290
  assert_equal section_2.paranoid_thing, child_2
224
291
  assert_equal section_2.paranoid_thing.class, ParanoidPolygon
225
292
 
226
- parent = ParanoidTime.create(:name => "paranoid_parent")
293
+ parent = ParanoidTime.create(name: "paranoid_parent")
227
294
  parent.paranoid_sections << section_1
228
295
  parent.paranoid_sections << section_2
229
296
 
@@ -254,7 +321,7 @@ class ParanoidTest < ParanoidBaseTest
254
321
  @paranoid_time_object.destroy
255
322
  @paranoid_time_object.reload
256
323
 
257
- @paranoid_time_object.recover(:recursive => false)
324
+ @paranoid_time_object.recover(recursive: false)
258
325
 
259
326
  assert_equal 3, ParanoidTime.count
260
327
  assert_equal 0, ParanoidHasManyDependant.count
@@ -265,6 +332,24 @@ class ParanoidTest < ParanoidBaseTest
265
332
  assert_equal 0, HasOneNotParanoid.count
266
333
  end
267
334
 
335
+ def test_dirty
336
+ pt = ParanoidTime.create
337
+ pt.destroy
338
+ assert_not pt.changed?
339
+ end
340
+
341
+ def test_delete_dirty
342
+ pt = ParanoidTime.create
343
+ pt.delete
344
+ assert_not pt.changed?
345
+ end
346
+
347
+ def test_destroy_fully_dirty
348
+ pt = ParanoidTime.create
349
+ pt.destroy_fully!
350
+ assert_not pt.changed?
351
+ end
352
+
268
353
  def test_deleted?
269
354
  ParanoidTime.first.destroy
270
355
  assert ParanoidTime.with_deleted.first.deleted?
@@ -273,6 +358,43 @@ class ParanoidTest < ParanoidBaseTest
273
358
  assert ParanoidString.with_deleted.first.deleted?
274
359
  end
275
360
 
361
+ def test_delete_deleted?
362
+ ParanoidTime.first.delete
363
+ assert ParanoidTime.with_deleted.first.deleted?
364
+
365
+ ParanoidString.first.delete
366
+ assert ParanoidString.with_deleted.first.deleted?
367
+ end
368
+
369
+ def test_destroy_fully_deleted?
370
+ object = ParanoidTime.first
371
+ object.destroy_fully!
372
+ assert object.deleted?
373
+
374
+ object = ParanoidString.first
375
+ object.destroy_fully!
376
+ assert object.deleted?
377
+ end
378
+
379
+ def test_deleted_fully?
380
+ ParanoidTime.first.destroy
381
+ assert_not ParanoidTime.with_deleted.first.deleted_fully?
382
+
383
+ ParanoidString.first.destroy
384
+ assert ParanoidString.with_deleted.first.deleted?
385
+ end
386
+
387
+ def test_delete_deleted_fully?
388
+ ParanoidTime.first.delete
389
+ assert_not ParanoidTime.with_deleted.first.deleted_fully?
390
+ end
391
+
392
+ def test_destroy_fully_deleted_fully?
393
+ object = ParanoidTime.first
394
+ object.destroy_fully!
395
+ assert object.deleted_fully?
396
+ end
397
+
276
398
  def test_paranoid_destroy_callbacks
277
399
  @paranoid_with_callback = ParanoidWithCallback.first
278
400
  ParanoidWithCallback.transaction do
@@ -368,104 +490,126 @@ class ParanoidTest < ParanoidBaseTest
368
490
 
369
491
  # Test string type columns that don't have a nil value when not deleted (Y/N for example)
370
492
  def test_string_type_with_no_nil_value_before_destroy
371
- ps = ParanoidString.create!(:deleted => 'not dead')
372
- assert_equal 1, ParanoidString.where(:id => ps).count
493
+ ps = ParanoidString.create!(deleted: "not dead")
494
+ assert_equal 1, ParanoidString.where(id: ps).count
373
495
  end
374
496
 
375
497
  def test_string_type_with_no_nil_value_after_destroy
376
- ps = ParanoidString.create!(:deleted => 'not dead')
498
+ ps = ParanoidString.create!(deleted: "not dead")
377
499
  ps.destroy
378
- assert_equal 0, ParanoidString.where(:id => ps).count
500
+ assert_equal 0, ParanoidString.where(id: ps).count
379
501
  end
380
502
 
381
503
  def test_string_type_with_no_nil_value_before_destroy_with_deleted
382
- ps = ParanoidString.create!(:deleted => 'not dead')
383
- assert_equal 1, ParanoidString.with_deleted.where(:id => ps).count
504
+ ps = ParanoidString.create!(deleted: "not dead")
505
+ assert_equal 1, ParanoidString.with_deleted.where(id: ps).count
384
506
  end
385
507
 
386
508
  def test_string_type_with_no_nil_value_after_destroy_with_deleted
387
- ps = ParanoidString.create!(:deleted => 'not dead')
509
+ ps = ParanoidString.create!(deleted: "not dead")
388
510
  ps.destroy
389
- assert_equal 1, ParanoidString.with_deleted.where(:id => ps).count
511
+ assert_equal 1, ParanoidString.with_deleted.where(id: ps).count
390
512
  end
391
513
 
392
514
  def test_string_type_with_no_nil_value_before_destroy_only_deleted
393
- ps = ParanoidString.create!(:deleted => 'not dead')
394
- assert_equal 0, ParanoidString.only_deleted.where(:id => ps).count
515
+ ps = ParanoidString.create!(deleted: "not dead")
516
+ assert_equal 0, ParanoidString.only_deleted.where(id: ps).count
395
517
  end
396
518
 
397
519
  def test_string_type_with_no_nil_value_after_destroy_only_deleted
398
- ps = ParanoidString.create!(:deleted => 'not dead')
520
+ ps = ParanoidString.create!(deleted: "not dead")
399
521
  ps.destroy
400
- assert_equal 1, ParanoidString.only_deleted.where(:id => ps).count
522
+ assert_equal 1, ParanoidString.only_deleted.where(id: ps).count
401
523
  end
402
524
 
403
525
  def test_string_type_with_no_nil_value_after_destroyed_twice
404
- ps = ParanoidString.create!(:deleted => 'not dead')
526
+ ps = ParanoidString.create!(deleted: "not dead")
405
527
  2.times { ps.destroy }
406
- assert_equal 0, ParanoidString.with_deleted.where(:id => ps).count
528
+ assert_equal 0, ParanoidString.with_deleted.where(id: ps).count
407
529
  end
408
530
 
409
531
  # Test boolean type columns, that are not nullable
410
532
  def test_boolean_type_with_no_nil_value_before_destroy
411
- ps = ParanoidBooleanNotNullable.create!()
412
- assert_equal 1, ParanoidBooleanNotNullable.where(:id => ps).count
533
+ ps = ParanoidBooleanNotNullable.create!
534
+ assert_equal 1, ParanoidBooleanNotNullable.where(id: ps).count
413
535
  end
414
536
 
415
537
  def test_boolean_type_with_no_nil_value_after_destroy
416
- ps = ParanoidBooleanNotNullable.create!()
538
+ ps = ParanoidBooleanNotNullable.create!
417
539
  ps.destroy
418
- assert_equal 0, ParanoidBooleanNotNullable.where(:id => ps).count
540
+ assert_equal 0, ParanoidBooleanNotNullable.where(id: ps).count
419
541
  end
420
542
 
421
543
  def test_boolean_type_with_no_nil_value_before_destroy_with_deleted
422
- ps = ParanoidBooleanNotNullable.create!()
423
- assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
544
+ ps = ParanoidBooleanNotNullable.create!
545
+ assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(id: ps).count
424
546
  end
425
547
 
426
548
  def test_boolean_type_with_no_nil_value_after_destroy_with_deleted
427
- ps = ParanoidBooleanNotNullable.create!()
549
+ ps = ParanoidBooleanNotNullable.create!
428
550
  ps.destroy
429
- assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
551
+ assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(id: ps).count
430
552
  end
431
553
 
432
554
  def test_boolean_type_with_no_nil_value_before_destroy_only_deleted
433
- ps = ParanoidBooleanNotNullable.create!()
434
- assert_equal 0, ParanoidBooleanNotNullable.only_deleted.where(:id => ps).count
555
+ ps = ParanoidBooleanNotNullable.create!
556
+ assert_equal 0, ParanoidBooleanNotNullable.only_deleted.where(id: ps).count
435
557
  end
436
558
 
437
559
  def test_boolean_type_with_no_nil_value_after_destroy_only_deleted
438
- ps = ParanoidBooleanNotNullable.create!()
560
+ ps = ParanoidBooleanNotNullable.create!
439
561
  ps.destroy
440
- assert_equal 1, ParanoidBooleanNotNullable.only_deleted.where(:id => ps).count
562
+ assert_equal 1, ParanoidBooleanNotNullable.only_deleted.where(id: ps).count
441
563
  end
442
564
 
443
565
  def test_boolean_type_with_no_nil_value_after_destroyed_twice
444
- ps = ParanoidBooleanNotNullable.create!()
566
+ ps = ParanoidBooleanNotNullable.create!
445
567
  2.times { ps.destroy }
446
- assert_equal 0, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
568
+ assert_equal 0, ParanoidBooleanNotNullable.with_deleted.where(id: ps).count
569
+ end
570
+
571
+ def test_boolean_type_with_no_nil_value_after_recover
572
+ ps = ParanoidBooleanNotNullable.create!
573
+ ps.destroy
574
+ assert_equal 1, ParanoidBooleanNotNullable.only_deleted.where(id: ps).count
575
+
576
+ ps.recover
577
+ assert_equal 1, ParanoidBooleanNotNullable.where(id: ps).count
578
+ end
579
+
580
+ def test_boolean_type_with_no_nil_value_after_recover!
581
+ ps = ParanoidBooleanNotNullable.create!
582
+ ps.destroy
583
+ assert_equal 1, ParanoidBooleanNotNullable.only_deleted.where(id: ps).count
584
+
585
+ ps.recover!
586
+ assert_equal 1, ParanoidBooleanNotNullable.where(id: ps).count
447
587
  end
448
588
 
449
589
  def test_no_double_tap_destroys_fully
450
- ps = ParanoidNoDoubleTapDestroysFully.create!()
590
+ ps = ParanoidNoDoubleTapDestroysFully.create!
451
591
  2.times { ps.destroy }
452
- assert_equal 1, ParanoidNoDoubleTapDestroysFully.with_deleted.where(:id => ps).count
592
+ assert_equal 1, ParanoidNoDoubleTapDestroysFully.with_deleted.where(id: ps).count
453
593
  end
454
594
 
455
- def test_decrement_counters
456
- paranoid_boolean = ParanoidBoolean.create!()
457
- paranoid_with_counter_cache = ParanoidWithCounterCache.create!(paranoid_boolean: paranoid_boolean)
595
+ def test_decrement_counters_without_touch
596
+ paranoid_boolean = ParanoidBoolean.create!
597
+ paranoid_with_counter_cache = ParanoidWithCounterCache
598
+ .create!(paranoid_boolean: paranoid_boolean)
458
599
 
459
600
  assert_equal 1, paranoid_boolean.paranoid_with_counter_caches_count
601
+ updated_at = paranoid_boolean.reload.updated_at
460
602
 
461
603
  paranoid_with_counter_cache.destroy
462
604
 
463
605
  assert_equal 0, paranoid_boolean.reload.paranoid_with_counter_caches_count
606
+ assert_equal updated_at, paranoid_boolean.reload.updated_at
464
607
  end
465
608
 
466
609
  def test_decrement_custom_counters
467
- paranoid_boolean = ParanoidBoolean.create!()
468
- paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache.create!(paranoid_boolean: paranoid_boolean)
610
+ paranoid_boolean = ParanoidBoolean.create!
611
+ paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache
612
+ .create!(paranoid_boolean: paranoid_boolean)
469
613
 
470
614
  assert_equal 1, paranoid_boolean.custom_counter_cache
471
615
 
@@ -474,15 +618,43 @@ class ParanoidTest < ParanoidBaseTest
474
618
  assert_equal 0, paranoid_boolean.reload.custom_counter_cache
475
619
  end
476
620
 
621
+ def test_decrement_counters_with_touch
622
+ paranoid_boolean = ParanoidBoolean.create!
623
+ paranoid_with_counter_cache = ParanoidWithTouchAndCounterCache
624
+ .create!(paranoid_boolean: paranoid_boolean)
625
+
626
+ assert_equal 1, paranoid_boolean.paranoid_with_touch_and_counter_caches_count
627
+ updated_at = paranoid_boolean.reload.updated_at
628
+
629
+ paranoid_with_counter_cache.destroy
630
+
631
+ assert_equal 0, paranoid_boolean.reload.paranoid_with_touch_and_counter_caches_count
632
+ assert_not_equal updated_at, paranoid_boolean.reload.updated_at
633
+ end
634
+
635
+ def test_touch_belongs_to
636
+ paranoid_boolean = ParanoidBoolean.create!
637
+ paranoid_with_counter_cache = ParanoidWithTouch
638
+ .create!(paranoid_boolean: paranoid_boolean)
639
+
640
+ updated_at = paranoid_boolean.reload.updated_at
641
+
642
+ paranoid_with_counter_cache.destroy
643
+
644
+ assert_not_equal updated_at, paranoid_boolean.reload.updated_at
645
+ end
646
+
477
647
  def test_destroy_with_optional_belongs_to_and_counter_cache
478
- ps = ParanoidWithCounterCacheOnOptionalBelognsTo.create!()
648
+ ps = ParanoidWithCounterCacheOnOptionalBelognsTo.create!
479
649
  ps.destroy
480
- assert_equal 1, ParanoidWithCounterCacheOnOptionalBelognsTo.only_deleted.where(:id => ps).count
650
+ assert_equal 1, ParanoidWithCounterCacheOnOptionalBelognsTo.only_deleted
651
+ .where(id: ps).count
481
652
  end
482
653
 
483
654
  def test_hard_destroy_decrement_counters
484
- paranoid_boolean = ParanoidBoolean.create!()
485
- paranoid_with_counter_cache = ParanoidWithCounterCache.create!(paranoid_boolean: paranoid_boolean)
655
+ paranoid_boolean = ParanoidBoolean.create!
656
+ paranoid_with_counter_cache = ParanoidWithCounterCache
657
+ .create!(paranoid_boolean: paranoid_boolean)
486
658
 
487
659
  assert_equal 1, paranoid_boolean.paranoid_with_counter_caches_count
488
660
 
@@ -492,8 +664,9 @@ class ParanoidTest < ParanoidBaseTest
492
664
  end
493
665
 
494
666
  def test_hard_destroy_decrement_custom_counters
495
- paranoid_boolean = ParanoidBoolean.create!()
496
- paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache.create!(paranoid_boolean: paranoid_boolean)
667
+ paranoid_boolean = ParanoidBoolean.create!
668
+ paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache
669
+ .create!(paranoid_boolean: paranoid_boolean)
497
670
 
498
671
  assert_equal 1, paranoid_boolean.custom_counter_cache
499
672
 
@@ -503,8 +676,9 @@ class ParanoidTest < ParanoidBaseTest
503
676
  end
504
677
 
505
678
  def test_increment_counters
506
- paranoid_boolean = ParanoidBoolean.create!()
507
- paranoid_with_counter_cache = ParanoidWithCounterCache.create!(paranoid_boolean: paranoid_boolean)
679
+ paranoid_boolean = ParanoidBoolean.create!
680
+ paranoid_with_counter_cache = ParanoidWithCounterCache
681
+ .create!(paranoid_boolean: paranoid_boolean)
508
682
 
509
683
  assert_equal 1, paranoid_boolean.paranoid_with_counter_caches_count
510
684
 
@@ -518,8 +692,9 @@ class ParanoidTest < ParanoidBaseTest
518
692
  end
519
693
 
520
694
  def test_increment_custom_counters
521
- paranoid_boolean = ParanoidBoolean.create!()
522
- paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache.create!(paranoid_boolean: paranoid_boolean)
695
+ paranoid_boolean = ParanoidBoolean.create!
696
+ paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache
697
+ .create!(paranoid_boolean: paranoid_boolean)
523
698
 
524
699
  assert_equal 1, paranoid_boolean.custom_counter_cache
525
700
 
@@ -533,6 +708,29 @@ class ParanoidTest < ParanoidBaseTest
533
708
  end
534
709
 
535
710
  def test_explicitly_setting_table_name_after_acts_as_paranoid_macro
536
- assert_equal "explicit_table.deleted_at", ParanoidWithExplicitTableNameAfterMacro.paranoid_column_reference
711
+ assert_equal "explicit_table.deleted_at", ParanoidWithExplicitTableNameAfterMacro
712
+ .paranoid_column_reference
713
+ end
714
+
715
+ def test_deleted_after_time
716
+ ParanoidTime.first.destroy
717
+ assert_equal 0, ParanoidTime.deleted_after_time(1.hour.from_now).count
718
+ assert_equal 1, ParanoidTime.deleted_after_time(1.hour.ago).count
719
+ end
720
+
721
+ def test_deleted_before_time
722
+ ParanoidTime.first.destroy
723
+ assert_equal 1, ParanoidTime.deleted_before_time(1.hour.from_now).count
724
+ assert_equal 0, ParanoidTime.deleted_before_time(1.hour.ago).count
725
+ end
726
+
727
+ def test_deleted_inside_time_window
728
+ ParanoidTime.first.destroy
729
+ assert_equal 1, ParanoidTime.deleted_inside_time_window(1.minute.ago, 2.minutes).count
730
+ assert_equal 1,
731
+ ParanoidTime.deleted_inside_time_window(1.minute.from_now, 2.minutes).count
732
+ assert_equal 0, ParanoidTime.deleted_inside_time_window(3.minutes.ago, 1.minute).count
733
+ assert_equal 0,
734
+ ParanoidTime.deleted_inside_time_window(3.minutes.from_now, 1.minute).count
537
735
  end
538
736
  end