acts_as_paranoid 0.5.0 → 0.7.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.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActsAsParanoid
2
4
  module Relation
3
5
  def self.included(base)
@@ -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,76 +8,17 @@ module ActsAsParanoid
6
8
  base.extend ClassMethods
7
9
  end
8
10
 
9
- class UniquenessWithoutDeletedValidator
10
- def self.[](version)
11
- version = version.to_s
12
- name = "V#{version.tr('.', '_')}"
13
- unless constants.include? name.to_sym
14
- raise "Unknown validator version #{version.inspect}; expected one of #{constants.sort.join(', ')}"
15
- end
16
- const_get name
17
- end
18
-
19
- class V5 < ActiveRecord::Validations::UniquenessValidator
20
- def validate_each(record, attribute, value)
21
- finder_class = find_finder_class_for(record)
22
- table = finder_class.arel_table
23
-
24
- coder = record.class.attribute_types[attribute.to_s]
25
- value = coder.type_cast_for_schema value if value && coder
26
-
27
- relation = build_relation(finder_class, table, attribute, value)
28
- [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value|
29
- relation = relation.where(table[pk_key.to_sym].not_eq(pk_value))
30
- end if record.persisted?
31
-
32
- Array.wrap(options[:scope]).each do |scope_item|
33
- relation = relation.where(table[scope_item].eq(record.public_send(scope_item)))
34
- end
35
-
36
- if relation.where(finder_class.paranoid_default_scope).where(relation).exists?
37
- record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
38
- end
39
- end
40
- end
41
-
42
- class V4 < ActiveRecord::Validations::UniquenessValidator
43
- def validate_each(record, attribute, value)
44
- finder_class = find_finder_class_for(record)
45
- table = finder_class.arel_table
46
-
47
- # TODO: Use record.class.column_types[attribute.to_s].coder ?
48
- coder = record.class.column_types[attribute.to_s]
49
-
50
- if value && coder
51
- value = if coder.respond_to? :type_cast_for_database
52
- coder.type_cast_for_database value
53
- else
54
- coder.type_cast_for_write value
55
- end
56
- end
57
-
58
- relation = build_relation(finder_class, table, attribute, value)
59
- [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value|
60
- relation = relation.and(table[pk_key.to_sym].not_eq(pk_value))
61
- end if record.persisted?
62
-
63
- Array.wrap(options[:scope]).each do |scope_item|
64
- scope_value = record.send(scope_item)
65
- relation = relation.and(table[scope_item].eq(scope_value))
66
- end
11
+ class UniquenessWithoutDeletedValidator < ActiveRecord::Validations::UniquenessValidator
12
+ private
67
13
 
68
- # Re-add ActsAsParanoid default scope conditions manually.
69
- if finder_class.unscoped.where(finder_class.paranoid_default_scope).where(relation).exists?
70
- record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
71
- end
72
- end
14
+ def build_relation(klass, attribute, value)
15
+ super.where(klass.paranoid_default_scope)
73
16
  end
74
17
  end
75
18
 
76
19
  module ClassMethods
77
20
  def validates_uniqueness_of_without_deleted(*attr_names)
78
- validates_with UniquenessWithoutDeletedValidator[ActiveRecord::VERSION::MAJOR], _merge_attributes(attr_names)
21
+ validates_with UniquenessWithoutDeletedValidator, _merge_attributes(attr_names)
79
22
  end
80
23
  end
81
24
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActsAsParanoid
2
- VERSION = "0.5.0"
4
+ VERSION = "0.7.0"
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,64 +45,122 @@ class AssociationsTest < ParanoidBaseTest
38
45
 
39
46
  def test_belongs_to_with_scope_option
40
47
  paranoid_has_many_dependant = ParanoidHasManyDependant.new
48
+
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
52
+
53
+ assert_equal expected_includes_values, includes_values
54
+
55
+ paranoid_time = ParanoidTime.create(name: "not-hello")
56
+ paranoid_has_many_dependant.paranoid_time = paranoid_time
57
+ paranoid_has_many_dependant.save!
58
+
59
+ assert_nil paranoid_has_many_dependant.paranoid_time_with_scope
60
+
61
+ paranoid_time.update(name: "hello")
62
+
63
+ paranoid_has_many_dependant.reload
64
+
65
+ assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_scope
66
+
67
+ paranoid_time.destroy
68
+
69
+ paranoid_has_many_dependant.reload
70
+
71
+ assert_nil paranoid_has_many_dependant.paranoid_time_with_scope
72
+ end
73
+
74
+ def test_belongs_to_with_scope_and_deleted_option
75
+ paranoid_has_many_dependant = ParanoidHasManyDependant.new
41
76
  includes_values = ParanoidTime.includes(:not_paranoid).includes_values
42
77
 
43
- assert_equal includes_values, paranoid_has_many_dependant.association(:paranoid_time_with_scope).scope.includes_values
78
+ assert_equal includes_values, paranoid_has_many_dependant
79
+ .association(:paranoid_time_with_scope_with_deleted).scope.includes_values
80
+
81
+ paranoid_time = ParanoidTime.create(name: "not-hello")
82
+ paranoid_has_many_dependant.paranoid_time = paranoid_time
83
+ paranoid_has_many_dependant.save!
84
+
85
+ assert_nil paranoid_has_many_dependant.paranoid_time_with_scope_with_deleted
86
+
87
+ paranoid_time.update(name: "hello")
88
+ paranoid_has_many_dependant.reload
89
+
90
+ assert_equal paranoid_time, paranoid_has_many_dependant
91
+ .paranoid_time_with_scope_with_deleted
92
+
93
+ paranoid_time.destroy
94
+ paranoid_has_many_dependant.reload
95
+
96
+ assert_equal paranoid_time, paranoid_has_many_dependant
97
+ .paranoid_time_with_scope_with_deleted
44
98
  end
45
99
 
46
100
  def test_belongs_to_with_deleted
47
101
  paranoid_time = ParanoidTime.first
48
- 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!")
49
104
 
50
105
  assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time
51
106
  assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_deleted
52
107
 
53
108
  paranoid_time.destroy
109
+ paranoid_has_many_dependant.reload
54
110
 
55
- assert_nil paranoid_has_many_dependant.paranoid_time(true)
56
- assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_deleted(true)
111
+ assert_nil paranoid_has_many_dependant.paranoid_time
112
+ assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_deleted
57
113
  end
58
114
 
59
115
  def test_belongs_to_polymorphic_with_deleted
60
116
  paranoid_time = ParanoidTime.first
61
- 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)
62
119
 
63
120
  assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time
64
- 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
65
123
 
66
124
  paranoid_time.destroy
67
125
 
68
- assert_nil paranoid_has_many_dependant.paranoid_time(true)
69
- assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted(true)
126
+ assert_nil paranoid_has_many_dependant.reload.paranoid_time
127
+ assert_equal paranoid_time, paranoid_has_many_dependant
128
+ .reload.paranoid_time_polymorphic_with_deleted
70
129
  end
71
130
 
72
131
  def test_belongs_to_nil_polymorphic_with_deleted
73
132
  paranoid_time = ParanoidTime.first
74
- 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)
75
136
 
