jumoku 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -0
- data/lib/jumoku.rb +4 -2
- data/lib/jumoku/version.rb +1 -1
- data/spec/raw_tree_spec.rb +353 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/tree_spec.rb +553 -0
- data/vendor/git/graphy/CREDITS.md +31 -0
- data/vendor/git/graphy/LICENSE +35 -0
- data/vendor/git/graphy/README.md +186 -0
- data/vendor/git/graphy/Rakefile +61 -0
- data/vendor/git/graphy/TODO.md +20 -0
- data/vendor/git/graphy/VERSION +1 -0
- data/vendor/git/graphy/examples/graph_self.rb +56 -0
- data/vendor/git/graphy/examples/module_graph.jpg +0 -0
- data/vendor/git/graphy/examples/module_graph.rb +14 -0
- data/vendor/git/graphy/examples/self_graph.jpg +0 -0
- data/vendor/git/graphy/examples/visualize.jpg +0 -0
- data/vendor/git/graphy/examples/visualize.rb +10 -0
- data/vendor/git/graphy/graphy.gemspec +149 -0
- data/vendor/git/graphy/lib/graphy.rb +90 -0
- data/vendor/git/graphy/lib/graphy/adjacency_graph.rb +224 -0
- data/vendor/git/graphy/lib/graphy/arc.rb +65 -0
- data/vendor/git/graphy/lib/graphy/arc_number.rb +52 -0
- data/vendor/git/graphy/lib/graphy/biconnected.rb +84 -0
- data/vendor/git/graphy/lib/graphy/chinese_postman.rb +91 -0
- data/vendor/git/graphy/lib/graphy/classes/graph_classes.rb +28 -0
- data/vendor/git/graphy/lib/graphy/common.rb +63 -0
- data/vendor/git/graphy/lib/graphy/comparability.rb +63 -0
- data/vendor/git/graphy/lib/graphy/directed_graph.rb +76 -0
- data/vendor/git/graphy/lib/graphy/directed_graph/algorithms.rb +92 -0
- data/vendor/git/graphy/lib/graphy/directed_graph/distance.rb +167 -0
- data/vendor/git/graphy/lib/graphy/dot.rb +94 -0
- data/vendor/git/graphy/lib/graphy/edge.rb +37 -0
- data/vendor/git/graphy/lib/graphy/ext.rb +79 -0
- data/vendor/git/graphy/lib/graphy/graph.rb +631 -0
- data/vendor/git/graphy/lib/graphy/graph_api.rb +35 -0
- data/vendor/git/graphy/lib/graphy/labels.rb +113 -0
- data/vendor/git/graphy/lib/graphy/maximum_flow.rb +77 -0
- data/vendor/git/graphy/lib/graphy/ruby_compatibility.rb +17 -0
- data/vendor/git/graphy/lib/graphy/search.rb +511 -0
- data/vendor/git/graphy/lib/graphy/strong_components.rb +93 -0
- data/vendor/git/graphy/lib/graphy/support/support.rb +9 -0
- data/vendor/git/graphy/lib/graphy/undirected_graph.rb +57 -0
- data/vendor/git/graphy/lib/graphy/undirected_graph/algorithms.rb +90 -0
- data/vendor/git/graphy/spec/biconnected_spec.rb +27 -0
- data/vendor/git/graphy/spec/chinese_postman_spec.rb +27 -0
- data/vendor/git/graphy/spec/community_spec.rb +44 -0
- data/vendor/git/graphy/spec/complement_spec.rb +27 -0
- data/vendor/git/graphy/spec/digraph_distance_spec.rb +121 -0
- data/vendor/git/graphy/spec/digraph_spec.rb +339 -0
- data/vendor/git/graphy/spec/dot_spec.rb +48 -0
- data/vendor/git/graphy/spec/edge_spec.rb +159 -0
- data/vendor/git/graphy/spec/inspection_spec.rb +40 -0
- data/vendor/git/graphy/spec/multi_edge_spec.rb +32 -0
- data/vendor/git/graphy/spec/neighborhood_spec.rb +38 -0
- data/vendor/git/graphy/spec/properties_spec.rb +146 -0
- data/vendor/git/graphy/spec/search_spec.rb +227 -0
- data/vendor/git/graphy/spec/spec.opts +4 -0
- data/vendor/git/graphy/spec/spec_helper.rb +56 -0
- data/vendor/git/graphy/spec/strong_components_spec.rb +61 -0
- data/vendor/git/graphy/spec/triangulated_spec.rb +125 -0
- data/vendor/git/graphy/spec/undirected_graph_spec.rb +220 -0
- data/vendor/git/graphy/vendor/priority-queue/CHANGELOG +33 -0
- data/vendor/git/graphy/vendor/priority-queue/Makefile +140 -0
- data/vendor/git/graphy/vendor/priority-queue/README +133 -0
- data/vendor/git/graphy/vendor/priority-queue/benchmark/dijkstra.rb +171 -0
- data/vendor/git/graphy/vendor/priority-queue/compare_comments.rb +49 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/c-vs-rb.png +0 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/compare_big.gp +14 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/compare_big.png +0 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/compare_small.gp +15 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/compare_small.png +0 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/results.csv +37 -0
- data/vendor/git/graphy/vendor/priority-queue/ext/priority_queue/CPriorityQueue/extconf.rb +2 -0
- data/vendor/git/graphy/vendor/priority-queue/ext/priority_queue/CPriorityQueue/priority_queue.c +947 -0
- data/vendor/git/graphy/vendor/priority-queue/lib/priority_queue.rb +14 -0
- data/vendor/git/graphy/vendor/priority-queue/lib/priority_queue/c_priority_queue.rb +1 -0
- data/vendor/git/graphy/vendor/priority-queue/lib/priority_queue/poor_priority_queue.rb +46 -0
- data/vendor/git/graphy/vendor/priority-queue/lib/priority_queue/ruby_priority_queue.rb +526 -0
- data/vendor/git/graphy/vendor/priority-queue/priority_queue.so +0 -0
- data/vendor/git/graphy/vendor/priority-queue/setup.rb +1551 -0
- data/vendor/git/graphy/vendor/priority-queue/test/priority_queue_test.rb +371 -0
- data/vendor/git/graphy/vendor/rdot.rb +360 -0
- metadata +83 -1
data/Gemfile
ADDED
data/lib/jumoku.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
libpath = File.expand_path(File.dirname(__FILE__))
|
2
|
+
$:.unshift File.dirname(__FILE__) unless $:.include?(File.dirname(__FILE__)) || $:.include?(libpath)
|
3
|
+
$: << libpath + '/../vendor/git/graphy/lib'
|
4
|
+
puts $:.inspect
|
3
5
|
|
4
6
|
require 'pathname'
|
5
7
|
require 'pp'
|
data/lib/jumoku/version.rb
CHANGED
@@ -0,0 +1,353 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
# The RawTree builder implements TreeAPI and ensures the tree
|
4
|
+
# is a valid tree as far as Graph Theory is concerned:
|
5
|
+
# a tree is an undirected, connected, acyclic graph.
|
6
|
+
#
|
7
|
+
# Note: these tests may make use of the "root"/"children" terminology.
|
8
|
+
# Be aware this has got *no* structural meaning as a tree is, by
|
9
|
+
# definition, undirected. Those terms are used only to simplify
|
10
|
+
# nodes creation within the tests, so I recall who branched who.
|
11
|
+
# For tests about rooted tree, see arborescence_spec.rb
|
12
|
+
describe "RawTreeBuilder" do
|
13
|
+
before :each do
|
14
|
+
#class MyTree
|
15
|
+
#include RawTreeBuilder
|
16
|
+
#end
|
17
|
+
|
18
|
+
@tree = RawTree.new
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#new" do
|
22
|
+
it "should create a valid tree graph" do
|
23
|
+
@tree.should_not be_directed
|
24
|
+
@tree.should be_acyclic
|
25
|
+
@tree.should be_connected
|
26
|
+
# aka @tree.should be_valid, 'll use that from now own
|
27
|
+
|
28
|
+
@tree.nodes.should be_empty
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Testing TreeAPI implementation.
|
33
|
+
|
34
|
+
describe "#add_node!" do
|
35
|
+
describe "an empty tree" do
|
36
|
+
it "should grow up as a valid tree when adding its first node" do
|
37
|
+
@tree.nodes.size.should == 0
|
38
|
+
|
39
|
+
@tree.add_node! "root"
|
40
|
+
@tree.nodes.size.should == 1
|
41
|
+
@tree.nodes.should == ["root"]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "a tree with only one node" do
|
46
|
+
before :each do
|
47
|
+
@tree.add_node! "root" # remember, this has no meaning
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should raise an error when trying to add a new (disconnected) node" do
|
51
|
+
lambda { @tree.add_node! "child1" }.should raise_error
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should grow up as a valid tree when adding new (connected) nodes" do
|
55
|
+
lambda { @tree.add_node! "child1", "root" }.should_not raise_error
|
56
|
+
|
57
|
+
@tree.add_node! "child2", "root"
|
58
|
+
@tree.add_node! "grand-child1", "child2"
|
59
|
+
@tree.add_node! Jumoku::Branch.new("grand-child2", "child2")
|
60
|
+
|
61
|
+
@tree.nodes.size.should == 5
|
62
|
+
|
63
|
+
the_nodes = ["root", "child1", "child2", "grand-child1", "grand-child2"]
|
64
|
+
@tree.nodes.should == the_nodes
|
65
|
+
@tree.topsort.should_not == the_nodes
|
66
|
+
|
67
|
+
@tree.add_node! "grand-grand-child1", "grand-child1"
|
68
|
+
@tree.add_node! "child3", "root"
|
69
|
+
@tree.add_node! "grand-child3", "child3"
|
70
|
+
@tree.add_node! "grand-grand-grand-child", "grand-grand-child1"
|
71
|
+
@tree.should_not be_directed
|
72
|
+
@tree.should be_acyclic
|
73
|
+
@tree.should be_connected
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should raise an error when trying to form a cycle" do
|
77
|
+
@tree.add_node! "child1", "root"
|
78
|
+
@tree.add_node! "child2", "root"
|
79
|
+
@tree.add_node! "grand-child", "child1"
|
80
|
+
|
81
|
+
lambda { @tree.add_node! "grand-child", "child2" }.should raise_error RawTreeError
|
82
|
+
|
83
|
+
@tree.add_node! "grand-grand-child", "grand-child"
|
84
|
+
lambda { @tree.add_node! "grand-grand-child", "child1" }.should raise_error RawTreeError
|
85
|
+
lambda { @tree.add_node! "grand-grand-child", "child2" }.should raise_error RawTreeError
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#add_branch!" do
|
91
|
+
describe "an empty tree" do
|
92
|
+
it "should allow for the creation of its first two nodes as a branch" do
|
93
|
+
lambda { @tree.add_branch! :first, :branch }.should_not raise_error
|
94
|
+
@tree.nodes.should == [:first, :branch]
|
95
|
+
@tree.should be_valid
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "a tree that's not empty" do
|
100
|
+
before :each do
|
101
|
+
@tree.add_node! 1
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should not allow for disconnected branch creation" do
|
105
|
+
lambda { @tree.add_branch! 10, 11 }.should raise_error RawTreeError
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should grow up as a valid tree when populated with (connected) branches" do
|
109
|
+
@tree.nodes.size.should == 1
|
110
|
+
|
111
|
+
@tree.add_branch! 1, 2
|
112
|
+
@tree.nodes.should_not be_empty
|
113
|
+
@tree.nodes.size.should == 2
|
114
|
+
@tree.nodes.should == [1, 2]
|
115
|
+
|
116
|
+
@tree.add_branch! 2, 3
|
117
|
+
@tree.nodes.size.should == 3
|
118
|
+
@tree.nodes.should == [1, 2, 3]
|
119
|
+
|
120
|
+
@tree.add_branch! 3, 4
|
121
|
+
@tree.add_branch! 2, 5
|
122
|
+
lambda { @tree.add_branch! 5, 5 }.should raise_error RawTreeError # cycle (loop)
|
123
|
+
@tree.add_branch! 4, 3
|
124
|
+
@tree.add_branch! 5, 6
|
125
|
+
@tree.nodes.size.should == 6
|
126
|
+
@tree.nodes.should == [1, 2, 3, 4, 5, 6]
|
127
|
+
@tree.should be_valid
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#remove_node!" do
|
133
|
+
describe "an empty tree" do
|
134
|
+
it "should not allow to remove a node since there's none" do
|
135
|
+
lambda { @tree.remove_node! "vapornode" }.should raise_error RawTreeError
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "a tree that's a single node" do
|
140
|
+
before :each do
|
141
|
+
@tree.add_node! :last
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should allow for last node deletion" do
|
145
|
+
lambda { @tree.remove_node! :last }.should_not raise_error
|
146
|
+
@tree.nodes.should be_empty
|
147
|
+
@tree.should be_valid
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "a tree that is one sole branch (two nodes)" do
|
152
|
+
before :each do
|
153
|
+
@tree1 = RawTree.new
|
154
|
+
@tree1.add_node! 1
|
155
|
+
@tree1.add_node! 2, 1
|
156
|
+
@tree2 = RawTree.new
|
157
|
+
@tree2.add_node! 1
|
158
|
+
@tree2.add_node! 2, 1
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should allow to remove both nodes in any order" do
|
162
|
+
@tree1.remove_node! 1
|
163
|
+
@tree1.should be_valid
|
164
|
+
@tree1.nodes.should == [2]
|
165
|
+
@tree1.should be_valid
|
166
|
+
|
167
|
+
@tree2.remove_node! 2
|
168
|
+
@tree2.should be_valid
|
169
|
+
@tree2.nodes.should == [1]
|
170
|
+
@tree2.should be_valid
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "a tree with more than two nodes" do
|
175
|
+
before :each do
|
176
|
+
# TODO: DRY this snippet
|
177
|
+
# i stands for internal, t for terminal
|
178
|
+
@tree.add_branch! :i1, :i2
|
179
|
+
@tree.add_branch! :i2, :i3
|
180
|
+
@tree.add_branch! :i3, :i4
|
181
|
+
@tree.add_branch! :i3, :i5
|
182
|
+
@tree.add_branch! :i4, :t6
|
183
|
+
@tree.add_branch! :i5, :t7
|
184
|
+
@tree.add_branch! :i1, :t8
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should allow deletion of its terminal nodes but not of its internal nodes" do
|
188
|
+
@tree.nodes.size.should == 8
|
189
|
+
lambda { @tree.remove_node! :t8 }.should_not raise_error
|
190
|
+
@tree.nodes.size.should == 7
|
191
|
+
@tree.nodes.should_not include :t8
|
192
|
+
lambda { @tree.remove_node! :i3 }.should raise_error RawTreeError
|
193
|
+
@tree.should be_valid
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should remain a valid tree after any terminal node was removed" do
|
197
|
+
@tree.remove_node! :t6
|
198
|
+
@tree.has_branch?(:i4, :t6).should_not be_true
|
199
|
+
@tree.should be_valid
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe "#remove_branch!" do
|
205
|
+
describe "an empty tree" do
|
206
|
+
it "should not allow for branch deletion" do
|
207
|
+
lambda { @tree.remove_branch! :null, :none }.should raise_error RawTreeError
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
describe "an tree that is only one node" do
|
212
|
+
before :each do
|
213
|
+
@tree.add_node! 1
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should not allow for branch deletion" do
|
217
|
+
lambda { @tree.remove_branch! 1, :none }.should raise_error RawTreeError
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
describe "a tree with more than two nodes" do
|
222
|
+
before :each do
|
223
|
+
# TODO: DRY this snippet
|
224
|
+
# i stands for internal, t for terminal
|
225
|
+
@tree.add_branch! :i1, :i2
|
226
|
+
@tree.add_branch! :i2, :i3
|
227
|
+
@tree.add_branch! :i3, :i4
|
228
|
+
@tree.add_branch! :i3, :i5
|
229
|
+
@tree.add_branch! :i4, :t6
|
230
|
+
@tree.add_branch! :i5, :t7
|
231
|
+
@tree.add_branch! :i1, :t8
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should allow for terminal branch deletion (triggers terminal node deletion)" do
|
235
|
+
@tree.nodes.size.should == 8
|
236
|
+
lambda { @tree.remove_branch! :i1, :i2 }.should raise_error RawTreeError
|
237
|
+
@tree.nodes.size.should == 8
|
238
|
+
lambda { @tree.remove_branch! :i1, :t8 }.should_not raise_error RawTreeError
|
239
|
+
@tree.nodes.should_not include :t8
|
240
|
+
@tree.has_branch?(:i1, :t8).should be_false
|
241
|
+
@tree.should be_valid
|
242
|
+
|
243
|
+
@tree.remove_branch! Branch.new(:i5, :t7)
|
244
|
+
@tree.has_branch?(:i5, :t7).should be_false
|
245
|
+
@tree.should be_valid
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
describe "#nodes" do
|
251
|
+
describe "an empty tree" do
|
252
|
+
it "should not have any node" do
|
253
|
+
@tree.nodes.should be_empty
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
describe "a tree with some node" do
|
258
|
+
it "should be aware of its node(s)" do
|
259
|
+
@tree.add_node! :solo
|
260
|
+
@tree.nodes.should == [:solo]
|
261
|
+
|
262
|
+
@tree.add_branch! 2, :solo
|
263
|
+
@tree.add_branch! 2, 3
|
264
|
+
@tree.nodes.should == [:solo, 2, 3]
|
265
|
+
@tree.should be_valid
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
describe "#terminal_nodes" do
|
271
|
+
describe "an empty tree" do
|
272
|
+
it "should have no terminal nodes" do
|
273
|
+
@tree.terminal_nodes.should be_empty
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
describe "a tree that's a single node" do
|
278
|
+
it "should have one terminal node" do
|
279
|
+
@tree.add_node! 1
|
280
|
+
@tree.terminal_nodes.should == [1]
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
describe "a populated tree" do
|
285
|
+
before :each do
|
286
|
+
@tree.add_node! 1
|
287
|
+
@tree.add_node! 2, 1
|
288
|
+
@tree.add_node! 3, 2
|
289
|
+
end
|
290
|
+
|
291
|
+
it "should have a least two terminal nodes" do
|
292
|
+
@tree.terminal_nodes.size.should >= 2
|
293
|
+
|
294
|
+
@tree.add_node! 4, 3
|
295
|
+
@tree.add_node! 5, 3
|
296
|
+
@tree.terminal_nodes.should == [1, 4, 5]
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
describe "#branches" do
|
302
|
+
describe "an empty tree" do
|
303
|
+
it "should not have any branch" do
|
304
|
+
@tree.branches.should be_empty
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
describe "a tree that's one node" do
|
309
|
+
it "should not have any branch" do
|
310
|
+
@tree.add_node! :solo
|
311
|
+
@tree.branches.should be_empty
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
describe "a tree that's one branch (two nodes)" do
|
316
|
+
it "should have one branch only (undirected)" do
|
317
|
+
@tree.add_node! :one
|
318
|
+
@tree.add_node! :two, :one
|
319
|
+
@tree.branches.size.should == 1
|
320
|
+
@tree.branches.first.class.should == Graphy::Edge # the Jumoku::Branch class is just
|
321
|
+
# a lazy wrapper of it
|
322
|
+
@tree.should be_valid
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
describe "a tree with n nodes" do
|
327
|
+
before :each do
|
328
|
+
# TODO: DRY this as random_tree(n = 10)
|
329
|
+
@n = rand(50) # number of nodes
|
330
|
+
@tree.add_node! @n
|
331
|
+
@old_node = @n
|
332
|
+
|
333
|
+
(@n - 1).times do
|
334
|
+
begin
|
335
|
+
@new_node = rand(100)
|
336
|
+
@tree.add_node!(@new_node, @old_node)
|
337
|
+
rescue RawTreeError
|
338
|
+
retry # cycle detected!
|
339
|
+
end
|
340
|
+
@old_node = @new_node
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
it "should have n - 1 branches" do
|
345
|
+
@tree.nodes.size.should == @n
|
346
|
+
@tree.branches.size.should == @n - 1
|
347
|
+
@tree.should be_valid
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
# TODO: add a final test which sums it up
|
353
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path("../../lib/jumoku.rb", __FILE__)
|
2
|
+
|
3
|
+
require 'jumoku'
|
4
|
+
include Jumoku
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
# Remove this line if you don't want RSpec's should and should_not
|
8
|
+
# methods or matchers
|
9
|
+
require 'rspec/expectations'
|
10
|
+
config.include RSpec::Matchers
|
11
|
+
|
12
|
+
# == Mock Framework
|
13
|
+
config.mock_with :rspec
|
14
|
+
end
|
data/spec/tree_spec.rb
ADDED
@@ -0,0 +1,553 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
# The Tree builder extends the core functionalities provided
|
4
|
+
# by RawTreeBuilder.
|
5
|
+
#
|
6
|
+
# Note: these tests may make use of the "root"/"children" terminology.
|
7
|
+
# Be aware this has got *no* structural meaning as a tree is, by
|
8
|
+
# definition, undirected. Those terms are used only to simplify
|
9
|
+
# nodes creation within the tests, so I recall who branched who.
|
10
|
+
# For tests about rooted tree, see arborescence_spec.rb
|
11
|
+
describe "TreeBuilder" do
|
12
|
+
before :each do
|
13
|
+
class MyTree
|
14
|
+
include TreeBuilder
|
15
|
+
end
|
16
|
+
|
17
|
+
@tree = MyTree.new
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#new" do
|
21
|
+
it "should create a valid tree graph" do
|
22
|
+
@tree.should be_valid
|
23
|
+
@tree.nodes.should be_empty
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
## Core API is tested in raw_tree_spec.rb.
|
28
|
+
## The following tests focus on TreeBuilder additional methods.
|
29
|
+
|
30
|
+
describe "#add_node" do
|
31
|
+
describe "an empty tree" do
|
32
|
+
it "should create a new, valid tree with a single node when its first node is added" do
|
33
|
+
@tree.add_node 1
|
34
|
+
@tree.should be_empty
|
35
|
+
|
36
|
+
new_tree = @tree.add_node 1
|
37
|
+
new_tree.nodes.should == [1]
|
38
|
+
new_tree.should be_valid
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "a populated tree" do
|
43
|
+
before :each do
|
44
|
+
@tree.add_branch! 1, 2
|
45
|
+
@tree.add_branch! 2, 3
|
46
|
+
@tree.add_branch! 3, 4
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should create a new, extended, valid tree when an additionnal node is added" do
|
50
|
+
@tree.add_node 5, 4
|
51
|
+
@tree.add_node 3, 6
|
52
|
+
@tree.nodes.size.should == 4
|
53
|
+
|
54
|
+
new_tree = @tree.add_node 5, 4
|
55
|
+
new_tree.nodes.size.should == @tree.nodes.size + 1
|
56
|
+
new_tree.nodes.should == [1, 2, 3, 4, 5]
|
57
|
+
new_tree.should be_valid
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#add_branch" do
|
63
|
+
describe "an empty tree" do
|
64
|
+
it "should create a new, valid tree with only two nodes when a branch is added" do
|
65
|
+
new_tree = @tree.add_branch :one, :two
|
66
|
+
@tree.should be_empty
|
67
|
+
@tree.should be_valid
|
68
|
+
new_tree.nodes.should == [:one, :two]
|
69
|
+
new_tree.should be_valid
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "a populate" do
|
74
|
+
before :each do
|
75
|
+
@tree.add_branch! 1, 2
|
76
|
+
@tree.add_branch! 2, 3
|
77
|
+
@tree.add_branch! 3, 4
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should create a new, extended, valid tree when a branch is added" do
|
81
|
+
@tree.add_branch 5, 4
|
82
|
+
@tree.add_branch 3, 6
|
83
|
+
@tree.nodes.size.should == 4
|
84
|
+
|
85
|
+
new_tree = @tree.add_branch 5, 4
|
86
|
+
new_tree.nodes.size.should == @tree.nodes.size + 1
|
87
|
+
new_tree.nodes.should == [1, 2, 3, 4, 5]
|
88
|
+
new_tree.should be_valid
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#remove_node" do
|
94
|
+
describe "an empty tree" do
|
95
|
+
it "should raise an error when trying to remove a node" do
|
96
|
+
lambda { @tree.remove_node :null }.should raise_error, RawTreeError
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "a tree that's one node only" do
|
101
|
+
before :each do
|
102
|
+
@tree.add_node! 1
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should create a new, empty, valid tree" do
|
106
|
+
new_tree = @tree.remove_node 1
|
107
|
+
@tree.nodes.should == [1]
|
108
|
+
@tree.should be_valid
|
109
|
+
new_tree.should be_empty
|
110
|
+
new_tree.should be_valid
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "#remove_branch" do
|
116
|
+
describe "an empty tree" do
|
117
|
+
it "should not allow for removing a branch (even if forced to)" do
|
118
|
+
lambda { @tree.remove_branch 1, 2 }.should raise_error, RawTreeError
|
119
|
+
lambda { @tree.remove_branch 1, 2, :force => true }.should raise_error, RawTreeError
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "a tree that's one node" do
|
124
|
+
before :each do
|
125
|
+
@tree.add_node! 1
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should not allow for removing a branch (even if forced to)" do
|
129
|
+
lambda { @tree.remove_branch 1, 2 }.should raise_error, RawTreeError
|
130
|
+
lambda { @tree.remove_branch 1, 2, :force => true }.should raise_error, RawTreeError
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "a tree with at least two nodes" do
|
135
|
+
before :each do
|
136
|
+
@tree.add_branch! 1, 2
|
137
|
+
@tree.add_branch! 2, 3
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should allow for removing a branch, creating a new, valid tree" do
|
141
|
+
lambda { @tree.remove_branch 1, 2, :force => true }.should_not raise_error
|
142
|
+
new_tree = @tree.remove_branch 1, 2, :force => true
|
143
|
+
@tree.nodes.should == [1, 2, 3]
|
144
|
+
new_tree.nodes.should == [2, 3]
|
145
|
+
new_tree.should be_valid
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "#add_nodes!" do
|
151
|
+
describe "an empty tree" do
|
152
|
+
it "should allow for adding its first nodes, by pairs and branches" do
|
153
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
154
|
+
@tree.nodes.should == [1, 2, 3, 4]
|
155
|
+
@tree.should be_valid
|
156
|
+
|
157
|
+
@tree.add_nodes! Branch.new(5, 2)
|
158
|
+
@tree.nodes.should == [1, 2, 3, 4, 5]
|
159
|
+
@tree.should be_valid
|
160
|
+
|
161
|
+
@tree.add_nodes! 3,4, 1,10, Branch.new(10, 11), -1,1
|
162
|
+
@tree.nodes.size.should == 8
|
163
|
+
@tree.should be_valid
|
164
|
+
|
165
|
+
lambda { @tree.add_nodes! 10, 11 }.should_not raise_error
|
166
|
+
lambda { @tree.add_nodes! 1, 11 }.should raise_error, RawTreeError # cycle
|
167
|
+
|
168
|
+
@tree = Tree.new
|
169
|
+
lambda { @tree.add_nodes! 1,2, 3,4 }.should raise_error, RawTreeError # not connected
|
170
|
+
lambda { @tree.add_nodes! 1,2, 2,3, 3,1 }.should raise_error, RawTreeError # cycle
|
171
|
+
lambda { @tree.add_nodes! 1, 2, 3 }.should raise_error, RawTreeError # even number of nodes
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "#add_nodes" do
|
177
|
+
describe "an empty tree" do
|
178
|
+
it "should allow for adding its first nodes, by pairs and branches, creating a new, valid tree" do
|
179
|
+
new_tree = @tree.add_nodes 1,2, 2,3, 3,4
|
180
|
+
@tree.should be_empty
|
181
|
+
new_tree.nodes.should == [1, 2, 3, 4]
|
182
|
+
new_tree.should be_valid
|
183
|
+
|
184
|
+
new_tree = @tree.add_nodes Branch.new(4, 5)
|
185
|
+
@tree.should be_empty
|
186
|
+
new_tree.nodes.should == [4, 5]
|
187
|
+
new_tree.should be_valid
|
188
|
+
|
189
|
+
new_tree = @tree.add_nodes 3,4, 4,10, Branch.new(10, 11), -1,3
|
190
|
+
@tree.should be_empty
|
191
|
+
new_tree.nodes.size.should == 5
|
192
|
+
new_tree.should be_valid
|
193
|
+
|
194
|
+
lambda { @tree.add_nodes 10, 11 }.should_not raise_error
|
195
|
+
|
196
|
+
@tree = Tree.new
|
197
|
+
lambda { @tree.add_nodes 1,2, 3,4 }.should raise_error, RawTreeError # not connected
|
198
|
+
lambda { @tree.add_nodes 1,2, 2,3, 3,1 }.should raise_error, RawTreeError # cycle
|
199
|
+
lambda { @tree.add_nodes 1, 2, 3 }.should raise_error, RawTreeError # even number of nodes
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe "#add_branches!" do
|
205
|
+
describe "an empty tree" do
|
206
|
+
it "should allow for adding its first branches" do
|
207
|
+
@tree.add_branches! Branch.new(1, 2), 1,3, 3,4
|
208
|
+
@tree.nodes.should == [1, 2, 3, 4]
|
209
|
+
@tree.should be_valid
|
210
|
+
|
211
|
+
branch = Branch.new(1, 4)
|
212
|
+
lambda { @tree.add_branches! branch }.should raise_error, RawTreeError
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe "a populated tree" do
|
217
|
+
before :each do
|
218
|
+
@tree.add_nodes! 1, 2
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should allow for adding new branches" do
|
222
|
+
@tree.add_branches! 2, 3
|
223
|
+
@tree.nodes.should == [1, 2, 3]
|
224
|
+
@tree.should be_valid
|
225
|
+
|
226
|
+
@tree.add_branches! Branch.new(0,1), 3,4, Branch.new(4,5)
|
227
|
+
[0..5].all? { |n| @tree.nodes.include? n } and @tree.nodes.size.should == 5
|
228
|
+
@tree.should be_valid
|
229
|
+
|
230
|
+
lambda { @tree.add_branches! Branch.new(2, 5) }.should raise_error, RawTreeError
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "add_branches" do
|
236
|
+
describe "an empty tree" do
|
237
|
+
it "should create a new, valid tree populated with its first branches" do
|
238
|
+
b1, b2, b3 = Branch.new(1, 2), Branch.new(2, 3), Branch.new(3, 4)
|
239
|
+
new_tree = @tree.add_branches b1, b2, b3
|
240
|
+
@tree.should be_empty
|
241
|
+
new_tree.nodes.should == [1, 2, 3, 4]
|
242
|
+
new_tree.should be_valid
|
243
|
+
|
244
|
+
lambda { @tree.add_branches 1,2, 2,3, 3,1 }.should raise_error, RawTreeError
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
describe "a populated tree" do
|
249
|
+
before :each do
|
250
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
251
|
+
end
|
252
|
+
|
253
|
+
it "should create a new, valid tree extended with its new branches" do
|
254
|
+
new_tree = @tree.add_branches 4, :five, Branch.new(:five, "six")
|
255
|
+
@tree.nodes.should == (1..4).to_a
|
256
|
+
new_tree.nodes.should == [1, 2, 3, 4, :five, "six"]
|
257
|
+
new_tree.should be_valid
|
258
|
+
|
259
|
+
lambda { @tree.add_branches 10, 11 }.should raise_error, RawTreeError
|
260
|
+
lambda { @tree.add_branches Branch.new 1,4 }.should raise_error, RawTreeError
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
describe "#remove_nodes!" do
|
266
|
+
describe "an empty tree" do
|
267
|
+
it "should not allow for removing nodes" do
|
268
|
+
lambda { @tree.remove_nodes! :foo, :bar }.should raise_error, RawTreeError
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
describe "a tree that's one node" do
|
273
|
+
before :each do
|
274
|
+
@tree.add_node! :one
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should allow for removing its sole node only (bad semantic)" do
|
278
|
+
@tree.remove_nodes! :one
|
279
|
+
@tree.nodes.should be_empty
|
280
|
+
@tree.should be_valid
|
281
|
+
|
282
|
+
lambda { @tree.remove_nodes! :foo, :bar }.should raise_error, RawTreeError
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
describe "a populated tree" do
|
287
|
+
before :each do
|
288
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
289
|
+
end
|
290
|
+
|
291
|
+
it "should allow for removing its nodes until it's empty" do
|
292
|
+
@tree.remove_nodes! (1..4).to_a
|
293
|
+
@tree.should be_empty
|
294
|
+
@tree.should be_valid
|
295
|
+
|
296
|
+
lambda { @tree.remove_nodes! :null }.should raise_error, RawTreeError
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
describe "#remove_nodes" do
|
302
|
+
describe "an empty tree" do
|
303
|
+
it "should not allow for removing nodes" do
|
304
|
+
lambda { @tree.remove_nodes :foo, :bar }.should raise_error, RawTreeError
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
describe "a populated tree" do
|
309
|
+
before :each do
|
310
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
311
|
+
end
|
312
|
+
|
313
|
+
it "should allow for removing nodes, creating a new, valid tree" do
|
314
|
+
new_tree = @tree.remove_nodes 1, 2, 3, 4
|
315
|
+
@tree.nodes.should == [1, 2, 3, 4]
|
316
|
+
new_tree.should be_empty
|
317
|
+
new_tree.should be_valid
|
318
|
+
|
319
|
+
lambda { @tree.remove_nodes! :null }.should raise_error, RawTreeError
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
describe "#remove_branches!" do
|
325
|
+
describe "an empty tree" do
|
326
|
+
it "should not allow for removing branches" do
|
327
|
+
lambda { @tree.remove_branches Branch.new(:foo, :bar), 1,2 }.should raise_error, RawTreeError
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
describe "a tree that's only one node" do
|
332
|
+
before :each do
|
333
|
+
@tree.add_node! :solo
|
334
|
+
end
|
335
|
+
|
336
|
+
it "should not allow for removing branches" do
|
337
|
+
lambda { @tree.remove_branches! :solo, :null }.should raise_error, RawTreeError
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
describe "a populated tree" do
|
342
|
+
before :each do
|
343
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should allow for removing branches until it has no more branches or a sole node" do
|
347
|
+
@tree.remove_branches! 1,2, Branch.new(2,3), 3,4
|
348
|
+
@tree.should be_empty
|
349
|
+
@tree.should be_valid
|
350
|
+
|
351
|
+
lambda { @tree.remove_branches! Branch.new(:foo, :bar), Branch.new(1, 2) }.should raise_error, RawTreeError
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
describe "#remove_branches" do
|
357
|
+
describe "an empty tree" do
|
358
|
+
it "should not allow for removing branches" do
|
359
|
+
lambda { @tree.remove_branches :foo, :bar, Branch.new(1, 2) }.should raise_error, RawTreeError
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
describe "a tree that's one node" do
|
364
|
+
before :each do
|
365
|
+
@tree.add_node! :solo
|
366
|
+
end
|
367
|
+
|
368
|
+
it "should not allow for removing branches" do
|
369
|
+
lambda { @tree.remove_branches :solo, :null }.should raise_error, RawTreeError
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
describe "a populated tree" do
|
374
|
+
before :each do
|
375
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
376
|
+
end
|
377
|
+
|
378
|
+
it "should allow for removing branches until it has no more branches or a sole node, creating a new, valid tree" do
|
379
|
+
new_tree = @tree.remove_branches 1,2, Branch.new(2,3), 3,4
|
380
|
+
@tree.nodes.should == [1, 2, 3, 4]
|
381
|
+
new_tree.should be_empty
|
382
|
+
new_tree.should be_valid
|
383
|
+
|
384
|
+
lambda { @tree.remove_branches Branch.new(:foo, :bar), Branch.new(1, 2) }.should raise_error, RawTreeError
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
describe "#node?" do
|
390
|
+
describe "an empty tree" do
|
391
|
+
it "should not report having any node" do
|
392
|
+
@tree.node?(:null).should be_false
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
describe "a populated tree" do
|
397
|
+
before :each do
|
398
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
399
|
+
end
|
400
|
+
|
401
|
+
it "should be aware of which nodes belong to itself" do
|
402
|
+
@tree.node?(1).should be_true
|
403
|
+
@tree.has_node?(:null).should be_false
|
404
|
+
end
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
describe "#nodes?" do
|
409
|
+
describe "an empty tree" do
|
410
|
+
it "should not report having any node" do
|
411
|
+
@tree.nodes?(:null, :foo, 0).should be_false
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
describe "a populated tree" do
|
416
|
+
before :each do
|
417
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
418
|
+
end
|
419
|
+
|
420
|
+
it "should be aware of which nodes belong to itself" do
|
421
|
+
@tree.nodes?(1, 4).should be_true
|
422
|
+
@tree.has_nodes?(:null, 1, 2).should be_false
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
describe "#nodes_among?" do
|
428
|
+
describe "an empty tree" do
|
429
|
+
it "should not report having any node" do
|
430
|
+
@tree.nodes_among?(:null, :foo, 0).should be_false
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
describe "a populated tree" do
|
435
|
+
before :each do
|
436
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
437
|
+
end
|
438
|
+
|
439
|
+
it "should be aware of which nodes belong to itself" do
|
440
|
+
@tree.nodes_among?(1, 4).should be_true
|
441
|
+
@tree.has_node_among?(:foo, 2, :bar).should be_true
|
442
|
+
@tree.has_nodes_among?(:foo, 2, :bar, 3, 4, Array.new).should be_true
|
443
|
+
@tree.has_nodes_among?(:null, :foo, :bar).should be_false
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
describe "#branch?" do
|
449
|
+
describe "an empty tree" do
|
450
|
+
it "should not have any branch" do
|
451
|
+
@tree.has_branch?(1,2).should be_false
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
describe "a tree that's one node" do
|
456
|
+
before :each do
|
457
|
+
@tree.add_node! :solo
|
458
|
+
end
|
459
|
+
|
460
|
+
it "should not have any branch" do
|
461
|
+
@tree.has_branch?(1,2).should be_false
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
describe "a populated tree" do
|
466
|
+
before :each do
|
467
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
468
|
+
end
|
469
|
+
|
470
|
+
it "should be aware of which branches belong to itself" do
|
471
|
+
@tree.has_branch?(2,3).should be_true
|
472
|
+
@tree.has_branch?(1,3).should be_false
|
473
|
+
@tree.has_branch?(1,:null).should be_false
|
474
|
+
end
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
# TODO: tests for #branches? and #branches_among?
|
479
|
+
# (actually, done within the tests for #add_consecutive_nodes!)
|
480
|
+
|
481
|
+
describe "#num_nodes" do
|
482
|
+
describe "an empty tree" do
|
483
|
+
it "should report having no node" do
|
484
|
+
@tree.number_of_nodes.should == 0
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
describe "a populated tree" do
|
489
|
+
before :each do
|
490
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
491
|
+
end
|
492
|
+
|
493
|
+
it "should report how many nodes belong to it" do
|
494
|
+
@tree.number_of_nodes.should == 4
|
495
|
+
end
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
describe "#num_branches" do
|
500
|
+
describe "an empty tree" do
|
501
|
+
it "should report having no branch" do
|
502
|
+
@tree.number_of_nodes.should == 0
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
describe "a tree that's one node" do
|
507
|
+
before :each do
|
508
|
+
@tree.add_node! :solo
|
509
|
+
end
|
510
|
+
|
511
|
+
it "should report having no branch" do
|
512
|
+
@tree.number_of_branches.should == 0
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
describe "a populated tree" do
|
517
|
+
before :each do
|
518
|
+
@tree.add_nodes! 1,2, 2,3, 3,4
|
519
|
+
end
|
520
|
+
|
521
|
+
it "should report how many branches belong to it" do
|
522
|
+
@tree.number_of_branches.should == @tree.number_of_nodes - 1
|
523
|
+
end
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
describe "#add_consecutive_nodes!" do
|
528
|
+
describe "a tree" do
|
529
|
+
it "should grow as a valid, populated tree if all specified nodes define a valid tree structure" do
|
530
|
+
@tree.add_consecutive_nodes!(1, 2, 3, :four, Branch.new(:foo, "bar"))
|
531
|
+
@tree.has_branches?(1,2, 2,3, Branch.new(3, :four), :four,:foo, :foo,"bar").should be_true # each specified branch exist
|
532
|
+
@tree.has_branches?(1,2, 2,3, Branch.new(3, :four), :four,:foo).should be_true # each specified branch exist
|
533
|
+
@tree.has_branches_among?(1,2, 2,3, Branch.new(3, :four), :four,:foo).should be_false # do not list every existing branch
|
534
|
+
@tree.has_branches_among?(1,2, 2,3, Branch.new(3, :four), :four,:foo, :foo,"bar").should be_true # list all existing branches
|
535
|
+
@tree.has_branches_among?(1,2, 2,3, Branch.new(3, :four), :four,:foo, :foo,"bar", Array.new, "NIL").should be_true # list all existing branches
|
536
|
+
@tree.should be_valid
|
537
|
+
end
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
541
|
+
describe "#add_consecutive_nodes" do
|
542
|
+
describe "a tree" do
|
543
|
+
it "should create a new, valid, populated tree if all specified nodes define a valid tree structure" do
|
544
|
+
new_tree = @tree.add_consecutive_nodes(1, 2, 3, :four, Branch.new(:foo, "bar"))
|
545
|
+
@tree.should be_empty
|
546
|
+
new_tree.has_branches?(1,2, 2,3, Branch.new(3, :four), :four,:foo, :foo,"bar").should be_true
|
547
|
+
new_tree.has_branches?(1,2, 2,3, Branch.new(3, :four), :four,:foo).should be_true
|
548
|
+
new_tree.should be_valid
|
549
|
+
end
|
550
|
+
end
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|