rubytree 0.6.2 → 0.7.0
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/API-CHANGES +42 -0
- data/COPYING +14 -0
- data/History.txt +21 -0
- data/Manifest.txt +1 -1
- data/README +63 -8
- data/Rakefile +12 -6
- data/TODO +45 -17
- data/lib/tree.rb +376 -115
- data/lib/tree/binarytree.rb +41 -8
- data/test/test_binarytree.rb +13 -2
- data/test/test_tree.rb +204 -50
- metadata +52 -30
- data/ChangeLog +0 -235
data/lib/tree/binarytree.rb
CHANGED
@@ -47,7 +47,10 @@ module Tree
|
|
47
47
|
# Provides a Binary tree implementation. This node allows only two child nodes (left and right child). It also
|
48
48
|
# provides direct access to the left or right child, including assignment to the same.
|
49
49
|
#
|
50
|
-
# This inherits from the Tree::TreeNode class.
|
50
|
+
# This inherits from the {Tree::TreeNode} class.
|
51
|
+
#
|
52
|
+
# @author Anupam Sengupta
|
53
|
+
#
|
51
54
|
class BinaryTreeNode < TreeNode
|
52
55
|
|
53
56
|
# Adds the specified child node to the receiver node. The child node's parent is set to be the receiver.
|
@@ -57,14 +60,20 @@ module Tree
|
|
57
60
|
#
|
58
61
|
# If only one child is present, then this will be the left child.
|
59
62
|
#
|
60
|
-
#
|
63
|
+
# @param [Tree::BinaryTreeNode] child The child to add.
|
64
|
+
#
|
65
|
+
# @raise [ArgumentError] This exception is raised if two children are already present.
|
61
66
|
def add(child)
|
62
|
-
raise "Already has two child nodes" if @children.size == 2
|
67
|
+
raise ArgumentError, "Already has two child nodes" if @children.size == 2
|
63
68
|
|
64
69
|
super(child)
|
65
70
|
end
|
66
71
|
|
67
72
|
# Returns the left child of the receiver node. Note that left Child == first Child.
|
73
|
+
#
|
74
|
+
# @return [Tree::BinaryTreeNode] The left most (or first) child.
|
75
|
+
#
|
76
|
+
# @see #rightChild
|
68
77
|
def leftChild
|
69
78
|
children.first
|
70
79
|
end
|
@@ -72,39 +81,63 @@ module Tree
|
|
72
81
|
# Returns the right child of the receiver node. Note that right child == last child unless there is only one child.
|
73
82
|
#
|
74
83
|
# Returns +nil+ if the right child does not exist.
|
84
|
+
#
|
85
|
+
# @return [Tree::BinaryTreeNode] The right child, or +nil+ if the right side child does not exist.
|
86
|
+
#
|
87
|
+
# @see #leftChild
|
75
88
|
def rightChild
|
76
89
|
children[1]
|
77
90
|
end
|
78
91
|
|
79
92
|
# Sets the left child of the receiver node. If a previous child existed, it is replaced.
|
93
|
+
#
|
94
|
+
# @param [Tree::BinaryTreeNode] child The child to add as the left-side node.
|
95
|
+
#
|
96
|
+
# @return [Tree::BinaryTreeNode] The assigned child node.
|
97
|
+
#
|
98
|
+
# @see #leftChild
|
99
|
+
# @see #rightChild=
|
80
100
|
def leftChild=(child)
|
81
101
|
@children[0] = child
|
82
102
|
@childrenHash[child.name] = child if child # Assign the name mapping
|
83
103
|
end
|
84
104
|
|
85
105
|
# Sets the right child of the receiver node. If a previous child existed, it is replaced.
|
106
|
+
#
|
107
|
+
# @param [Tree::BinaryTreeNode] child The child to add as the right-side node.
|
108
|
+
#
|
109
|
+
# @return [Tree::BinaryTreeNode] The assigned child node.
|
110
|
+
#
|
111
|
+
# @see #rightChild
|
112
|
+
# @see #leftChild=
|
86
113
|
def rightChild=(child)
|
87
114
|
@children[1] = child
|
88
115
|
@childrenHash[child.name] = child if child # Assign the name mapping
|
89
116
|
end
|
90
117
|
|
91
|
-
# Returns +true+ if the receiver node is the left child of its parent.
|
118
|
+
# Returns +true+ if the receiver node is the left child of its parent.
|
119
|
+
# Always returns +false+ if it is a root node.
|
120
|
+
#
|
121
|
+
# @return [Boolean] +true+ if this is the left child of its parent.
|
92
122
|
def isLeftChild?
|
93
123
|
return false if isRoot?
|
94
124
|
self == parent.leftChild
|
95
125
|
end
|
96
126
|
|
97
|
-
# Returns +true+ if the receiver node is the right child of its parent.
|
127
|
+
# Returns +true+ if the receiver node is the right child of its parent.
|
128
|
+
# Always returns +false+ if it is a root node.
|
129
|
+
#
|
130
|
+
# @return [Boolean] +true+ if this is the right child of its parent.
|
98
131
|
def isRightChild?
|
99
132
|
return false if isRoot?
|
100
133
|
self == parent.rightChild
|
101
134
|
end
|
102
135
|
|
103
136
|
# Swaps the left and right child nodes of the receiver node with each other.
|
137
|
+
#
|
138
|
+
# @todo Define the return value.
|
104
139
|
def swap_children
|
105
|
-
|
106
|
-
self.leftChild = rightChild
|
107
|
-
self.rightChild = tempChild
|
140
|
+
self.leftChild, self.rightChild = self.rightChild, self.leftChild
|
108
141
|
end
|
109
142
|
end
|
110
143
|
|
data/test/test_binarytree.rb
CHANGED
@@ -41,6 +41,7 @@ module TestTree
|
|
41
41
|
# Test class for the binary tree node.
|
42
42
|
class TestBinaryTreeNode < Test::Unit::TestCase
|
43
43
|
|
44
|
+
# Setup the test data scaffolding.
|
44
45
|
def setup
|
45
46
|
@root = Tree::BinaryTreeNode.new("ROOT", "Root Node")
|
46
47
|
|
@@ -49,16 +50,19 @@ module TestTree
|
|
49
50
|
|
50
51
|
end
|
51
52
|
|
53
|
+
# Tear down the test data scaffolding.
|
52
54
|
def teardown
|
53
55
|
@root.remove!(@left_child1)
|
54
56
|
@root.remove!(@right_child1)
|
55
57
|
@root = nil
|
56
58
|
end
|
57
59
|
|
60
|
+
# Test initialization of the binary tree.
|
58
61
|
def test_initialize
|
59
62
|
assert_not_nil(@root, "Binary tree's Root should have been created")
|
60
63
|
end
|
61
64
|
|
65
|
+
# Test the add method.
|
62
66
|
def test_add
|
63
67
|
@root.add @left_child1
|
64
68
|
assert_same(@left_child1, @root.leftChild, "The left node should be left_child1")
|
@@ -68,15 +72,16 @@ module TestTree
|
|
68
72
|
assert_same(@right_child1, @root.rightChild, "The right node should be right_child1")
|
69
73
|
assert_same(@right_child1, @root.lastChild, "The first node should be right_child1")
|
70
74
|
|
71
|
-
assert_raise
|
75
|
+
assert_raise ArgumentError do
|
72
76
|
@root.add Tree::BinaryTreeNode.new("The third child!")
|
73
77
|
end
|
74
78
|
|
75
|
-
assert_raise
|
79
|
+
assert_raise ArgumentError do
|
76
80
|
@root << Tree::BinaryTreeNode.new("The third child!")
|
77
81
|
end
|
78
82
|
end
|
79
83
|
|
84
|
+
# Test the leftChild method.
|
80
85
|
def test_leftChild
|
81
86
|
@root << @left_child1
|
82
87
|
@root << @right_child1
|
@@ -84,6 +89,7 @@ module TestTree
|
|
84
89
|
assert_not_same(@right_child1, @root.leftChild, "The right_child1 is not the left child")
|
85
90
|
end
|
86
91
|
|
92
|
+
# Test the rightChild method.
|
87
93
|
def test_rightChild
|
88
94
|
@root << @left_child1
|
89
95
|
@root << @right_child1
|
@@ -91,6 +97,7 @@ module TestTree
|
|
91
97
|
assert_not_same(@left_child1, @root.rightChild, "The left_child1 is not the left child")
|
92
98
|
end
|
93
99
|
|
100
|
+
# Test leftChild= method.
|
94
101
|
def test_leftChild_equals
|
95
102
|
@root << @left_child1
|
96
103
|
@root << @right_child1
|
@@ -107,6 +114,7 @@ module TestTree
|
|
107
114
|
assert_equal("B Child at Right", @root.lastChild.name, "The last child should now be the right child")
|
108
115
|
end
|
109
116
|
|
117
|
+
# Test rightChild= method.
|
110
118
|
def test_rightChild_equals
|
111
119
|
@root << @left_child1
|
112
120
|
@root << @right_child1
|
@@ -124,6 +132,7 @@ module TestTree
|
|
124
132
|
assert_nil(@root.lastChild, "The first child is now nil")
|
125
133
|
end
|
126
134
|
|
135
|
+
# Test isLeftChild? method.
|
127
136
|
def test_isLeftChild_eh
|
128
137
|
@root << @left_child1
|
129
138
|
@root << @right_child1
|
@@ -138,6 +147,7 @@ module TestTree
|
|
138
147
|
assert(!@root.isLeftChild?, "Root is neither left child nor right")
|
139
148
|
end
|
140
149
|
|
150
|
+
# Test isRightChild? method.
|
141
151
|
def test_isRightChild_eh
|
142
152
|
@root << @left_child1
|
143
153
|
@root << @right_child1
|
@@ -151,6 +161,7 @@ module TestTree
|
|
151
161
|
assert(!@root.isRightChild?, "Root is neither left child nor right")
|
152
162
|
end
|
153
163
|
|
164
|
+
# Test swap_children method.
|
154
165
|
def test_swap_children
|
155
166
|
@root << @left_child1
|
156
167
|
@root << @right_child1
|
data/test/test_tree.rb
CHANGED
@@ -35,6 +35,8 @@
|
|
35
35
|
#
|
36
36
|
|
37
37
|
require 'test/unit'
|
38
|
+
require 'rubygems'
|
39
|
+
require 'json'
|
38
40
|
require 'tree'
|
39
41
|
|
40
42
|
module TestTree
|
@@ -43,15 +45,6 @@ module TestTree
|
|
43
45
|
|
44
46
|
Person = Struct::new(:First, :last) # A simple structure to use as the content for the nodes.
|
45
47
|
|
46
|
-
def setup
|
47
|
-
@root = Tree::TreeNode.new("ROOT", "Root Node")
|
48
|
-
|
49
|
-
@child1 = Tree::TreeNode.new("Child1", "Child Node 1")
|
50
|
-
@child2 = Tree::TreeNode.new("Child2", "Child Node 2")
|
51
|
-
@child3 = Tree::TreeNode.new("Child3", "Child Node 3")
|
52
|
-
@child4 = Tree::TreeNode.new("Child31", "Grand Child 1")
|
53
|
-
|
54
|
-
end
|
55
48
|
|
56
49
|
# Create this structure for the tests
|
57
50
|
#
|
@@ -71,12 +64,25 @@ module TestTree
|
|
71
64
|
# +----+ CHILD3 +---+ CHILD4 |
|
72
65
|
# +---------------+ +------------------+
|
73
66
|
#
|
74
|
-
|
67
|
+
# Some basic setup to create the nodes for the test tree.
|
68
|
+
def setup
|
69
|
+
@root = Tree::TreeNode.new("ROOT", "Root Node")
|
70
|
+
|
71
|
+
@child1 = Tree::TreeNode.new("Child1", "Child Node 1")
|
72
|
+
@child2 = Tree::TreeNode.new("Child2", "Child Node 2")
|
73
|
+
@child3 = Tree::TreeNode.new("Child3", "Child Node 3")
|
74
|
+
@child4 = Tree::TreeNode.new("Child31", "Grand Child 1")
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
# Create the actual test tree.
|
79
|
+
def setup_test_tree
|
75
80
|
@root << @child1
|
76
81
|
@root << @child2
|
77
82
|
@root << @child3 << @child4
|
78
83
|
end
|
79
84
|
|
85
|
+
# Tear down the entire structure
|
80
86
|
def teardown
|
81
87
|
@root = nil
|
82
88
|
end
|
@@ -93,21 +99,25 @@ module TestTree
|
|
93
99
|
assert(@root.hasContent? , "This root should have content")
|
94
100
|
assert_equal(1 , @root.size, "Number of nodes should be one")
|
95
101
|
assert_nil(@root.siblings , "This root does not have any children")
|
96
|
-
|
102
|
+
assert_equal(0, @root.in_degree, "Root should have an in-degree of 0")
|
97
103
|
assert_equal(0, @root.nodeHeight, "Root's height before adding any children is 0")
|
98
|
-
assert_raise(
|
104
|
+
assert_raise(ArgumentError) { Tree::TreeNode.new(nil) }
|
99
105
|
end
|
100
106
|
|
101
|
-
# This test is for the state after the children are linked to the root
|
107
|
+
# This test is for the state after the children are linked to the root.
|
102
108
|
def test_root
|
103
|
-
|
109
|
+
setup_test_tree
|
104
110
|
|
111
|
+
# TODO: Should probably change this logic. Root's root should
|
112
|
+
# return nil so that the possibility of a recursive error does not exist
|
113
|
+
# at all.
|
105
114
|
assert_same(@root , @root.root, "Root's root is self")
|
106
115
|
assert_same(@root , @child1.root, "Root should be ROOT")
|
107
116
|
assert_same(@root , @child4.root, "Root should be ROOT")
|
108
117
|
assert_equal(2 , @root.nodeHeight, "Root's height after adding the children should be 2")
|
109
118
|
end
|
110
119
|
|
120
|
+
# Test the presence of content in the nodes.
|
111
121
|
def test_hasContent_eh
|
112
122
|
aNode = Tree::TreeNode.new("A Node")
|
113
123
|
assert_nil(aNode.content , "The node should not have content")
|
@@ -118,12 +128,14 @@ module TestTree
|
|
118
128
|
assert(aNode.hasContent?, "The node should now have content")
|
119
129
|
end
|
120
130
|
|
121
|
-
|
122
|
-
|
131
|
+
# Test the equivalence of size and length methods.
|
132
|
+
def test_length_is_size
|
133
|
+
setup_test_tree
|
123
134
|
assert_equal(@root.size, @root.length, "Length and size methods should return the same result")
|
124
135
|
end
|
125
136
|
|
126
|
-
|
137
|
+
# Test the <=> operator.
|
138
|
+
def test_spaceship
|
127
139
|
firstNode = Tree::TreeNode.new(1)
|
128
140
|
secondNode = Tree::TreeNode.new(2)
|
129
141
|
|
@@ -143,6 +155,7 @@ module TestTree
|
|
143
155
|
assert_equal(firstNode <=> secondNode, 0)
|
144
156
|
end
|
145
157
|
|
158
|
+
# Test the to_s method. This is probably a little fragile right now.
|
146
159
|
def test_to_s
|
147
160
|
aNode = Tree::TreeNode.new("A Node", "Some Content")
|
148
161
|
|
@@ -151,9 +164,11 @@ module TestTree
|
|
151
164
|
assert_equal(expectedString, aNode.to_s, "The string representation should be same")
|
152
165
|
end
|
153
166
|
|
167
|
+
# Test the firstSibling method.
|
154
168
|
def test_firstSibling
|
155
|
-
|
169
|
+
setup_test_tree
|
156
170
|
|
171
|
+
# TODO: Need to fix the firstSibling method to return nil for nodes with no siblings.
|
157
172
|
assert_same(@root, @root.firstSibling, "Root's first sibling is itself")
|
158
173
|
assert_same(@child1, @child1.firstSibling, "Child1's first sibling is itself")
|
159
174
|
assert_same(@child1, @child2.firstSibling, "Child2's first sibling should be child1")
|
@@ -161,9 +176,11 @@ module TestTree
|
|
161
176
|
assert_not_same(@child1, @child4.firstSibling, "Child4's first sibling is itself")
|
162
177
|
end
|
163
178
|
|
179
|
+
# Test the isFirstSibling? method.
|
164
180
|
def test_isFirstSibling_eh
|
165
|
-
|
181
|
+
setup_test_tree
|
166
182
|
|
183
|
+
# TODO: Need to fix the firstSibling method to return nil for nodes with no siblings.
|
167
184
|
assert(@root.isFirstSibling?, "Root's first sibling is itself")
|
168
185
|
assert( @child1.isFirstSibling?, "Child1's first sibling is itself")
|
169
186
|
assert(!@child2.isFirstSibling?, "Child2 is not the first sibling")
|
@@ -171,9 +188,11 @@ module TestTree
|
|
171
188
|
assert( @child4.isFirstSibling?, "Child4's first sibling is itself")
|
172
189
|
end
|
173
190
|
|
191
|
+
# Test the isLastSibling? method.
|
174
192
|
def test_isLastSibling_eh
|
175
|
-
|
193
|
+
setup_test_tree
|
176
194
|
|
195
|
+
# TODO: Need to fix the lastSibling method to return nil for nodes with no siblings.
|
177
196
|
assert(@root.isLastSibling?, "Root's last sibling is itself")
|
178
197
|
assert(!@child1.isLastSibling?, "Child1 is not the last sibling")
|
179
198
|
assert(!@child2.isLastSibling?, "Child2 is not the last sibling")
|
@@ -181,9 +200,11 @@ module TestTree
|
|
181
200
|
assert( @child4.isLastSibling?, "Child4's last sibling is itself")
|
182
201
|
end
|
183
202
|
|
203
|
+
# Test the lastSibling method.
|
184
204
|
def test_lastSibling
|
185
|
-
|
205
|
+
setup_test_tree
|
186
206
|
|
207
|
+
# TODO: Need to fix the lastSibling method to return nil for nodes with no siblings.
|
187
208
|
assert_same(@root, @root.lastSibling, "Root's last sibling is itself")
|
188
209
|
assert_same(@child3, @child1.lastSibling, "Child1's last sibling should be child3")
|
189
210
|
assert_same(@child3, @child2.lastSibling, "Child2's last sibling should be child3")
|
@@ -191,11 +212,14 @@ module TestTree
|
|
191
212
|
assert_not_same(@child3, @child4.lastSibling, "Child4's last sibling is itself")
|
192
213
|
end
|
193
214
|
|
215
|
+
# Test the siblings method, which is essentially an iterator.
|
194
216
|
def test_siblings
|
195
|
-
|
217
|
+
setup_test_tree
|
196
218
|
|
219
|
+
# Lets first collect the siblings in an array.
|
197
220
|
siblings = []
|
198
221
|
@child1.siblings { |sibling| siblings << sibling}
|
222
|
+
|
199
223
|
assert_equal(2, siblings.length, "Should have two siblings")
|
200
224
|
assert(siblings.include?(@child2), "Should have 2nd child as sibling")
|
201
225
|
assert(siblings.include?(@child3), "Should have 3rd child as sibling")
|
@@ -206,37 +230,47 @@ module TestTree
|
|
206
230
|
|
207
231
|
siblings.clear
|
208
232
|
@child4.siblings {|sibling| siblings << sibling}
|
209
|
-
assert(siblings.empty?, "Should not have any
|
233
|
+
assert(siblings.empty?, "Should not have any siblings")
|
210
234
|
|
235
|
+
siblings.clear
|
236
|
+
siblings = @root.siblings
|
237
|
+
assert_nil(siblings, "Root should not have any siblings")
|
211
238
|
end
|
212
239
|
|
240
|
+
# Test the isOnlyChild? method.
|
213
241
|
def test_isOnlyChild_eh
|
214
|
-
|
242
|
+
setup_test_tree
|
215
243
|
|
244
|
+
assert( @root.isOnlyChild? , "Root is an only child")
|
216
245
|
assert(!@child1.isOnlyChild?, "Child1 is not the only child")
|
217
246
|
assert(!@child2.isOnlyChild?, "Child2 is not the only child")
|
218
247
|
assert(!@child3.isOnlyChild?, "Child3 is not the only child")
|
219
|
-
assert( @child4.isOnlyChild?, "Child4 is
|
248
|
+
assert( @child4.isOnlyChild?, "Child4 is an only child")
|
220
249
|
end
|
221
250
|
|
251
|
+
# Test the nextSibling method.
|
222
252
|
def test_nextSibling
|
223
|
-
|
253
|
+
setup_test_tree
|
224
254
|
|
255
|
+
assert_nil(@root.nextSibling, "Root does not have any next sibling")
|
225
256
|
assert_equal(@child2, @child1.nextSibling, "Child1's next sibling is Child2")
|
226
257
|
assert_equal(@child3, @child2.nextSibling, "Child2's next sibling is Child3")
|
227
258
|
assert_nil(@child3.nextSibling, "Child3 does not have a next sibling")
|
228
259
|
assert_nil(@child4.nextSibling, "Child4 does not have a next sibling")
|
229
260
|
end
|
230
261
|
|
262
|
+
# Test the previousSibling method.
|
231
263
|
def test_previousSibling
|
232
|
-
|
264
|
+
setup_test_tree
|
233
265
|
|
266
|
+
assert_nil(@root.previousSibling, "Root does not have any previous sibling")
|
234
267
|
assert_nil(@child1.previousSibling, "Child1 does not have previous sibling")
|
235
268
|
assert_equal(@child1, @child2.previousSibling, "Child2's previous sibling is Child1")
|
236
269
|
assert_equal(@child2, @child3.previousSibling, "Child3's previous sibling is Child2")
|
237
270
|
assert_nil(@child4.previousSibling, "Child4 does not have a previous sibling")
|
238
271
|
end
|
239
272
|
|
273
|
+
# Test the add method.
|
240
274
|
def test_add
|
241
275
|
assert(!@root.hasChildren?, "Should not have any children")
|
242
276
|
|
@@ -253,10 +287,14 @@ module TestTree
|
|
253
287
|
assert_equal(5, @root.size, "Should have five nodes")
|
254
288
|
assert_equal(2, @child3.size, "Should have two nodes")
|
255
289
|
|
290
|
+
# Test the addition of a duplicate node (duplicate being defined as a node with the same name).
|
256
291
|
assert_raise(RuntimeError) { @root.add(Tree::TreeNode.new(@child1.name)) }
|
257
292
|
|
293
|
+
# Test the addition of a nil node.
|
294
|
+
assert_raise(ArgumentError) { @root.add(nil) }
|
258
295
|
end
|
259
296
|
|
297
|
+
# Test the remove! and removeAll! methods.
|
260
298
|
def test_remove_bang
|
261
299
|
@root << @child1
|
262
300
|
@root << @child2
|
@@ -282,10 +320,16 @@ module TestTree
|
|
282
320
|
assert(!@root.hasChildren?, "Should have no children")
|
283
321
|
assert_equal(1, @root.size, "Should have one node")
|
284
322
|
|
323
|
+
# Some negative testing
|
324
|
+
@root.remove!(nil)
|
325
|
+
assert(!@root.hasChildren?, "Should have no children")
|
326
|
+
assert_equal(1, @root.size, "Should have one node")
|
285
327
|
end
|
286
328
|
|
329
|
+
# Test the removeAll! method.
|
287
330
|
def test_removeAll_bang
|
288
|
-
|
331
|
+
setup_test_tree
|
332
|
+
|
289
333
|
assert(@root.hasChildren?, "Should have children")
|
290
334
|
@root.removeAll!
|
291
335
|
|
@@ -293,8 +337,9 @@ module TestTree
|
|
293
337
|
assert_equal(1, @root.size, "Should have one node")
|
294
338
|
end
|
295
339
|
|
340
|
+
# Test the removeFromParent! method.
|
296
341
|
def test_removeFromParent_bang
|
297
|
-
|
342
|
+
setup_test_tree
|
298
343
|
assert(@root.hasChildren?, "Should have children")
|
299
344
|
assert(!@root.isLeaf?, "Root is not a leaf here")
|
300
345
|
|
@@ -310,8 +355,9 @@ module TestTree
|
|
310
355
|
assert_same(child1, child1.root, "Child 1's root should still be self")
|
311
356
|
end
|
312
357
|
|
358
|
+
# Test the children method.
|
313
359
|
def test_children
|
314
|
-
|
360
|
+
setup_test_tree
|
315
361
|
|
316
362
|
assert(@root.hasChildren?, "Should have children")
|
317
363
|
assert_equal(5, @root.size, "Should have five nodes")
|
@@ -341,8 +387,9 @@ module TestTree
|
|
341
387
|
|
342
388
|
end
|
343
389
|
|
390
|
+
# Test the firstChild method.
|
344
391
|
def test_firstChild
|
345
|
-
|
392
|
+
setup_test_tree
|
346
393
|
|
347
394
|
assert_equal(@child1, @root.firstChild, "Root's first child is Child1")
|
348
395
|
assert_nil(@child1.firstChild, "Child1 does not have any children")
|
@@ -350,8 +397,9 @@ module TestTree
|
|
350
397
|
|
351
398
|
end
|
352
399
|
|
400
|
+
# Test the lastChild method.
|
353
401
|
def test_lastChild
|
354
|
-
|
402
|
+
setup_test_tree
|
355
403
|
|
356
404
|
assert_equal(@child3, @root.lastChild, "Root's last child is Child3")
|
357
405
|
assert_nil(@child1.lastChild, "Child1 does not have any children")
|
@@ -359,8 +407,9 @@ module TestTree
|
|
359
407
|
|
360
408
|
end
|
361
409
|
|
410
|
+
# Test the find method.
|
362
411
|
def test_find
|
363
|
-
|
412
|
+
setup_test_tree
|
364
413
|
foundNode = @root.find { |node| node == @child2}
|
365
414
|
assert_same(@child2, foundNode, "The node should be Child 2")
|
366
415
|
|
@@ -373,16 +422,18 @@ module TestTree
|
|
373
422
|
assert_nil(foundNode, "The node should not be found")
|
374
423
|
end
|
375
424
|
|
425
|
+
# Test the parentage method.
|
376
426
|
def test_parentage
|
377
|
-
|
427
|
+
setup_test_tree
|
378
428
|
|
379
429
|
assert_nil(@root.parentage, "Root does not have any parentage")
|
380
430
|
assert_equal([@root], @child1.parentage, "Child1 has Root as its parent")
|
381
431
|
assert_equal([@child3, @root], @child4.parentage, "Child4 has Child3 and Root as ancestors")
|
382
432
|
end
|
383
433
|
|
434
|
+
# Test the each method.
|
384
435
|
def test_each
|
385
|
-
|
436
|
+
setup_test_tree
|
386
437
|
assert(@root.hasChildren?, "Should have children")
|
387
438
|
assert_equal(5, @root.size, "Should have five nodes")
|
388
439
|
assert(@child3.hasChildren?, "Should have children")
|
@@ -398,8 +449,9 @@ module TestTree
|
|
398
449
|
assert(nodes.include?(@child4), "Should have child 4")
|
399
450
|
end
|
400
451
|
|
452
|
+
# Test the each_leaf method.
|
401
453
|
def test_each_leaf
|
402
|
-
|
454
|
+
setup_test_tree
|
403
455
|
|
404
456
|
nodes = []
|
405
457
|
@root.each_leaf { |node| nodes << node }
|
@@ -412,8 +464,9 @@ module TestTree
|
|
412
464
|
assert(nodes.include?(@child4), "Should have child 4")
|
413
465
|
end
|
414
466
|
|
467
|
+
# Test the parent method.
|
415
468
|
def test_parent
|
416
|
-
|
469
|
+
setup_test_tree
|
417
470
|
assert_nil(@root.parent, "Root's parent should be nil")
|
418
471
|
assert_equal(@root, @child1.parent, "Parent should be root")
|
419
472
|
assert_equal(@root, @child3.parent, "Parent should be root")
|
@@ -421,16 +474,19 @@ module TestTree
|
|
421
474
|
assert_equal(@root, @child4.parent.parent, "Parent should be root")
|
422
475
|
end
|
423
476
|
|
477
|
+
# Test the [] method.
|
424
478
|
def test_indexed_access
|
425
|
-
|
479
|
+
setup_test_tree
|
426
480
|
assert_equal(@child1, @root[0], "Should be the first child")
|
427
481
|
assert_equal(@child4, @root[2][0], "Should be the grandchild")
|
428
482
|
assert_nil(@root["TEST"], "Should be nil")
|
429
|
-
|
483
|
+
assert_nil(@root[99], "Should be nil")
|
484
|
+
assert_raise(ArgumentError) { @root[nil] }
|
430
485
|
end
|
431
486
|
|
487
|
+
# Test the printTree method.
|
432
488
|
def test_printTree
|
433
|
-
|
489
|
+
setup_test_tree
|
434
490
|
#puts
|
435
491
|
#@root.printTree
|
436
492
|
end
|
@@ -482,7 +538,7 @@ module TestTree
|
|
482
538
|
|
483
539
|
# Test the collect method from the mixed-in Enumerable functionality.
|
484
540
|
def test_collect
|
485
|
-
|
541
|
+
setup_test_tree
|
486
542
|
collectArray = @root.collect do |node|
|
487
543
|
node.content = "abc"
|
488
544
|
node
|
@@ -492,7 +548,7 @@ module TestTree
|
|
492
548
|
|
493
549
|
# Test freezing the tree
|
494
550
|
def test_freezeTree_bang
|
495
|
-
|
551
|
+
setup_test_tree
|
496
552
|
@root.content = "ABC"
|
497
553
|
assert_equal("ABC", @root.content, "Content should be 'ABC'")
|
498
554
|
@root.freezeTree!
|
@@ -569,7 +625,7 @@ module TestTree
|
|
569
625
|
def test_nodeDepth
|
570
626
|
assert_equal(0, @root.nodeDepth, "A root node's depth is 0")
|
571
627
|
|
572
|
-
|
628
|
+
setup_test_tree
|
573
629
|
for child in [@child1, @child2, @child3]
|
574
630
|
assert_equal(1, child.nodeDepth, "Node #{child.name} should have depth 1")
|
575
631
|
end
|
@@ -577,6 +633,21 @@ module TestTree
|
|
577
633
|
assert_equal(2, @child4.nodeDepth, "Child 4 should have depth 2")
|
578
634
|
end
|
579
635
|
|
636
|
+
# Test the level method. Since this is an alias of nodeDepth, we just test for equivalence
|
637
|
+
def test_level
|
638
|
+
assert_equal(0, @root.level, "A root node's level is 0")
|
639
|
+
|
640
|
+
assert_equal(@root.nodeDepth, @root.level, "Level and depth should be the same")
|
641
|
+
|
642
|
+
setup_test_tree
|
643
|
+
for child in [@child1, @child2, @child3]
|
644
|
+
assert_equal(1, child.level, "Node #{child.name} should have level 1")
|
645
|
+
assert_equal(@root.nodeDepth, @root.level, "Level and depth should be the same")
|
646
|
+
end
|
647
|
+
|
648
|
+
assert_equal(2, @child4.level, "Child 4 should have level 2")
|
649
|
+
end
|
650
|
+
|
580
651
|
# Test the breadth computation algorithm
|
581
652
|
def test_breadth
|
582
653
|
assert_equal(1, @root.breadth, "A single node's breadth is 1")
|
@@ -633,7 +704,7 @@ module TestTree
|
|
633
704
|
end
|
634
705
|
end
|
635
706
|
|
636
|
-
|
707
|
+
# Test the preordered_each method.
|
637
708
|
def test_preordered_each
|
638
709
|
j = Tree::TreeNode.new("j")
|
639
710
|
f = Tree::TreeNode.new("f")
|
@@ -667,8 +738,9 @@ module TestTree
|
|
667
738
|
end
|
668
739
|
end
|
669
740
|
|
741
|
+
# test the detached_copy method.
|
670
742
|
def test_detached_copy
|
671
|
-
|
743
|
+
setup_test_tree
|
672
744
|
|
673
745
|
assert(@root.hasChildren?, "The root should have children")
|
674
746
|
copy_of_root = @root.detached_copy
|
@@ -683,22 +755,26 @@ module TestTree
|
|
683
755
|
assert(!copy_of_child3.hasChildren?, "Child 3's copy does not have children")
|
684
756
|
end
|
685
757
|
|
758
|
+
# Test the hasChildren? method.
|
686
759
|
def test_hasChildren_eh
|
687
|
-
|
760
|
+
setup_test_tree
|
688
761
|
assert(@root.hasChildren?, "The Root node MUST have children")
|
689
762
|
end
|
690
763
|
|
764
|
+
# test the isLeaf? method.
|
691
765
|
def test_isLeaf_eh
|
692
|
-
|
766
|
+
setup_test_tree
|
693
767
|
assert(!@child3.isLeaf?, "Child 3 is not a leaf node")
|
694
768
|
assert(@child4.isLeaf?, "Child 4 is a leaf node")
|
695
769
|
end
|
696
770
|
|
771
|
+
# Test the isRoot? method.
|
697
772
|
def test_isRoot_eh
|
698
|
-
|
773
|
+
setup_test_tree
|
699
774
|
assert(@root.isRoot?, "The ROOT node must respond as the root node")
|
700
775
|
end
|
701
776
|
|
777
|
+
# Test the content= method.
|
702
778
|
def test_content_equals
|
703
779
|
@root.content = nil
|
704
780
|
assert_nil(@root.content, "Root's content should be nil")
|
@@ -706,13 +782,15 @@ module TestTree
|
|
706
782
|
assert_equal("ABCD", @root.content, "Root's content should now be 'ABCD'")
|
707
783
|
end
|
708
784
|
|
785
|
+
# Test the size method.
|
709
786
|
def test_size
|
710
787
|
assert_equal(1, @root.size, "Root's size should be 1")
|
711
|
-
|
788
|
+
setup_test_tree
|
712
789
|
assert_equal(5, @root.size, "Root's size should be 5")
|
713
790
|
assert_equal(2, @child3.size, "Child 3's size should be 2")
|
714
791
|
end
|
715
792
|
|
793
|
+
# Test the << method.
|
716
794
|
def test_lt2 # Test the << method
|
717
795
|
@root << @child1
|
718
796
|
@root << @child2
|
@@ -723,8 +801,9 @@ module TestTree
|
|
723
801
|
assert_not_nil(@child3['Child31'], "Child 31 should have been added to Child3")
|
724
802
|
end
|
725
803
|
|
804
|
+
# Test the [] method.
|
726
805
|
def test_index # Test the [] method
|
727
|
-
assert_raise(
|
806
|
+
assert_raise(ArgumentError) {@root[nil]}
|
728
807
|
|
729
808
|
@root << @child1
|
730
809
|
@root << @child2
|
@@ -736,6 +815,81 @@ module TestTree
|
|
736
815
|
assert_nil(@root['Some Random Name'], "Should return nil")
|
737
816
|
assert_nil(@root[99], "Should return nil")
|
738
817
|
end
|
818
|
+
|
819
|
+
# Test the in_degree method.
|
820
|
+
def test_in_degree
|
821
|
+
setup_test_tree
|
822
|
+
|
823
|
+
assert_equal(0, @root.in_degree, "Root's in-degree should be zero")
|
824
|
+
assert_equal(1, @child1.in_degree, "Child 1's in-degree should be 1")
|
825
|
+
assert_equal(1, @child2.in_degree, "Child 2's in-degree should be 1")
|
826
|
+
assert_equal(1, @child3.in_degree, "Child 3's in-degree should be 1")
|
827
|
+
assert_equal(1, @child4.in_degree, "Child 4's in-degree should be 1")
|
828
|
+
end
|
829
|
+
|
830
|
+
# Test the out_degree method.
|
831
|
+
def test_out_degree
|
832
|
+
setup_test_tree
|
833
|
+
|
834
|
+
assert_equal(3, @root.out_degree, "Root's out-degree should be 3")
|
835
|
+
assert_equal(0, @child1.out_degree, "Child 1's out-degree should be 0")
|
836
|
+
assert_equal(0, @child2.out_degree, "Child 2's out-degree should be 0")
|
837
|
+
assert_equal(1, @child3.out_degree, "Child 3's out-degree should be 1")
|
838
|
+
assert_equal(0, @child4.out_degree, "Child 4's out-degree should be 0")
|
839
|
+
end
|
840
|
+
|
841
|
+
# Test the new JSON serialization method.
|
842
|
+
def test_json_serialization
|
843
|
+
setup_test_tree
|
844
|
+
|
845
|
+
expected_json = {
|
846
|
+
"name" => "ROOT",
|
847
|
+
"content" => "Root Node",
|
848
|
+
JSON.create_id => "Tree::TreeNode",
|
849
|
+
"children" => [
|
850
|
+
{"name" => "Child1", "content" => "Child Node 1", JSON.create_id => "Tree::TreeNode"},
|
851
|
+
{"name" => "Child2", "content" => "Child Node 2", JSON.create_id => "Tree::TreeNode"},
|
852
|
+
{
|
853
|
+
"name" => "Child3",
|
854
|
+
"content" => "Child Node 3",
|
855
|
+
JSON.create_id => "Tree::TreeNode",
|
856
|
+
"children" => [
|
857
|
+
{"name" => "Child31", "content" => "Grand Child 1", JSON.create_id => "Tree::TreeNode"}
|
858
|
+
]
|
859
|
+
}
|
860
|
+
]
|
861
|
+
}.to_json
|
862
|
+
|
863
|
+
assert_equal(expected_json, @root.to_json)
|
864
|
+
end
|
865
|
+
|
866
|
+
def test_json_deserialization
|
867
|
+
tree_as_json = {
|
868
|
+
"name" => "ROOT",
|
869
|
+
"content" => "Root Node",
|
870
|
+
JSON.create_id => "Tree::TreeNode",
|
871
|
+
"children" => [
|
872
|
+
{"name" => "Child1", "content" => "Child Node 1", JSON.create_id => "Tree::TreeNode"},
|
873
|
+
{"name" => "Child2", "content" => "Child Node 2", JSON.create_id => "Tree::TreeNode"},
|
874
|
+
{
|
875
|
+
"name" => "Child3",
|
876
|
+
"content" => "Child Node 3",
|
877
|
+
JSON.create_id => "Tree::TreeNode",
|
878
|
+
"children" => [
|
879
|
+
{"name" => "Child31", "content" => "Grand Child 1", JSON.create_id => "Tree::TreeNode"}
|
880
|
+
]
|
881
|
+
}
|
882
|
+
]
|
883
|
+
}.to_json
|
884
|
+
|
885
|
+
tree = JSON.parse(tree_as_json)
|
886
|
+
|
887
|
+
assert_equal(@root.name, tree.root.name, "Root should be returned")
|
888
|
+
assert_equal(@child1.name, tree[0].name, "Child 1 should be returned")
|
889
|
+
assert_equal(@child2.name, tree[1].name, "Child 2 should be returned")
|
890
|
+
assert_equal(@child3.name, tree[2].name, "Child 3 should be returned")
|
891
|
+
assert_equal(@child4.name, tree[2][0].name, "Grand Child 1 should be returned")
|
892
|
+
end
|
739
893
|
end
|
740
894
|
end
|
741
895
|
|