76
137
  assert_nil paranoid_has_many_dependant.paranoid_time
77
138
  assert_nil paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted
78
139
 
79
140
  paranoid_time.destroy
80
141
 
81
- assert_nil paranoid_has_many_dependant.paranoid_time(true)
82
- assert_nil paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted(true)
142
+ assert_nil paranoid_has_many_dependant.reload.paranoid_time
143
+ assert_nil paranoid_has_many_dependant.reload.paranoid_time_polymorphic_with_deleted
83
144
  end
84
145
 
85
146
  def test_belongs_to_options
86
- paranoid_time = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time]
147
+ paranoid_time = ParanoidHasManyDependant.reflections
148
+ .with_indifferent_access[:paranoid_time]
87
149
  assert_equal :belongs_to, paranoid_time.macro
88
150
  assert_nil paranoid_time.options[:with_deleted]
89
151
  end
90
152
 
91
153
  def test_belongs_to_with_deleted_options
92
- 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]
93
157
  assert_equal :belongs_to, paranoid_time_with_deleted.macro
94
158
  assert paranoid_time_with_deleted.options[:with_deleted]
95
159
  end
96
160
 
97
161
  def test_belongs_to_polymorphic_with_deleted_options
98
- 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]
99
164
  assert_equal :belongs_to, paranoid_time_polymorphic_with_deleted.macro
