rubytree 0.2.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/README +6 -0
- data/Rakefile +54 -0
- data/lib/tree.rb +278 -0
- data/test/person.rb +13 -0
- data/test/testtree.rb +259 -0
- metadata +43 -0
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
|
7
|
+
desc "Default Task"
|
8
|
+
task :default => :gem
|
9
|
+
|
10
|
+
PKG_VERSION = '0.2.2'
|
11
|
+
PKG_FILES = FileList[
|
12
|
+
'[A-Z]*',
|
13
|
+
'lib/**/*.rb',
|
14
|
+
'test/**/*.rb'
|
15
|
+
]
|
16
|
+
|
17
|
+
spec = Gem::Specification.new do |s|
|
18
|
+
s.name = "rubytree"
|
19
|
+
s.version = PKG_VERSION
|
20
|
+
s.platform = Gem::Platform::RUBY
|
21
|
+
s.author = "Anupam Sengupta"
|
22
|
+
s.email = "anupamsg@gmail.com"
|
23
|
+
s.summary = "Ruby implementation of the Tree data structure."
|
24
|
+
|
25
|
+
s.description = <<-END
|
26
|
+
Provides a generic tree data structure with ability to
|
27
|
+
store keyed node elements in the tree. The implementation
|
28
|
+
mixes in the Enumerable module.
|
29
|
+
END
|
30
|
+
|
31
|
+
s.has_rdoc = true
|
32
|
+
s.extra_rdoc_files = ['README']
|
33
|
+
s.autorequire = "tree"
|
34
|
+
s.files = PKG_FILES.to_a
|
35
|
+
s.test_files = Dir.glob('test/test*.rb')
|
36
|
+
end
|
37
|
+
|
38
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
39
|
+
pkg.need_zip = true
|
40
|
+
pkg.need_tar = true
|
41
|
+
end
|
42
|
+
|
43
|
+
Rake::TestTask.new do |t|
|
44
|
+
t.libs << "test"
|
45
|
+
t.test_files = FileList['test/test*.rb']
|
46
|
+
t.verbose = true
|
47
|
+
end
|
48
|
+
|
49
|
+
Rake::RDocTask.new do |rd|
|
50
|
+
rd.rdoc_files.include("README", "lib/**/*.rb")
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
|
data/lib/tree.rb
ADDED
@@ -0,0 +1,278 @@
|
|
1
|
+
#
|
2
|
+
# = tree.rb - Generic Tree implementation
|
3
|
+
#
|
4
|
+
# Provides a generic tree data structure with ability to
|
5
|
+
# store keyed node elements in the tree. The implementation
|
6
|
+
# mixes in the Enumerable module.
|
7
|
+
#
|
8
|
+
# Author:: Anupam Sengupta (anupamsg@gmail.com)
|
9
|
+
#
|
10
|
+
|
11
|
+
module Tree
|
12
|
+
|
13
|
+
# The Tree node class implementation. Mixes in the Enumerable
|
14
|
+
# module.
|
15
|
+
# == Example
|
16
|
+
#
|
17
|
+
# require 'tree'
|
18
|
+
#
|
19
|
+
# myTreeRoot = Tree::TreeNode.new("ROOT", "Root Content")
|
20
|
+
#
|
21
|
+
# myTreeRoot << Tree::TreeNode.new("CHILD1", "Child1 Content") << Tree::TreeNode.new("GRANDCHILD1", "GrandChild1 Content")
|
22
|
+
#
|
23
|
+
# myTreeRoot << Tree::TreeNode.new("CHILD2", "Child2 Content")
|
24
|
+
#
|
25
|
+
# myTreeRoot.printTree
|
26
|
+
#
|
27
|
+
# child1 = myTreeRoot["CHILD1"]
|
28
|
+
#
|
29
|
+
# grandChild1 = myTreeRoot["CHILD1"]["GRANDCHILD1"]
|
30
|
+
#
|
31
|
+
# siblingsOfChild1Array = child1.siblings
|
32
|
+
#
|
33
|
+
# immediateChildrenArray = myTreeRoot.children
|
34
|
+
#
|
35
|
+
# # Process all nodes
|
36
|
+
#
|
37
|
+
# myTreeRoot.each { |node| node.content.reverse }
|
38
|
+
#
|
39
|
+
# myTreeRoot.remove!(child1) # Remove the child
|
40
|
+
class TreeNode
|
41
|
+
include Enumerable
|
42
|
+
|
43
|
+
attr_reader :content, :name, :parent
|
44
|
+
attr_writer :content
|
45
|
+
|
46
|
+
@@fieldSep = '|'
|
47
|
+
@@recordSep = "\n"
|
48
|
+
|
49
|
+
# Constructor which expects the name of the node
|
50
|
+
#
|
51
|
+
# name of the node is expected to be unique across the
|
52
|
+
# tree.
|
53
|
+
#
|
54
|
+
# The content can be of any type, and is defaulted to _nil_.
|
55
|
+
def initialize(name, content = nil)
|
56
|
+
|
57
|
+
raise "Node name HAS to be provided" if name == nil
|
58
|
+
|
59
|
+
@name = name
|
60
|
+
@content = content
|
61
|
+
|
62
|
+
self.setAsRoot!
|
63
|
+
|
64
|
+
@childrenHash = Hash.new
|
65
|
+
@children = []
|
66
|
+
end
|
67
|
+
|
68
|
+
# Print the string representation of this node.
|
69
|
+
def to_s
|
70
|
+
s = size()
|
71
|
+
"Node ID: #{@name} Content: #{@content} Parent: " +
|
72
|
+
(isRoot?() ? "ROOT" : "#{@parent.name}") +
|
73
|
+
" Children: #{@children.length}" +
|
74
|
+
" Total Nodes: #{s}"
|
75
|
+
end
|
76
|
+
|
77
|
+
# Protected method to set the parent node.
|
78
|
+
# This method should NOT be invoked by client code.
|
79
|
+
def parent=(parent)
|
80
|
+
@parent = parent
|
81
|
+
end
|
82
|
+
|
83
|
+
# Convenience synonym for Tree#add method.
|
84
|
+
# This method allows a convenient method to add
|
85
|
+
# children hierarchies in the tree.
|
86
|
+
# E.g. root << child << grand_child
|
87
|
+
def <<(child)
|
88
|
+
add(child)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Adds the specified child node to the receiver node.
|
92
|
+
# The child node's parent is set to be the receiver.
|
93
|
+
# The child is added as the last child in the current
|
94
|
+
# list of children for the receiver node.
|
95
|
+
def add(child)
|
96
|
+
raise "Child already added" if @childrenHash.has_key?(child.name)
|
97
|
+
|
98
|
+
@childrenHash[child.name] = child
|
99
|
+
@children << child
|
100
|
+
child.parent = self
|
101
|
+
return child
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
# Removes the specified child node from the receiver node.
|
106
|
+
# The removed children nodes are orphaned but available
|
107
|
+
# if an alternate reference exists.
|
108
|
+
# Returns the child node.
|
109
|
+
def remove!(child)
|
110
|
+
@childrenHash.delete(child.name)
|
111
|
+
@children.delete(child)
|
112
|
+
child.setAsRoot! unless child == nil
|
113
|
+
return child
|
114
|
+
end
|
115
|
+
|
116
|
+
# Removes this node from its parent. If this is the root node,
|
117
|
+
# then does nothing.
|
118
|
+
def removeFromParent!
|
119
|
+
@parent.remove!(self) unless isRoot?
|
120
|
+
end
|
121
|
+
|
122
|
+
# Removes all children from the receiver node.
|
123
|
+
def removeAll!
|
124
|
+
for child in @children
|
125
|
+
child.setAsRoot!
|
126
|
+
end
|
127
|
+
@childrenHash.clear
|
128
|
+
@children.clear
|
129
|
+
self
|
130
|
+
end
|
131
|
+
|
132
|
+
# Indicates whether this node has any associated content.
|
133
|
+
def hasContent?
|
134
|
+
@content != nil
|
135
|
+
end
|
136
|
+
|
137
|
+
# Private method which sets this node as a root node.
|
138
|
+
def setAsRoot!
|
139
|
+
@parent = nil
|
140
|
+
end
|
141
|
+
|
142
|
+
# Indicates whether this node is a root node. Note that
|
143
|
+
# orphaned children will also be reported as root nodes.
|
144
|
+
def isRoot?
|
145
|
+
@parent == nil
|
146
|
+
end
|
147
|
+
|
148
|
+
# Indicates whether this node has any immediate child nodes.
|
149
|
+
def hasChildren?
|
150
|
+
@children.length != 0
|
151
|
+
end
|
152
|
+
|
153
|
+
# Returns an array of all the immediate children.
|
154
|
+
# If a block is given, yields each child node to the block.
|
155
|
+
def children
|
156
|
+
if block_given?
|
157
|
+
@children.each {|child| yield child}
|
158
|
+
else
|
159
|
+
@children
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Returns every node (including the receiver node) from the
|
164
|
+
# tree to the specified block.
|
165
|
+
def each &block
|
166
|
+
yield self
|
167
|
+
children { |child| child.each(&block) }
|
168
|
+
end
|
169
|
+
|
170
|
+
# Returns the requested node from the set of immediate
|
171
|
+
# children.
|
172
|
+
#
|
173
|
+
# If the key is _numeric_, then the in-sequence array of
|
174
|
+
# children is accessed (see Tree#children).
|
175
|
+
# If the key is not _numeric_, then it is assumed to be
|
176
|
+
# the *name* of the child node to be returned.
|
177
|
+
def [](key)
|
178
|
+
raise "Key needs to be provided" if key == nil
|
179
|
+
|
180
|
+
if key.kind_of?(Integer)
|
181
|
+
@children[key]
|
182
|
+
else
|
183
|
+
@childrenHash[key]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Returns the total number of nodes in this tree, rooted
|
188
|
+
# at the receiver node.
|
189
|
+
def size
|
190
|
+
@children.inject(1) {|sum, node| sum + node.size}
|
191
|
+
end
|
192
|
+
|
193
|
+
# Convenience synonym for Tree#size
|
194
|
+
def length
|
195
|
+
size()
|
196
|
+
end
|
197
|
+
|
198
|
+
# Pretty prints the tree starting with the receiver node.
|
199
|
+
def printTree(tab = 0)
|
200
|
+
puts((' ' * tab) + self.to_s)
|
201
|
+
children {|child| child.printTree(tab + 4)}
|
202
|
+
end
|
203
|
+
|
204
|
+
# Returns the root for this node.
|
205
|
+
def root
|
206
|
+
root = self
|
207
|
+
root = root.parent while !root.isRoot?
|
208
|
+
root
|
209
|
+
end
|
210
|
+
|
211
|
+
# Returns an array of siblings for this node.
|
212
|
+
# If a block is provided, yeilds each of the sibling
|
213
|
+
# nodes to the block.
|
214
|
+
def siblings
|
215
|
+
if block_given?
|
216
|
+
return nil if isRoot?
|
217
|
+
for sibling in parent.children
|
218
|
+
yield sibling if sibling != self
|
219
|
+
end
|
220
|
+
else
|
221
|
+
siblings = []
|
222
|
+
parent.children {|sibling| siblings << sibling if sibling != self}
|
223
|
+
siblings
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
# Provides a comparision operation for the nodes. Comparision
|
228
|
+
# is based on the natural character-set ordering for the
|
229
|
+
# node names.
|
230
|
+
def <=>(other)
|
231
|
+
return +1 if other == nil
|
232
|
+
self.name <=> other.name
|
233
|
+
end
|
234
|
+
|
235
|
+
# Freezes all nodes in the tree
|
236
|
+
def freezeTree!
|
237
|
+
each {|node| node.freeze}
|
238
|
+
end
|
239
|
+
|
240
|
+
# Creates a dump representation
|
241
|
+
def createDumpRep
|
242
|
+
strRep = String.new
|
243
|
+
strRep << @name << @@fieldSep << (isRoot? ? @name : @parent.name)
|
244
|
+
strRep << @@fieldSep << Marshal.dump(@content) << @@recordSep
|
245
|
+
end
|
246
|
+
|
247
|
+
def _dump(depth)
|
248
|
+
strRep = String.new
|
249
|
+
each {|node| strRep << node.createDumpRep}
|
250
|
+
strRep
|
251
|
+
end
|
252
|
+
|
253
|
+
def TreeNode.loadDumpRep(str)
|
254
|
+
nodeHash = Hash.new
|
255
|
+
rootNode = nil
|
256
|
+
str.split(@@recordSep).each do |line|
|
257
|
+
name, parent, contentStr = line.split(@@fieldSep)
|
258
|
+
content = Marshal.load(contentStr)
|
259
|
+
currentNode = Tree::TreeNode.new(name, content)
|
260
|
+
nodeHash[name] = currentNode
|
261
|
+
if name != parent # Do for a child node
|
262
|
+
nodeHash[parent].add(currentNode)
|
263
|
+
else
|
264
|
+
rootNode = currentNode
|
265
|
+
end
|
266
|
+
end
|
267
|
+
rootNode
|
268
|
+
end
|
269
|
+
|
270
|
+
def TreeNode._load(str)
|
271
|
+
loadDumpRep(str)
|
272
|
+
end
|
273
|
+
|
274
|
+
protected :parent=, :setAsRoot!
|
275
|
+
private_class_method :loadDumpRep
|
276
|
+
|
277
|
+
end
|
278
|
+
end
|
data/test/person.rb
ADDED
data/test/testtree.rb
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'tree'
|
5
|
+
require 'person'
|
6
|
+
|
7
|
+
# Test class for the Tree node.
|
8
|
+
class TC_TreeTest < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@root = Tree::TreeNode.new("ROOT", "Root Node")
|
12
|
+
|
13
|
+
@child1 = Tree::TreeNode.new("Child1", "Child Node 1")
|
14
|
+
@child2 = Tree::TreeNode.new("Child2", "Child Node 2")
|
15
|
+
@child3 = Tree::TreeNode.new("Child3", "Child Node 3")
|
16
|
+
@child4 = Tree::TreeNode.new("Child31", "Grand Child 1")
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def loadChildren
|
21
|
+
@root << @child1
|
22
|
+
@root << @child2
|
23
|
+
@root << @child3 << @child4
|
24
|
+
end
|
25
|
+
|
26
|
+
def teardown
|
27
|
+
@root = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_root_setup
|
31
|
+
assert_not_nil(@root, "Root cannot be nil")
|
32
|
+
assert_nil(@root.parent, "Parent of root node should be nil")
|
33
|
+
assert_not_nil(@root.name, "Name should not be nil")
|
34
|
+
assert_equal("ROOT", @root.name, "Name should be 'ROOT'")
|
35
|
+
assert_equal("Root Node", @root.content, "Content should be 'Root Node'")
|
36
|
+
assert(@root.isRoot?, "Should identify as root")
|
37
|
+
assert(!@root.hasChildren?, "Cannot have any children")
|
38
|
+
assert_equal(1, @root.size, "Number of nodes should be one")
|
39
|
+
|
40
|
+
assert_raise(RuntimeError) { Tree::TreeNode.new(nil) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_root
|
44
|
+
loadChildren
|
45
|
+
|
46
|
+
assert_same(@root, @root.root, "Root's root is self")
|
47
|
+
assert_same(@root, @child1.root, "Root should be ROOT")
|
48
|
+
assert_same(@root, @child4.root, "Root should be ROOT")
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_siblings
|
52
|
+
loadChildren
|
53
|
+
|
54
|
+
siblings = []
|
55
|
+
@child1.siblings { |sibling| siblings << sibling}
|
56
|
+
assert_equal(2, siblings.length, "Should have two siblings")
|
57
|
+
assert(siblings.include?(@child2), "Should have 2nd child as sibling")
|
58
|
+
assert(siblings.include?(@child3), "Should have 3rd child as sibling")
|
59
|
+
|
60
|
+
siblings.clear
|
61
|
+
siblings = @child1.siblings
|
62
|
+
assert_equal(2, siblings.length, "Should have two siblings")
|
63
|
+
|
64
|
+
siblings.clear
|
65
|
+
@child4.siblings {|sibling| siblings << sibling}
|
66
|
+
assert(siblings.empty?, "Should not have any children")
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_add
|
71
|
+
assert(!@root.hasChildren?, "Should not have any children")
|
72
|
+
|
73
|
+
@root.add(@child1)
|
74
|
+
|
75
|
+
@root << @child2
|
76
|
+
|
77
|
+
assert(@root.hasChildren?, "Should have children")
|
78
|
+
assert_equal(3, @root.size, "Should have three nodes")
|
79
|
+
|
80
|
+
@root << @child3 << @child4
|
81
|
+
|
82
|
+
assert_equal(5, @root.size, "Should have five nodes")
|
83
|
+
assert_equal(2, @child3.size, "Should have two nodes")
|
84
|
+
|
85
|
+
assert_raise(RuntimeError) { @root.add(Tree::TreeNode.new(@child1.name)) }
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_remove
|
90
|
+
@root << @child1
|
91
|
+
@root << @child2
|
92
|
+
|
93
|
+
assert(@root.hasChildren?, "Should have children")
|
94
|
+
assert_equal(3, @root.size, "Should have three nodes")
|
95
|
+
|
96
|
+
@root.remove!(@child1)
|
97
|
+
assert_equal(2, @root.size, "Should have two nodes")
|
98
|
+
@root.remove!(@child2)
|
99
|
+
|
100
|
+
assert(!@root.hasChildren?, "Should have no children")
|
101
|
+
assert_equal(1, @root.size, "Should have one node")
|
102
|
+
|
103
|
+
@root << @child1
|
104
|
+
@root << @child2
|
105
|
+
|
106
|
+
assert(@root.hasChildren?, "Should have children")
|
107
|
+
assert_equal(3, @root.size, "Should have three nodes")
|
108
|
+
|
109
|
+
@root.removeAll!
|
110
|
+
|
111
|
+
assert(!@root.hasChildren?, "Should have no children")
|
112
|
+
assert_equal(1, @root.size, "Should have one node")
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_removeAll
|
117
|
+
loadChildren
|
118
|
+
assert(@root.hasChildren?, "Should have children")
|
119
|
+
@root.removeAll!
|
120
|
+
|
121
|
+
assert(!@root.hasChildren?, "Should have no children")
|
122
|
+
assert_equal(1, @root.size, "Should have one node")
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_removeFromParent
|
126
|
+
loadChildren
|
127
|
+
assert(@root.hasChildren?, "Should have children")
|
128
|
+
|
129
|
+
child1 = @root[0]
|
130
|
+
assert_not_nil(child1, "Child 1 should exist")
|
131
|
+
assert_same(@root, child1.root, "Child 1's root should be ROOT")
|
132
|
+
assert(@root.include?(child1), "root should have child1")
|
133
|
+
child1.removeFromParent!
|
134
|
+
assert_same(child1, child1.root, "Child 1's root should be self")
|
135
|
+
assert(!@root.include?(child1), "root should not have child1")
|
136
|
+
|
137
|
+
child1.removeFromParent!
|
138
|
+
assert_same(child1, child1.root, "Child 1's root should still be self")
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_children
|
142
|
+
loadChildren
|
143
|
+
|
144
|
+
assert(@root.hasChildren?, "Should have children")
|
145
|
+
assert_equal(5, @root.size, "Should have four nodes")
|
146
|
+
assert(@child3.hasChildren?, "Should have children")
|
147
|
+
|
148
|
+
children = []
|
149
|
+
for child in @root.children
|
150
|
+
children << child
|
151
|
+
end
|
152
|
+
|
153
|
+
assert_equal(3, children.length, "Should have three direct children")
|
154
|
+
assert(!children.include?(@root), "Should not have root")
|
155
|
+
assert(children.include?(@child1), "Should have child 1")
|
156
|
+
assert(children.include?(@child2), "Should have child 2")
|
157
|
+
assert(children.include?(@child3), "Should have child 3")
|
158
|
+
assert(!children.include?(@child4), "Should not have child 4")
|
159
|
+
|
160
|
+
children.clear
|
161
|
+
children = @root.children
|
162
|
+
assert_equal(3, children.length, "Should have three children")
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_find
|
167
|
+
loadChildren
|
168
|
+
foundNode = @root.find { |node| node == @child2}
|
169
|
+
assert_same(@child2, foundNode, "The node should be Child 2")
|
170
|
+
|
171
|
+
foundNode = @root.find { |node| node == @child4}
|
172
|
+
assert_same(@child4, foundNode, "The node should be Child 4")
|
173
|
+
|
174
|
+
foundNode = @root.find { |node| node.name == "Child31" }
|
175
|
+
assert_same(@child4, foundNode, "The node should be Child 4")
|
176
|
+
foundNode = @root.find { |node| node.name == "NOT PRESENT" }
|
177
|
+
assert_nil(foundNode, "The node should not be found")
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_each
|
181
|
+
loadChildren
|
182
|
+
assert(@root.hasChildren?, "Should have children")
|
183
|
+
assert_equal(5, @root.size, "Should have five nodes")
|
184
|
+
assert(@child3.hasChildren?, "Should have children")
|
185
|
+
|
186
|
+
nodes = []
|
187
|
+
@root.each { |node| nodes << node }
|
188
|
+
|
189
|
+
assert_equal(5, nodes.length, "Should have FIVE NODES")
|
190
|
+
assert(nodes.include?(@root), "Should have root")
|
191
|
+
assert(nodes.include?(@child1), "Should have child 1")
|
192
|
+
assert(nodes.include?(@child2), "Should have child 2")
|
193
|
+
assert(nodes.include?(@child3), "Should have child 3")
|
194
|
+
assert(nodes.include?(@child4), "Should have child 4")
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_parent
|
198
|
+
loadChildren
|
199
|
+
assert_nil(@root.parent, "Root's parent should be nil")
|
200
|
+
assert_equal(@root, @child1.parent, "Parent should be root")
|
201
|
+
assert_equal(@root, @child3.parent, "Parent should be root")
|
202
|
+
assert_equal(@child3, @child4.parent, "Parent should be child3")
|
203
|
+
assert_equal(@root, @child4.parent.parent, "Parent should be root")
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_indexed_access
|
207
|
+
loadChildren
|
208
|
+
assert_equal(@child1, @root[0], "Should be the first child")
|
209
|
+
assert_equal(@child4, @root[2][0], "Should be the grandchild")
|
210
|
+
assert_nil(@root["TEST"], "Should be nil")
|
211
|
+
assert_raise(RuntimeError) { @root[nil] }
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_printTree
|
215
|
+
loadChildren
|
216
|
+
#puts
|
217
|
+
#@root.printTree
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_dump
|
221
|
+
loadChildren
|
222
|
+
|
223
|
+
pers = Person.new("John", "Doe")
|
224
|
+
#@root.content = pers
|
225
|
+
|
226
|
+
data = Marshal.dump(@root)
|
227
|
+
|
228
|
+
newRoot = Marshal.load(data)
|
229
|
+
assert(newRoot.isRoot?, "Must be a root node")
|
230
|
+
assert_equal("ROOT", newRoot.name, "Must identify as ROOT")
|
231
|
+
assert_equal("Root Node", newRoot.content, "Must have root's content")
|
232
|
+
#assert_equal(pers.first, newRoot.content.first, "Must be the same content")
|
233
|
+
assert_equal(@child4.name, newRoot['Child3']['Child31'].name, "Must be the grand child")
|
234
|
+
end
|
235
|
+
|
236
|
+
def test_collect
|
237
|
+
loadChildren
|
238
|
+
collectArray = @root.collect do |node|
|
239
|
+
node.content = "abc"
|
240
|
+
node
|
241
|
+
end
|
242
|
+
collectArray.each {|node| assert_equal("abc", node.content, "Should be 'abc'")}
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_freezeTree
|
246
|
+
loadChildren
|
247
|
+
@root.content = "ABC"
|
248
|
+
assert_equal("ABC", @root.content, "Content should be 'ABC'")
|
249
|
+
@root.freezeTree!
|
250
|
+
assert_raise(TypeError) {@root.content = "123"}
|
251
|
+
assert_raise(TypeError) {@root[0].content = "123"}
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_content
|
255
|
+
pers = Person.new("John", "Doe")
|
256
|
+
@root.content = pers
|
257
|
+
assert_same(pers, @root.content, "Content should be the same")
|
258
|
+
end
|
259
|
+
end
|
metadata
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.10
|
3
|
+
specification_version: 1
|
4
|
+
name: rubytree
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.2.2
|
7
|
+
date: 2006-01-02
|
8
|
+
summary: Ruby implementation of the Tree data structure.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: anupamsg@gmail.com
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description: Provides a generic tree data structure with ability to store keyed node elements in the tree. The implementation mixes in the Enumerable module.
|
15
|
+
autorequire: tree
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
authors:
|
28
|
+
- Anupam Sengupta
|
29
|
+
files:
|
30
|
+
- Rakefile
|
31
|
+
- README
|
32
|
+
- lib/tree.rb
|
33
|
+
- test/person.rb
|
34
|
+
- test/testtree.rb
|
35
|
+
test_files:
|
36
|
+
- test/testtree.rb
|
37
|
+
rdoc_options: []
|
38
|
+
extra_rdoc_files:
|
39
|
+
- README
|
40
|
+
executables: []
|
41
|
+
extensions: []
|
42
|
+
requirements: []
|
43
|
+
dependencies: []
|