Mercurial > hg > soundsoftware-site
comparison .svn/pristine/ee/ee3e0d946d377acd7e76d501db77540601a10ca7.svn-base @ 1295:622f24f53b42 redmine-2.3
Update to Redmine SVN revision 11972 on 2.3-stable branch
author | Chris Cannam |
---|---|
date | Fri, 14 Jun 2013 09:02:21 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1294:3e4c3460b6ca | 1295:622f24f53b42 |
---|---|
1 require 'spec_helper' | |
2 | |
3 describe "AwesomeNestedSet" do | |
4 before(:all) do | |
5 self.class.fixtures :categories, :departments, :notes, :things, :brokens | |
6 end | |
7 | |
8 describe "defaults" do | |
9 it "should have left_column_default" do | |
10 Default.acts_as_nested_set_options[:left_column].should == 'lft' | |
11 end | |
12 | |
13 it "should have right_column_default" do | |
14 Default.acts_as_nested_set_options[:right_column].should == 'rgt' | |
15 end | |
16 | |
17 it "should have parent_column_default" do | |
18 Default.acts_as_nested_set_options[:parent_column].should == 'parent_id' | |
19 end | |
20 | |
21 it "should have scope_default" do | |
22 Default.acts_as_nested_set_options[:scope].should be_nil | |
23 end | |
24 | |
25 it "should have left_column_name" do | |
26 Default.left_column_name.should == 'lft' | |
27 Default.new.left_column_name.should == 'lft' | |
28 RenamedColumns.left_column_name.should == 'red' | |
29 RenamedColumns.new.left_column_name.should == 'red' | |
30 end | |
31 | |
32 it "should have right_column_name" do | |
33 Default.right_column_name.should == 'rgt' | |
34 Default.new.right_column_name.should == 'rgt' | |
35 RenamedColumns.right_column_name.should == 'black' | |
36 RenamedColumns.new.right_column_name.should == 'black' | |
37 end | |
38 | |
39 it "should have parent_column_name" do | |
40 Default.parent_column_name.should == 'parent_id' | |
41 Default.new.parent_column_name.should == 'parent_id' | |
42 RenamedColumns.parent_column_name.should == 'mother_id' | |
43 RenamedColumns.new.parent_column_name.should == 'mother_id' | |
44 end | |
45 end | |
46 | |
47 it "creation_with_altered_column_names" do | |
48 lambda { | |
49 RenamedColumns.create!() | |
50 }.should_not raise_exception | |
51 end | |
52 | |
53 it "creation when existing record has nil left column" do | |
54 assert_nothing_raised do | |
55 Broken.create! | |
56 end | |
57 end | |
58 | |
59 it "quoted_left_column_name" do | |
60 quoted = Default.connection.quote_column_name('lft') | |
61 Default.quoted_left_column_name.should == quoted | |
62 Default.new.quoted_left_column_name.should == quoted | |
63 end | |
64 | |
65 it "quoted_right_column_name" do | |
66 quoted = Default.connection.quote_column_name('rgt') | |
67 Default.quoted_right_column_name.should == quoted | |
68 Default.new.quoted_right_column_name.should == quoted | |
69 end | |
70 | |
71 it "left_column_protected_from_assignment" do | |
72 lambda { | |
73 Category.new.lft = 1 | |
74 }.should raise_exception(ActiveRecord::ActiveRecordError) | |
75 end | |
76 | |
77 it "right_column_protected_from_assignment" do | |
78 lambda { | |
79 Category.new.rgt = 1 | |
80 }.should raise_exception(ActiveRecord::ActiveRecordError) | |
81 end | |
82 | |
83 it "scoped_appends_id" do | |
84 ScopedCategory.acts_as_nested_set_options[:scope].should == :organization_id | |
85 end | |
86 | |
87 it "roots_class_method" do | |
88 Category.roots.should == Category.find_all_by_parent_id(nil) | |
89 end | |
90 | |
91 it "root_class_method" do | |
92 Category.root.should == categories(:top_level) | |
93 end | |
94 | |
95 it "root" do | |
96 categories(:child_3).root.should == categories(:top_level) | |
97 end | |
98 | |
99 it "root?" do | |
100 categories(:top_level).root?.should be_true | |
101 categories(:top_level_2).root?.should be_true | |
102 end | |
103 | |
104 it "leaves_class_method" do | |
105 Category.find(:all, :conditions => "#{Category.right_column_name} - #{Category.left_column_name} = 1").should == Category.leaves | |
106 Category.leaves.count.should == 4 | |
107 Category.leaves.should include(categories(:child_1)) | |
108 Category.leaves.should include(categories(:child_2_1)) | |
109 Category.leaves.should include(categories(:child_3)) | |
110 Category.leaves.should include(categories(:top_level_2)) | |
111 end | |
112 | |
113 it "leaf" do | |
114 categories(:child_1).leaf?.should be_true | |
115 categories(:child_2_1).leaf?.should be_true | |
116 categories(:child_3).leaf?.should be_true | |
117 categories(:top_level_2).leaf?.should be_true | |
118 | |
119 categories(:top_level).leaf?.should be_false | |
120 categories(:child_2).leaf?.should be_false | |
121 Category.new.leaf?.should be_false | |
122 end | |
123 | |
124 | |
125 it "parent" do | |
126 categories(:child_2_1).parent.should == categories(:child_2) | |
127 end | |
128 | |
129 it "self_and_ancestors" do | |
130 child = categories(:child_2_1) | |
131 self_and_ancestors = [categories(:top_level), categories(:child_2), child] | |
132 self_and_ancestors.should == child.self_and_ancestors | |
133 end | |
134 | |
135 it "ancestors" do | |
136 child = categories(:child_2_1) | |
137 ancestors = [categories(:top_level), categories(:child_2)] | |
138 ancestors.should == child.ancestors | |
139 end | |
140 | |
141 it "self_and_siblings" do | |
142 child = categories(:child_2) | |
143 self_and_siblings = [categories(:child_1), child, categories(:child_3)] | |
144 self_and_siblings.should == child.self_and_siblings | |
145 lambda do | |
146 tops = [categories(:top_level), categories(:top_level_2)] | |
147 assert_equal tops, categories(:top_level).self_and_siblings | |
148 end.should_not raise_exception | |
149 end | |
150 | |
151 it "siblings" do | |
152 child = categories(:child_2) | |
153 siblings = [categories(:child_1), categories(:child_3)] | |
154 siblings.should == child.siblings | |
155 end | |
156 | |
157 it "leaves" do | |
158 leaves = [categories(:child_1), categories(:child_2_1), categories(:child_3)] | |
159 categories(:top_level).leaves.should == leaves | |
160 end | |
161 | |
162 it "level" do | |
163 categories(:top_level).level.should == 0 | |
164 categories(:child_1).level.should == 1 | |
165 categories(:child_2_1).level.should == 2 | |
166 end | |
167 | |
168 it "has_children?" do | |
169 categories(:child_2_1).children.empty?.should be_true | |
170 categories(:child_2).children.empty?.should be_false | |
171 categories(:top_level).children.empty?.should be_false | |
172 end | |
173 | |
174 it "self_and_descendents" do | |
175 parent = categories(:top_level) | |
176 self_and_descendants = [parent, categories(:child_1), categories(:child_2), | |
177 categories(:child_2_1), categories(:child_3)] | |
178 self_and_descendants.should == parent.self_and_descendants | |
179 self_and_descendants.count.should == parent.self_and_descendants.count | |
180 end | |
181 | |
182 it "descendents" do | |
183 lawyers = Category.create!(:name => "lawyers") | |
184 us = Category.create!(:name => "United States") | |
185 us.move_to_child_of(lawyers) | |
186 patent = Category.create!(:name => "Patent Law") | |
187 patent.move_to_child_of(us) | |
188 lawyers.reload | |
189 | |
190 lawyers.children.size.should == 1 | |
191 us.children.size.should == 1 | |
192 lawyers.descendants.size.should == 2 | |
193 end | |
194 | |
195 it "self_and_descendents" do | |
196 parent = categories(:top_level) | |
197 descendants = [categories(:child_1), categories(:child_2), | |
198 categories(:child_2_1), categories(:child_3)] | |
199 descendants.should == parent.descendants | |
200 end | |
201 | |
202 it "children" do | |
203 category = categories(:top_level) | |
204 category.children.each {|c| category.id.should == c.parent_id } | |
205 end | |
206 | |
207 it "order_of_children" do | |
208 categories(:child_2).move_left | |
209 categories(:child_2).should == categories(:top_level).children[0] | |
210 categories(:child_1).should == categories(:top_level).children[1] | |
211 categories(:child_3).should == categories(:top_level).children[2] | |
212 end | |
213 | |
214 it "is_or_is_ancestor_of?" do | |
215 categories(:top_level).is_or_is_ancestor_of?(categories(:child_1)).should be_true | |
216 categories(:top_level).is_or_is_ancestor_of?(categories(:child_2_1)).should be_true | |
217 categories(:child_2).is_or_is_ancestor_of?(categories(:child_2_1)).should be_true | |
218 categories(:child_2_1).is_or_is_ancestor_of?(categories(:child_2)).should be_false | |
219 categories(:child_1).is_or_is_ancestor_of?(categories(:child_2)).should be_false | |
220 categories(:child_1).is_or_is_ancestor_of?(categories(:child_1)).should be_true | |
221 end | |
222 | |
223 it "is_ancestor_of?" do | |
224 categories(:top_level).is_ancestor_of?(categories(:child_1)).should be_true | |
225 categories(:top_level).is_ancestor_of?(categories(:child_2_1)).should be_true | |
226 categories(:child_2).is_ancestor_of?(categories(:child_2_1)).should be_true | |
227 categories(:child_2_1).is_ancestor_of?(categories(:child_2)).should be_false | |
228 categories(:child_1).is_ancestor_of?(categories(:child_2)).should be_false | |
229 categories(:child_1).is_ancestor_of?(categories(:child_1)).should be_false | |
230 end | |
231 | |
232 it "is_or_is_ancestor_of_with_scope" do | |
233 root = ScopedCategory.root | |
234 child = root.children.first | |
235 root.is_or_is_ancestor_of?(child).should be_true | |
236 child.update_attribute :organization_id, 'different' | |
237 root.is_or_is_ancestor_of?(child).should be_false | |
238 end | |
239 | |
240 it "is_or_is_descendant_of?" do | |
241 categories(:child_1).is_or_is_descendant_of?(categories(:top_level)).should be_true | |
242 categories(:child_2_1).is_or_is_descendant_of?(categories(:top_level)).should be_true | |
243 categories(:child_2_1).is_or_is_descendant_of?(categories(:child_2)).should be_true | |
244 categories(:child_2).is_or_is_descendant_of?(categories(:child_2_1)).should be_false | |
245 categories(:child_2).is_or_is_descendant_of?(categories(:child_1)).should be_false | |
246 categories(:child_1).is_or_is_descendant_of?(categories(:child_1)).should be_true | |
247 end | |
248 | |
249 it "is_descendant_of?" do | |
250 categories(:child_1).is_descendant_of?(categories(:top_level)).should be_true | |
251 categories(:child_2_1).is_descendant_of?(categories(:top_level)).should be_true | |
252 categories(:child_2_1).is_descendant_of?(categories(:child_2)).should be_true | |
253 categories(:child_2).is_descendant_of?(categories(:child_2_1)).should be_false | |
254 categories(:child_2).is_descendant_of?(categories(:child_1)).should be_false | |
255 categories(:child_1).is_descendant_of?(categories(:child_1)).should be_false | |
256 end | |
257 | |
258 it "is_or_is_descendant_of_with_scope" do | |
259 root = ScopedCategory.root | |
260 child = root.children.first | |
261 child.is_or_is_descendant_of?(root).should be_true | |
262 child.update_attribute :organization_id, 'different' | |
263 child.is_or_is_descendant_of?(root).should be_false | |
264 end | |
265 | |
266 it "same_scope?" do | |
267 root = ScopedCategory.root | |
268 child = root.children.first | |
269 child.same_scope?(root).should be_true | |
270 child.update_attribute :organization_id, 'different' | |
271 child.same_scope?(root).should be_false | |
272 end | |
273 | |
274 it "left_sibling" do | |
275 categories(:child_1).should == categories(:child_2).left_sibling | |
276 categories(:child_2).should == categories(:child_3).left_sibling | |
277 end | |
278 | |
279 it "left_sibling_of_root" do | |
280 categories(:top_level).left_sibling.should be_nil | |
281 end | |
282 | |
283 it "left_sibling_without_siblings" do | |
284 categories(:child_2_1).left_sibling.should be_nil | |
285 end | |
286 | |
287 it "left_sibling_of_leftmost_node" do | |
288 categories(:child_1).left_sibling.should be_nil | |
289 end | |
290 | |
291 it "right_sibling" do | |
292 categories(:child_3).should == categories(:child_2).right_sibling | |
293 categories(:child_2).should == categories(:child_1).right_sibling | |
294 end | |
295 | |
296 it "right_sibling_of_root" do | |
297 categories(:top_level_2).should == categories(:top_level).right_sibling | |
298 categories(:top_level_2).right_sibling.should be_nil | |
299 end | |
300 | |
301 it "right_sibling_without_siblings" do | |
302 categories(:child_2_1).right_sibling.should be_nil | |
303 end | |
304 | |
305 it "right_sibling_of_rightmost_node" do | |
306 categories(:child_3).right_sibling.should be_nil | |
307 end | |
308 | |
309 it "move_left" do | |
310 categories(:child_2).move_left | |
311 categories(:child_2).left_sibling.should be_nil | |
312 categories(:child_1).should == categories(:child_2).right_sibling | |
313 Category.valid?.should be_true | |
314 end | |
315 | |
316 it "move_right" do | |
317 categories(:child_2).move_right | |
318 categories(:child_2).right_sibling.should be_nil | |
319 categories(:child_3).should == categories(:child_2).left_sibling | |
320 Category.valid?.should be_true | |
321 end | |
322 | |
323 it "move_to_left_of" do | |
324 categories(:child_3).move_to_left_of(categories(:child_1)) | |
325 categories(:child_3).left_sibling.should be_nil | |
326 categories(:child_1).should == categories(:child_3).right_sibling | |
327 Category.valid?.should be_true | |
328 end | |
329 | |
330 it "move_to_right_of" do | |
331 categories(:child_1).move_to_right_of(categories(:child_3)) | |
332 categories(:child_1).right_sibling.should be_nil | |
333 categories(:child_3).should == categories(:child_1).left_sibling | |
334 Category.valid?.should be_true | |
335 end | |
336 | |
337 it "move_to_root" do | |
338 categories(:child_2).move_to_root | |
339 categories(:child_2).parent.should be_nil | |
340 categories(:child_2).level.should == 0 | |
341 categories(:child_2_1).level.should == 1 | |
342 categories(:child_2).left.should == 1 | |
343 categories(:child_2).right.should == 4 | |
344 Category.valid?.should be_true | |
345 end | |
346 | |
347 it "move_to_child_of" do | |
348 categories(:child_1).move_to_child_of(categories(:child_3)) | |
349 categories(:child_3).id.should == categories(:child_1).parent_id | |
350 Category.valid?.should be_true | |
351 end | |
352 | |
353 it "move_to_child_of_appends_to_end" do | |
354 child = Category.create! :name => 'New Child' | |
355 child.move_to_child_of categories(:top_level) | |
356 child.should == categories(:top_level).children.last | |
357 end | |
358 | |
359 it "subtree_move_to_child_of" do | |
360 categories(:child_2).left.should == 4 | |
361 categories(:child_2).right.should == 7 | |
362 | |
363 categories(:child_1).left.should == 2 | |
364 categories(:child_1).right.should == 3 | |
365 | |
366 categories(:child_2).move_to_child_of(categories(:child_1)) | |
367 Category.valid?.should be_true | |
368 categories(:child_1).id.should == categories(:child_2).parent_id | |
369 | |
370 categories(:child_2).left.should == 3 | |
371 categories(:child_2).right.should == 6 | |
372 categories(:child_1).left.should == 2 | |
373 categories(:child_1).right.should == 7 | |
374 end | |
375 | |
376 it "slightly_difficult_move_to_child_of" do | |
377 categories(:top_level_2).left.should == 11 | |
378 categories(:top_level_2).right.should == 12 | |
379 | |
380 # create a new top-level node and move single-node top-level tree inside it. | |
381 new_top = Category.create(:name => 'New Top') | |
382 new_top.left.should == 13 | |
383 new_top.right.should == 14 | |
384 | |
385 categories(:top_level_2).move_to_child_of(new_top) | |
386 | |
387 Category.valid?.should be_true | |
388 new_top.id.should == categories(:top_level_2).parent_id | |
389 | |
390 categories(:top_level_2).left.should == 12 | |
391 categories(:top_level_2).right.should == 13 | |
392 new_top.left.should == 11 | |
393 new_top.right.should == 14 | |
394 end | |
395 | |
396 it "difficult_move_to_child_of" do | |
397 categories(:top_level).left.should == 1 | |
398 categories(:top_level).right.should == 10 | |
399 categories(:child_2_1).left.should == 5 | |
400 categories(:child_2_1).right.should == 6 | |
401 | |
402 # create a new top-level node and move an entire top-level tree inside it. | |
403 new_top = Category.create(:name => 'New Top') | |
404 categories(:top_level).move_to_child_of(new_top) | |
405 categories(:child_2_1).reload | |
406 Category.valid?.should be_true | |
407 new_top.id.should == categories(:top_level).parent_id | |
408 | |
409 categories(:top_level).left.should == 4 | |
410 categories(:top_level).right.should == 13 | |
411 categories(:child_2_1).left.should == 8 | |
412 categories(:child_2_1).right.should == 9 | |
413 end | |
414 | |
415 #rebuild swaps the position of the 2 children when added using move_to_child twice onto same parent | |
416 it "move_to_child_more_than_once_per_parent_rebuild" do | |
417 root1 = Category.create(:name => 'Root1') | |
418 root2 = Category.create(:name => 'Root2') | |
419 root3 = Category.create(:name => 'Root3') | |
420 | |
421 root2.move_to_child_of root1 | |
422 root3.move_to_child_of root1 | |
423 | |
424 output = Category.roots.last.to_text | |
425 Category.update_all('lft = null, rgt = null') | |
426 Category.rebuild! | |
427 | |
428 Category.roots.last.to_text.should == output | |
429 end | |
430 | |
431 # doing move_to_child twice onto same parent from the furthest right first | |
432 it "move_to_child_more_than_once_per_parent_outside_in" do | |
433 node1 = Category.create(:name => 'Node-1') | |
434 node2 = Category.create(:name => 'Node-2') | |
435 node3 = Category.create(:name => 'Node-3') | |
436 | |
437 node2.move_to_child_of node1 | |
438 node3.move_to_child_of node1 | |
439 | |
440 output = Category.roots.last.to_text | |
441 Category.update_all('lft = null, rgt = null') | |
442 Category.rebuild! | |
443 | |
444 Category.roots.last.to_text.should == output | |
445 end | |
446 | |
447 it "should be able to rebuild without validating each record" do | |
448 root1 = Category.create(:name => 'Root1') | |
449 root2 = Category.create(:name => 'Root2') | |
450 root3 = Category.create(:name => 'Root3') | |
451 | |
452 root2.move_to_child_of root1 | |
453 root3.move_to_child_of root1 | |
454 | |
455 root2.name = nil | |
456 root2.save!(:validate => false) | |
457 | |
458 output = Category.roots.last.to_text | |
459 Category.update_all('lft = null, rgt = null') | |
460 Category.rebuild!(false) | |
461 | |
462 Category.roots.last.to_text.should == output | |
463 end | |
464 | |
465 it "valid_with_null_lefts" do | |
466 Category.valid?.should be_true | |
467 Category.update_all('lft = null') | |
468 Category.valid?.should be_false | |
469 end | |
470 | |
471 it "valid_with_null_rights" do | |
472 Category.valid?.should be_true | |
473 Category.update_all('rgt = null') | |
474 Category.valid?.should be_false | |
475 end | |
476 | |
477 it "valid_with_missing_intermediate_node" do | |
478 # Even though child_2_1 will still exist, it is a sign of a sloppy delete, not an invalid tree. | |
479 Category.valid?.should be_true | |
480 Category.delete(categories(:child_2).id) | |
481 Category.valid?.should be_true | |
482 end | |
483 | |
484 it "valid_with_overlapping_and_rights" do | |
485 Category.valid?.should be_true | |
486 categories(:top_level_2)['lft'] = 0 | |
487 categories(:top_level_2).save | |
488 Category.valid?.should be_false | |
489 end | |
490 | |
491 it "rebuild" do | |
492 Category.valid?.should be_true | |
493 before_text = Category.root.to_text | |
494 Category.update_all('lft = null, rgt = null') | |
495 Category.rebuild! | |
496 Category.valid?.should be_true | |
497 before_text.should == Category.root.to_text | |
498 end | |
499 | |
500 it "move_possible_for_sibling" do | |
501 categories(:child_2).move_possible?(categories(:child_1)).should be_true | |
502 end | |
503 | |
504 it "move_not_possible_to_self" do | |
505 categories(:top_level).move_possible?(categories(:top_level)).should be_false | |
506 end | |
507 | |
508 it "move_not_possible_to_parent" do | |
509 categories(:top_level).descendants.each do |descendant| | |
510 categories(:top_level).move_possible?(descendant).should be_false | |
511 descendant.move_possible?(categories(:top_level)).should be_true | |
512 end | |
513 end | |
514 | |
515 it "is_or_is_ancestor_of?" do | |
516 [:child_1, :child_2, :child_2_1, :child_3].each do |c| | |
517 categories(:top_level).is_or_is_ancestor_of?(categories(c)).should be_true | |
518 end | |
519 categories(:top_level).is_or_is_ancestor_of?(categories(:top_level_2)).should be_false | |
520 end | |
521 | |
522 it "left_and_rights_valid_with_blank_left" do | |
523 Category.left_and_rights_valid?.should be_true | |
524 categories(:child_2)[:lft] = nil | |
525 categories(:child_2).save(:validate => false) | |
526 Category.left_and_rights_valid?.should be_false | |
527 end | |
528 | |
529 it "left_and_rights_valid_with_blank_right" do | |
530 Category.left_and_rights_valid?.should be_true | |
531 categories(:child_2)[:rgt] = nil | |
532 categories(:child_2).save(:validate => false) | |
533 Category.left_and_rights_valid?.should be_false | |
534 end | |
535 | |
536 it "left_and_rights_valid_with_equal" do | |
537 Category.left_and_rights_valid?.should be_true | |
538 categories(:top_level_2)[:lft] = categories(:top_level_2)[:rgt] | |
539 categories(:top_level_2).save(:validate => false) | |
540 Category.left_and_rights_valid?.should be_false | |
541 end | |
542 | |
543 it "left_and_rights_valid_with_left_equal_to_parent" do | |
544 Category.left_and_rights_valid?.should be_true | |
545 categories(:child_2)[:lft] = categories(:top_level)[:lft] | |
546 categories(:child_2).save(:validate => false) | |
547 Category.left_and_rights_valid?.should be_false | |
548 end | |
549 | |
550 it "left_and_rights_valid_with_right_equal_to_parent" do | |
551 Category.left_and_rights_valid?.should be_true | |
552 categories(:child_2)[:rgt] = categories(:top_level)[:rgt] | |
553 categories(:child_2).save(:validate => false) | |
554 Category.left_and_rights_valid?.should be_false | |
555 end | |
556 | |
557 it "moving_dirty_objects_doesnt_invalidate_tree" do | |
558 r1 = Category.create :name => "Test 1" | |
559 r2 = Category.create :name => "Test 2" | |
560 r3 = Category.create :name => "Test 3" | |
561 r4 = Category.create :name => "Test 4" | |
562 nodes = [r1, r2, r3, r4] | |
563 | |
564 r2.move_to_child_of(r1) | |
565 Category.valid?.should be_true | |
566 | |
567 r3.move_to_child_of(r1) | |
568 Category.valid?.should be_true | |
569 | |
570 r4.move_to_child_of(r2) | |
571 Category.valid?.should be_true | |
572 end | |
573 | |
574 it "multi_scoped_no_duplicates_for_columns?" do | |
575 lambda { | |
576 Note.no_duplicates_for_columns? | |
577 }.should_not raise_exception | |
578 end | |
579 | |
580 it "multi_scoped_all_roots_valid?" do | |
581 lambda { | |
582 Note.all_roots_valid? | |
583 }.should_not raise_exception | |
584 end | |
585 | |
586 it "multi_scoped" do | |
587 note1 = Note.create!(:body => "A", :notable_id => 2, :notable_type => 'Category') | |
588 note2 = Note.create!(:body => "B", :notable_id => 2, :notable_type => 'Category') | |
589 note3 = Note.create!(:body => "C", :notable_id => 2, :notable_type => 'Default') | |
590 | |
591 [note1, note2].should == note1.self_and_siblings | |
592 [note3].should == note3.self_and_siblings | |
593 end | |
594 | |
595 it "multi_scoped_rebuild" do | |
596 root = Note.create!(:body => "A", :notable_id => 3, :notable_type => 'Category') | |
597 child1 = Note.create!(:body => "B", :notable_id => 3, :notable_type => 'Category') | |
598 child2 = Note.create!(:body => "C", :notable_id => 3, :notable_type => 'Category') | |
599 | |
600 child1.move_to_child_of root | |
601 child2.move_to_child_of root | |
602 | |
603 Note.update_all('lft = null, rgt = null') | |
604 Note.rebuild! | |
605 | |
606 Note.roots.find_by_body('A').should == root | |
607 [child1, child2].should == Note.roots.find_by_body('A').children | |
608 end | |
609 | |
610 it "same_scope_with_multi_scopes" do | |
611 lambda { | |
612 notes(:scope1).same_scope?(notes(:child_1)) | |
613 }.should_not raise_exception | |
614 notes(:scope1).same_scope?(notes(:child_1)).should be_true | |
615 notes(:child_1).same_scope?(notes(:scope1)).should be_true | |
616 notes(:scope1).same_scope?(notes(:scope2)).should be_false | |
617 end | |
618 | |
619 it "quoting_of_multi_scope_column_names" do | |
620 ["\"notable_id\"", "\"notable_type\""].should == Note.quoted_scope_column_names | |
621 end | |
622 | |
623 it "equal_in_same_scope" do | |
624 notes(:scope1).should == notes(:scope1) | |
625 notes(:scope1).should_not == notes(:child_1) | |
626 end | |
627 | |
628 it "equal_in_different_scopes" do | |
629 notes(:scope1).should_not == notes(:scope2) | |
630 end | |
631 | |
632 it "delete_does_not_invalidate" do | |
633 Category.acts_as_nested_set_options[:dependent] = :delete | |
634 categories(:child_2).destroy | |
635 Category.valid?.should be_true | |
636 end | |
637 | |
638 it "destroy_does_not_invalidate" do | |
639 Category.acts_as_nested_set_options[:dependent] = :destroy | |
640 categories(:child_2).destroy | |
641 Category.valid?.should be_true | |
642 end | |
643 | |
644 it "destroy_multiple_times_does_not_invalidate" do | |
645 Category.acts_as_nested_set_options[:dependent] = :destroy | |
646 categories(:child_2).destroy | |
647 categories(:child_2).destroy | |
648 Category.valid?.should be_true | |
649 end | |
650 | |
651 it "assigning_parent_id_on_create" do | |
652 category = Category.create!(:name => "Child", :parent_id => categories(:child_2).id) | |
653 categories(:child_2).should == category.parent | |
654 categories(:child_2).id.should == category.parent_id | |
655 category.left.should_not be_nil | |
656 category.right.should_not be_nil | |
657 Category.valid?.should be_true | |
658 end | |
659 | |
660 it "assigning_parent_on_create" do | |
661 category = Category.create!(:name => "Child", :parent => categories(:child_2)) | |
662 categories(:child_2).should == category.parent | |
663 categories(:child_2).id.should == category.parent_id | |
664 category.left.should_not be_nil | |
665 category.right.should_not be_nil | |
666 Category.valid?.should be_true | |
667 end | |
668 | |
669 it "assigning_parent_id_to_nil_on_create" do | |
670 category = Category.create!(:name => "New Root", :parent_id => nil) | |
671 category.parent.should be_nil | |
672 category.parent_id.should be_nil | |
673 category.left.should_not be_nil | |
674 category.right.should_not be_nil | |
675 Category.valid?.should be_true | |
676 end | |
677 | |
678 it "assigning_parent_id_on_update" do | |
679 category = categories(:child_2_1) | |
680 category.parent_id = categories(:child_3).id | |
681 category.save | |
682 category.reload | |
683 categories(:child_3).reload | |
684 categories(:child_3).should == category.parent | |
685 categories(:child_3).id.should == category.parent_id | |
686 Category.valid?.should be_true | |
687 end | |
688 | |
689 it "assigning_parent_on_update" do | |
690 category = categories(:child_2_1) | |
691 category.parent = categories(:child_3) | |
692 category.save | |
693 category.reload | |
694 categories(:child_3).reload | |
695 categories(:child_3).should == category.parent | |
696 categories(:child_3).id.should == category.parent_id | |
697 Category.valid?.should be_true | |
698 end | |
699 | |
700 it "assigning_parent_id_to_nil_on_update" do | |
701 category = categories(:child_2_1) | |
702 category.parent_id = nil | |
703 category.save | |
704 category.parent.should be_nil | |
705 category.parent_id.should be_nil | |
706 Category.valid?.should be_true | |
707 end | |
708 | |
709 it "creating_child_from_parent" do | |
710 category = categories(:child_2).children.create!(:name => "Child") | |
711 categories(:child_2).should == category.parent | |
712 categories(:child_2).id.should == category.parent_id | |
713 category.left.should_not be_nil | |
714 category.right.should_not be_nil | |
715 Category.valid?.should be_true | |
716 end | |
717 | |
718 def check_structure(entries, structure) | |
719 structure = structure.dup | |
720 Category.each_with_level(entries) do |category, level| | |
721 expected_level, expected_name = structure.shift | |
722 expected_name.should == category.name | |
723 expected_level.should == level | |
724 end | |
725 end | |
726 | |
727 it "each_with_level" do | |
728 levels = [ | |
729 [0, "Top Level"], | |
730 [1, "Child 1"], | |
731 [1, "Child 2"], | |
732 [2, "Child 2.1"], | |
733 [1, "Child 3" ]] | |
734 | |
735 check_structure(Category.root.self_and_descendants, levels) | |
736 | |
737 # test some deeper structures | |
738 category = Category.find_by_name("Child 1") | |
739 c1 = Category.new(:name => "Child 1.1") | |
740 c2 = Category.new(:name => "Child 1.1.1") | |
741 c3 = Category.new(:name => "Child 1.1.1.1") | |
742 c4 = Category.new(:name => "Child 1.2") | |
743 [c1, c2, c3, c4].each(&:save!) | |
744 | |
745 c1.move_to_child_of(category) | |
746 c2.move_to_child_of(c1) | |
747 c3.move_to_child_of(c2) | |
748 c4.move_to_child_of(category) | |
749 | |
750 levels = [ | |
751 [0, "Top Level"], | |
752 [1, "Child 1"], | |
753 [2, "Child 1.1"], | |
754 [3, "Child 1.1.1"], | |
755 [4, "Child 1.1.1.1"], | |
756 [2, "Child 1.2"], | |
757 [1, "Child 2"], | |
758 [2, "Child 2.1"], | |
759 [1, "Child 3" ]] | |
760 | |
761 check_structure(Category.root.self_and_descendants, levels) | |
762 end | |
763 | |
764 it "should not error on a model with attr_accessible" do | |
765 model = Class.new(ActiveRecord::Base) | |
766 model.table_name = 'categories' | |
767 model.attr_accessible :name | |
768 lambda { | |
769 model.acts_as_nested_set | |
770 model.new(:name => 'foo') | |
771 }.should_not raise_exception | |
772 end | |
773 | |
774 describe "before_move_callback" do | |
775 it "should fire the callback" do | |
776 categories(:child_2).should_receive(:custom_before_move) | |
777 categories(:child_2).move_to_root | |
778 end | |
779 | |
780 it "should stop move when callback returns false" do | |
781 Category.test_allows_move = false | |
782 categories(:child_3).move_to_root.should be_false | |
783 categories(:child_3).root?.should be_false | |
784 end | |
785 | |
786 it "should not halt save actions" do | |
787 Category.test_allows_move = false | |
788 categories(:child_3).parent_id = nil | |
789 categories(:child_3).save.should be_true | |
790 end | |
791 end | |
792 | |
793 describe "counter_cache" do | |
794 | |
795 it "should allow use of a counter cache for children" do | |
796 note1 = things(:parent1) | |
797 note1.children.count.should == 2 | |
798 end | |
799 | |
800 it "should increment the counter cache on create" do | |
801 note1 = things(:parent1) | |
802 note1.children.count.should == 2 | |
803 note1[:children_count].should == 2 | |
804 note1.children.create :body => 'Child 3' | |
805 note1.children.count.should == 3 | |
806 note1.reload | |
807 note1[:children_count].should == 3 | |
808 end | |
809 | |
810 it "should decrement the counter cache on destroy" do | |
811 note1 = things(:parent1) | |
812 note1.children.count.should == 2 | |
813 note1[:children_count].should == 2 | |
814 note1.children.last.destroy | |
815 note1.children.count.should == 1 | |
816 note1.reload | |
817 note1[:children_count].should == 1 | |
818 end | |
819 end | |
820 | |
821 describe "association callbacks on children" do | |
822 it "should call the appropriate callbacks on the children :has_many association " do | |
823 root = DefaultWithCallbacks.create | |
824 root.should_not be_new_record | |
825 | |
826 child = root.children.build | |
827 | |
828 root.before_add.should == child | |
829 root.after_add.should == child | |
830 | |
831 root.before_remove.should_not == child | |
832 root.after_remove.should_not == child | |
833 | |
834 child.save.should be_true | |
835 root.children.delete(child).should be_true | |
836 | |
837 root.before_remove.should == child | |
838 root.after_remove.should == child | |
839 end | |
840 end | |
841 end |