100
165
  assert paranoid_time_polymorphic_with_deleted.options[:with_deleted]
101
166
  end
@@ -118,6 +183,50 @@ class AssociationsTest < ParanoidBaseTest
118
183
  assert_equal [child], parent.paranoid_has_many_dependants.with_deleted.to_a
119
184
  end
120
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
+
121
230
  def test_cannot_find_a_paranoid_deleted_many_many_association
122
231
  left = ParanoidManyManyParentLeft.create
123
232
  right = ParanoidManyManyParentRight.create
@@ -128,8 +237,10 @@ class AssociationsTest < ParanoidBaseTest
128
237
  left.reload
129
238
 
130
239
  assert_equal [], left.paranoid_many_many_children, "Linking objects not deleted"
131
- assert_equal [], left.paranoid_many_many_parent_rights, "Associated objects not unlinked"
132
- 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"
133
244
  end
134
245
 
135
246
  def test_cannot_find_a_paranoid_destroyed_many_many_association
@@ -142,11 +253,13 @@ class AssociationsTest < ParanoidBaseTest
142
253
  left.reload
143
254
 
144
255
  assert_equal [], left.paranoid_many_many_children, "Linking objects not deleted"
145
- assert_equal [], left.paranoid_many_many_parent_rights, "Associated objects not unlinked"
146
- 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"
147
260
  end
148
261
 
149
- 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
150
263
  left = ParanoidManyManyParentLeft.create
151
264
  right = ParanoidManyManyParentRight.create
152
265
  left.paranoid_many_many_parent_rights << right
@@ -175,8 +288,10 @@ class AssociationsTest < ParanoidBaseTest
175
288
  left.paranoid_many_many_parent_rights << right
176
289
 
177
290
  child = left.paranoid_many_many_children.first
178
- assert_equal left, child.paranoid_many_many_parent_left, "Child's left parent is incorrect"
179
- 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"
180
295
 
181
296
  left.paranoid_many_many_parent_rights.clear
182
297
 
@@ -189,8 +304,10 @@ class AssociationsTest < ParanoidBaseTest
189
304
  left.paranoid_many_many_parent_rights << right
190
305
 
191
306
  child = left.paranoid_many_many_children.first
192
- assert_equal left, child.paranoid_many_many_parent_left, "Child's left parent is incorrect"
193
- 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"
194
311
 
195
312
  left.paranoid_many_many_parent_rights.destroy(right)
196
313
 
@@ -203,8 +320,10 @@ class AssociationsTest < ParanoidBaseTest
203
320
  left.paranoid_many_many_parent_rights << right
204
321
 
205
322
  child = left.paranoid_many_many_children.first
206
- assert_equal left, child.paranoid_many_many_parent_left, "Child's left parent is incorrect"
207
- 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"
208
327
 
209
328
  left.paranoid_many_many_parent_rights.delete(right)
210
329
 
@@ -228,9 +347,12 @@ class AssociationsTest < ParanoidBaseTest
228
347
  end
229
348
 
230
349
  def test_mass_assignment_of_paranoid_column_enabled
350
+ if Gem.loaded_specs["activerecord"].version >= Gem::Version.new("5.2.0")
351
+ skip "Creation as deleted is not supported with Rails >= 5.2"
352
+ end
231
353
  now = Time.now
232
- record = ParanoidTime.create! :name => 'Foo', :deleted_at => now
233
- assert_equal 'Foo', record.name
354
+ record = ParanoidTime.create! name: "Foo", deleted_at: now
355
+ assert_equal "Foo", record.name
234
356
  assert_equal now, record.deleted_at
235
357
  end
236
358
  end
@@ -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,34 @@ 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
+ # Rails does not allow saving deleted records
116
+ def test_no_save_after_destroy
117
+ paranoid = ParanoidString.first
118
+ paranoid.destroy
119
+ paranoid.name = "Let's update!"
120
+
121
+ assert_not paranoid.save
122
+ assert_raises ActiveRecord::RecordNotSaved do
123
+ paranoid.save!
124
+ end
125
+ end
126
+
97
127
  def setup_recursive_tests
