mongoid-tree 1.0.1 → 1.0.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.
- checksums.yaml +7 -0
- data/Gemfile +2 -1
- data/lib/mongoid/tree.rb +3 -3
- data/lib/mongoid/tree/ordering.rb +51 -40
- data/spec/mongoid/tree/ordering_spec.rb +93 -79
- data/spec/mongoid/tree/traversal_spec.rb +22 -22
- data/spec/mongoid/tree_spec.rb +106 -80
- data/spec/spec_helper.rb +3 -0
- metadata +13 -23
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 839d3ab28af5b3c0b2c9d4050f1c6940c444bd29
|
4
|
+
data.tar.gz: c9d5033394a48416907f5500fa990b8bf6d96f6e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a85f4ac7c49b858afd70a696aa0595df7af63ae85f21b15330cc3b88b3e277ee30cec3f1fe43dad34246126d3dec8f1da701a162430878f0ae30ef363e569696
|
7
|
+
data.tar.gz: 458d20a30a99b0940c882e14bc080b5c2efaeedbc90f92cc28eae56ee835795194f8695d3c9c9a55e5f0e6977a4ef7eec97d19860b845b9f3656b15d475848f1
|
data/Gemfile
CHANGED
data/lib/mongoid/tree.rb
CHANGED
@@ -103,7 +103,7 @@ module Mongoid
|
|
103
103
|
end
|
104
104
|
|
105
105
|
##
|
106
|
-
# This module implements class methods that will be available
|
106
|
+
# This module implements class methods that will be available
|
107
107
|
# on the document that includes Mongoid::Tree
|
108
108
|
module ClassMethods
|
109
109
|
|
@@ -213,7 +213,7 @@ module Mongoid
|
|
213
213
|
# @note Generated by Mongoid
|
214
214
|
#
|
215
215
|
# @param [Mongoid::Tree] document
|
216
|
-
|
216
|
+
|
217
217
|
##
|
218
218
|
# @!method parent_ids
|
219
219
|
# Returns a list of the document's parent_ids, starting with the root node.
|
@@ -272,7 +272,7 @@ module Mongoid
|
|
272
272
|
#
|
273
273
|
# @return [Mongoid::Criteria] Mongoid criteria to retrieve the documents ancestors
|
274
274
|
def ancestors
|
275
|
-
base_class.
|
275
|
+
base_class.or(parent_ids.map { |id| { :_id => id } })
|
276
276
|
end
|
277
277
|
|
278
278
|
##
|
@@ -37,7 +37,7 @@ module Mongoid
|
|
37
37
|
|
38
38
|
default_scope asc(:position)
|
39
39
|
|
40
|
-
before_save :assign_default_position
|
40
|
+
before_save :assign_default_position, :if => :assign_default_position?
|
41
41
|
before_save :reposition_former_siblings, :if => :sibling_reposition_required?
|
42
42
|
after_destroy :move_lower_siblings_up
|
43
43
|
end
|
@@ -45,29 +45,39 @@ module Mongoid
|
|
45
45
|
##
|
46
46
|
# Returns a chainable criteria for this document's ancestors
|
47
47
|
#
|
48
|
-
# @return [Mongoid::Criteria] Mongoid criteria to retrieve the
|
48
|
+
# @return [Mongoid::Criteria] Mongoid criteria to retrieve the document's ancestors
|
49
49
|
def ancestors
|
50
|
-
base_class.unscoped
|
50
|
+
base_class.unscoped { super }
|
51
51
|
end
|
52
52
|
|
53
53
|
##
|
54
54
|
# Returns siblings below the current document.
|
55
|
-
# Siblings with a position greater than this
|
55
|
+
# Siblings with a position greater than this document's position.
|
56
56
|
#
|
57
|
-
# @return [Mongoid::Criteria] Mongoid criteria to retrieve the
|
57
|
+
# @return [Mongoid::Criteria] Mongoid criteria to retrieve the document's lower siblings
|
58
58
|
def lower_siblings
|
59
59
|
self.siblings.where(:position.gt => self.position)
|
60
60
|
end
|
61
61
|
|
62
62
|
##
|
63
63
|
# Returns siblings above the current document.
|
64
|
-
# Siblings with a position lower than this
|
64
|
+
# Siblings with a position lower than this document's position.
|
65
65
|
#
|
66
|
-
# @return [Mongoid::Criteria] Mongoid criteria to retrieve the
|
66
|
+
# @return [Mongoid::Criteria] Mongoid criteria to retrieve the document's higher siblings
|
67
67
|
def higher_siblings
|
68
68
|
self.siblings.where(:position.lt => self.position)
|
69
69
|
end
|
70
70
|
|
71
|
+
##
|
72
|
+
# Returns siblings between the current document and the other document
|
73
|
+
# Siblings with a position between this document's position and the other document's position.
|
74
|
+
#
|
75
|
+
# @return [Mongoid::Criteria] Mongoid criteria to retrieve the documents between this and the other document
|
76
|
+
def siblings_between(other)
|
77
|
+
range = [self.position, other.position].sort
|
78
|
+
self.siblings.where(:position.gt => range.first, :position.lt => range.last)
|
79
|
+
end
|
80
|
+
|
71
81
|
##
|
72
82
|
# Returns the lowest sibling (could be self)
|
73
83
|
#
|
@@ -123,9 +133,7 @@ module Mongoid
|
|
123
133
|
#
|
124
134
|
# @return [undefined]
|
125
135
|
def move_up
|
126
|
-
|
127
|
-
siblings.where(:position => self.position - 1).first.inc(:position, 1)
|
128
|
-
inc(:position, -1)
|
136
|
+
switch_with_sibling_at_offset(-1) unless at_top?
|
129
137
|
end
|
130
138
|
|
131
139
|
##
|
@@ -133,9 +141,7 @@ module Mongoid
|
|
133
141
|
#
|
134
142
|
# @return [undefined]
|
135
143
|
def move_down
|
136
|
-
|
137
|
-
siblings.where(:position => self.position + 1).first.inc(:position, -1)
|
138
|
-
inc(:position, 1)
|
144
|
+
switch_with_sibling_at_offset(1) unless at_bottom?
|
139
145
|
end
|
140
146
|
|
141
147
|
##
|
@@ -147,23 +153,19 @@ module Mongoid
|
|
147
153
|
#
|
148
154
|
# @return [undefined]
|
149
155
|
def move_above(other)
|
150
|
-
|
151
|
-
self.parent_id = other.parent_id
|
152
|
-
save!
|
153
|
-
end
|
156
|
+
ensure_to_be_sibling_of(other)
|
154
157
|
|
155
158
|
if position > other.position
|
156
159
|
new_position = other.position
|
157
|
-
|
160
|
+
self.siblings_between(other).inc(:position, 1)
|
158
161
|
other.inc(:position, 1)
|
159
|
-
self.position = new_position
|
160
|
-
save!
|
161
162
|
else
|
162
163
|
new_position = other.position - 1
|
163
|
-
|
164
|
-
self.position = new_position
|
165
|
-
save!
|
164
|
+
self.siblings_between(other).inc(:position, -1)
|
166
165
|
end
|
166
|
+
|
167
|
+
self.position = new_position
|
168
|
+
save!
|
167
169
|
end
|
168
170
|
|
169
171
|
##
|
@@ -175,36 +177,43 @@ module Mongoid
|
|
175
177
|
#
|
176
178
|
# @return [undefined]
|
177
179
|
def move_below(other)
|
178
|
-
|
179
|
-
self.parent_id = other.parent_id
|
180
|
-
save!
|
181
|
-
end
|
180
|
+
ensure_to_be_sibling_of(other)
|
182
181
|
|
183
182
|
if position > other.position
|
184
183
|
new_position = other.position + 1
|
185
|
-
|
186
|
-
self.position = new_position
|
187
|
-
save!
|
184
|
+
self.siblings_between(other).inc(:position, 1)
|
188
185
|
else
|
189
186
|
new_position = other.position
|
190
|
-
|
187
|
+
self.siblings_between(other).inc(:position, -1)
|
191
188
|
other.inc(:position, -1)
|
192
|
-
self.position = new_position
|
193
|
-
save!
|
194
189
|
end
|
190
|
+
|
191
|
+
self.position = new_position
|
192
|
+
save!
|
195
193
|
end
|
196
194
|
|
197
195
|
private
|
198
196
|
|
197
|
+
def switch_with_sibling_at_offset(offset)
|
198
|
+
siblings.where(:position => self.position + offset).first.inc(:position, -offset)
|
199
|
+
inc(:position, offset)
|
200
|
+
end
|
201
|
+
|
202
|
+
def ensure_to_be_sibling_of(other)
|
203
|
+
return if sibling_of?(other)
|
204
|
+
self.parent_id = other.parent_id
|
205
|
+
save!
|
206
|
+
end
|
207
|
+
|
199
208
|
def move_lower_siblings_up
|
200
|
-
lower_siblings.
|
209
|
+
lower_siblings.inc(:position, -1)
|
201
210
|
end
|
202
211
|
|
203
212
|
def reposition_former_siblings
|
204
213
|
former_siblings = base_class.where(:parent_id => attribute_was('parent_id')).
|
205
214
|
and(:position.gt => (attribute_was('position') || 0)).
|
206
215
|
excludes(:id => self.id)
|
207
|
-
former_siblings.
|
216
|
+
former_siblings.inc(:position, -1)
|
208
217
|
end
|
209
218
|
|
210
219
|
def sibling_reposition_required?
|
@@ -212,14 +221,16 @@ module Mongoid
|
|
212
221
|
end
|
213
222
|
|
214
223
|
def assign_default_position
|
215
|
-
|
216
|
-
|
217
|
-
if self.siblings.empty? || self.siblings.collect(&:position).compact.empty?
|
218
|
-
self.position = 0
|
224
|
+
self.position = if self.siblings.where(:position.ne => nil).any?
|
225
|
+
self.last_sibling_in_list.position + 1
|
219
226
|
else
|
220
|
-
|
227
|
+
0
|
221
228
|
end
|
222
229
|
end
|
230
|
+
|
231
|
+
def assign_default_position?
|
232
|
+
self.position.nil? || self.parent_id_changed?
|
233
|
+
end
|
223
234
|
end
|
224
235
|
end
|
225
236
|
end
|
@@ -6,9 +6,9 @@ describe Mongoid::Tree::Ordering do
|
|
6
6
|
|
7
7
|
it "should store position as an Integer with a default of nil" do
|
8
8
|
f = OrderedNode.fields['position']
|
9
|
-
f.
|
10
|
-
f.options[:type].
|
11
|
-
f.options[:default].
|
9
|
+
expect(f).not_to be_nil
|
10
|
+
expect(f.options[:type]).to eq(Integer)
|
11
|
+
expect(f.options[:default]).not_to be
|
12
12
|
end
|
13
13
|
|
14
14
|
describe 'when saved' do
|
@@ -25,48 +25,48 @@ describe Mongoid::Tree::Ordering do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should assign a default position of 0 to each node without a sibling" do
|
28
|
-
node(:child).position.
|
29
|
-
node(:subchild).position.
|
30
|
-
node(:subsubchild).position.
|
28
|
+
expect(node(:child).position).to eq(0)
|
29
|
+
expect(node(:subchild).position).to eq(0)
|
30
|
+
expect(node(:subsubchild).position).to eq(0)
|
31
31
|
end
|
32
32
|
|
33
33
|
it "should place siblings at the end of the list by default" do
|
34
|
-
node(:root).position.
|
35
|
-
node(:other_root).position.
|
36
|
-
node(:other_child).position.
|
37
|
-
node(:another_child).position.
|
34
|
+
expect(node(:root).position).to eq(0)
|
35
|
+
expect(node(:other_root).position).to eq(1)
|
36
|
+
expect(node(:other_child).position).to eq(0)
|
37
|
+
expect(node(:another_child).position).to eq(1)
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should move a node to the end of a list when it is moved to a new parent" do
|
41
41
|
other_root = node(:other_root)
|
42
42
|
child = node(:child)
|
43
|
-
child.position.
|
43
|
+
expect(child.position).to eq(0)
|
44
44
|
other_root.children << child
|
45
45
|
child.reload
|
46
|
-
child.position.
|
46
|
+
expect(child.position).to eq(2)
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should correctly reposition siblings when one of them is removed" do
|
50
50
|
node(:other_child).destroy
|
51
|
-
node(:another_child).position.
|
51
|
+
expect(node(:another_child).position).to eq(0)
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should correctly reposition siblings when one of them is added to another parent" do
|
55
55
|
node(:root).children << node(:other_child)
|
56
|
-
node(:another_child).position.
|
56
|
+
expect(node(:another_child).position).to eq(0)
|
57
57
|
end
|
58
58
|
|
59
59
|
it "should correctly reposition siblings when the parent is changed" do
|
60
60
|
other_child = node(:other_child)
|
61
61
|
other_child.parent = node(:root)
|
62
62
|
other_child.save!
|
63
|
-
node(:another_child).position.
|
63
|
+
expect(node(:another_child).position).to eq(0)
|
64
64
|
end
|
65
65
|
|
66
66
|
it "should not reposition siblings when it's not yet saved" do
|
67
67
|
new_node = OrderedNode.new(:name => 'new')
|
68
68
|
new_node.parent = node(:root)
|
69
|
-
new_node.
|
69
|
+
expect(new_node).not_to receive(:reposition_former_siblings)
|
70
70
|
new_node.save
|
71
71
|
end
|
72
72
|
end
|
@@ -85,8 +85,8 @@ describe Mongoid::Tree::Ordering do
|
|
85
85
|
describe ':move_children_to_parent' do
|
86
86
|
it "should set its childen's parent_id to the documents parent_id" do
|
87
87
|
node(:child).move_children_to_parent
|
88
|
-
node(:child).
|
89
|
-
node(:root).children.to_a.
|
88
|
+
expect(node(:child)).to be_leaf
|
89
|
+
expect(node(:root).children.to_a).to eq([node(:child), node(:other_child), node(:subchild)])
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end
|
@@ -105,68 +105,68 @@ describe Mongoid::Tree::Ordering do
|
|
105
105
|
describe '#lower_siblings' do
|
106
106
|
it "should return a collection of siblings lower on the list" do
|
107
107
|
node(:second_child_of_first_root).reload
|
108
|
-
node(:first_root).lower_siblings.to_a.
|
109
|
-
node(:second_root).lower_siblings.to_a.
|
110
|
-
node(:third_root).lower_siblings.to_a.
|
111
|
-
node(:first_child_of_first_root).lower_siblings.to_a.
|
112
|
-
node(:second_child_of_first_root).lower_siblings.to_a.
|
108
|
+
expect(node(:first_root).lower_siblings.to_a).to eq([node(:second_root), node(:third_root)])
|
109
|
+
expect(node(:second_root).lower_siblings.to_a).to eq([node(:third_root)])
|
110
|
+
expect(node(:third_root).lower_siblings.to_a).to eq([])
|
111
|
+
expect(node(:first_child_of_first_root).lower_siblings.to_a).to eq([node(:second_child_of_first_root)])
|
112
|
+
expect(node(:second_child_of_first_root).lower_siblings.to_a).to eq([])
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
116
|
describe '#higher_siblings' do
|
117
117
|
it "should return a collection of siblings lower on the list" do
|
118
|
-
node(:first_root).higher_siblings.to_a.
|
119
|
-
node(:second_root).higher_siblings.to_a.
|
120
|
-
node(:third_root).higher_siblings.to_a.
|
121
|
-
node(:first_child_of_first_root).higher_siblings.to_a.
|
122
|
-
node(:second_child_of_first_root).higher_siblings.to_a.
|
118
|
+
expect(node(:first_root).higher_siblings.to_a).to eq([])
|
119
|
+
expect(node(:second_root).higher_siblings.to_a).to eq([node(:first_root)])
|
120
|
+
expect(node(:third_root).higher_siblings.to_a).to eq([node(:first_root), node(:second_root)])
|
121
|
+
expect(node(:first_child_of_first_root).higher_siblings.to_a).to eq([])
|
122
|
+
expect(node(:second_child_of_first_root).higher_siblings.to_a).to eq([node(:first_child_of_first_root)])
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
126
|
describe '#at_top?' do
|
127
127
|
it "should return true when the node is first in the list" do
|
128
|
-
node(:first_root).
|
129
|
-
node(:first_child_of_first_root).
|
128
|
+
expect(node(:first_root)).to be_at_top
|
129
|
+
expect(node(:first_child_of_first_root)).to be_at_top
|
130
130
|
end
|
131
131
|
|
132
132
|
it "should return false when the node is not first in the list" do
|
133
|
-
node(:second_root).
|
134
|
-
node(:third_root).
|
135
|
-
node(:second_child_of_first_root).
|
133
|
+
expect(node(:second_root)).not_to be_at_top
|
134
|
+
expect(node(:third_root)).not_to be_at_top
|
135
|
+
expect(node(:second_child_of_first_root)).not_to be_at_top
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
139
139
|
describe '#at_bottom?' do
|
140
140
|
it "should return true when the node is last in the list" do
|
141
|
-
node(:third_root).
|
142
|
-
node(:second_child_of_first_root).
|
141
|
+
expect(node(:third_root)).to be_at_bottom
|
142
|
+
expect(node(:second_child_of_first_root)).to be_at_bottom
|
143
143
|
end
|
144
144
|
|
145
145
|
it "should return false when the node is not last in the list" do
|
146
|
-
node(:first_root).
|
147
|
-
node(:second_root).
|
148
|
-
node(:first_child_of_first_root).
|
146
|
+
expect(node(:first_root)).not_to be_at_bottom
|
147
|
+
expect(node(:second_root)).not_to be_at_bottom
|
148
|
+
expect(node(:first_child_of_first_root)).not_to be_at_bottom
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
152
|
describe '#last_sibling_in_list' do
|
153
153
|
it "should return the last sibling in the list containing the current sibling" do
|
154
|
-
node(:first_root).last_sibling_in_list.
|
155
|
-
node(:second_root).last_sibling_in_list.
|
156
|
-
node(:third_root).last_sibling_in_list.
|
154
|
+
expect(node(:first_root).last_sibling_in_list).to eq(node(:third_root))
|
155
|
+
expect(node(:second_root).last_sibling_in_list).to eq(node(:third_root))
|
156
|
+
expect(node(:third_root).last_sibling_in_list).to eq(node(:third_root))
|
157
157
|
end
|
158
158
|
end
|
159
159
|
|
160
160
|
describe '#first_sibling_in_list' do
|
161
161
|
it "should return the first sibling in the list containing the current sibling" do
|
162
|
-
node(:first_root).first_sibling_in_list.
|
163
|
-
node(:second_root).first_sibling_in_list.
|
164
|
-
node(:third_root).first_sibling_in_list.
|
162
|
+
expect(node(:first_root).first_sibling_in_list).to eq(node(:first_root))
|
163
|
+
expect(node(:second_root).first_sibling_in_list).to eq(node(:first_root))
|
164
|
+
expect(node(:third_root).first_sibling_in_list).to eq(node(:first_root))
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
168
|
-
describe 'ancestors' do
|
169
|
-
it "
|
168
|
+
describe '#ancestors' do
|
169
|
+
it "should be returned in the correct order" do
|
170
170
|
setup_tree <<-ENDTREE
|
171
171
|
- root:
|
172
172
|
- level_1_a
|
@@ -175,7 +175,21 @@ describe Mongoid::Tree::Ordering do
|
|
175
175
|
- leaf
|
176
176
|
ENDTREE
|
177
177
|
|
178
|
-
node(:leaf).ancestors.to_a.
|
178
|
+
expect(node(:leaf).ancestors.to_a).to eq([node(:root), node(:level_1_b), node(:level_2_a)])
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should return the ancestors in correct order even after rearranging" do
|
182
|
+
setup_tree <<-ENDTREE
|
183
|
+
- root:
|
184
|
+
- child:
|
185
|
+
- subchild
|
186
|
+
ENDTREE
|
187
|
+
|
188
|
+
child = node(:child); child.parent = nil; child.save!
|
189
|
+
root = node(:root); root.parent = node(:child); root.save!
|
190
|
+
subchild = node(:subchild); subchild.parent = root; subchild.save!
|
191
|
+
|
192
|
+
expect(subchild.ancestors.to_a).to eq([child, root])
|
179
193
|
end
|
180
194
|
end
|
181
195
|
end
|
@@ -199,7 +213,7 @@ describe Mongoid::Tree::Ordering do
|
|
199
213
|
it 'should fix positions within the current list when moving an sibling away from its current parent' do
|
200
214
|
node_to_move = node(:first_child_of_first_root)
|
201
215
|
node_to_move.move_below(node(:first_child_of_second_root))
|
202
|
-
node(:second_child_of_first_root).position.
|
216
|
+
expect(node(:second_child_of_first_root).position).to eq(0)
|
203
217
|
end
|
204
218
|
|
205
219
|
it 'should work when moving to a different parent' do
|
@@ -207,8 +221,8 @@ describe Mongoid::Tree::Ordering do
|
|
207
221
|
new_parent = node(:second_root)
|
208
222
|
node_to_move.move_below(node(:first_child_of_second_root))
|
209
223
|
node_to_move.reload
|
210
|
-
node_to_move.
|
211
|
-
node(:first_child_of_second_root).
|
224
|
+
expect(node_to_move).to be_at_bottom
|
225
|
+
expect(node(:first_child_of_second_root)).to be_at_top
|
212
226
|
end
|
213
227
|
|
214
228
|
it 'should be able to move the first node below the second node' do
|
@@ -217,8 +231,8 @@ describe Mongoid::Tree::Ordering do
|
|
217
231
|
first_node.move_below(second_node)
|
218
232
|
first_node.reload
|
219
233
|
second_node.reload
|
220
|
-
second_node.
|
221
|
-
first_node.higher_siblings.to_a.
|
234
|
+
expect(second_node).to be_at_top
|
235
|
+
expect(first_node.higher_siblings.to_a).to eq([second_node])
|
222
236
|
end
|
223
237
|
|
224
238
|
it 'should be able to move the last node below the first node' do
|
@@ -227,9 +241,9 @@ describe Mongoid::Tree::Ordering do
|
|
227
241
|
last_node.move_below(first_node)
|
228
242
|
first_node.reload
|
229
243
|
last_node.reload
|
230
|
-
last_node.
|
231
|
-
node(:second_root).
|
232
|
-
last_node.higher_siblings.to_a.
|
244
|
+
expect(last_node).not_to be_at_bottom
|
245
|
+
expect(node(:second_root)).to be_at_bottom
|
246
|
+
expect(last_node.higher_siblings.to_a).to eq([first_node])
|
233
247
|
end
|
234
248
|
end
|
235
249
|
|
@@ -237,7 +251,7 @@ describe Mongoid::Tree::Ordering do
|
|
237
251
|
it 'should fix positions within the current list when moving an sibling away from its current parent' do
|
238
252
|
node_to_move = node(:first_child_of_first_root)
|
239
253
|
node_to_move.move_above(node(:first_child_of_second_root))
|
240
|
-
node(:second_child_of_first_root).position.
|
254
|
+
expect(node(:second_child_of_first_root).position).to eq(0)
|
241
255
|
end
|
242
256
|
|
243
257
|
it 'should work when moving to a different parent' do
|
@@ -245,8 +259,8 @@ describe Mongoid::Tree::Ordering do
|
|
245
259
|
new_parent = node(:second_root)
|
246
260
|
node_to_move.move_above(node(:first_child_of_second_root))
|
247
261
|
node_to_move.reload
|
248
|
-
node_to_move.
|
249
|
-
node(:first_child_of_second_root).
|
262
|
+
expect(node_to_move).to be_at_top
|
263
|
+
expect(node(:first_child_of_second_root)).to be_at_bottom
|
250
264
|
end
|
251
265
|
|
252
266
|
it 'should be able to move the last node above the second node' do
|
@@ -255,8 +269,8 @@ describe Mongoid::Tree::Ordering do
|
|
255
269
|
last_node.move_above(second_node)
|
256
270
|
last_node.reload
|
257
271
|
second_node.reload
|
258
|
-
second_node.
|
259
|
-
last_node.higher_siblings.to_a.
|
272
|
+
expect(second_node).to be_at_bottom
|
273
|
+
expect(last_node.higher_siblings.to_a).to eq([node(:first_root)])
|
260
274
|
end
|
261
275
|
|
262
276
|
it 'should be able to move the first node above the last node' do
|
@@ -265,15 +279,15 @@ describe Mongoid::Tree::Ordering do
|
|
265
279
|
first_node.move_above(last_node)
|
266
280
|
first_node.reload
|
267
281
|
last_node.reload
|
268
|
-
node(:second_root).
|
269
|
-
first_node.higher_siblings.to_a.
|
282
|
+
expect(node(:second_root)).to be_at_top
|
283
|
+
expect(first_node.higher_siblings.to_a).to eq([node(:second_root)])
|
270
284
|
end
|
271
285
|
end
|
272
286
|
|
273
287
|
describe "#move_to_top" do
|
274
288
|
it "should return true when attempting to move the first sibling" do
|
275
|
-
node(:first_root).move_to_top.
|
276
|
-
node(:first_child_of_first_root).move_to_top.
|
289
|
+
expect(node(:first_root).move_to_top).to eq(true)
|
290
|
+
expect(node(:first_child_of_first_root).move_to_top).to eq(true)
|
277
291
|
end
|
278
292
|
|
279
293
|
it "should be able to move the last sibling to the top" do
|
@@ -281,17 +295,17 @@ describe Mongoid::Tree::Ordering do
|
|
281
295
|
last_node = node(:third_root)
|
282
296
|
last_node.move_to_top
|
283
297
|
first_node.reload
|
284
|
-
last_node.
|
285
|
-
first_node.
|
286
|
-
first_node.higher_siblings.to_a.
|
287
|
-
last_node.lower_siblings.to_a.
|
298
|
+
expect(last_node).to be_at_top
|
299
|
+
expect(first_node).not_to be_at_top
|
300
|
+
expect(first_node.higher_siblings.to_a).to eq([last_node])
|
301
|
+
expect(last_node.lower_siblings.to_a).to eq([first_node, node(:second_root)])
|
288
302
|
end
|
289
303
|
end
|
290
304
|
|
291
305
|
describe "#move_to_bottom" do
|
292
306
|
it "should return true when attempting to move the last sibling" do
|
293
|
-
node(:third_root).move_to_bottom.
|
294
|
-
node(:second_child_of_first_root).move_to_bottom.
|
307
|
+
expect(node(:third_root).move_to_bottom).to eq(true)
|
308
|
+
expect(node(:second_child_of_first_root).move_to_bottom).to eq(true)
|
295
309
|
end
|
296
310
|
|
297
311
|
it "should be able to move the first sibling to the bottom" do
|
@@ -301,27 +315,27 @@ describe Mongoid::Tree::Ordering do
|
|
301
315
|
first_node.move_to_bottom
|
302
316
|
middle_node.reload
|
303
317
|
last_node.reload
|
304
|
-
first_node.
|
305
|
-
first_node.
|
306
|
-
last_node.
|
307
|
-
last_node.
|
308
|
-
middle_node.
|
309
|
-
first_node.lower_siblings.to_a.
|
310
|
-
last_node.higher_siblings.to_a.
|
318
|
+
expect(first_node).not_to be_at_top
|
319
|
+
expect(first_node).to be_at_bottom
|
320
|
+
expect(last_node).not_to be_at_bottom
|
321
|
+
expect(last_node).not_to be_at_top
|
322
|
+
expect(middle_node).to be_at_top
|
323
|
+
expect(first_node.lower_siblings.to_a).to eq([])
|
324
|
+
expect(last_node.higher_siblings.to_a).to eq([middle_node])
|
311
325
|
end
|
312
326
|
end
|
313
327
|
|
314
328
|
describe "#move_up" do
|
315
329
|
it "should correctly move nodes up" do
|
316
330
|
node(:third).move_up
|
317
|
-
node(:third_root).children.
|
331
|
+
expect(node(:third_root).children).to eq([node(:first), node(:third), node(:second)])
|
318
332
|
end
|
319
333
|
end
|
320
334
|
|
321
335
|
describe "#move_down" do
|
322
336
|
it "should correctly move nodes down" do
|
323
337
|
node(:first).move_down
|
324
|
-
node(:third_root).children.
|
338
|
+
expect(node(:third_root).children).to eq([node(:second), node(:first), node(:third)])
|
325
339
|
end
|
326
340
|
end
|
327
341
|
end # moving nodes around
|
@@ -19,7 +19,7 @@ describe Mongoid::Tree::Traversal do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should default to depth_first traversal" do
|
22
|
-
subject.
|
22
|
+
expect(subject).to receive(:depth_first_traversal)
|
23
23
|
subject.traverse {}
|
24
24
|
end
|
25
25
|
end
|
@@ -42,12 +42,12 @@ describe Mongoid::Tree::Traversal do
|
|
42
42
|
it "should traverse correctly" do
|
43
43
|
result = []
|
44
44
|
node(:node1).traverse(:depth_first) { |node| result << node }
|
45
|
-
result.collect { |n| n.name.to_sym }.
|
45
|
+
expect(result.collect { |n| n.name.to_sym }).to eq([:node1, :node2, :node3, :node4, :node5, :node6, :node7])
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should return and array containing the results of the block for each node" do
|
49
49
|
result = node(:node1).traverse(:depth_first) { |n| n.name.to_sym }
|
50
|
-
result.
|
50
|
+
expect(result).to eq([:node1, :node2, :node3, :node4, :node5, :node6, :node7])
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -69,7 +69,7 @@ describe Mongoid::Tree::Traversal do
|
|
69
69
|
|
70
70
|
it "should traverse correctly" do
|
71
71
|
result = node(:node1).traverse(:depth_first) { |n| n.name.to_sym }
|
72
|
-
result.
|
72
|
+
expect(result).to eq([:node1, :node2, :node3, :node4, :node5, :node6, :node7])
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
@@ -92,12 +92,12 @@ describe Mongoid::Tree::Traversal do
|
|
92
92
|
it 'should iterate through the nodes in the correct order' do
|
93
93
|
result = []
|
94
94
|
node(:node1).traverse(:depth_first) { |node| result << node }
|
95
|
-
result.collect { |n| n.name.to_sym }.
|
95
|
+
expect(result.collect { |n| n.name.to_sym }).to eq([:node1, :node2, :node3, :node4, :node5, :node6, :node7])
|
96
96
|
end
|
97
97
|
|
98
98
|
it 'should return the nodes in the correct order' do
|
99
99
|
result = node(:node1).traverse(:depth_first)
|
100
|
-
result.collect { |n| n.name.to_sym }.
|
100
|
+
expect(result.collect { |n| n.name.to_sym }).to eq([:node1, :node2, :node3, :node4, :node5, :node6, :node7])
|
101
101
|
end
|
102
102
|
|
103
103
|
end
|
@@ -121,12 +121,12 @@ describe Mongoid::Tree::Traversal do
|
|
121
121
|
it "should traverse correctly" do
|
122
122
|
result = []
|
123
123
|
node(:node1).traverse(:breadth_first) { |n| result << n }
|
124
|
-
result.collect { |n| n.name.to_sym }.
|
124
|
+
expect(result.collect { |n| n.name.to_sym }).to eq([:node1, :node2, :node3, :node4, :node5, :node6, :node7])
|
125
125
|
end
|
126
126
|
|
127
127
|
it "should return and array containing the results of the block for each node" do
|
128
128
|
result = node(:node1).traverse(:breadth_first) { |n| n.name.to_sym }
|
129
|
-
result.
|
129
|
+
expect(result).to eq([:node1, :node2, :node3, :node4, :node5, :node6, :node7])
|
130
130
|
end
|
131
131
|
|
132
132
|
end
|
@@ -144,31 +144,31 @@ describe Mongoid::Tree::Traversal do
|
|
144
144
|
Node.stub(:roots).and_return [@root1, @root2]
|
145
145
|
end
|
146
146
|
|
147
|
-
it '
|
148
|
-
Node.
|
147
|
+
it 'should grab each root' do
|
148
|
+
expect(Node).to receive(:roots).and_return []
|
149
149
|
|
150
|
-
Node.traverse.
|
150
|
+
expect(Node.traverse).to eq([])
|
151
151
|
end
|
152
152
|
|
153
|
-
it '
|
154
|
-
@root1.
|
155
|
-
@root2.
|
153
|
+
it 'should default the "type" arg to :depth_first' do
|
154
|
+
expect(@root1).to receive(:traverse).with(:depth_first).and_return([])
|
155
|
+
expect(@root2).to receive(:traverse).with(:depth_first).and_return([])
|
156
156
|
|
157
|
-
Node.traverse.
|
157
|
+
expect(Node.traverse).to eq([])
|
158
158
|
end
|
159
159
|
|
160
|
-
it '
|
161
|
-
@root1.
|
162
|
-
@root2.
|
160
|
+
it 'should traverse each root' do
|
161
|
+
expect(@root1).to receive(:traverse).and_return([1, 2])
|
162
|
+
expect(@root2).to receive(:traverse).and_return([3, 4])
|
163
163
|
|
164
|
-
Node.traverse.
|
164
|
+
expect(Node.traverse).to eq([1, 2, 3, 4])
|
165
165
|
end
|
166
166
|
|
167
167
|
describe 'when the "type" arg is :breadth_first' do
|
168
168
|
|
169
|
-
it '
|
170
|
-
@root1.
|
171
|
-
@root2.
|
169
|
+
it 'should traverse breadth-first' do
|
170
|
+
expect(@root1).to receive(:traverse).with(:breadth_first).and_return([])
|
171
|
+
expect(@root2).to receive(:traverse).with(:breadth_first).and_return([])
|
172
172
|
|
173
173
|
Node.traverse :breadth_first
|
174
174
|
end
|
data/spec/mongoid/tree_spec.rb
CHANGED
@@ -6,46 +6,46 @@ describe Mongoid::Tree do
|
|
6
6
|
|
7
7
|
it "should reference many children as inverse of parent with index" do
|
8
8
|
a = Node.reflect_on_association(:children)
|
9
|
-
a.
|
10
|
-
a.macro.
|
11
|
-
a.class_name.
|
12
|
-
a.foreign_key.
|
13
|
-
Node.index_options.
|
9
|
+
expect(a).to be
|
10
|
+
expect(a.macro).to eq(:has_many)
|
11
|
+
expect(a.class_name).to eq('Node')
|
12
|
+
expect(a.foreign_key).to eq('parent_id')
|
13
|
+
expect(Node.index_options).to have_key(:parent_id => 1)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should be referenced in one parent as inverse of children" do
|
17
17
|
a = Node.reflect_on_association(:parent)
|
18
|
-
a.
|
19
|
-
a.macro.
|
20
|
-
a.class_name.
|
21
|
-
a.inverse_of.
|
18
|
+
expect(a).to be
|
19
|
+
expect(a.macro).to eq(:belongs_to)
|
20
|
+
expect(a.class_name).to eq('Node')
|
21
|
+
expect(a.inverse_of).to eq(:children)
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should store parent_ids as Array with [] as default with index" do
|
25
25
|
f = Node.fields['parent_ids']
|
26
|
-
f.
|
27
|
-
f.options[:type].
|
28
|
-
f.options[:default].
|
29
|
-
Node.index_options.
|
26
|
+
expect(f).to be
|
27
|
+
expect(f.options[:type]).to eq(Array)
|
28
|
+
expect(f.options[:default]).to eq([])
|
29
|
+
expect(Node.index_options).to have_key(:parent_ids => 1)
|
30
30
|
end
|
31
31
|
|
32
32
|
describe 'when new' do
|
33
33
|
it "should not require a saved parent when adding children" do
|
34
34
|
root = Node.new(:name => 'root'); child = Node.new(:name => 'child')
|
35
|
-
expect { root.children << child; root.save! }.to_not raise_error
|
36
|
-
child.
|
35
|
+
expect { root.children << child; root.save! }.to_not raise_error
|
36
|
+
expect(child).to be_persisted
|
37
37
|
end
|
38
38
|
|
39
39
|
it "should not be saved when parent is not saved" do
|
40
40
|
root = Node.new(:name => 'root'); child = Node.new(:name => 'child')
|
41
|
-
child.
|
41
|
+
expect(child).not_to receive(:save)
|
42
42
|
root.children << child
|
43
43
|
end
|
44
44
|
|
45
45
|
it "should save its unsaved children" do
|
46
46
|
root = Node.new(:name => 'root'); child = Node.new(:name => 'child')
|
47
47
|
root.children << child
|
48
|
-
child.
|
48
|
+
expect(child).to receive(:save)
|
49
49
|
root.save
|
50
50
|
end
|
51
51
|
end
|
@@ -66,61 +66,61 @@ describe Mongoid::Tree do
|
|
66
66
|
it "should set the child's parent_id when added to parent's children" do
|
67
67
|
root = Node.create; child = Node.create
|
68
68
|
root.children << child
|
69
|
-
child.parent.
|
70
|
-
child.parent_id.
|
69
|
+
expect(child.parent).to eq(root)
|
70
|
+
expect(child.parent_id).to eq(root.id)
|
71
71
|
end
|
72
72
|
|
73
73
|
it "should set the child's parent_id parent is set on child" do
|
74
74
|
root = Node.create; child = Node.create
|
75
75
|
child.parent = root
|
76
|
-
child.parent.
|
77
|
-
child.parent_id.
|
76
|
+
expect(child.parent).to eq(root)
|
77
|
+
expect(child.parent_id).to eq(root.id)
|
78
78
|
end
|
79
79
|
|
80
80
|
it "should rebuild its parent_ids" do
|
81
81
|
root = Node.create; child = Node.create
|
82
82
|
root.children << child
|
83
|
-
child.parent_ids.
|
83
|
+
expect(child.parent_ids).to eq([root.id])
|
84
84
|
end
|
85
85
|
|
86
86
|
it "should rebuild its children's parent_ids when its own parent_ids changed" do
|
87
87
|
other_root = node(:other_root); child = node(:child); subchild = node(:subchild);
|
88
88
|
other_root.children << child
|
89
89
|
subchild.reload # To get the updated version
|
90
|
-
subchild.parent_ids.
|
90
|
+
expect(subchild.parent_ids).to eq([other_root.id, child.id])
|
91
91
|
end
|
92
92
|
|
93
93
|
it "should correctly rebuild its descendants' parent_ids when moved into an other subtree" do
|
94
94
|
subchild = node(:subchild); subsubchild = node(:subsubchild); other_child = node(:other_child)
|
95
95
|
other_child.children << subchild
|
96
96
|
subsubchild.reload
|
97
|
-
subsubchild.parent_ids.
|
97
|
+
expect(subsubchild.parent_ids).to eq([node(:other_root).id, other_child.id, subchild.id])
|
98
98
|
end
|
99
99
|
|
100
100
|
it "should rebuild its children's parent_ids when its own parent_id is removed" do
|
101
101
|
c = node(:child)
|
102
102
|
c.parent_id = nil
|
103
103
|
c.save
|
104
|
-
node(:subchild).parent_ids.
|
104
|
+
expect(node(:subchild).parent_ids).to eq([node(:child).id])
|
105
105
|
end
|
106
106
|
|
107
107
|
it "should not rebuild its children's parent_ids when it's not required" do
|
108
108
|
root = node(:root)
|
109
|
-
root.
|
109
|
+
expect(root).not_to receive(:rearrange_children)
|
110
110
|
root.save
|
111
111
|
end
|
112
112
|
|
113
113
|
it "should prevent cycles" do
|
114
114
|
child = node(:child)
|
115
115
|
child.parent = node(:subchild)
|
116
|
-
child.
|
117
|
-
child.errors[:parent_id].
|
116
|
+
expect(child).not_to be_valid
|
117
|
+
expect(child.errors[:parent_id]).not_to be_nil
|
118
118
|
end
|
119
119
|
|
120
120
|
it "should save its children when added" do
|
121
121
|
new_child = Node.new(:name => 'new_child')
|
122
122
|
node(:root).children << new_child
|
123
|
-
new_child.
|
123
|
+
expect(new_child).to be_persisted
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
@@ -139,7 +139,7 @@ describe Mongoid::Tree do
|
|
139
139
|
it "should allow to store any subclass within the tree" do
|
140
140
|
subclassed = SubclassedNode.create!(:name => 'subclassed_subchild')
|
141
141
|
node(:child).children << subclassed
|
142
|
-
subclassed.root.
|
142
|
+
expect(subclassed.root).to eq(node(:root))
|
143
143
|
end
|
144
144
|
|
145
145
|
end
|
@@ -159,23 +159,23 @@ describe Mongoid::Tree do
|
|
159
159
|
describe ':nullify_children' do
|
160
160
|
it "should set its children's parent_id to null" do
|
161
161
|
node(:root).nullify_children
|
162
|
-
node(:child).
|
163
|
-
node(:subchild).reload.
|
162
|
+
expect(node(:child)).to be_root
|
163
|
+
expect(node(:subchild).reload).not_to be_descendant_of node(:root)
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
167
167
|
describe ':move_children_to_parent' do
|
168
168
|
it "should set its childen's parent_id to the documents parent_id" do
|
169
169
|
node(:child).move_children_to_parent
|
170
|
-
node(:child).
|
171
|
-
node(:root).children.to_a.
|
170
|
+
expect(node(:child)).to be_leaf
|
171
|
+
expect(node(:root).children.to_a).to match_array([node(:child), node(:other_child), node(:subchild)])
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
175
175
|
describe ':destroy_children' do
|
176
176
|
it "should destroy all children" do
|
177
177
|
root = node(:root)
|
178
|
-
root.children.
|
178
|
+
expect(root.children).to receive(:destroy_all)
|
179
179
|
root.destroy_children
|
180
180
|
end
|
181
181
|
end
|
@@ -183,7 +183,7 @@ describe Mongoid::Tree do
|
|
183
183
|
describe ':delete_descendants' do
|
184
184
|
it "should delete all descendants" do
|
185
185
|
root = node(:root)
|
186
|
-
Node.
|
186
|
+
expect(Node).to receive(:delete_all).with(:conditions => { :parent_ids => root.id })
|
187
187
|
root.delete_descendants
|
188
188
|
end
|
189
189
|
end
|
@@ -204,137 +204,163 @@ describe Mongoid::Tree do
|
|
204
204
|
|
205
205
|
describe '.root' do
|
206
206
|
it "should return the first root document" do
|
207
|
-
Node.root.
|
207
|
+
expect(Node.root).to eq(node(:root))
|
208
208
|
end
|
209
209
|
end
|
210
210
|
|
211
211
|
describe '.roots' do
|
212
212
|
it "should return all root documents" do
|
213
|
-
Node.roots.to_a.
|
213
|
+
expect(Node.roots.to_a).to eq([node(:root), node(:other_root)])
|
214
214
|
end
|
215
215
|
end
|
216
216
|
|
217
217
|
describe '.leaves' do
|
218
218
|
it "should return all leaf documents" do
|
219
|
-
Node.leaves.to_a.
|
219
|
+
expect(Node.leaves.to_a).to match_array([node(:subchild), node(:other_child), node(:other_root)])
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
223
223
|
describe '#root?' do
|
224
224
|
it "should return true for root documents" do
|
225
|
-
node(:root).
|
225
|
+
expect(node(:root)).to be_root
|
226
226
|
end
|
227
227
|
|
228
228
|
it "should return false for non-root documents" do
|
229
|
-
node(:child).
|
229
|
+
expect(node(:child)).not_to be_root
|
230
230
|
end
|
231
231
|
end
|
232
232
|
|
233
233
|
describe '#leaf?' do
|
234
234
|
it "should return true for leaf documents" do
|
235
|
-
node(:subchild).
|
236
|
-
node(:other_child).
|
237
|
-
Node.new.
|
235
|
+
expect(node(:subchild)).to be_leaf
|
236
|
+
expect(node(:other_child)).to be_leaf
|
237
|
+
expect(Node.new).to be_leaf
|
238
238
|
end
|
239
239
|
|
240
240
|
it "should return false for non-leaf documents" do
|
241
|
-
node(:child).
|
242
|
-
node(:root).
|
241
|
+
expect(node(:child)).not_to be_leaf
|
242
|
+
expect(node(:root)).not_to be_leaf
|
243
243
|
end
|
244
244
|
end
|
245
245
|
|
246
246
|
describe '#depth' do
|
247
247
|
it "should return the depth of this document" do
|
248
|
-
node(:root).depth.
|
249
|
-
node(:child).depth.
|
250
|
-
node(:subchild).depth.
|
248
|
+
expect(node(:root).depth).to eq(0)
|
249
|
+
expect(node(:child).depth).to eq(1)
|
250
|
+
expect(node(:subchild).depth).to eq(2)
|
251
251
|
end
|
252
252
|
end
|
253
253
|
|
254
254
|
describe '#root' do
|
255
255
|
it "should return the root for this document" do
|
256
|
-
node(:subchild).root.
|
256
|
+
expect(node(:subchild).root).to eq(node(:root))
|
257
257
|
end
|
258
258
|
|
259
259
|
it "should return itself when there is no root" do
|
260
260
|
new_node = Node.new
|
261
|
-
new_node.root.
|
261
|
+
expect(new_node.root).to be(new_node)
|
262
262
|
end
|
263
263
|
|
264
264
|
it "should return it root when it's not saved yet" do
|
265
265
|
root = Node.new(:name => 'root')
|
266
266
|
new_node = Node.new(:name => 'child')
|
267
267
|
new_node.parent = root
|
268
|
-
new_node.root.
|
268
|
+
expect(new_node.root).to be(root)
|
269
269
|
end
|
270
270
|
end
|
271
271
|
|
272
272
|
describe 'ancestors' do
|
273
|
-
|
274
|
-
|
273
|
+
describe '#ancestors' do
|
274
|
+
it "should return the documents ancestors" do
|
275
|
+
expect(node(:subchild).ancestors.to_a).to eq([node(:root), node(:child)])
|
276
|
+
end
|
277
|
+
|
278
|
+
it "should return the ancestors in correct order even after rearranging" do
|
279
|
+
setup_tree <<-ENDTREE
|
280
|
+
- root:
|
281
|
+
- child:
|
282
|
+
- subchild
|
283
|
+
ENDTREE
|
284
|
+
|
285
|
+
child = node(:child); child.parent = nil; child.save!
|
286
|
+
root = node(:root); root.parent = node(:child); root.save!
|
287
|
+
subchild = node(:subchild); subchild.parent = root; subchild.save!
|
288
|
+
|
289
|
+
expect(subchild.ancestors.to_a).to eq([child, root])
|
290
|
+
end
|
275
291
|
end
|
276
292
|
|
277
|
-
|
278
|
-
|
293
|
+
describe '#ancestors_and_self' do
|
294
|
+
it "should return the documents ancestors and itself" do
|
295
|
+
expect(node(:subchild).ancestors_and_self.to_a).to eq([node(:root), node(:child), node(:subchild)])
|
296
|
+
end
|
279
297
|
end
|
280
298
|
|
281
299
|
describe '#ancestor_of?' do
|
282
300
|
it "should return true for ancestors" do
|
283
|
-
node(:child).
|
301
|
+
expect(node(:child)).to be_ancestor_of(node(:subchild))
|
284
302
|
end
|
285
303
|
|
286
304
|
it "should return false for non-ancestors" do
|
287
|
-
node(:other_child).
|
305
|
+
expect(node(:other_child)).not_to be_ancestor_of(node(:subchild))
|
288
306
|
end
|
289
307
|
end
|
290
308
|
end
|
291
309
|
|
292
310
|
describe 'descendants' do
|
293
|
-
|
294
|
-
|
311
|
+
describe '#descendants' do
|
312
|
+
it "should return the documents descendants" do
|
313
|
+
expect(node(:root).descendants.to_a).to match_array([node(:child), node(:other_child), node(:subchild)])
|
314
|
+
end
|
295
315
|
end
|
296
316
|
|
297
|
-
|
298
|
-
|
317
|
+
describe '#descendants_and_self' do
|
318
|
+
it "should return the documents descendants and itself" do
|
319
|
+
expect(node(:root).descendants_and_self.to_a).to match_array([node(:root), node(:child), node(:other_child), node(:subchild)])
|
320
|
+
end
|
299
321
|
end
|
300
322
|
|
301
323
|
describe '#descendant_of?' do
|
302
324
|
it "should return true for descendants" do
|
303
325
|
subchild = node(:subchild)
|
304
|
-
subchild.
|
305
|
-
subchild.
|
326
|
+
expect(subchild).to be_descendant_of(node(:child))
|
327
|
+
expect(subchild).to be_descendant_of(node(:root))
|
306
328
|
end
|
307
329
|
|
308
330
|
it "should return false for non-descendants" do
|
309
|
-
node(:subchild).
|
331
|
+
expect(node(:subchild)).not_to be_descendant_of(node(:other_child))
|
310
332
|
end
|
311
333
|
end
|
312
334
|
end
|
313
335
|
|
314
336
|
describe 'siblings' do
|
315
|
-
|
316
|
-
|
337
|
+
describe '#siblings' do
|
338
|
+
it "should return the documents siblings" do
|
339
|
+
expect(node(:child).siblings.to_a).to eq([node(:other_child)])
|
340
|
+
end
|
317
341
|
end
|
318
342
|
|
319
|
-
|
320
|
-
|
321
|
-
|
343
|
+
describe '#siblings_and_self' do
|
344
|
+
it "should return the documents siblings and itself" do
|
345
|
+
expect(node(:child).siblings_and_self).to be_kind_of(Mongoid::Criteria)
|
346
|
+
expect(node(:child).siblings_and_self.to_a).to eq([node(:child), node(:other_child)])
|
347
|
+
end
|
322
348
|
end
|
323
349
|
|
324
350
|
describe '#sibling_of?' do
|
325
351
|
it "should return true for siblings" do
|
326
|
-
node(:child).
|
352
|
+
expect(node(:child)).to be_sibling_of(node(:other_child))
|
327
353
|
end
|
328
354
|
|
329
355
|
it "should return false for non-siblings" do
|
330
|
-
node(:root).
|
356
|
+
expect(node(:root)).not_to be_sibling_of(node(:other_child))
|
331
357
|
end
|
332
358
|
end
|
333
359
|
end
|
334
360
|
|
335
361
|
describe '#leaves' do
|
336
362
|
it "should return this documents leaves" do
|
337
|
-
node(:root).leaves.to_a.
|
363
|
+
expect(node(:root).leaves.to_a).to match_array([node(:other_child), node(:subchild)])
|
338
364
|
end
|
339
365
|
end
|
340
366
|
|
@@ -347,11 +373,11 @@ describe Mongoid::Tree do
|
|
347
373
|
end
|
348
374
|
|
349
375
|
it "should provide a before_rearrange callback" do
|
350
|
-
Node.
|
376
|
+
expect(Node).to respond_to :before_rearrange
|
351
377
|
end
|
352
378
|
|
353
379
|
it "should provida an after_rearrange callback" do
|
354
|
-
Node.
|
380
|
+
expect(Node).to respond_to :after_rearrange
|
355
381
|
end
|
356
382
|
|
357
383
|
describe 'before rearrange callback' do
|
@@ -359,8 +385,8 @@ describe Mongoid::Tree do
|
|
359
385
|
it "should be called before the document is rearranged" do
|
360
386
|
Node.before_rearrange :callback
|
361
387
|
node = Node.new
|
362
|
-
node.
|
363
|
-
node.
|
388
|
+
expect(node).to receive(:callback).ordered
|
389
|
+
expect(node).to receive(:rearrange).ordered
|
364
390
|
node.save
|
365
391
|
end
|
366
392
|
|
@@ -371,8 +397,8 @@ describe Mongoid::Tree do
|
|
371
397
|
it "should be called after the document is rearranged" do
|
372
398
|
Node.after_rearrange :callback
|
373
399
|
node = Node.new
|
374
|
-
node.
|
375
|
-
node.
|
400
|
+
expect(node).to receive(:rearrange).ordered
|
401
|
+
expect(node).to receive(:callback).ordered
|
376
402
|
node.save
|
377
403
|
end
|
378
404
|
|
@@ -383,7 +409,7 @@ describe Mongoid::Tree do
|
|
383
409
|
it 'should not raise a NoMethodError' do
|
384
410
|
node = NodeWithEmbeddedDocument.new
|
385
411
|
document = node.build_embedded_document
|
386
|
-
expect { node.save }.to_not raise_error
|
412
|
+
expect { node.save }.to_not raise_error
|
387
413
|
end
|
388
414
|
|
389
415
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,74 +1,66 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Benedikt Deicke
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-07-14 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: mongoid
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - <=
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '4.0'
|
22
|
-
- -
|
20
|
+
- - '>='
|
23
21
|
- !ruby/object:Gem::Version
|
24
22
|
version: '3.0'
|
25
23
|
type: :runtime
|
26
24
|
prerelease: false
|
27
25
|
version_requirements: !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
26
|
requirements:
|
30
27
|
- - <=
|
31
28
|
- !ruby/object:Gem::Version
|
32
29
|
version: '4.0'
|
33
|
-
- -
|
30
|
+
- - '>='
|
34
31
|
- !ruby/object:Gem::Version
|
35
32
|
version: '3.0'
|
36
33
|
- !ruby/object:Gem::Dependency
|
37
34
|
name: rake
|
38
35
|
requirement: !ruby/object:Gem::Requirement
|
39
|
-
none: false
|
40
36
|
requirements:
|
41
|
-
- -
|
37
|
+
- - '>='
|
42
38
|
- !ruby/object:Gem::Version
|
43
39
|
version: 0.9.2
|
44
40
|
type: :development
|
45
41
|
prerelease: false
|
46
42
|
version_requirements: !ruby/object:Gem::Requirement
|
47
|
-
none: false
|
48
43
|
requirements:
|
49
|
-
- -
|
44
|
+
- - '>='
|
50
45
|
- !ruby/object:Gem::Version
|
51
46
|
version: 0.9.2
|
52
47
|
- !ruby/object:Gem::Dependency
|
53
48
|
name: rspec
|
54
49
|
requirement: !ruby/object:Gem::Requirement
|
55
|
-
none: false
|
56
50
|
requirements:
|
57
51
|
- - ~>
|
58
52
|
- !ruby/object:Gem::Version
|
59
|
-
version: '2.
|
53
|
+
version: '2.14'
|
60
54
|
type: :development
|
61
55
|
prerelease: false
|
62
56
|
version_requirements: !ruby/object:Gem::Requirement
|
63
|
-
none: false
|
64
57
|
requirements:
|
65
58
|
- - ~>
|
66
59
|
- !ruby/object:Gem::Version
|
67
|
-
version: '2.
|
60
|
+
version: '2.14'
|
68
61
|
- !ruby/object:Gem::Dependency
|
69
62
|
name: yard
|
70
63
|
requirement: !ruby/object:Gem::Requirement
|
71
|
-
none: false
|
72
64
|
requirements:
|
73
65
|
- - ~>
|
74
66
|
- !ruby/object:Gem::Version
|
@@ -76,7 +68,6 @@ dependencies:
|
|
76
68
|
type: :development
|
77
69
|
prerelease: false
|
78
70
|
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
none: false
|
80
71
|
requirements:
|
81
72
|
- - ~>
|
82
73
|
- !ruby/object:Gem::Version
|
@@ -104,27 +95,26 @@ files:
|
|
104
95
|
- .rspec
|
105
96
|
homepage: https://github.com/benedikt/mongoid-tree
|
106
97
|
licenses: []
|
98
|
+
metadata: {}
|
107
99
|
post_install_message:
|
108
100
|
rdoc_options: []
|
109
101
|
require_paths:
|
110
102
|
- lib
|
111
103
|
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
-
none: false
|
113
104
|
requirements:
|
114
|
-
- -
|
105
|
+
- - '>='
|
115
106
|
- !ruby/object:Gem::Version
|
116
107
|
version: '0'
|
117
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
-
none: false
|
119
109
|
requirements:
|
120
|
-
- -
|
110
|
+
- - '>='
|
121
111
|
- !ruby/object:Gem::Version
|
122
112
|
version: '0'
|
123
113
|
requirements: []
|
124
114
|
rubyforge_project:
|
125
|
-
rubygems_version:
|
115
|
+
rubygems_version: 2.0.0
|
126
116
|
signing_key:
|
127
|
-
specification_version:
|
117
|
+
specification_version: 4
|
128
118
|
summary: A tree structure for Mongoid documents
|
129
119
|
test_files: []
|
130
120
|
has_rdoc:
|