acts_as_ordered_tree 1.3.1 → 2.0.0.beta3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/acts_as_ordered_tree.rb +22 -100
- data/lib/acts_as_ordered_tree/adapters.rb +17 -0
- data/lib/acts_as_ordered_tree/adapters/abstract.rb +23 -0
- data/lib/acts_as_ordered_tree/adapters/postgresql.rb +150 -0
- data/lib/acts_as_ordered_tree/adapters/recursive.rb +157 -0
- data/lib/acts_as_ordered_tree/compatibility.rb +22 -0
- data/lib/acts_as_ordered_tree/compatibility/active_record/association_scope.rb +9 -0
- data/lib/acts_as_ordered_tree/compatibility/active_record/default_scoped.rb +19 -0
- data/lib/acts_as_ordered_tree/compatibility/active_record/null_relation.rb +71 -0
- data/lib/acts_as_ordered_tree/compatibility/features.rb +153 -0
- data/lib/acts_as_ordered_tree/deprecate.rb +24 -0
- data/lib/acts_as_ordered_tree/hooks.rb +38 -0
- data/lib/acts_as_ordered_tree/hooks/update.rb +86 -0
- data/lib/acts_as_ordered_tree/instance_methods.rb +92 -453
- data/lib/acts_as_ordered_tree/iterators/arranger.rb +35 -0
- data/lib/acts_as_ordered_tree/iterators/level_calculator.rb +52 -0
- data/lib/acts_as_ordered_tree/iterators/orphans_pruner.rb +58 -0
- data/lib/acts_as_ordered_tree/node.rb +78 -0
- data/lib/acts_as_ordered_tree/node/attributes.rb +48 -0
- data/lib/acts_as_ordered_tree/node/movement.rb +62 -0
- data/lib/acts_as_ordered_tree/node/movements.rb +111 -0
- data/lib/acts_as_ordered_tree/node/predicates.rb +98 -0
- data/lib/acts_as_ordered_tree/node/reloading.rb +49 -0
- data/lib/acts_as_ordered_tree/node/siblings.rb +139 -0
- data/lib/acts_as_ordered_tree/node/traversals.rb +53 -0
- data/lib/acts_as_ordered_tree/persevering_transaction.rb +93 -0
- data/lib/acts_as_ordered_tree/position.rb +143 -0
- data/lib/acts_as_ordered_tree/relation/arrangeable.rb +33 -0
- data/lib/acts_as_ordered_tree/relation/iterable.rb +41 -0
- data/lib/acts_as_ordered_tree/relation/preloaded.rb +46 -11
- data/lib/acts_as_ordered_tree/transaction/base.rb +57 -0
- data/lib/acts_as_ordered_tree/transaction/callbacks.rb +67 -0
- data/lib/acts_as_ordered_tree/transaction/create.rb +68 -0
- data/lib/acts_as_ordered_tree/transaction/destroy.rb +34 -0
- data/lib/acts_as_ordered_tree/transaction/dsl.rb +214 -0
- data/lib/acts_as_ordered_tree/transaction/factory.rb +67 -0
- data/lib/acts_as_ordered_tree/transaction/move.rb +70 -0
- data/lib/acts_as_ordered_tree/transaction/passthrough.rb +12 -0
- data/lib/acts_as_ordered_tree/transaction/reorder.rb +42 -0
- data/lib/acts_as_ordered_tree/transaction/save.rb +64 -0
- data/lib/acts_as_ordered_tree/transaction/update.rb +78 -0
- data/lib/acts_as_ordered_tree/tree.rb +148 -0
- data/lib/acts_as_ordered_tree/tree/association.rb +20 -0
- data/lib/acts_as_ordered_tree/tree/callbacks.rb +57 -0
- data/lib/acts_as_ordered_tree/tree/children_association.rb +120 -0
- data/lib/acts_as_ordered_tree/tree/columns.rb +102 -0
- data/lib/acts_as_ordered_tree/tree/deprecated_columns_accessors.rb +24 -0
- data/lib/acts_as_ordered_tree/tree/parent_association.rb +31 -0
- data/lib/acts_as_ordered_tree/tree/perseverance.rb +19 -0
- data/lib/acts_as_ordered_tree/tree/scopes.rb +56 -0
- data/lib/acts_as_ordered_tree/validators.rb +1 -1
- data/lib/acts_as_ordered_tree/version.rb +1 -1
- data/spec/acts_as_ordered_tree_spec.rb +80 -909
- data/spec/adapters/postgresql_spec.rb +14 -0
- data/spec/adapters/recursive_spec.rb +12 -0
- data/spec/adapters/shared.rb +272 -0
- data/spec/callbacks_spec.rb +177 -0
- data/spec/counter_cache_spec.rb +31 -0
- data/spec/create_spec.rb +110 -0
- data/spec/destroy_spec.rb +57 -0
- data/spec/inheritance_spec.rb +176 -0
- data/spec/move_spec.rb +94 -0
- data/spec/node/movements/concurrent_movements_spec.rb +354 -0
- data/spec/node/movements/move_higher_spec.rb +46 -0
- data/spec/node/movements/move_lower_spec.rb +46 -0
- data/spec/node/movements/move_to_child_of_spec.rb +147 -0
- data/spec/node/movements/move_to_child_with_index_spec.rb +124 -0
- data/spec/node/movements/move_to_child_with_position_spec.rb +85 -0
- data/spec/node/movements/move_to_left_of_spec.rb +120 -0
- data/spec/node/movements/move_to_right_of_spec.rb +120 -0
- data/spec/node/movements/move_to_root_spec.rb +67 -0
- data/spec/node/predicates_spec.rb +211 -0
- data/spec/node/reloading_spec.rb +42 -0
- data/spec/node/siblings_spec.rb +193 -0
- data/spec/node/traversals_spec.rb +71 -0
- data/spec/persevering_transaction_spec.rb +98 -0
- data/spec/relation/arrangeable_spec.rb +88 -0
- data/spec/relation/iterable_spec.rb +104 -0
- data/spec/relation/preloaded_spec.rb +57 -0
- data/spec/reorder_spec.rb +83 -0
- data/spec/spec_helper.rb +30 -38
- data/spec/support/db/boot.rb +22 -0
- data/spec/{db → support/db}/config.travis.yml +2 -0
- data/spec/{db → support/db}/config.yml +1 -0
- data/spec/{db → support/db}/schema.rb +9 -0
- data/spec/support/factories.rb +2 -2
- data/spec/support/matchers.rb +67 -58
- data/spec/support/models.rb +6 -14
- data/spec/support/tree_factory.rb +315 -0
- data/spec/tree/children_association_spec.rb +72 -0
- data/spec/tree/columns_spec.rb +65 -0
- data/spec/tree/scopes_spec.rb +39 -0
- metadata +161 -43
- data/lib/acts_as_ordered_tree/adapters/postgresql_adapter.rb +0 -104
- data/lib/acts_as_ordered_tree/arrangeable.rb +0 -80
- data/lib/acts_as_ordered_tree/class_methods.rb +0 -72
- data/lib/acts_as_ordered_tree/relation/base.rb +0 -26
- data/lib/acts_as_ordered_tree/tenacious_transaction.rb +0 -30
- data/spec/concurrency_support_spec.rb +0 -156
@@ -1,947 +1,125 @@
|
|
1
1
|
require File.expand_path('../spec_helper', __FILE__)
|
2
2
|
|
3
3
|
describe ActsAsOrderedTree, :transactional do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
its(:parent_column) { should eq :parent_id }
|
8
|
-
its(:position_column) { should eq :position }
|
9
|
-
its(:depth_column) { should eq :depth }
|
10
|
-
its(:children_counter_cache_column) { be_nil }
|
11
|
-
|
12
|
-
if ActsAsOrderedTree::PROTECTED_ATTRIBUTES_SUPPORTED
|
13
|
-
context "instance" do
|
14
|
-
subject { Default.new }
|
15
|
-
|
16
|
-
it { should_not allow_mass_assignment_of(:position) }
|
17
|
-
it { should_not allow_mass_assignment_of(:depth) }
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe "default with counter cache" do
|
23
|
-
subject { DefaultWithCounterCache }
|
24
|
-
|
25
|
-
its(:children_counter_cache_column) { should eq :categories_count }
|
26
|
-
end
|
27
|
-
|
28
|
-
describe "renamed columns" do
|
29
|
-
subject { RenamedColumns }
|
30
|
-
|
31
|
-
its(:parent_column) { should eq :mother_id }
|
32
|
-
its(:position_column) { should eq :red }
|
33
|
-
its(:depth_column) { should eq :pitch }
|
34
|
-
|
35
|
-
if ActsAsOrderedTree::PROTECTED_ATTRIBUTES_SUPPORTED
|
36
|
-
context "instance" do
|
37
|
-
subject { RenamedColumns.new }
|
38
|
-
|
39
|
-
it { should_not allow_mass_assignment_of(:red) }
|
40
|
-
it { should_not allow_mass_assignment_of(:pitch) }
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
it "creation_with_altered_column_names" do
|
46
|
-
lambda {
|
47
|
-
RenamedColumns.create!()
|
48
|
-
}.should_not raise_exception
|
49
|
-
end
|
50
|
-
|
51
|
-
describe ".roots" do
|
52
|
-
# create fixture
|
53
|
-
before { FactoryGirl.create_list(:default, 3) }
|
54
|
-
|
55
|
-
subject { Default.roots }
|
56
|
-
|
57
|
-
its(:entries) { should eq Default.where(:parent_id => nil).order(:position).to_a }
|
58
|
-
end
|
59
|
-
|
60
|
-
describe ".leaves" do
|
61
|
-
# create fixture
|
62
|
-
let(:root) { create :default_with_counter_cache }
|
63
|
-
before { create_list :default_with_counter_cache, 2, :parent => root }
|
64
|
-
|
65
|
-
subject { DefaultWithCounterCache }
|
66
|
-
|
67
|
-
it { should respond_to(:leaves) }
|
68
|
-
its(:leaves) { should have(2).items }
|
69
|
-
end
|
70
|
-
|
71
|
-
describe ".root" do
|
72
|
-
# create fixture
|
73
|
-
let!(:root) { create :default }
|
74
|
-
|
75
|
-
context "given a single root node" do
|
76
|
-
subject { root }
|
77
|
-
|
78
|
-
its(:position) { should eq 1 }
|
79
|
-
end
|
80
|
-
|
81
|
-
context "given multiple root nodes" do
|
82
|
-
before { create_list :default, 3 }
|
83
|
-
|
84
|
-
subject { Default }
|
85
|
-
|
86
|
-
its(:root) { should eq root }
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
describe "#root?, #child?, #leaf?, #branch? and #root" do
|
91
|
-
shared_examples "tree with predicates" do |factory_name|
|
92
|
-
# create fixture
|
93
|
-
let!(:root) { create factory_name }
|
94
|
-
let!(:child) { create factory_name, :parent => root }
|
95
|
-
let!(:grandchild) { create factory_name, :parent => child }
|
96
|
-
|
97
|
-
before { root.reload }
|
98
|
-
before { child.reload }
|
99
|
-
before { grandchild.reload }
|
100
|
-
|
101
|
-
context "given root node" do
|
102
|
-
subject { root }
|
103
|
-
|
104
|
-
it { should be_root }
|
105
|
-
it { should_not be_child }
|
106
|
-
it { should_not be_leaf }
|
107
|
-
it { should be_branch }
|
108
|
-
its(:root) { should eq root }
|
109
|
-
its(:level) { should eq 0 }
|
110
|
-
end
|
111
|
-
|
112
|
-
context "given a branch node with children" do
|
113
|
-
subject { child }
|
114
|
-
|
115
|
-
it { should_not be_root }
|
116
|
-
it { should be_child }
|
117
|
-
it { should_not be_leaf }
|
118
|
-
it { should be_branch }
|
119
|
-
its(:root) { should eq root }
|
120
|
-
its(:level) { should eq 1 }
|
121
|
-
end
|
122
|
-
|
123
|
-
context "given a leaf node" do
|
124
|
-
subject { grandchild }
|
125
|
-
|
126
|
-
it { should_not be_root }
|
127
|
-
it { should be_child }
|
128
|
-
it { should be_leaf }
|
129
|
-
it { should_not be_branch }
|
130
|
-
its(:root) { should eq root }
|
131
|
-
its(:level) { should eq 2 }
|
132
|
-
end
|
133
|
-
|
134
|
-
context "given a new record" do
|
135
|
-
subject { build factory_name }
|
136
|
-
|
137
|
-
it { should_not be_leaf }
|
138
|
-
it { should be_branch }
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
it_behaves_like "tree with predicates", :default
|
143
|
-
it_behaves_like "tree with predicates", :default_with_counter_cache
|
4
|
+
example 'creation_with_altered_column_names' do
|
5
|
+
expect{RenamedColumns.create!}.not_to raise_error
|
144
6
|
end
|
145
7
|
|
146
|
-
describe
|
147
|
-
|
148
|
-
let!(:child_1) { create :default, :parent => root }
|
149
|
-
let!(:child_2) { create :default, :parent => root }
|
150
|
-
let!(:child_3) { create :default, :parent => root }
|
151
|
-
|
152
|
-
context "given a node without siblings" do
|
153
|
-
subject { root }
|
154
|
-
|
155
|
-
it { should be_first }
|
156
|
-
it { should be_last }
|
157
|
-
end
|
158
|
-
|
159
|
-
context "given a node, first in the list" do
|
160
|
-
subject { child_1 }
|
161
|
-
|
162
|
-
it { should be_first }
|
163
|
-
it { should_not be_last }
|
164
|
-
end
|
165
|
-
|
166
|
-
context "given a node, nor first neither last" do
|
167
|
-
subject { child_2 }
|
168
|
-
|
169
|
-
it { should_not be_first }
|
170
|
-
it { should_not be_last }
|
171
|
-
end
|
172
|
-
|
173
|
-
context "given a node, last in the list" do
|
174
|
-
subject { child_3 }
|
175
|
-
|
176
|
-
it { should_not be_first }
|
177
|
-
it { should be_last }
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
describe "#level" do
|
182
|
-
context "given a persistent root node" do
|
8
|
+
describe '#level' do
|
9
|
+
context 'given a persistent root node' do
|
183
10
|
subject { create :default }
|
184
11
|
|
185
|
-
|
12
|
+
it { expect(subject.level).to eq 0 }
|
186
13
|
end
|
187
|
-
|
14
|
+
|
15
|
+
context 'given a new root record' do
|
188
16
|
subject { build :default }
|
189
17
|
|
190
|
-
|
18
|
+
it { expect(subject.level).to eq 0 }
|
191
19
|
end
|
192
|
-
|
20
|
+
|
21
|
+
context 'given a persistent node with parent' do
|
193
22
|
let(:root) { create :default }
|
194
23
|
subject { create :default, :parent => root }
|
195
|
-
its(:level) { should eq 1 }
|
196
|
-
end
|
197
|
-
context "given a new node with parent" do
|
198
|
-
let(:root) { create :default }
|
199
|
-
subject { build :default, :parent => root }
|
200
|
-
its(:level) { should eq 1 }
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
describe "#self_and_ancestors" do
|
205
|
-
# create fixture
|
206
|
-
let!(:root) { create :default }
|
207
|
-
let!(:child) { create :default, :parent => root }
|
208
|
-
let!(:grandchild) { create :default, :parent => child }
|
209
|
-
|
210
|
-
context "leaf" do
|
211
|
-
subject { grandchild.self_and_ancestors }
|
212
|
-
|
213
|
-
it { should be_a ActiveRecord::Relation }
|
214
|
-
it { should have(3).items }
|
215
|
-
its(:first) { should eq root }
|
216
|
-
its(:last) { should eq grandchild }
|
217
|
-
end
|
218
|
-
|
219
|
-
context "child" do
|
220
|
-
subject { child.self_and_ancestors }
|
221
24
|
|
222
|
-
it {
|
223
|
-
it { should have(2).items }
|
224
|
-
its(:first) { should eq root }
|
225
|
-
its(:last) { should eq child }
|
25
|
+
it { expect(subject.level).to eq 1 }
|
226
26
|
end
|
227
27
|
|
228
|
-
context
|
229
|
-
|
230
|
-
|
231
|
-
it { should be_a ActiveRecord::Relation }
|
232
|
-
it { should have(1).item }
|
233
|
-
its(:first) { should eq root }
|
234
|
-
end
|
235
|
-
|
236
|
-
context "when record is new" do
|
237
|
-
let(:record) { build(:default, :parent => grandchild) }
|
238
|
-
subject { record.self_and_ancestors }
|
239
|
-
|
240
|
-
it { should have(4).items }
|
241
|
-
it { should include root }
|
242
|
-
it { should include child }
|
243
|
-
it { should include grandchild }
|
244
|
-
it { should include record }
|
245
|
-
end
|
246
|
-
|
247
|
-
context "when parent is changed" do
|
248
|
-
before { grandchild.parent = root }
|
249
|
-
subject { grandchild.self_and_ancestors }
|
250
|
-
|
251
|
-
it { should include root }
|
252
|
-
it { should_not include child }
|
253
|
-
it { should include grandchild }
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
describe "#ancestors" do
|
258
|
-
# create fixture
|
259
|
-
let!(:root) { create :default }
|
260
|
-
let!(:child) { create :default, :parent => root }
|
261
|
-
let!(:grandchild) { create :default, :parent => child }
|
262
|
-
|
263
|
-
context "leaf" do
|
264
|
-
subject { grandchild.ancestors }
|
265
|
-
|
266
|
-
it { should be_a ActiveRecord::Relation }
|
267
|
-
it { should have(2).items }
|
268
|
-
its(:first) { should eq root }
|
269
|
-
its(:last) { should eq child }
|
270
|
-
end
|
271
|
-
|
272
|
-
context "child" do
|
273
|
-
subject { child.ancestors }
|
274
|
-
|
275
|
-
it { should be_a ActiveRecord::Relation }
|
276
|
-
it { should have(1).item }
|
277
|
-
its(:first) { should eq root }
|
278
|
-
end
|
279
|
-
|
280
|
-
context "root" do
|
281
|
-
subject { root.ancestors }
|
282
|
-
|
283
|
-
it { should be_a ActiveRecord::Relation }
|
284
|
-
it { should be_empty }
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
describe "#self_and_descendants" do
|
289
|
-
# create fixture
|
290
|
-
let!(:root) { create :default }
|
291
|
-
let!(:child) { create :default, :parent => root }
|
292
|
-
let!(:grandchild) { create :default, :parent => child }
|
293
|
-
|
294
|
-
context "leaf" do
|
295
|
-
subject { grandchild.self_and_descendants }
|
296
|
-
|
297
|
-
it { should be_a ActiveRecord::Relation }
|
298
|
-
it { should have(1).item }
|
299
|
-
its(:first) { should eq grandchild }
|
300
|
-
end
|
301
|
-
|
302
|
-
context "child" do
|
303
|
-
subject { child.self_and_descendants }
|
304
|
-
|
305
|
-
it { should be_a ActiveRecord::Relation }
|
306
|
-
it { should have(2).items }
|
307
|
-
its(:first) { should eq child }
|
308
|
-
its(:last) { should eq grandchild }
|
309
|
-
end
|
310
|
-
|
311
|
-
context "root" do
|
312
|
-
subject { root.self_and_descendants }
|
313
|
-
|
314
|
-
it { should be_a ActiveRecord::Relation }
|
315
|
-
it { should have(3).items }
|
316
|
-
its(:first) { should eq root }
|
317
|
-
its(:last) { should eq grandchild }
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
describe "#is_descendant_of?, #is_or_is_descendant_of?, #is_ancestor_of?, #is_or_is_ancestor_of?" do
|
322
|
-
# create fixture
|
323
|
-
let!(:root) { create :default }
|
324
|
-
let!(:child) { create :default, :parent => root }
|
325
|
-
let!(:grandchild) { create :default, :parent => child }
|
326
|
-
|
327
|
-
context "grandchild" do
|
328
|
-
subject { grandchild }
|
329
|
-
|
330
|
-
it { should be_is_descendant_of(root) }
|
331
|
-
it { should be_is_or_is_descendant_of(root) }
|
332
|
-
it { should_not be_is_ancestor_of(root) }
|
333
|
-
it { should_not be_is_or_is_ancestor_of(root) }
|
334
|
-
|
335
|
-
it { should be_is_descendant_of(child) }
|
336
|
-
it { should be_is_or_is_descendant_of(child) }
|
337
|
-
it { should_not be_is_ancestor_of(child) }
|
338
|
-
it { should_not be_is_or_is_ancestor_of(child) }
|
339
|
-
|
340
|
-
it { should_not be_is_descendant_of(grandchild) }
|
341
|
-
it { should be_is_or_is_descendant_of(grandchild) }
|
342
|
-
it { should_not be_is_ancestor_of(grandchild) }
|
343
|
-
it { should be_is_or_is_ancestor_of(grandchild) }
|
344
|
-
end
|
345
|
-
|
346
|
-
context "child" do
|
347
|
-
subject { child }
|
348
|
-
|
349
|
-
it { should be_is_descendant_of(root) }
|
350
|
-
it { should be_is_or_is_descendant_of(root) }
|
351
|
-
it { should_not be_is_ancestor_of(root) }
|
352
|
-
it { should_not be_is_or_is_ancestor_of(root) }
|
353
|
-
|
354
|
-
it { should_not be_is_descendant_of(child) }
|
355
|
-
it { should be_is_or_is_descendant_of(child) }
|
356
|
-
it { should_not be_is_ancestor_of(child) }
|
357
|
-
it { should be_is_or_is_ancestor_of(child) }
|
358
|
-
|
359
|
-
it { should_not be_is_descendant_of(grandchild) }
|
360
|
-
it { should_not be_is_or_is_descendant_of(grandchild) }
|
361
|
-
it { should be_is_ancestor_of(grandchild) }
|
362
|
-
it { should be_is_or_is_ancestor_of(grandchild) }
|
363
|
-
end
|
364
|
-
|
365
|
-
context "root" do
|
366
|
-
subject { root }
|
367
|
-
|
368
|
-
it { should_not be_is_descendant_of(root) }
|
369
|
-
it { should be_is_or_is_descendant_of(root) }
|
370
|
-
it { should_not be_is_ancestor_of(root) }
|
371
|
-
it { should be_is_or_is_ancestor_of(root) }
|
372
|
-
|
373
|
-
it { should_not be_is_descendant_of(child) }
|
374
|
-
it { should_not be_is_or_is_descendant_of(child) }
|
375
|
-
it { should be_is_ancestor_of(child) }
|
376
|
-
it { should be_is_or_is_ancestor_of(child) }
|
377
|
-
|
378
|
-
it { should_not be_is_descendant_of(grandchild) }
|
379
|
-
it { should_not be_is_or_is_descendant_of(grandchild) }
|
380
|
-
it { should be_is_ancestor_of(grandchild) }
|
381
|
-
it { should be_is_or_is_ancestor_of(grandchild) }
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
describe "#left_sibling" do
|
386
|
-
shared_examples "tree with siblings" do
|
387
|
-
subject { items }
|
388
|
-
|
389
|
-
its('first.left_sibling') { should be_nil }
|
390
|
-
its('first.right_sibling') { should eq items.second }
|
391
|
-
|
392
|
-
its('second.left_sibling') { should eq items.first }
|
393
|
-
its('second.right_sibling') { should eq items.last }
|
394
|
-
|
395
|
-
its('third.left_sibling') { should eq items.second }
|
396
|
-
its('third.right_sibling') { should be_nil }
|
397
|
-
end
|
398
|
-
|
399
|
-
context "given unscoped tree" do
|
400
|
-
it_should_behave_like "tree with siblings" do
|
401
|
-
let(:items) { create_list :default, 3 }
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
|
-
context "given scoped tree" do
|
406
|
-
let!(:items_1) { create_list :scoped, 3, :scope_type => "s1" }
|
407
|
-
let!(:items_2) { create_list :scoped, 3, :scope_type => "s2" }
|
28
|
+
context 'given a new node with parent' do
|
29
|
+
let(:root) { create :default }
|
30
|
+
subject { build :default, :parent => root }
|
408
31
|
|
409
|
-
|
410
|
-
let(:items) { items_1 }
|
411
|
-
end
|
412
|
-
it_should_behave_like "tree with siblings" do
|
413
|
-
let(:items) { items_2 }
|
414
|
-
end
|
32
|
+
it { expect(subject.level).to eq 1 }
|
415
33
|
end
|
416
|
-
end
|
417
|
-
|
418
|
-
describe '#arrange' do
|
419
|
-
shared_examples 'arrangeable' do
|
420
|
-
let(:child_1) { root.children.first }
|
421
|
-
let(:child_2) { root.children.last }
|
422
|
-
let(:grandchild_11) { child_1.children.first }
|
423
|
-
let(:grandchild_12) { child_1.children.last }
|
424
|
-
let(:grandchild_21) { child_2.children.first }
|
425
|
-
let(:grandchild_22) { child_2.children.last }
|
426
|
-
|
427
|
-
specify '#descendants scope should be arrangeable' do
|
428
|
-
expect(root.descendants.arrange).to eq Hash[
|
429
|
-
child_1 => {
|
430
|
-
grandchild_11 => {},
|
431
|
-
grandchild_12 => {}
|
432
|
-
},
|
433
|
-
child_2 => {
|
434
|
-
grandchild_21 => {},
|
435
|
-
grandchild_22 => {}
|
436
|
-
}
|
437
|
-
]
|
438
|
-
end
|
439
34
|
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
grandchild_12 => {}
|
446
|
-
},
|
447
|
-
child_2 => {
|
448
|
-
grandchild_21 => {},
|
449
|
-
grandchild_22 => {}
|
450
|
-
}
|
35
|
+
context 'a model without depth column' do
|
36
|
+
tree :factory => :scoped do
|
37
|
+
root {
|
38
|
+
child {
|
39
|
+
grandchild
|
451
40
|
}
|
452
|
-
|
41
|
+
}
|
453
42
|
end
|
454
43
|
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
child_1 => {}
|
459
|
-
}
|
460
|
-
]
|
461
|
-
end
|
462
|
-
|
463
|
-
specify '#self_and_ancestors should be arrangeable' do
|
464
|
-
expect(grandchild_11.self_and_ancestors.arrange).to eq Hash[
|
465
|
-
root => {
|
466
|
-
child_1 => {
|
467
|
-
grandchild_11 => {}
|
468
|
-
}
|
469
|
-
}
|
470
|
-
]
|
471
|
-
end
|
44
|
+
before { root.reload }
|
45
|
+
before { child.reload }
|
46
|
+
before { grandchild.reload }
|
472
47
|
|
473
|
-
it
|
474
|
-
|
48
|
+
it { expect(root.level).to eq 0 }
|
49
|
+
it { expect{root.level}.not_to query_database }
|
475
50
|
|
476
|
-
|
477
|
-
|
478
|
-
grandchild_12 => {},
|
479
|
-
child_2 => {
|
480
|
-
grandchild_21 => {},
|
481
|
-
grandchild_22 => {}
|
482
|
-
}
|
483
|
-
]
|
484
|
-
end
|
51
|
+
it { expect(child.level).to eq 1 }
|
52
|
+
it { expect{child.level}.to query_database.once }
|
485
53
|
|
486
|
-
it
|
487
|
-
|
54
|
+
it { expect(grandchild.level).to eq 2 }
|
55
|
+
it { expect{grandchild.level}.to query_database.at_least(:once) }
|
488
56
|
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
grandchild_22 => {}
|
493
|
-
}
|
494
|
-
]
|
495
|
-
end
|
496
|
-
end
|
57
|
+
context 'given a record with already loaded parent' do
|
58
|
+
before { child.association(:parent).load_target }
|
59
|
+
before { grandchild.parent.association(:parent).load_target }
|
497
60
|
|
498
|
-
|
499
|
-
|
500
|
-
let(:root) { create :default }
|
61
|
+
it { expect(child.level).to eq 1 }
|
62
|
+
it { expect{child.level}.not_to query_database }
|
501
63
|
|
502
|
-
|
503
|
-
|
504
|
-
before { create_list :default, 2, :parent => root.children.last }
|
64
|
+
it { expect(grandchild.level).to eq 2 }
|
65
|
+
it { expect{grandchild.level}.not_to query_database }
|
505
66
|
end
|
506
67
|
end
|
507
68
|
end
|
508
69
|
|
509
|
-
describe
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
subject { root.reload }
|
520
|
-
its(:parent_id) { should be_nil }
|
521
|
-
its(:level) { should be_zero }
|
522
|
-
its(:position) { should eq 1 }
|
523
|
-
its(:categories_count) { should eq 3}
|
524
|
-
end
|
525
|
-
|
526
|
-
context "on_save_when_parent_changed" do
|
527
|
-
example "move_1_to_root" do
|
528
|
-
child_1.parent = nil
|
529
|
-
expect{ child_1.save! }.to_not raise_exception
|
530
|
-
expect(child_1.position).to eq 2
|
531
|
-
expect([root, child_1]).to be_sorted
|
532
|
-
end
|
533
|
-
|
534
|
-
example "move_3_to_root" do
|
535
|
-
child_3.parent = nil
|
536
|
-
expect{ child_3.save! }.to_not raise_exception
|
537
|
-
expect(child_3.position).to eq 2
|
538
|
-
expect([root, child_3]).to be_sorted
|
539
|
-
|
540
|
-
expect(child_3.reload.level).to eq 0
|
541
|
-
expect(child_4.reload.level).to eq 1
|
542
|
-
end
|
543
|
-
|
544
|
-
example "move_grandchild" do
|
545
|
-
grandchild = FactoryGirl.create(:default_with_counter_cache, :parent => child_3)
|
546
|
-
grandchild.parent = child_2
|
547
|
-
expect{ grandchild.save! }.to_not raise_exception
|
548
|
-
expect([grandchild]).to eq child_2.children
|
549
|
-
end
|
550
|
-
end
|
551
|
-
|
552
|
-
describe "#move_left" do
|
553
|
-
example "move_1_left" do
|
554
|
-
expect{ child_1.move_left }.to raise_exception ActiveRecord::ActiveRecordError
|
555
|
-
expect([child_1, child_2, child_3]).to be_sorted
|
556
|
-
end
|
557
|
-
|
558
|
-
example "move_2_left" do
|
559
|
-
child_2.move_left
|
560
|
-
expect([child_2, child_1, child_3]).to be_sorted
|
561
|
-
end
|
562
|
-
|
563
|
-
example "move_3_left" do
|
564
|
-
child_3.move_left
|
565
|
-
expect([child_1, child_3, child_2]).to be_sorted
|
566
|
-
end
|
567
|
-
end
|
568
|
-
|
569
|
-
describe "#move_right" do
|
570
|
-
example "move_3_right" do
|
571
|
-
expect{ child_3.move_right }.to raise_exception ActiveRecord::ActiveRecordError
|
572
|
-
expect([child_1, child_2, child_3]).to be_sorted
|
573
|
-
end
|
574
|
-
|
575
|
-
example "move_2_right" do
|
576
|
-
child_2.move_right
|
577
|
-
expect([child_1, child_3, child_2]).to be_sorted
|
578
|
-
end
|
579
|
-
|
580
|
-
example "move_1_right" do
|
581
|
-
child_1.move_right
|
582
|
-
expect([child_2, child_1, child_3]).to be_sorted
|
583
|
-
end
|
584
|
-
end
|
585
|
-
|
586
|
-
describe "#move_to_left_of" do
|
587
|
-
example "move_3_to_left_of_1" do
|
588
|
-
child_3.move_to_left_of child_1
|
589
|
-
expect([child_3, child_1, child_2]).to be_sorted
|
590
|
-
end
|
591
|
-
|
592
|
-
example "move_3_to_left_of_2" do
|
593
|
-
child_3.move_to_left_of child_2
|
594
|
-
expect([child_1, child_3, child_2]).to be_sorted
|
595
|
-
end
|
596
|
-
|
597
|
-
example "move_1_to_left_of_3" do
|
598
|
-
child_1.move_to_left_of child_3
|
599
|
-
expect([child_2, child_1, child_3]).to be_sorted
|
600
|
-
end
|
601
|
-
|
602
|
-
example "move_1_to_left_of_3_id" do
|
603
|
-
child_1.move_to_left_of child_3.id
|
604
|
-
expect([child_2, child_1, child_3]).to be_sorted
|
605
|
-
end
|
606
|
-
|
607
|
-
example "move_root_to_left_of_child_2" do
|
608
|
-
expect{ root.move_to_left_of child_2 }.to raise_exception ActiveRecord::ActiveRecordError
|
609
|
-
end
|
610
|
-
end
|
611
|
-
|
612
|
-
describe "#move_to_right_of" do
|
613
|
-
example "move_1_to_right_of_2" do
|
614
|
-
child_1.move_to_right_of child_2
|
615
|
-
expect([child_2, child_1, child_3]).to be_sorted
|
616
|
-
end
|
617
|
-
|
618
|
-
example "move_1_to_right_of_3" do
|
619
|
-
child_1.move_to_right_of child_3
|
620
|
-
expect([child_2, child_3, child_1]).to be_sorted
|
621
|
-
end
|
622
|
-
|
623
|
-
example "move_1_to_right_of_3_id" do
|
624
|
-
child_1.move_to_right_of child_3.id
|
625
|
-
expect([child_2, child_3, child_1]).to be_sorted
|
626
|
-
end
|
627
|
-
|
628
|
-
example "move_3_to_right_of_1" do
|
629
|
-
child_3.move_to_right_of child_1
|
630
|
-
expect([child_1, child_3, child_2]).to be_sorted
|
631
|
-
end
|
632
|
-
|
633
|
-
example "move_root_to_right_of_child_2" do
|
634
|
-
expect{ root.move_to_right_of child_2 }.to raise_exception ActiveRecord::ActiveRecordError
|
635
|
-
end
|
636
|
-
end
|
637
|
-
|
638
|
-
describe "#move_to_root" do
|
639
|
-
before { child_2.move_to_root }
|
640
|
-
|
641
|
-
context "child_2" do
|
642
|
-
subject { child_2 }
|
643
|
-
|
644
|
-
its(:level) { should be_zero }
|
645
|
-
its(:parent_id) { should be_nil }
|
646
|
-
its(:position) { should eq 2 }
|
647
|
-
|
648
|
-
it "should not become new root" do
|
649
|
-
DefaultWithCounterCache.root.should eq root
|
650
|
-
end
|
651
|
-
end
|
652
|
-
|
653
|
-
context "other_nodes" do
|
654
|
-
specify { child_1.reload.position.should eq 1 }
|
655
|
-
specify { child_3.reload.position.should eq 2 }
|
656
|
-
specify { root.reload.categories_count.should eq 2 }
|
657
|
-
end
|
658
|
-
|
659
|
-
|
660
|
-
context "given a root node" do
|
661
|
-
before { root.move_to_root }
|
662
|
-
subject { root }
|
663
|
-
|
664
|
-
its(:position) { should eq 1 }
|
665
|
-
|
666
|
-
it "positions should not change" do
|
667
|
-
expect([root, child_3]).to be_sorted
|
668
|
-
end
|
669
|
-
end
|
670
|
-
end
|
671
|
-
|
672
|
-
describe "#move_to_child_of" do
|
673
|
-
let(:moved_child) { create :default_with_counter_cache, :name => 'moved_child' }
|
674
|
-
|
675
|
-
before { moved_child.move_to_child_of root }
|
676
|
-
context "moved_child" do
|
677
|
-
subject { moved_child }
|
678
|
-
its(:level) { should eq 1 }
|
679
|
-
its(:position) { should eq 4 }
|
680
|
-
end
|
681
|
-
|
682
|
-
context "root" do
|
683
|
-
subject { root.reload }
|
684
|
-
its(:right_sibling) { should be_nil }
|
685
|
-
its(:categories_count) { should eq 4 }
|
686
|
-
end
|
687
|
-
|
688
|
-
context "given a node which already is children of target" do
|
689
|
-
subject { child_2 }
|
690
|
-
before { child_2.move_to_child_of root }
|
691
|
-
|
692
|
-
its(:position) { should eq 2 }
|
693
|
-
|
694
|
-
it "positions_should_not_change" do
|
695
|
-
expect([child_1, child_2, child_3, moved_child]).to be_sorted
|
696
|
-
end
|
697
|
-
end
|
698
|
-
|
699
|
-
it { expect([child_1, child_2, child_3, moved_child]).to be_sorted }
|
700
|
-
it { expect{ root.move_to_child_of root }.to raise_exception ActiveRecord::ActiveRecordError }
|
701
|
-
it { expect{ root.move_to_child_of child_1 }.to raise_exception ActiveRecord::ActiveRecordError }
|
702
|
-
|
703
|
-
context "when node with descendants moved and depth is changed" do
|
704
|
-
before { child_3.move_to_child_of child_2 }
|
705
|
-
before { child_4.reload }
|
706
|
-
|
707
|
-
it "changes parent of child_3" do
|
708
|
-
expect(child_3.parent).to eq child_2
|
709
|
-
end
|
710
|
-
|
711
|
-
it "moves to the end of new parents children list" do
|
712
|
-
expect(child_3).to be_last
|
713
|
-
end
|
714
|
-
|
715
|
-
it "changes depth of child_3 descendants" do
|
716
|
-
expect(child_4.level).to eq 3
|
717
|
-
end
|
718
|
-
end
|
719
|
-
end
|
720
|
-
|
721
|
-
describe "#move_to_child_with_index" do
|
722
|
-
let(:moved_child) { create :default, :name => 'moved_child' }
|
723
|
-
|
724
|
-
example "move_to_child_as_first" do
|
725
|
-
moved_child.move_to_child_with_index root, 0
|
726
|
-
expect([moved_child, child_1, child_2, child_3]).to be_sorted
|
727
|
-
moved_child.position.should eq 1
|
728
|
-
end
|
729
|
-
|
730
|
-
example "move_to_child_as_second" do
|
731
|
-
moved_child.move_to_child_with_index root, 1
|
732
|
-
expect([child_1, moved_child, child_2, child_3]).to be_sorted
|
733
|
-
moved_child.position.should eq 2
|
734
|
-
end
|
735
|
-
|
736
|
-
example "move_to_child_as_third" do
|
737
|
-
moved_child.move_to_child_with_index root, 2
|
738
|
-
expect([child_1, child_2, moved_child, child_3]).to be_sorted
|
739
|
-
moved_child.position.should eq 3
|
740
|
-
end
|
741
|
-
|
742
|
-
example "move_to_child_as_last" do
|
743
|
-
moved_child.move_to_child_with_index root, 3
|
744
|
-
expect([child_1, child_2, child_3, moved_child]).to be_sorted
|
745
|
-
moved_child.position.should eq 4
|
746
|
-
end
|
747
|
-
|
748
|
-
example "move_child_to_root_as_first" do
|
749
|
-
child_3.move_to_child_with_index nil, 0
|
750
|
-
child_3.level.should be_zero
|
751
|
-
expect([child_3, root, moved_child]).to be_sorted
|
752
|
-
expect([child_1, child_2]).to be_sorted
|
753
|
-
child_2.right_sibling.should be_nil
|
754
|
-
end
|
755
|
-
|
756
|
-
example "move_to_child_with_large_index" do
|
757
|
-
moved_child.move_to_child_with_index root, 100
|
758
|
-
expect([child_1, child_2, child_3, moved_child]).to be_sorted
|
759
|
-
moved_child.position.should eq 4
|
760
|
-
end
|
761
|
-
|
762
|
-
example "move_to_child_with_negative_index" do
|
763
|
-
moved_child.move_to_child_with_index root, -2
|
764
|
-
expect([child_1, child_2, moved_child, child_3]).to be_sorted
|
765
|
-
moved_child.position.should eq 3
|
766
|
-
end
|
767
|
-
|
768
|
-
example "move_to_child_with_large_negative_index" do
|
769
|
-
expect{ moved_child.move_to_child_with_index root, -100 }.to raise_exception ActiveRecord::ActiveRecordError
|
770
|
-
end
|
771
|
-
|
772
|
-
example "move_to_child_with_nil_index" do
|
773
|
-
expect{ moved_child.move_to_child_with_index root, nil }.to raise_exception ActiveRecord::ActiveRecordError
|
774
|
-
end
|
775
|
-
|
776
|
-
example "move_to_child_with_float_index" do
|
777
|
-
moved_child.move_to_child_with_index root, 1.7
|
778
|
-
expect([child_1, moved_child, child_2, child_3]).to be_sorted
|
779
|
-
end
|
780
|
-
|
781
|
-
example "move_root_to_child_of_self" do
|
782
|
-
expect{ root.move_to_child_with_index child_1, 1 }.to raise_exception ActiveRecord::ActiveRecordError
|
783
|
-
end
|
784
|
-
|
785
|
-
context "with scoped tree" do
|
786
|
-
let!(:root1) { create :scoped, :scope_type => 's1' }
|
787
|
-
let!(:node1) { create :scoped, :scope_type => 's1', :parent => root1 }
|
788
|
-
let!(:root2) { create :scoped, :scope_type => 's2' }
|
789
|
-
let!(:node2) { create :scoped, :scope_type => 's2', :parent => root2 }
|
790
|
-
|
791
|
-
example "move_node1_to_root" do
|
792
|
-
node1.should_receive(:move_to_right_of).with(root1)
|
793
|
-
node1.move_to_child_with_index nil, 100
|
794
|
-
end
|
795
|
-
|
796
|
-
example "move_node2_to_root" do
|
797
|
-
node2.should_receive(:move_to_right_of).with(root2)
|
798
|
-
node2.move_to_child_with_index nil, 100
|
799
|
-
end
|
800
|
-
end
|
801
|
-
|
70
|
+
describe 'move actions' do
|
71
|
+
tree :factory => :default_with_counter_cache do
|
72
|
+
root {
|
73
|
+
child_1
|
74
|
+
child_2 :name => 'child_2'
|
75
|
+
child_3 {
|
76
|
+
child_4
|
77
|
+
}
|
78
|
+
}
|
802
79
|
end
|
803
80
|
|
804
|
-
describe
|
805
|
-
before { child_3.insert_at(1) }
|
81
|
+
describe '#insert_at' do
|
82
|
+
before { ActiveSupport::Deprecation.silence { child_3.insert_at(1) } }
|
806
83
|
before { child_3.reload }
|
807
84
|
|
808
85
|
specify { expect([child_3, child_1, child_2]).to be_sorted }
|
809
86
|
end
|
87
|
+
end
|
810
88
|
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
it { should fire_callback(:around_move).when_calling(:move_to_root).once }
|
817
|
-
|
818
|
-
it { should_not fire_callback(:before_move).when_calling(:move_left) }
|
819
|
-
it { should_not fire_callback(:after_move).when_calling(:move_left) }
|
820
|
-
it { should_not fire_callback(:around_move).when_calling(:move_left) }
|
821
|
-
|
822
|
-
it { should fire_callback(:before_reorder).when_calling(:move_higher).once }
|
823
|
-
it { should fire_callback(:after_reorder).when_calling(:move_higher).once }
|
824
|
-
|
825
|
-
it { should_not fire_callback(:before_reorder).when_calling(:move_to_root) }
|
826
|
-
|
827
|
-
it "should cache depth on save" do
|
828
|
-
record = build :default_with_counter_cache
|
829
|
-
|
830
|
-
record.depth.should be_nil
|
831
|
-
record.save
|
832
|
-
|
833
|
-
record.depth.should eq 0
|
834
|
-
|
835
|
-
record.move_to_left_of child_3
|
836
|
-
record.depth.should eq child_3.level
|
837
|
-
end
|
838
|
-
|
839
|
-
it "should recalculate depth of descendants" do
|
840
|
-
record = create :default_with_counter_cache, :parent => child_3
|
841
|
-
record.depth.should eq 2
|
842
|
-
|
843
|
-
child_3.move_to_root
|
844
|
-
record.reload.depth.should eq 1
|
845
|
-
|
846
|
-
child_3.move_to_child_of child_1
|
847
|
-
record.reload.depth.should eq 3
|
848
|
-
end
|
849
|
-
|
850
|
-
context "DefaultWithCallbacks" do
|
851
|
-
let!(:cb_root_1) { create :default_with_callbacks, :name => 'root_1' }
|
852
|
-
let!(:cb_root_2) { create :default_with_callbacks, :name => 'root_2' }
|
853
|
-
let!(:cb_child_1) { create :default_with_callbacks, :name => 'child_1', :parent => cb_root_1 }
|
854
|
-
let!(:cb_child_2) { create :default_with_callbacks, :name => 'child_2', :parent => cb_root_1 }
|
855
|
-
|
856
|
-
specify "new parent_id should be available in before_move" do
|
857
|
-
cb_root_2.stub(:before_move) { cb_root_2.parent_id.should eq cb_root_1.id }
|
858
|
-
cb_root_2.move_to_left_of cb_child_1
|
859
|
-
end
|
860
|
-
|
861
|
-
specify "new position should be available in before_reorder" do
|
862
|
-
cb_child_2.stub(:before_reorder) { cb_child_2.position.should eq 1 }
|
863
|
-
cb_child_2.move_to_left_of cb_child_1
|
864
|
-
end
|
89
|
+
describe 'scoped trees' do
|
90
|
+
tree :factory => :scoped do
|
91
|
+
root1 :scope_type => 't1' do
|
92
|
+
child1
|
93
|
+
orphan
|
865
94
|
end
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
context "changed attributes" do
|
870
|
-
before do
|
871
|
-
child_2.name = 'changed_100'
|
872
|
-
child_2.move_to_left_of child_1
|
95
|
+
root2 :scope_type => 't2' do
|
96
|
+
child2
|
873
97
|
end
|
874
|
-
|
875
|
-
it { child_2.reload.name.should eq 'child_2' }
|
876
|
-
end
|
877
|
-
|
878
|
-
end
|
879
|
-
|
880
|
-
describe "scoped trees" do
|
881
|
-
let!(:root1) { create :scoped, :scope_type => "t1" }
|
882
|
-
let!(:child1) { create :scoped, :parent => root1 }
|
883
|
-
let!(:orphan) do
|
884
|
-
record = create :scoped, :parent => root1
|
885
|
-
record.class.where(:id => record.id).update_all(:scope_type => "t0", :position => 1)
|
886
|
-
record
|
887
98
|
end
|
888
99
|
|
889
|
-
|
890
|
-
let!(:child2) { create :scoped, :scope_type => "t2", :parent => root2 }
|
100
|
+
before { Scoped.where(:id => orphan.id).update_all(:scope_type => 't0', :position => 1) }
|
891
101
|
|
892
|
-
it
|
893
|
-
root1.position.
|
102
|
+
it 'should not stick positions together for different scopes' do
|
103
|
+
expect(root1.position).to eq root2.position
|
894
104
|
end
|
895
|
-
it
|
896
|
-
child1.
|
105
|
+
it 'should automatically set scope for new records with parent' do
|
106
|
+
expect(child1.ordered_tree_node).to be_same_scope root1
|
897
107
|
end
|
898
|
-
it
|
899
|
-
root1.children.reload.
|
900
|
-
root1.descendants.reload.
|
108
|
+
it 'should not include orphans' do
|
109
|
+
expect(root1.children.reload).not_to include orphan
|
110
|
+
expect(root1.descendants.reload).not_to include orphan
|
901
111
|
end
|
902
|
-
it
|
903
|
-
expect
|
112
|
+
it 'should not allow to move records between scopes' do
|
113
|
+
expect(child2.move_to_child_of(root1)).to be false
|
114
|
+
expect(child2.errors_on(:parent).size).to be >= 1
|
904
115
|
end
|
905
|
-
it
|
116
|
+
it 'should not allow to change scope' do
|
906
117
|
child2.parent = root1
|
907
|
-
child2.
|
118
|
+
expect(child2.errors_on(:parent).size).to be >= 1
|
908
119
|
end
|
909
|
-
it
|
120
|
+
it 'should not allow to add scoped record to children collection' do
|
910
121
|
root1.children << child2
|
911
|
-
root1.children.reload.
|
912
|
-
end
|
913
|
-
end
|
914
|
-
|
915
|
-
describe "#destroy behavior" do
|
916
|
-
let!(:root) { create :default_with_counter_cache, :name => 'root' }
|
917
|
-
let!(:child_1) { create :default_with_counter_cache, :parent => root, :name => 'child_1' }
|
918
|
-
let!(:child_2) { create :default_with_counter_cache, :parent => root, :name => 'child_2' }
|
919
|
-
let!(:child_3) { create :default_with_counter_cache, :parent => root, :name => 'child_3' }
|
920
|
-
|
921
|
-
describe "it should destroy descendants" do
|
922
|
-
subject { root }
|
923
|
-
before { subject.destroy }
|
924
|
-
|
925
|
-
it { should be_destroyed }
|
926
|
-
its('descendants.reload') { should be_empty }
|
927
|
-
|
928
|
-
specify "ensure the loneliness" do
|
929
|
-
root.class.all.should be_empty
|
930
|
-
end
|
931
|
-
end
|
932
|
-
|
933
|
-
describe "it should stick positions together" do
|
934
|
-
before { child_2.destroy }
|
935
|
-
before { child_3.reload }
|
936
|
-
|
937
|
-
subject { child_3 }
|
938
|
-
|
939
|
-
its(:left_sibling) { should eq child_1 }
|
940
|
-
its(:position) { should eq 2 }
|
941
|
-
|
942
|
-
specify "root categories_count should decrease" do
|
943
|
-
root.reload.categories_count.should eq 2
|
944
|
-
end
|
122
|
+
expect(root1.children.reload).not_to include child2
|
945
123
|
end
|
946
124
|
end
|
947
125
|
|
@@ -956,32 +134,25 @@ describe ActsAsOrderedTree, :transactional do
|
|
956
134
|
context "given self as parent" do
|
957
135
|
before { root.parent = root }
|
958
136
|
|
959
|
-
it
|
137
|
+
it 'has at least 1 error_on' do
|
138
|
+
expect(subject.error_on(:parent).size).to be >= 1
|
139
|
+
end
|
960
140
|
end
|
961
141
|
|
962
142
|
context "given child as parent" do
|
963
143
|
before { root.parent = child }
|
964
144
|
|
965
|
-
it
|
145
|
+
it 'has at least 1 error_on' do
|
146
|
+
expect(subject.error_on(:parent).size).to be >= 1
|
147
|
+
end
|
966
148
|
end
|
967
149
|
|
968
150
|
context "given grandchild as parent" do
|
969
151
|
before { root.parent = grandchild }
|
970
152
|
|
971
|
-
it
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
describe "attempt to create node with wrong position" do
|
976
|
-
it "should not throw error" do
|
977
|
-
expect{ create :default, :position => 22 }.not_to raise_error
|
978
|
-
end
|
979
|
-
|
980
|
-
it "should be saved at proper position" do
|
981
|
-
root = create :default
|
982
|
-
|
983
|
-
node = create :default, :position => 2
|
984
|
-
node.position.should eq 2
|
153
|
+
it 'has at least 1 error_on' do
|
154
|
+
expect(subject.error_on(:parent).size).to be >= 1
|
155
|
+
end
|
985
156
|
end
|
986
157
|
end
|
987
158
|
end
|