98
128
  @paranoid_time_object = ParanoidTime.first
99
129
 
100
130
  # Create one extra ParanoidHasManyDependant record so that we can validate
101
131
  # 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
132
+ ParanoidTime.where("id <> ?", @paranoid_time_object.id).first
133
+ .paranoid_has_many_dependants.create(name: "should not be recovered").destroy
103
134
 
104
135
  @paranoid_boolean_count = ParanoidBoolean.count
105
136
 
@@ -108,20 +139,21 @@ class ParanoidTest < ParanoidBaseTest
108
139
  assert_equal 1, NotParanoid.count
109
140
 
110
141
  (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}")
142
+ has_many_object = @paranoid_time_object.paranoid_has_many_dependants
143
+ .create(name: "has_many_#{i}")
144
+ has_many_object.create_paranoid_belongs_dependant(name: "belongs_to_#{i}")
113
145
  has_many_object.save
114
146
 
115
- paranoid_boolean = @paranoid_time_object.paranoid_booleans.create(:name => "boolean_#{i}")
116
- paranoid_boolean.create_paranoid_has_one_dependant(:name => "has_one_#{i}")
147
+ paranoid_boolean = @paranoid_time_object.paranoid_booleans
148
+ .create(name: "boolean_#{i}")
149
+ paranoid_boolean.create_paranoid_has_one_dependant(name: "has_one_#{i}")
117
150
  paranoid_boolean.save
118
151
 
119
- @paranoid_time_object.not_paranoids.create(:name => "not_paranoid_a#{i}")
120
-
152
+ @paranoid_time_object.not_paranoids.create(name: "not_paranoid_a#{i}")
121
153
  end
122
154
 
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")
155
+ @paranoid_time_object.create_not_paranoid(name: "not_paranoid_belongs_to")
156
+ @paranoid_time_object.create_has_one_not_paranoid(name: "has_one_not_paranoid")
125
157
 
126
158
  assert_equal 3, ParanoidTime.count
127
159
  assert_equal 3, ParanoidHasManyDependant.count
@@ -172,7 +204,7 @@ class ParanoidTest < ParanoidBaseTest
172
204
  @paranoid_time_object.destroy
173
205
  @paranoid_time_object.reload
174
206
 
175
- @paranoid_time_object.recover(:recursive => true)
207
+ @paranoid_time_object.recover(recursive: true)
176
208
 
177
209
  assert_equal 3, ParanoidTime.count
178
210
  assert_equal 3, ParanoidHasManyDependant.count
@@ -186,17 +218,21 @@ class ParanoidTest < ParanoidBaseTest
186
218
  def test_recursive_recovery_dependant_window
187
219
  setup_recursive_tests
188
220
 
189
- @paranoid_time_object.destroy
190
- @paranoid_time_object.reload
191
-
192
221
  # Stop the following from recovering:
193
222
  # - ParanoidHasManyDependant and its ParanoidBelongsDependant
194
223
  # - A single ParanoidBelongsDependant, but not its parent
195
- dependants = @paranoid_time_object.paranoid_has_many_dependants.with_deleted
196
- dependants.first.update_attribute(:deleted_at, 2.days.ago)
197
- ParanoidBelongsDependant.with_deleted.where(:id => dependants.last.paranoid_belongs_dependant_id).first.update_attribute(:deleted_at, 1.hour.ago)
224
+ Time.stub :now, 2.days.ago do
225
+ @paranoid_time_object.paranoid_has_many_dependants.first.destroy
226
+ end
227
+ Time.stub :now, 1.hour.ago do
228
+ @paranoid_time_object.paranoid_has_many_dependants
229
+ .last.paranoid_belongs_dependant
230
+ .destroy
231
+ end
232
+ @paranoid_time_object.destroy
233
+ @paranoid_time_object.reload
198
234
 
199
- @paranoid_time_object.recover(:recursive => true)
235
+ @paranoid_time_object.recover(recursive: true)
200
236
 
201
237
  assert_equal 3, ParanoidTime.count
202
238
  assert_equal 2, ParanoidHasManyDependant.count
