kakurenbo 0.1.3 → 0.2.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,3 @@
1
1
  module Kakurenbo
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,178 @@
1
+ require 'spec_helper'
2
+
3
+ #
4
+ # NormalChildModel [has_many]
5
+ # ParentModel < ParanoidChildModel [has_many]
6
+ # ParanoidSingleChildModel [has_many][belongs_to]
7
+ #
8
+ describe Kakurenbo::Core do
9
+ create_temp_table(:parent_models) { |t| t.integer :child_belongs_to_id; t.datetime :deleted_at }
10
+ create_temp_table(:normal_child_models) { |t| t.integer :parent_model_id }
11
+ create_temp_table(:paranoid_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
12
+ create_temp_table(:paranoid_single_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
13
+
14
+ subject :subject_soft_delete do
15
+ create_unrelated_children
16
+ expect { parent.destroy! }.to change(child_class, :count).by(children.length * -1)
17
+ end
18
+
19
+ subject :subject_restore do
20
+ create_unrelated_children
21
+ expect { parent.destroy! }.to change(child_class, :count).by(children.length * -1)
22
+ expect { parent.restore! }.to change(child_class, :count).by(children.length)
23
+ end
24
+
25
+ subject :subject_not_restore do
26
+ parent.destroy!
27
+ expect { parent.restore! }.not_to change(child_class, :count)
28
+ end
29
+
30
+ let :create_unrelated_children do
31
+ [
32
+ child_class.create!,
33
+ child_class.create!,
34
+ ]
35
+ end
36
+
37
+ let :destroy_children do
38
+ children.each {|child| child.destroy!}
39
+ end
40
+
41
+ let :parent do
42
+ parent_class.create!
43
+ end
44
+
45
+ let :parent_class do
46
+ ParentModel.tap do |parent_class|
47
+ parent_class.has_many :normal_child_models, :dependent => :destroy
48
+ parent_class.has_many :paranoid_child_models, :dependent => :destroy
49
+
50
+ parent_class.has_one :child_has_one, :class_name => :ParanoidSingleChildModel, :dependent => :destroy
51
+ parent_class.belongs_to :child_belongs_to, :class_name => :ParanoidSingleChildModel, :dependent => :destroy
52
+ end
53
+ end
54
+
55
+ describe 'NormalChildModel' do
56
+ let :child_class do
57
+ NormalChildModel
58
+ end
59
+
60
+ let :children do
61
+ [
62
+ parent.normal_child_models.create!,
63
+ parent.normal_child_models.create!,
64
+ parent.normal_child_models.create!,
65
+ ]
66
+ end
67
+
68
+ context 'when parent is destroyed' do
69
+ it 'related children will be destroyed.' do
70
+ subject_soft_delete
71
+ end
72
+ end
73
+ end
74
+
75
+ describe 'ParanoidChildModel(has_many)' do
76
+ let :child_class do
77
+ ParanoidChildModel
78
+ end
79
+
80
+ let :children do
81
+ [
82
+ parent.paranoid_child_models.create!,
83
+ parent.paranoid_child_models.create!,
84
+ parent.paranoid_child_models.create!,
85
+ ]
86
+ end
87
+
88
+ context 'when parent is destroyed' do
89
+ it 'related children will be destroyed.' do
90
+ subject_soft_delete
91
+ end
92
+ end
93
+
94
+ context 'when parent is restored' do
95
+ it 'related children will be restored.' do
96
+ subject_restore
97
+ end
98
+
99
+ context 'when children are deleted, before restore parent' do
100
+ before :each do
101
+ destroy_children
102
+ end
103
+
104
+ it 'related children will be not restored.' do
105
+ subject_not_restore
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ describe 'ParanoidSingleChildModel(has_one)' do
112
+ let :child_class do
113
+ ParanoidSingleChildModel
114
+ end
115
+
116
+ let :children do
117
+ [
118
+ parent.create_child_has_one!
119
+ ]
120
+ end
121
+
122
+ context 'when parent is destroyed' do
123
+ it 'related children will be destroyed.' do
124
+ subject_soft_delete
125
+ end
126
+ end
127
+
128
+ context 'when parent is restored' do
129
+ it 'related children will be restored.' do
130
+ subject_restore
131
+ end
132
+
133
+ context 'when children are deleted, before restore parent' do
134
+ before :each do
135
+ destroy_children
136
+ end
137
+
138
+ it 'related children will be not restored.' do
139
+ subject_not_restore
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ describe 'ParanoidSingleChildModel(has_one)' do
146
+ let :child_class do
147
+ ParanoidSingleChildModel
148
+ end
149
+
150
+ let :children do
151
+ [
152
+ parent.create_child_belongs_to!
153
+ ]
154
+ end
155
+
156
+ context 'when parent is destroyed' do
157
+ it 'related children will be destroyed.' do
158
+ subject_soft_delete
159
+ end
160
+ end
161
+
162
+ context 'when parent is restored' do
163
+ it 'related children will be restored.' do
164
+ subject_restore
165
+ end
166
+
167
+ context 'when children are deleted, before restore parent' do
168
+ before :each do
169
+ destroy_children
170
+ end
171
+
172
+ it 'related children will be not restored.' do
173
+ subject_not_restore
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kakurenbo::Core::Callbacks do
4
+ create_temp_table(:paranoid_models){ |t| t.datetime :deleted_at }
5
+ before :all do
6
+ ParanoidModel.tap do |klass|
7
+ klass.before_destroy :callback_before_destroy
8
+ klass.after_destroy :callback_after_destroy
9
+ klass.after_commit :callback_after_commit
10
+
11
+ klass.before_restore :callback_before_restore
12
+ klass.after_restore :callback_after_restore
13
+
14
+ klass.before_update :callback_before_update
15
+ klass.before_save :callback_before_save
16
+ klass.before_validation :callback_before_validation
17
+ end
18
+ end
19
+
20
+ let! :model do
21
+ model_class.create!
22
+ end
23
+
24
+ let :model_class do
25
+ ParanoidModel.tap do |klass|
26
+ allow_any_instance_of(klass).to receive(:callback_before_destroy) { true }
27
+ allow_any_instance_of(klass).to receive(:callback_after_destroy) { true }
28
+ allow_any_instance_of(klass).to receive(:callback_after_commit) { true }
29
+
30
+ allow_any_instance_of(klass).to receive(:callback_before_restore) { true }
31
+ allow_any_instance_of(klass).to receive(:callback_after_restore) { true }
32
+
33
+ allow_any_instance_of(klass).to receive(:callback_before_update) { true }
34
+ allow_any_instance_of(klass).to receive(:callback_before_save) { true }
35
+ allow_any_instance_of(klass).to receive(:callback_before_validation) { true }
36
+ end
37
+ end
38
+
39
+ context 'when call #delete' do
40
+ subject { model.delete }
41
+
42
+ it 'destroy-callbacks will not be called.' do
43
+ expect(model).not_to receive(:callback_before_destroy)
44
+ expect(model).not_to receive(:callback_after_destroy)
45
+ expect(model).not_to receive(:callback_after_commit)
46
+
47
+ subject
48
+ end
49
+
50
+ it 'save-callbacks will not be called.' do
51
+ expect(model).not_to receive(:callback_before_update)
52
+ expect(model).not_to receive(:callback_before_save)
53
+ expect(model).not_to receive(:callback_before_validation)
54
+
55
+ subject
56
+ end
57
+ end
58
+
59
+ context 'when call #destroy' do
60
+ subject { model.destroy }
61
+
62
+ it 'destroy-callbacks will be called.' do
63
+ expect(model).to receive(:callback_before_destroy).once
64
+ expect(model).to receive(:callback_after_destroy).once
65
+ expect(model).to receive(:callback_after_commit).once
66
+
67
+ subject
68
+ end
69
+
70
+ it 'save-callbacks will not be called.' do
71
+ expect(model).not_to receive(:callback_before_update)
72
+ expect(model).not_to receive(:callback_before_save)
73
+ expect(model).not_to receive(:callback_before_validation)
74
+
75
+ subject
76
+ end
77
+ end
78
+
79
+ context 'when call #restore' do
80
+ before :each do
81
+ model.destroy!
82
+ end
83
+
84
+ subject { model.restore }
85
+
86
+ it 'restore-callbacks will be called.' do
87
+ expect(model).to receive(:callback_before_restore).once
88
+ expect(model).to receive(:callback_after_restore).once
89
+ expect(model).to receive(:callback_after_commit).once
90
+
91
+ subject
92
+ end
93
+
94
+ it 'save-callbacks will not be called.' do
95
+ expect(model).not_to receive(:callback_before_update)
96
+ expect(model).not_to receive(:callback_before_save)
97
+ expect(model).not_to receive(:callback_before_validation)
98
+
99
+ subject
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,186 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kakurenbo::Core do
4
+ create_temp_table(:paranoid_models){ |t| t.datetime :deleted_at }
5
+ before :all do
6
+ ParanoidModel.tap do |klass|
7
+ klass.before_destroy :callback_before_destroy
8
+ klass.before_restore :callback_before_restore
9
+ end
10
+ end
11
+
12
+ subject :subject_hard_delete do
13
+ expect {
14
+ subject
15
+ }.to change {
16
+ model_class.with_deleted.find_by(:id => model.id)
17
+ }.to(nil)
18
+ end
19
+
20
+ subject :subject_not_hard_delete do
21
+ expect {
22
+ subject
23
+ }.not_to change {
24
+ model_class.with_deleted.find_by(:id => model.id)
25
+ }
26
+ end
27
+
28
+ subject :subject_soft_delete do
29
+ expect { subject }.to change { model.reload.destroyed? }.from(false).to(true)
30
+ end
31
+
32
+ subject :subject_restore do
33
+ expect { subject }.to change { model.reload.destroyed? }.from(true).to(false)
34
+ end
35
+
36
+ let! :model do
37
+ model_class.create!
38
+ end
39
+
40
+ let :model_class do
41
+ ParanoidModel.tap do |klass|
42
+ allow_any_instance_of(klass).to receive(:callback_before_destroy) { true }
43
+ allow_any_instance_of(klass).to receive(:callback_before_restore) { true }
44
+ end
45
+ end
46
+
47
+ let :now do
48
+ Time.now.tap do |now|
49
+ allow(Time).to receive(:now) { now.dup }
50
+ end
51
+ end
52
+
53
+ describe '#delete' do
54
+ subject { model.delete }
55
+
56
+ it 'record will be soft-deleted.' do
57
+ subject_soft_delete
58
+ end
59
+
60
+ it 'record will not be hard-deleted.' do
61
+ subject_not_hard_delete
62
+ end
63
+
64
+ context 'when with hard-delete option' do
65
+ subject { model.delete(:hard => true) }
66
+
67
+ it 'record will be hard-deleted.' do
68
+ subject_hard_delete
69
+ end
70
+ end
71
+ end
72
+
73
+ describe '#destroy' do
74
+ subject { model.destroy }
75
+
76
+ it 'record will be soft-deleted.' do
77
+ subject_soft_delete
78
+ end
79
+
80
+ it 'record will not be hard-deleted.' do
81
+ subject_not_hard_delete
82
+ end
83
+
84
+ it 'return self' do
85
+ expect(subject).to eq(model)
86
+ end
87
+
88
+ context 'when action is cancelled' do
89
+ before :each do
90
+ allow(model).to receive(:callback_before_destroy) { false }
91
+ end
92
+
93
+ it 'record will not be soft-deleted.' do
94
+ expect { subject }.not_to change { model.reload.destroyed? }
95
+ end
96
+
97
+ it 'return falsey' do
98
+ expect(subject).to be_falsey
99
+ end
100
+ end
101
+
102
+ context 'when with hard-delete option' do
103
+ subject { model.destroy(:hard => true) }
104
+
105
+ it 'record will be hard-deleted.' do
106
+ subject_hard_delete
107
+ end
108
+ end
109
+ end
110
+
111
+ describe '#destroy!' do
112
+ subject { model.destroy! }
113
+ context 'when action is cancelled' do
114
+ before :each do
115
+ allow(model).to receive(:callback_before_destroy) { false }
116
+ end
117
+
118
+ it 'raise ActiveRecord::RecordNotDestroyed' do
119
+ expect{subject}.to raise_error(ActiveRecord::RecordNotDestroyed)
120
+ end
121
+ end
122
+ end
123
+
124
+ describe '#destroyed?' do
125
+ subject { model.destroyed? }
126
+
127
+ context 'when model not deleted' do
128
+ it 'return falsey' do
129
+ expect(subject).to be_falsey
130
+ end
131
+ end
132
+
133
+ context 'when model deleted' do
134
+ before :each do
135
+ model.destroy
136
+ end
137
+
138
+ it 'return truthy' do
139
+ expect(subject).to be_truthy
140
+ end
141
+ end
142
+ end
143
+
144
+ describe '#restore' do
145
+ before :each do
146
+ model.destroy
147
+ end
148
+
149
+ subject { model.restore }
150
+
151
+ it 'record will be restored.' do
152
+ subject_restore
153
+ end
154
+
155
+ it 'return self' do
156
+ expect(subject).to eq(model)
157
+ end
158
+
159
+ context 'when action is cancelled' do
160
+ before :each do
161
+ allow(model).to receive(:callback_before_restore) { false }
162
+ end
163
+
164
+ it 'record will not be restored.' do
165
+ expect { subject }.not_to change { model.reload.destroyed? }
166
+ end
167
+
168
+ it 'return falsey' do
169
+ expect(subject).to be_falsey
170
+ end
171
+ end
172
+ end
173
+
174
+ describe '#restore!' do
175
+ subject { model.restore! }
176
+ context 'when action is cancelled' do
177
+ before :each do
178
+ allow(model).to receive(:callback_before_restore) { false }
179
+ end
180
+
181
+ it 'raise ActiveRecord::RecordNotRestored' do
182
+ expect{subject}.to raise_error(ActiveRecord::RecordNotRestored)
183
+ end
184
+ end
185
+ end
186
+ end