mm-tree 0.1.1 → 0.1.2
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.
- data/lib/locale/en.yml +1 -1
- data/lib/locale/nb.yml +8 -0
- data/lib/mongo_mapper/plugins/tree.rb +67 -42
- data/lib/version.rb +1 -1
- data/test/helper.rb +32 -0
- data/test/test_search_class_multi.rb +6 -5
- data/test/test_tree.rb +79 -12
- metadata +49 -36
data/lib/locale/en.yml
CHANGED
@@ -5,4 +5,4 @@ en:
|
|
5
5
|
tree:
|
6
6
|
cyclic: "Can't be children of a descendant"
|
7
7
|
incorrect_parent_nv_dv: "Positional values doesn't match parent (check nv/dv values)"
|
8
|
-
search_class_mismatch: "Mismatch between search classes. Parent: %{parent_search_class} Node: %{node_search_class}
|
8
|
+
search_class_mismatch: "Mismatch between search classes. Parent: %{parent_search_class} Node: %{node_search_class}"
|
data/lib/locale/nb.yml
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
nb:
|
2
|
+
mongo_mapper:
|
3
|
+
errors:
|
4
|
+
messages:
|
5
|
+
tree:
|
6
|
+
cyclic: "Kan ikke være barnet av en etterkommer."
|
7
|
+
incorrect_parent_nv_dv: "Posisjonelle/rasjonelle verdier stemmer ikke (check nv/dv values)"
|
8
|
+
search_class_mismatch: "Søke klassene er ikke identiske. Forelder: %{parent_search_class} Node/barn: %{node_search_class}."
|
@@ -12,6 +12,22 @@ module MongoMapper
|
|
12
12
|
self.where(tree_parent_id_field => nil).sort(tree_sort_order()).all
|
13
13
|
end
|
14
14
|
|
15
|
+
# force all keys to update
|
16
|
+
def rekey_all!
|
17
|
+
# rekey keys for each root. will do children
|
18
|
+
_pos = 1
|
19
|
+
self.roots.each do |root|
|
20
|
+
new_keys = keys_from_parent_keys_and_position({:nv => 0, :dv => 1, :snv => 1, :sdv => 0}, _pos)
|
21
|
+
if !compare_keys(root.tree_keys(), new_keys)
|
22
|
+
root.move_nv_dv(new_keys[:nv], new_keys[:dv], {:ignore_conflict => true})
|
23
|
+
root.save!
|
24
|
+
root.reload
|
25
|
+
end
|
26
|
+
root.rekey_children
|
27
|
+
_pos += 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
15
31
|
def position_from_nv_dv(nv, dv)
|
16
32
|
anc_tree_keys = ancestor_tree_keys(nv, dv)
|
17
33
|
(nv - anc_tree_keys[:nv]) / anc_tree_keys[:snv]
|
@@ -51,11 +67,25 @@ module MongoMapper
|
|
51
67
|
return rethash
|
52
68
|
end #get_ancestor_keys(nv,dv)
|
53
69
|
|
70
|
+
def keys_from_parent_keys_and_position(parent_keys, position)
|
71
|
+
{ :nv => parent_keys[:nv] + (position * parent_keys[:snv]),
|
72
|
+
:dv => parent_keys[:dv] + (position * parent_keys[:sdv]),
|
73
|
+
:snv => parent_keys[:nv] + ((position + 1) * parent_keys[:snv]),
|
74
|
+
:sdv => parent_keys[:dv] + ((position + 1) * parent_keys[:sdv]) }
|
75
|
+
end
|
76
|
+
|
77
|
+
def compare_keys(key1, key2)
|
78
|
+
( (key1[:nv] === key2[:nv]) and
|
79
|
+
(key1[:dv] === key2[:dv]) and
|
80
|
+
(key1[:snv] === key2[:snv]) and
|
81
|
+
(key1[:sdv] === key2[:sdv]))
|
82
|
+
end
|
83
|
+
|
54
84
|
def tree_sort_order
|
55
85
|
if !tree_use_rational_numbers
|
56
|
-
"#{tree_order}
|
86
|
+
"#{tree_order} #{tree_info_depth_field}"
|
57
87
|
else
|
58
|
-
|
88
|
+
tree_info_nv_div_dv_field.asc
|
59
89
|
end
|
60
90
|
end
|
61
91
|
|
@@ -85,11 +115,17 @@ module MongoMapper
|
|
85
115
|
self.tree_search_class ||= self
|
86
116
|
|
87
117
|
class_attribute :tree_parent_id_field
|
88
|
-
self.tree_parent_id_field ||=
|
118
|
+
self.tree_parent_id_field ||= :parent_id
|
89
119
|
|
90
120
|
class_attribute :tree_use_rational_numbers
|
91
121
|
self.tree_use_rational_numbers ||= true
|
92
122
|
|
123
|
+
class_attribute :tree_info_depth_field
|
124
|
+
self.tree_info_depth_field ||= :tree_info_depth
|
125
|
+
|
126
|
+
class_attribute :tree_info_nv_div_dv_field
|
127
|
+
self.tree_info_nv_div_dv_field ||= :tree_info_nv_div_dv
|
128
|
+
|
93
129
|
class_attribute :tree_order
|
94
130
|
|
95
131
|
key tree_parent_id_field, ObjectId
|
@@ -139,11 +175,11 @@ module MongoMapper
|
|
139
175
|
if parent.nil?
|
140
176
|
self[tree_parent_id_field] = nil
|
141
177
|
self.tree_info.path = []
|
142
|
-
self
|
178
|
+
self[tree_info_depth_field] = 0
|
143
179
|
elsif !!opts[:force] || self.changes.include?(tree_parent_id_field)
|
144
180
|
@_will_move = true
|
145
181
|
self.tree_info.path = parent.tree_info.path + [parent._id]
|
146
|
-
self
|
182
|
+
self[tree_info_depth_field] = parent[tree_info_depth_field] + 1
|
147
183
|
end
|
148
184
|
end
|
149
185
|
|
@@ -156,8 +192,8 @@ module MongoMapper
|
|
156
192
|
self.tree_info.dv = dv
|
157
193
|
end
|
158
194
|
|
159
|
-
|
160
|
-
|
195
|
+
# Should calculate next free nv/dv and set that if parent has changed.
|
196
|
+
# (set values to "missing and call missing function should work")
|
161
197
|
def update_nv_dv(opts = {})
|
162
198
|
return if !tree_use_rational_numbers
|
163
199
|
if @_set_nv_dv == true
|
@@ -172,9 +208,8 @@ module MongoMapper
|
|
172
208
|
elsif (self.changes.include?(tree_parent_id_field)) || opts[:force]
|
173
209
|
# only changed parent, needs to find next free position
|
174
210
|
# use function for "missing nv/dv"
|
175
|
-
|
176
|
-
new_keys = self.
|
177
|
-
new_keys = self.next_keys_available(self[tree_parent_id_field], (opts[:position] + 1)) if opts[:position]
|
211
|
+
new_keys = self.keys_from_position((self.has_siblings? + 1)) if !opts[:position]
|
212
|
+
new_keys = self.keys_from_position((opts[:position] + 1)) if opts[:position]
|
178
213
|
self.move_nv_dv(new_keys[:nv], new_keys[:dv])
|
179
214
|
end
|
180
215
|
end
|
@@ -193,12 +228,12 @@ module MongoMapper
|
|
193
228
|
else
|
194
229
|
last_sibling_position = self.class.position_from_nv_dv(last_sibling.tree_info.nv, last_sibling.tree_info.dv)
|
195
230
|
end
|
196
|
-
new_keys = self.
|
231
|
+
new_keys = self.keys_from_position((last_sibling_position + 1) )
|
197
232
|
self.tree_info.nv = new_keys[:nv]
|
198
233
|
self.tree_info.dv = new_keys[:dv]
|
199
234
|
self.tree_info.snv = new_keys[:snv]
|
200
235
|
self.tree_info.sdv = new_keys[:sdv]
|
201
|
-
self
|
236
|
+
self[tree_info_nv_div_dv_field] = Float(new_keys[:nv]/Float(new_keys[:dv]))
|
202
237
|
@_set_nv_dv = true
|
203
238
|
end
|
204
239
|
end
|
@@ -208,9 +243,6 @@ module MongoMapper
|
|
208
243
|
# can force move without updating conflicting siblings
|
209
244
|
def move_nv_dv(nv, dv, opts = {})
|
210
245
|
return if !tree_use_rational_numbers
|
211
|
-
# return
|
212
|
-
# nv_div_dv = Float(nv)/Float(dv)
|
213
|
-
# find nv_div_dv?
|
214
246
|
position = self.class.position_from_nv_dv(nv, dv)
|
215
247
|
if !self.root?
|
216
248
|
anc_keys = self.class.ancestor_tree_keys(nv, dv)
|
@@ -240,14 +272,14 @@ module MongoMapper
|
|
240
272
|
self.tree_info.dv = dv
|
241
273
|
self.tree_info.snv = rnv
|
242
274
|
self.tree_info.sdv = rdv
|
243
|
-
self
|
275
|
+
self[tree_info_nv_div_dv_field] = Float(self.tree_info.nv)/Float(self.tree_info.dv)
|
244
276
|
# as this is triggered from after_validation, save should be triggered by the caller.
|
245
277
|
end
|
246
278
|
# change this require ancestor data + position,
|
247
279
|
# next position can be found using: self.has_siblings? + 1
|
248
280
|
# as when moving children, the sibling_count won't work
|
249
|
-
def
|
250
|
-
_parent = tree_search_class.where(:_id =>
|
281
|
+
def keys_from_position(position)
|
282
|
+
_parent = tree_search_class.where(:_id => self[tree_parent_id_field]).first
|
251
283
|
_parent = nil if ((_parent.nil?) || (_parent == []))
|
252
284
|
ancnv = 0
|
253
285
|
ancsnv = 1
|
@@ -259,24 +291,11 @@ module MongoMapper
|
|
259
291
|
ancdv = _parent.tree_info.dv
|
260
292
|
ancsdv = _parent.tree_info.sdv
|
261
293
|
end
|
262
|
-
|
263
|
-
rethash = {:nv => 1, :dv => 1, :snv => 2, :sdv => 1}
|
264
|
-
else
|
265
|
-
# get values from sibling_count
|
266
|
-
_nv = ancnv + (position * ancsnv)
|
267
|
-
_dv = ancdv + (position * ancsdv)
|
268
|
-
rethash = {
|
269
|
-
:nv => _nv,
|
270
|
-
:dv => _dv,
|
271
|
-
:snv => ancnv + ((position + 1) * ancsnv),
|
272
|
-
:sdv => ancdv + ((position + 1) * ancsdv)
|
273
|
-
}
|
274
|
-
end
|
275
|
-
rethash
|
294
|
+
self.class.keys_from_parent_keys_and_position({:nv => ancnv, :dv => ancdv, :snv => ancsnv, :sdv => ancsdv}, position)
|
276
295
|
end
|
277
296
|
|
278
297
|
def next_sibling_keys
|
279
|
-
|
298
|
+
keys_from_position(self.class.position_from_nv_dv(self.tree_info.nv, self.tree_info.dv) +1)
|
280
299
|
end
|
281
300
|
|
282
301
|
# to save queries, this will calculate ancestor tree keys instead of query them
|
@@ -330,6 +349,21 @@ module MongoMapper
|
|
330
349
|
end
|
331
350
|
end
|
332
351
|
|
352
|
+
def rekey_children
|
353
|
+
return if (!self.children?)
|
354
|
+
_pos = 1
|
355
|
+
self.children.each do |child|
|
356
|
+
new_keys = self.class.keys_from_parent_keys_and_position(self.tree_keys(), _pos)
|
357
|
+
if !self.class.compare_keys(child.tree_keys(), new_keys)
|
358
|
+
child.move_nv_dv(new_keys[:nv], new_keys[:dv], {:ignore_conflict => true})
|
359
|
+
child.save!
|
360
|
+
child.reload
|
361
|
+
end
|
362
|
+
child.rekey_children
|
363
|
+
_pos += 1
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
333
367
|
def root?
|
334
368
|
self[tree_parent_id_field].nil?
|
335
369
|
end
|
@@ -416,17 +450,8 @@ module MongoMapper
|
|
416
450
|
self.children.each do |child|
|
417
451
|
child.update_path!
|
418
452
|
child.update_nv_dv!(:position => _position)
|
419
|
-
# puts "Update Child - #{child.name.inspect} #{child.changes.inspect}"
|
420
|
-
# puts "#{child.updated_at.to_f}"
|
421
|
-
child.save
|
422
|
-
child.reload
|
423
|
-
# puts "#{child.updated_at.to_f}"
|
424
453
|
child.save
|
425
454
|
child.reload
|
426
|
-
# puts "#{child.updated_at.to_f}"
|
427
|
-
child.reload
|
428
|
-
# puts "#{child.updated_at.to_f}"
|
429
|
-
|
430
455
|
_position += 1
|
431
456
|
end
|
432
457
|
self.enable_timestamp_callback()
|
data/lib/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -41,4 +41,36 @@ class Test::Unit::TestCase
|
|
41
41
|
def eql_arrays?(first, second)
|
42
42
|
first.collect(&:_id).to_set == second.collect(&:_id).to_set
|
43
43
|
end
|
44
|
+
|
45
|
+
custom_matcher :verify_keys do |receiver, matcher, args|
|
46
|
+
testkeys = args[0]
|
47
|
+
matcher.positive_failure_message = "Expected #{receiver.name} to match keys #{testkeys}, but got #{receiver.tree_keys()}"
|
48
|
+
matcher.negative_failure_message = "Expected #{receiver.name} to NOT match keys #{testkeys}, but got #{receiver.tree_keys()}"
|
49
|
+
rkeys = receiver.tree_keys()
|
50
|
+
( (rkeys[:nv] === testkeys[:nv]) and
|
51
|
+
(rkeys[:dv] === testkeys[:dv]) and
|
52
|
+
(rkeys[:snv] === testkeys[:snv]) and
|
53
|
+
(rkeys[:sdv] === testkeys[:sdv]))
|
54
|
+
end
|
55
|
+
|
56
|
+
custom_matcher :verify_order do |receiver, matcher, args|
|
57
|
+
matching_order = args[0]
|
58
|
+
order_from_reciever_ids = Array.new
|
59
|
+
order_from_reciever_names = Array.new
|
60
|
+
receiver.each do |reci|
|
61
|
+
# order_from_reciever_ids << reci._id
|
62
|
+
order_from_reciever_names << reci.name
|
63
|
+
end
|
64
|
+
|
65
|
+
order_from_matching_ids = Array.new
|
66
|
+
order_from_matching_names = Array.new
|
67
|
+
matching_order.each do |matc|
|
68
|
+
# order_from_matching_ids << matc._id
|
69
|
+
order_from_matching_names << matc.name
|
70
|
+
end
|
71
|
+
matcher.positive_failure_message = "Expected order to be #{order_from_matching_names}, but got #{order_from_reciever_names}"
|
72
|
+
matcher.negative_failure_message = "Expected order to be different from #{order_from_matching_names}, but got #{order_from_reciever_names}"
|
73
|
+
receiver == args[0]
|
74
|
+
end
|
75
|
+
|
44
76
|
end
|
@@ -14,7 +14,7 @@ class TestSearchScope < Test::Unit::TestCase
|
|
14
14
|
@cube_1_2 = Cube.create(:name => "Cube 1.2", :parent => @cube_1)
|
15
15
|
@cube_1_2_1 = Cube.create(:name => "Cube 1.2.1", :parent => @cube_1_2)
|
16
16
|
@cube_1_2_2 = Cube.create(:name => "Cube 1.2.2", :parent => @cube_1_2)
|
17
|
-
@
|
17
|
+
@cube_1_2_1_1 = Cube.create(:name => "Cube 1.2.1.1", :parent => @cube_1_2_1)
|
18
18
|
end
|
19
19
|
|
20
20
|
should "return cubes as children of cube_1" do
|
@@ -37,9 +37,10 @@ class TestSearchScope < Test::Unit::TestCase
|
|
37
37
|
@cube_1_2.reload
|
38
38
|
@cube_1_2_1.reload
|
39
39
|
@cube_1_2_2.reload
|
40
|
-
@
|
41
|
-
@cube_1_1.siblings.should
|
42
|
-
@cube_1.descendants.should
|
40
|
+
@cube_1_2_1_1.reload
|
41
|
+
@cube_1_1.siblings.should verify_order(Array[@cube_1_2, @cube_1_2_2])
|
42
|
+
@cube_1.descendants.should verify_order(Array[@cube_1_1, @cube_1_2, @cube_1_2_1, @cube_1_2_1_1, @cube_1_2_2])
|
43
|
+
@cube_1.children.should verify_order(Array[@cube_1_1, @cube_1_2, @cube_1_2_2])
|
43
44
|
end
|
44
45
|
|
45
46
|
should "not return any triangles or cubes descendants of shape_1" do
|
@@ -64,7 +65,7 @@ class TestSearchScope < Test::Unit::TestCase
|
|
64
65
|
@cube_1.errors.count.should == 1 #should have an error
|
65
66
|
@cube_1.errors.each do |attribute, errmsg|
|
66
67
|
attribute.to_s.should == "base"
|
67
|
-
errmsg.should == ("Mismatch between search classes. Parent: Triangle Node: Cube
|
68
|
+
errmsg.should == ("Mismatch between search classes. Parent: Triangle Node: Cube")
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
data/test/test_tree.rb
CHANGED
@@ -8,8 +8,7 @@ class TestMongomapperActsAsTree < Test::Unit::TestCase
|
|
8
8
|
@node_1_2_1 = Category.create(:name => "Node 1.2.1", :parent => @node_1_2)
|
9
9
|
@node_1_2_2 = Category.create(:name => "Node 1.2.2", :parent => @node_1_2)
|
10
10
|
@node_1_3 = Category.create(:name => "Node 1.3", :parent => @node_1)
|
11
|
-
|
12
|
-
@node_2 = Category.create(:name => "Node 2")
|
11
|
+
@node_2 = Category.create(:name => "Node 2")
|
13
12
|
@node_2_1 = Category.create(:name => "Node 2.1", :parent => @node_2)
|
14
13
|
@node_2_2 = Category.create(:name => "Node 2.2", :parent => @node_2)
|
15
14
|
@node_2_3 = Category.create(:name => "Node 2.3", :parent => @node_2)
|
@@ -53,9 +52,9 @@ class TestMongomapperActsAsTree < Test::Unit::TestCase
|
|
53
52
|
end
|
54
53
|
|
55
54
|
should "set depth" do
|
56
|
-
@node_1.
|
57
|
-
@node_1_1.
|
58
|
-
@node_1_2_1.
|
55
|
+
@node_1[Category.tree_info_depth_field].should == 0
|
56
|
+
@node_1_1[Category.tree_info_depth_field].should == 1
|
57
|
+
@node_1_2_1[Category.tree_info_depth_field].should == 2
|
59
58
|
end
|
60
59
|
|
61
60
|
should "have children" do
|
@@ -118,7 +117,7 @@ class TestMongomapperActsAsTree < Test::Unit::TestCase
|
|
118
117
|
assert @node_1_2.descendants.include?(@node_1_3)
|
119
118
|
assert @node_1_2_1.is_or_is_sibling_of?(@node_1_3)
|
120
119
|
assert @node_1_2_2.is_or_is_sibling_of?(@node_1_3)
|
121
|
-
@node_1_3.
|
120
|
+
@node_1_3[Category.tree_info_depth_field].should == 2
|
122
121
|
end
|
123
122
|
|
124
123
|
should "move children on save" do
|
@@ -194,6 +193,26 @@ class TestMongomapperActsAsTree < Test::Unit::TestCase
|
|
194
193
|
end
|
195
194
|
|
196
195
|
context "node (keys)" do
|
196
|
+
should "verify order of tree" do
|
197
|
+
all_category_items = Category.sort(Category.tree_sort_order).all
|
198
|
+
correct_order = Array[@node_1,
|
199
|
+
@node_1_1,
|
200
|
+
@node_1_2,
|
201
|
+
@node_1_2_1,
|
202
|
+
@node_1_2_2,
|
203
|
+
@node_1_3,
|
204
|
+
@node_2,
|
205
|
+
@node_2_1,
|
206
|
+
@node_2_2,
|
207
|
+
@node_2_3,
|
208
|
+
@node_2_4,
|
209
|
+
@node_2_4_1,
|
210
|
+
@node_2_4_1_1,
|
211
|
+
@node_2_4_2,
|
212
|
+
@node_2_4_3]
|
213
|
+
all_category_items.should verify_order(correct_order);
|
214
|
+
end
|
215
|
+
|
197
216
|
should "find keys from id" do
|
198
217
|
assert Category.find(@node_1._id).tree_keys == @node_1.tree_keys, "Query doesn't match created object #{@node_1.name}"
|
199
218
|
assert Category.find(@node_2_4_1_1._id).tree_keys == @node_2_4_1_1.tree_keys, "Query doesn't match created object #{@node_2_4_1_1.name}"
|
@@ -236,7 +255,7 @@ class TestMongomapperActsAsTree < Test::Unit::TestCase
|
|
236
255
|
|
237
256
|
should "move to new specific nv, dv location and move conflicting items" do
|
238
257
|
assert @node_2_4.ancestor_tree_keys() == @node_2.tree_keys(), "Before move: #{@node_2_4.name} ancestor keys should match #{@node_2.name} got: #{@node_2_4.ancestor_tree_keys()} expected: #{@node_2.tree_keys()}"
|
239
|
-
assert @node_2_4_1.
|
258
|
+
assert @node_2_4_1[Category.tree_info_depth_field] == 2, "Before move: Depth of #{@node_2_4_1.name} should be 2"
|
240
259
|
old_1_2_keys = @node_1_2.tree_keys()
|
241
260
|
new_node_1_2_keys = @node_1_2.next_sibling_keys
|
242
261
|
@node_2_4.set_position(@node_1_2.tree_info.nv, @node_1_2.tree_info.dv)
|
@@ -253,7 +272,7 @@ class TestMongomapperActsAsTree < Test::Unit::TestCase
|
|
253
272
|
|
254
273
|
should "move @node_2_4 to root position" do
|
255
274
|
assert @node_2_4.ancestor_tree_keys() == @node_2.tree_keys(), "Before move: #{@node_2_4.name} ancestor keys should match #{@node_2.name} got: #{@node_2_4.ancestor_tree_keys()} expected: #{@node_2.tree_keys()}"
|
256
|
-
assert @node_2_4_1.
|
275
|
+
assert @node_2_4_1[Category.tree_info_depth_field] == 2, "Before move: Depth of #{@node_2_4_1.name} should be 2"
|
257
276
|
@node_2_4.parent = nil
|
258
277
|
@node_2_4.save
|
259
278
|
@node_2_4.reload
|
@@ -263,7 +282,7 @@ class TestMongomapperActsAsTree < Test::Unit::TestCase
|
|
263
282
|
# TODO: OVERRIDE RELOAD TO LOAD ALL CHILDREN IN MEMORY/CACHE/ASSOCS
|
264
283
|
@node_2_4_1.reload
|
265
284
|
assert @node_2_4_1.tree_info.path.count == 1, "After move: Path length of #{@node_2_4_1.name} should only be 1"
|
266
|
-
assert @node_2_4_1.
|
285
|
+
assert @node_2_4_1[Category.tree_info_depth_field] == 1, "After move: Depth of #{@node_2_4_1.name} should be 1"
|
267
286
|
assert @node_2_4_1.ancestor_tree_keys() == @node_2_4.tree_keys(), "After move: #{@node_2_4_1.name} ancestor keys should match #{@node_2_4.name} got: #{@node_2_4_1.ancestor_tree_keys()} expected: #{@node_2_4.tree_keys()}"
|
268
287
|
# TODO: OVERRIDE RELOAD TO LOAD ALL CHILDREN IN MEMORY/CACHE/ASSOCS
|
269
288
|
@node_2_4_1_1.reload
|
@@ -295,11 +314,59 @@ class TestMongomapperActsAsTree < Test::Unit::TestCase
|
|
295
314
|
node_1_4.tree_keys.should_not == Hash[:nv => 7, :dv => 4, :snv => 9, :sdv => 5]
|
296
315
|
node_1_4.tree_keys.should == Hash[:nv => 9, :dv => 5, :snv => 11, :sdv => 6]
|
297
316
|
end
|
298
|
-
end # tree keys
|
299
317
|
|
300
|
-
|
301
|
-
|
318
|
+
end # context "node (keys)" do
|
319
|
+
context "when rekeying" do
|
320
|
+
should "be able to update the entire treestructre" do
|
321
|
+
return true
|
322
|
+
old_keys_node_1_2 = @node_1_2.tree_keys()
|
323
|
+
old_keys_node_2_4_2 = @node_2_4_2.tree_keys()
|
324
|
+
@node_1_2.destroy
|
325
|
+
@node_2_4_2.destroy
|
326
|
+
Category.rekey_all!
|
327
|
+
|
328
|
+
# verify some nodes that should be unaffected by rekeying
|
329
|
+
@node_1.reload
|
330
|
+
@node_2.reload
|
331
|
+
@node_2_1.reload
|
332
|
+
@node_1.should verify_keys(Hash[:nv => 1, :dv => 1, :snv => 2, :sdv => 1])
|
333
|
+
@node_2.should verify_keys(Hash[:nv => 2, :dv => 1, :snv => 3, :sdv => 1])
|
334
|
+
@node_2_1.should verify_keys(Hash[:nv => 5, :dv => 2, :snv => 8, :sdv => 3])
|
335
|
+
|
336
|
+
@node_1_3.reload
|
337
|
+
@node_2_4_3.reload
|
338
|
+
@node_1_3.should verify_keys(old_keys_node_1_2)
|
339
|
+
@node_2_4_3.should verify_keys(old_keys_node_2_4_2)
|
340
|
+
end
|
341
|
+
|
342
|
+
should "rekey descendants of node_2" do
|
343
|
+
_node_2_2_1 = Category.create(:name => "Node 2.2.1", :parent => @node_2_2)
|
344
|
+
_node_2_2_1_1 = Category.create(:name => "Node 2.2.1.1", :parent => _node_2_2_1)
|
345
|
+
old_keys_node_2_4_1_1 = @node_2_4_1_1.tree_keys()
|
346
|
+
old_keys_node_2_4_1 = @node_2_4_1.tree_keys()
|
347
|
+
old_keys_node_2_2 = @node_2_2.tree_keys()
|
348
|
+
old_keys_node_2_2_1_1 = _node_2_2_1_1.tree_keys()
|
349
|
+
old_keys_node_2_2_1 = _node_2_2_1.tree_keys()
|
350
|
+
_node_2_2_1.destroy # delete temporary node
|
351
|
+
@node_2_2.destroy
|
352
|
+
@node_2_3.destroy
|
353
|
+
@node_2.rekey_children()
|
354
|
+
@node_2_4.reload
|
355
|
+
@node_2_4_1.reload
|
356
|
+
@node_2_4_1_1.reload
|
357
|
+
|
358
|
+
# verify some nodes that should be unaffected by rekeying
|
359
|
+
@node_1.reload
|
360
|
+
@node_1.should verify_keys(Hash[:nv => 1, :dv => 1, :snv => 2, :sdv => 1])
|
361
|
+
@node_2_4.should verify_keys(old_keys_node_2_2)
|
362
|
+
@node_2_4_1.should_not verify_keys(old_keys_node_2_4_1)
|
363
|
+
@node_2_4_1_1.should_not verify_keys(old_keys_node_2_4_1_1)
|
364
|
+
@node_2_4_1.should verify_keys(old_keys_node_2_2_1)
|
365
|
+
@node_2_4_1_1.should verify_keys(old_keys_node_2_2_1_1)
|
366
|
+
end
|
367
|
+
|
302
368
|
end
|
303
369
|
|
370
|
+
|
304
371
|
end #Context "Tree" do
|
305
372
|
end
|
metadata
CHANGED
@@ -1,40 +1,50 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: mm-tree
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Leif Ringstad
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: 0.11.2
|
17
|
+
|
18
|
+
date: 2012-09-02 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
22
21
|
type: :runtime
|
23
|
-
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
23
|
none: false
|
26
|
-
requirements:
|
24
|
+
requirements:
|
27
25
|
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 55
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
- 11
|
31
|
+
- 2
|
29
32
|
version: 0.11.2
|
33
|
+
version_requirements: *id001
|
34
|
+
prerelease: false
|
35
|
+
name: mongo_mapper
|
30
36
|
description: Tree structure for MongoMapper with rational number sorting
|
31
|
-
email:
|
37
|
+
email:
|
32
38
|
- leifcr@gmail.com
|
33
39
|
executables: []
|
40
|
+
|
34
41
|
extensions: []
|
42
|
+
|
35
43
|
extra_rdoc_files: []
|
36
|
-
|
44
|
+
|
45
|
+
files:
|
37
46
|
- lib/locale/en.yml
|
47
|
+
- lib/locale/nb.yml
|
38
48
|
- lib/mm-tree.rb
|
39
49
|
- lib/mongo_mapper/plugins/tree.rb
|
40
50
|
- lib/mongo_mapper/plugins/tree_info.rb
|
@@ -51,35 +61,38 @@ files:
|
|
51
61
|
- README.rdoc
|
52
62
|
homepage: http://github.com/leifcr/mm-tree
|
53
63
|
licenses: []
|
64
|
+
|
54
65
|
post_install_message:
|
55
66
|
rdoc_options: []
|
56
|
-
|
67
|
+
|
68
|
+
require_paths:
|
57
69
|
- lib
|
58
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
71
|
none: false
|
60
|
-
requirements:
|
61
|
-
- -
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
|
64
|
-
segments:
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
65
77
|
- 0
|
66
|
-
|
67
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
version: "0"
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
80
|
none: false
|
69
|
-
requirements:
|
70
|
-
- -
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
|
73
|
-
segments:
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
74
86
|
- 0
|
75
|
-
|
87
|
+
version: "0"
|
76
88
|
requirements: []
|
89
|
+
|
77
90
|
rubyforge_project:
|
78
91
|
rubygems_version: 1.8.24
|
79
92
|
signing_key:
|
80
93
|
specification_version: 3
|
81
94
|
summary: Tree structure for MongoMapper
|
82
|
-
test_files:
|
95
|
+
test_files:
|
83
96
|
- test/helper.rb
|
84
97
|
- test/models/category.rb
|
85
98
|
- test/models/ordered_category.rb
|