@@ -209,31 +245,31 @@ class ParanoidTest < ParanoidBaseTest
209
245
 
210
246
  def test_recursive_recovery_for_belongs_to_polymorphic
211
247
  child_1 = ParanoidAndroid.create
212
- section_1 = ParanoidSection.create(:paranoid_thing => child_1)
248
+ section_1 = ParanoidSection.create(paranoid_thing: child_1)
213
249
 
214
- child_2 = ParanoidHuman.create(:gender => 'male')
215
- section_2 = ParanoidSection.create(:paranoid_thing => child_2)
250
+ child_2 = ParanoidPolygon.create(sides: 3)
251
+ section_2 = ParanoidSection.create(paranoid_thing: child_2)
216
252
 
217
253
  assert_equal section_1.paranoid_thing, child_1
218
254
  assert_equal section_1.paranoid_thing.class, ParanoidAndroid
219
255
  assert_equal section_2.paranoid_thing, child_2
220
- assert_equal section_2.paranoid_thing.class, ParanoidHuman
256
+ assert_equal section_2.paranoid_thing.class, ParanoidPolygon
221
257
 
222
- parent = ParanoidTime.create(:name => "paranoid_parent")
258
+ parent = ParanoidTime.create(name: "paranoid_parent")
223
259
  parent.paranoid_sections << section_1
224
260
  parent.paranoid_sections << section_2
225
261
 
226
262
  assert_equal 4, ParanoidTime.count
227
263
  assert_equal 2, ParanoidSection.count
228
264
  assert_equal 1, ParanoidAndroid.count
229
- assert_equal 1, ParanoidHuman.count
265
+ assert_equal 1, ParanoidPolygon.count
230
266
 
231
267
  parent.destroy
232
268
 
233
269
  assert_equal 3, ParanoidTime.count
234
270
  assert_equal 0, ParanoidSection.count
235
271
  assert_equal 0, ParanoidAndroid.count
236
- assert_equal 0, ParanoidHuman.count
272
+ assert_equal 0, ParanoidPolygon.count
237
273
 
238
274
  parent.reload
239
275
  parent.recover
@@ -241,7 +277,7 @@ class ParanoidTest < ParanoidBaseTest
241
277
  assert_equal 4, ParanoidTime.count
242
278
  assert_equal 2, ParanoidSection.count
243
279
  assert_equal 1, ParanoidAndroid.count
244
- assert_equal 1, ParanoidHuman.count
280
+ assert_equal 1, ParanoidPolygon.count
245
281
  end
246
282
 
247
283
  def test_non_recursive_recovery
@@ -250,7 +286,7 @@ class ParanoidTest < ParanoidBaseTest
250
286
  @paranoid_time_object.destroy
251
287
  @paranoid_time_object.reload
252
288
 
253
- @paranoid_time_object.recover(:recursive => false)
289
+ @paranoid_time_object.recover(recursive: false)
254
290
 
255
291
  assert_equal 3, ParanoidTime.count
256
292
  assert_equal 0, ParanoidHasManyDependant.count
@@ -261,6 +297,24 @@ class ParanoidTest < ParanoidBaseTest
261
297
  assert_equal 0, HasOneNotParanoid.count
262
298
  end
263
299
 
300
+ def test_dirty
301
+ pt = ParanoidTime.create
302
+ pt.destroy
303
+ assert_not pt.changed?
304
+ end
305
+
306
+ def test_delete_dirty
307
+ pt = ParanoidTime.create
308
+ pt.delete
309
+ assert_not pt.changed?
310
+ end
311
+
312
+ def test_destroy_fully_dirty
313
+ pt = ParanoidTime.create
314
+ pt.destroy_fully!
315
+ assert_not pt.changed?
316
+ end
317
+
264
318
  def test_deleted?
265
319
  ParanoidTime.first.destroy
266
320
  assert ParanoidTime.with_deleted.first.deleted?
@@ -269,6 +323,43 @@ class ParanoidTest < ParanoidBaseTest
269
323
  assert ParanoidString.with_deleted.first.deleted?
270
324
  end
271
325
 
