rubytree 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|