julik-make_like_a_tree 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/make_like_a_tree.rb +23 -2
- data/test/test_ordered_tree.rb +17 -7
- metadata +1 -1
data/lib/make_like_a_tree.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module Julik
|
2
2
|
module MakeLikeTree
|
3
|
-
|
3
|
+
class ImpossibleReparent < RuntimeError
|
4
|
+
end
|
5
|
+
|
6
|
+
VERSION = '1.0.2'
|
4
7
|
def self.included(base) #:nodoc:
|
5
8
|
super
|
6
9
|
base.extend(ClassMethods)
|
@@ -215,7 +218,25 @@ module Julik
|
|
215
218
|
# other elements in the tree and shift them to the right, keeping everything
|
216
219
|
# balanced.
|
217
220
|
def add_child(child)
|
218
|
-
|
221
|
+
begin
|
222
|
+
add_child!(child)
|
223
|
+
rescue ImpossibleReparent
|
224
|
+
false
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# Tells you if a reparent might be invalid
|
229
|
+
def child_can_be_added?(child)
|
230
|
+
impossible = (child[root_column] == self[root_column] &&
|
231
|
+
child[left_col_name] < self[left_col_name]) &&
|
232
|
+
(child[right_col_name] > self[right_col_name])
|
233
|
+
!impossible
|
234
|
+
end
|
235
|
+
|
236
|
+
# A noisy version of add_child, will raise an ImpossibleReparent if you try to reparent a node onto its indirect child
|
237
|
+
def add_child!(child)
|
238
|
+
raise ImpossibleReparent, "Cannot reparent #{child} onto its child node #{self}" unless child_can_be_added?(child)
|
239
|
+
|
219
240
|
k = self.class
|
220
241
|
|
221
242
|
new_left, new_right = determine_range_for_child(child)
|
data/test/test_ordered_tree.rb
CHANGED
@@ -93,6 +93,7 @@ context "A Node used with OrderedTree should" do
|
|
93
93
|
|
94
94
|
reload(root_node, child_node)
|
95
95
|
|
96
|
+
root_node.child_can_be_added?(child_node).should.blaming("possible move").equal true
|
96
97
|
root_node._lr.should.blaming("root node with one subset is 1,4").equal [1, 4]
|
97
98
|
child_node._lr.should.blaming("first in nested range is 2,3").equal [2, 3]
|
98
99
|
end
|
@@ -115,7 +116,7 @@ context "A Node used with OrderedTree should" do
|
|
115
116
|
end
|
116
117
|
end
|
117
118
|
|
118
|
-
specify "
|
119
|
+
specify "shift siblings to the right on child assignment to their left neighbour" do
|
119
120
|
root_node = emit :name => "Root one"
|
120
121
|
|
121
122
|
sub_node = emit :name => "Child 1", :parent_id => root_node.id
|
@@ -140,7 +141,7 @@ context "A Node used with OrderedTree should" do
|
|
140
141
|
b.root_id.should.equal b.id
|
141
142
|
end
|
142
143
|
|
143
|
-
specify "
|
144
|
+
specify "replant a branch" do
|
144
145
|
root_node_1 = emit :name => "First root"
|
145
146
|
root_node_2 = emit :name => "Second root"
|
146
147
|
root_node_3 = emit :name => "Third root"
|
@@ -163,7 +164,7 @@ context "A Node used with OrderedTree should" do
|
|
163
164
|
root_node_2._lr.should.blaming("shifted right to make room").equal [9, 10]
|
164
165
|
end
|
165
166
|
|
166
|
-
specify "
|
167
|
+
specify "report size after moving a branch from underneath" do
|
167
168
|
root_node_1 = emit :name => "First root"
|
168
169
|
root_node_2 = emit :name => "First root"
|
169
170
|
|
@@ -181,7 +182,7 @@ context "A Node used with OrderedTree should" do
|
|
181
182
|
root_node_1.child_count.should.blaming("now has one child").equal 1
|
182
183
|
end
|
183
184
|
|
184
|
-
specify "
|
185
|
+
specify "return siblings" do
|
185
186
|
root_1 = emit :name => "Foo"
|
186
187
|
root_2 = emit :name => "Bar"
|
187
188
|
|
@@ -191,7 +192,7 @@ context "A Node used with OrderedTree should" do
|
|
191
192
|
root_2.siblings.should.equal [root_1]
|
192
193
|
end
|
193
194
|
|
194
|
-
specify "
|
195
|
+
specify "return siblings and self" do
|
195
196
|
root_1 = emit :name => "Foo"
|
196
197
|
root_2 = emit :name => "Bar"
|
197
198
|
|
@@ -310,8 +311,17 @@ context "A Node used with OrderedTree should" do
|
|
310
311
|
c._lr.should.equal [5, 6]
|
311
312
|
end
|
312
313
|
|
313
|
-
|
314
|
-
|
314
|
+
specify "should not allow reparenting an item into its child" do
|
315
|
+
root = emit :name => "foo"
|
316
|
+
child = emit :name => "bar", :parent_id => root.id
|
317
|
+
reload(root, child)
|
318
|
+
|
319
|
+
child.child_can_be_added?(root).should.blaming("Impossible move").equal false
|
320
|
+
lambda { child.add_child!(root)}.should.raise(Julik::MakeLikeTree::ImpossibleReparent)
|
321
|
+
child.add_child(root).should.equal false
|
322
|
+
end
|
323
|
+
|
324
|
+
specify "support promote_to_root" do
|
315
325
|
a, b = emit_many(2)
|
316
326
|
c = emit(:name => "Subtree", :parent_id => a.id)
|
317
327
|
|