326
+ def test_delete_deleted?
327
+ ParanoidTime.first.delete
328
+ assert ParanoidTime.with_deleted.first.deleted?
329
+
330
+ ParanoidString.first.delete
331
+ assert ParanoidString.with_deleted.first.deleted?
332
+ end
333
+
334
+ def test_destroy_fully_deleted?
335
+ object = ParanoidTime.first
336
+ object.destroy_fully!
337
+ assert object.deleted?
338
+
339
+ object = ParanoidString.first
340
+ object.destroy_fully!
341
+ assert object.deleted?
342
+ end
343
+
344
+ def test_deleted_fully?
345
+ ParanoidTime.first.destroy
346
+ assert_not ParanoidTime.with_deleted.first.deleted_fully?
347
+
348
+ ParanoidString.first.destroy
349
+ assert ParanoidString.with_deleted.first.deleted?
350
+ end
351
+
352
+ def test_delete_deleted_fully?
353
+ ParanoidTime.first.delete
354
+ assert_not ParanoidTime.with_deleted.first.deleted_fully?
355
+ end
356
+
357
+ def test_destroy_fully_deleted_fully?
358
+ object = ParanoidTime.first
359
+ object.destroy_fully!
360
+ assert object.deleted_fully?
361
+ end
362
+
272
363
  def test_paranoid_destroy_callbacks
273
364
  @paranoid_with_callback = ParanoidWithCallback.first
274
365
  ParanoidWithCallback.transaction do
@@ -308,6 +399,14 @@ class ParanoidTest < ParanoidBaseTest
308
399
  assert @paranoid_with_callback.called_after_recover
309
400
  end
310
401
 
402
+ def test_recovery_callbacks_without_destroy
403
+ @paranoid_with_callback = ParanoidWithCallback.first
404
+ @paranoid_with_callback.recover
405
+
406
+ assert_nil @paranoid_with_callback.called_before_recover
407
+ assert_nil @paranoid_with_callback.called_after_recover
408
+ end
409
+
311
410
  def test_delete_by_multiple_id_is_paranoid
312
411
  model_a = ParanoidBelongsDependant.create
313
412
  model_b = ParanoidBelongsDependant.create
@@ -356,81 +455,179 @@ class ParanoidTest < ParanoidBaseTest
356
455
 
357
456
  # Test string type columns that don't have a nil value when not deleted (Y/N for example)
358
457
  def test_string_type_with_no_nil_value_before_destroy
359
- ps = ParanoidString.create!(:deleted => 'not dead')
360
- assert_equal 1, ParanoidString.where(:id => ps).count
458
+ ps = ParanoidString.create!(deleted: "not dead")
459
+ assert_equal 1, ParanoidString.where(id: ps).count
361
460
  end
362
461
 
363
462
  def test_string_type_with_no_nil_value_after_destroy
364
- ps = ParanoidString.create!(:deleted => 'not dead')
463
+ ps = ParanoidString.create!(deleted: "not dead")
365
464
  ps.destroy
366
- assert_equal 0, ParanoidString.where(:id => ps).count
465
+ assert_equal 0, ParanoidString.where(id: ps).count
367
466
  end
368
467
 
369
468
  def test_string_type_with_no_nil_value_before_destroy_with_deleted
370
- ps = ParanoidString.create!(:deleted => 'not dead')
371
- assert_equal 1, ParanoidString.with_deleted.where(:id => ps).count
469
+ ps = ParanoidString.create!(deleted: "not dead")
470
+ assert_equal 1, ParanoidString.with_deleted.where(id: ps).count
372
471
  end
373
472
 
374
473
  def test_string_type_with_no_nil_value_after_destroy_with_deleted
375
- ps = ParanoidString.create!(:deleted => 'not dead')
474
+ ps = ParanoidString.create!(deleted: "not dead")
376
475
  ps.destroy
377
- assert_equal 1, ParanoidString.with_deleted.where(:id => ps).count
476
+ assert_equal 1, ParanoidString.with_deleted.where(id: ps).count
378
477
  end
379
478
 
380
479
  def test_string_type_with_no_nil_value_before_destroy_only_deleted
381
- ps = ParanoidString.create!(:deleted => 'not dead')
382
- assert_equal 0, ParanoidString.only_deleted.where(:id => ps).count
480
+ ps = ParanoidString.create!(deleted: "not dead")
481
+ assert_equal 0, ParanoidString.only_deleted.where(id: ps).count
383
482
  end
384
483
 
385
484
  def test_string_type_with_no_nil_value_after_destroy_only_deleted
386
- ps = ParanoidString.create!(:deleted => 'not dead')
485
+ ps = ParanoidString.create!(deleted: "not dead")
387
486
  ps.destroy
388
- assert_equal 1, ParanoidString.only_deleted.where(:id => ps).count
487
+ assert_equal 1, ParanoidString.only_deleted.where(id: ps).count
389
488
  end
390
489
 
391
490
  def test_string_type_with_no_nil_value_after_destroyed_twice
392
- ps = ParanoidString.create!(:deleted => 'not dead')
491
+ ps = ParanoidString.create!(deleted: "not dead")
393
492
  2.times { ps.destroy }
394
- assert_equal 0, ParanoidString.with_deleted.where(:id => ps).count
493
+ assert_equal 0, ParanoidString.with_deleted.where(id: ps).count
395
494
  end
396
495
 
397
496
  # Test boolean type columns, that are not nullable
398
497
  def test_boolean_type_with_no_nil_value_before_destroy
399
- ps = ParanoidBooleanNotNullable.create!()
400
- assert_equal 1, ParanoidBooleanNotNullable.where(:id => ps).count
498
+ ps = ParanoidBooleanNotNullable.create!
499
+ assert_equal 1, ParanoidBooleanNotNullable.where(id: ps).count
401
500
  end
402
501
 
403
502
  def test_boolean_type_with_no_nil_value_after_destroy
404
- ps = ParanoidBooleanNotNullable.create!()
503
+ ps = ParanoidBooleanNotNullable.create!
405
504
  ps.destroy
406
- assert_equal 0, ParanoidBooleanNotNullable.where(:id => ps).count
505
+ assert_equal 0, ParanoidBooleanNotNullable.where(id: ps).count
407
506
  end
408
507
 
409
508
  def test_boolean_type_with_no_nil_value_before_destroy_with_deleted
410
- ps = ParanoidBooleanNotNullable.create!()
411
- assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
509
+ ps = ParanoidBooleanNotNullable.create!
510
+ assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(id: ps).count
412
511
  end
413
512
 
414
513
  def test_boolean_type_with_no_nil_value_after_destroy_with_deleted
415
- ps = ParanoidBooleanNotNullable.create!()
514
+ ps = ParanoidBooleanNotNullable.create!
416
515
  ps.destroy
417
- assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
516
+ assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(id: ps).count
418
517
  end
419
518
 
420
519
  def test_boolean_type_with_no_nil_value_before_destroy_only_deleted
421
- ps = ParanoidBooleanNotNullable.create!()
422
- assert_equal 0, ParanoidBooleanNotNullable.only_deleted.where(:id => ps).count
520
+ ps = ParanoidBooleanNotNullable.create!
521
+ assert_equal 0, ParanoidBooleanNotNullable.only_deleted.where(id: ps).count
423
522
  end
424
523
 
425
524
  def test_boolean_type_with_no_nil_value_after_destroy_only_deleted
426
- ps = ParanoidBooleanNotNullable.create!()
525
+ ps = ParanoidBooleanNotNullable.create!
427
526
  ps.destroy
428
- assert_equal 1, ParanoidBooleanNotNullable.only_deleted.where(:id => ps).count
527
+ assert_equal 1, ParanoidBooleanNotNullable.only_deleted.where(id: ps).count
429
528
  end
430
529
 
431
530
  def test_boolean_type_with_no_nil_value_after_destroyed_twice
432
- ps = ParanoidBooleanNotNullable.create!()
531
+ ps = ParanoidBooleanNotNullable.create!
532
+ 2.times { ps.destroy }
533
+ assert_equal 0, ParanoidBooleanNotNullable.with_deleted.where(id: ps).count
534
+ end
535
+
536
+ def test_no_double_tap_destroys_fully
537
+ ps = ParanoidNoDoubleTapDestroysFully.create!
433
538
  2.times { ps.destroy }
434
- assert_equal 0, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
539
+ assert_equal 1, ParanoidNoDoubleTapDestroysFully.with_deleted.where(id: ps).count
540
+ end
541
+
542
+ def test_decrement_counters
543
+ paranoid_boolean = ParanoidBoolean.create!
544
+ paranoid_with_counter_cache = ParanoidWithCounterCache
545
+ .create!(paranoid_boolean: paranoid_boolean)
546
+
547
+ assert_equal 1, paranoid_boolean.paranoid_with_counter_caches_count
548
+
549
+ paranoid_with_counter_cache.destroy
550
+
551
+ assert_equal 0, paranoid_boolean.reload.paranoid_with_counter_caches_count
552
+ end
553
+
554
+ def test_decrement_custom_counters
555
+ paranoid_boolean = ParanoidBoolean.create!
556
+ paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache
557
+ .create!(paranoid_boolean: paranoid_boolean)
558
+
559
+ assert_equal 1, paranoid_boolean.custom_counter_cache
560
+
561
+ paranoid_with_custom_counter_cache.destroy
562
+
563
+ assert_equal 0, paranoid_boolean.reload.custom_counter_cache
564
+ end
565
+
566
+ def test_destroy_with_optional_belongs_to_and_counter_cache
567
+ ps = ParanoidWithCounterCacheOnOptionalBelognsTo.create!
568
+ ps.destroy
569
+ assert_equal 1, ParanoidWithCounterCacheOnOptionalBelognsTo.only_deleted
570
+ .where(id: ps).count
571
+ end
572
+
573
+ def test_hard_destroy_decrement_counters
574
+ paranoid_boolean = ParanoidBoolean.create!
575
+ paranoid_with_counter_cache = ParanoidWithCounterCache
576
+ .create!(paranoid_boolean: paranoid_boolean)
577
+
578
+ assert_equal 1, paranoid_boolean.paranoid_with_counter_caches_count
579
+
580
+ paranoid_with_counter_cache.destroy_fully!
581
+
582
+ assert_equal 0, paranoid_boolean.reload.paranoid_with_counter_caches_count
583
+ end
584
+
585
+ def test_hard_destroy_decrement_custom_counters
586
+ paranoid_boolean = ParanoidBoolean.create!
587
+ paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache
588
+ .create!(paranoid_boolean: paranoid_boolean)
589
+
590
+ assert_equal 1, paranoid_boolean.custom_counter_cache
591
+
592
+ paranoid_with_custom_counter_cache.destroy_fully!
593
+
594
+ assert_equal 0, paranoid_boolean.reload.custom_counter_cache
595
+ end
596
+
597
+ def test_increment_counters
598
+ paranoid_boolean = ParanoidBoolean.create!
599
+ paranoid_with_counter_cache = ParanoidWithCounterCache
600
+ .create!(paranoid_boolean: paranoid_boolean)
601
+
602
+ assert_equal 1, paranoid_boolean.paranoid_with_counter_caches_count
603
+
604
+ paranoid_with_counter_cache.destroy
605
+
606
+ assert_equal 0, paranoid_boolean.reload.paranoid_with_counter_caches_count
607
+
608
+ paranoid_with_counter_cache.recover
609
+
610
+ assert_equal 1, paranoid_boolean.reload.paranoid_with_counter_caches_count
611
+ end
612
+
613
+ def test_increment_custom_counters
614
+ paranoid_boolean = ParanoidBoolean.create!
615
+ paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache
616
+ .create!(paranoid_boolean: paranoid_boolean)
617
+
618
+ assert_equal 1, paranoid_boolean.custom_counter_cache
619
+
620
+ paranoid_with_custom_counter_cache.destroy
621
+
622
+ assert_equal 0, paranoid_boolean.reload.custom_counter_cache
623
+
624
+ paranoid_with_custom_counter_cache.recover
625
+
626
+ assert_equal 1, paranoid_boolean.reload.custom_counter_cache
627
+ end
628
+
629
+ def test_explicitly_setting_table_name_after_acts_as_paranoid_macro
630
+ assert_equal "explicit_table.deleted_at", ParanoidWithExplicitTableNameAfterMacro
631
+ .paranoid_column_reference
435
632
  end
436
633
  end