jumoku 0.1.3 → 0.2.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/README.md +0 -2
- data/lib/jumoku.rb +36 -8
- data/lib/jumoku/builders/arborescence.rb +11 -0
- data/lib/jumoku/builders/extended.rb +327 -0
- data/lib/jumoku/builders/raw_directed_tree.rb +33 -0
- data/lib/jumoku/builders/raw_undirected_tree.rb +37 -0
- data/lib/jumoku/builders/{raw_tree.rb → shared.rb} +38 -63
- data/lib/jumoku/builders/tree.rb +5 -330
- data/lib/jumoku/classes/tree_classes.rb +6 -4
- data/lib/jumoku/ext/ext.rb +8 -2
- data/lib/jumoku/raw_tree_node.rb +5 -5
- data/lib/jumoku/support/branch.rb +9 -1
- data/lib/jumoku/support/support.rb +6 -13
- data/lib/jumoku/tree_api.rb +7 -7
- data/lib/jumoku/version.rb +2 -2
- data/spec/{raw_tree_spec.rb → raw_undirected_tree_spec.rb} +48 -86
- data/spec/tree_spec.rb +36 -48
- metadata +8 -4
@@ -1,7 +1,9 @@
|
|
1
1
|
module Jumoku
|
2
|
-
#
|
3
|
-
class
|
2
|
+
# "Raw" implementations.
|
3
|
+
class RawUndirectedTree; include RawUndirectedTreeBuilder; end
|
4
|
+
class RawDirectedTree; include RawDirectedTreeBuilder; end
|
4
5
|
|
5
|
-
#
|
6
|
-
class Tree;
|
6
|
+
# "Useful" implementations.
|
7
|
+
class Tree; include TreeBuilder; end
|
8
|
+
class Arborescence; include ArborescenceBuilder; end
|
7
9
|
end
|
data/lib/jumoku/ext/ext.rb
CHANGED
@@ -42,9 +42,15 @@ class Array
|
|
42
42
|
self.create_pairs.flatten(1)
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
# Create a list of branches object based on an expandable array of nodes.
|
46
|
+
#
|
47
|
+
# TODO: refacto, it's painful having to pass the branch_type
|
48
|
+
#
|
49
|
+
# @param [DirectedBranch, UndirectedBranch] branch_type
|
50
|
+
#
|
51
|
+
def create_branches_list(branch_type)
|
46
52
|
branches = []
|
47
|
-
self.expand_branches!.each_by(2) { |pair| branches <<
|
53
|
+
self.expand_branches!.each_by(2) { |pair| branches << branch_type.new(pair[0], pair[1]) }
|
48
54
|
branches
|
49
55
|
end
|
50
56
|
end
|
data/lib/jumoku/raw_tree_node.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Jumoku
|
2
2
|
module RawTree
|
3
|
-
|
4
|
-
#
|
3
|
+
# This module describes RawTree nodes.
|
4
|
+
#
|
5
|
+
# You may also use this module as a mixin to have a class behave
|
6
|
+
# as a RawTree node, while customizing behaviors.
|
5
7
|
#
|
6
|
-
# You can include it in a class of your own to make it act
|
7
|
-
# as a raw tree node, while customizing behaviors.
|
8
8
|
module Node
|
9
|
-
|
10
9
|
# Creates a new node.
|
11
10
|
#
|
12
11
|
# @param [#to_s, #to_sym] name a valid name, considering the :names_as options
|
@@ -15,6 +14,7 @@ module Jumoku
|
|
15
14
|
# @param [Array(#to_s)] children an array of children nodes ids
|
16
15
|
#
|
17
16
|
# @return [OpenObject] the node as an OpenObject instance
|
17
|
+
#
|
18
18
|
def create name, data = OpenObject.new, children = []
|
19
19
|
@name = name
|
20
20
|
@data = data
|
@@ -1,15 +1,8 @@
|
|
1
1
|
module Jumoku
|
2
|
-
|
3
|
-
class
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
class RawTreeError < JumokuError; end
|
9
|
-
# Error related to nodes.
|
10
|
-
|
11
|
-
class RawTreeNodeError < RawTreeError; end
|
12
|
-
# Raised if one attempts to add an already existing branch to a tree.
|
13
|
-
|
14
|
-
class BranchAlreadyExistError < JumokuError; end
|
2
|
+
class JumokuError < StandardError; end
|
3
|
+
class RawTreeError < JumokuError; end
|
4
|
+
class RawTreeNodeError < RawTreeError; end
|
5
|
+
class BranchAlreadyExistError < JumokuError; end
|
6
|
+
class ForbiddenCycle < JumokuError; end
|
7
|
+
class UndefinedNode < JumokuError; end
|
15
8
|
end
|
data/lib/jumoku/tree_api.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Jumoku
|
2
|
-
# This module defines the minimum set of
|
3
|
-
# use the algorithms defined
|
2
|
+
# This module defines the minimum set of methods required to build a tree
|
3
|
+
# which can use the algorithms defined in this library.
|
4
4
|
#
|
5
|
-
#
|
5
|
+
# A module based abiding to the TreeAPI must implement the following routines:
|
6
6
|
#
|
7
7
|
# * add_node!(n, l = nil) — adds a node to the tree and return the tree; l is an optional label (see Plexus library).
|
8
8
|
# * add_branch!(i, j = nil, l = nil) — adds a branch to the tree and return the tree. i can be a {Branch}, or (i,j) a node pair; l is an optional label.
|
@@ -11,17 +11,17 @@ module Jumoku
|
|
11
11
|
# * nodes — returns an array of all nodes.
|
12
12
|
# * terminal_nodes — returns an array of all terminal nodes.
|
13
13
|
# * branches — returns an array of all branches.
|
14
|
+
#
|
14
15
|
module TreeAPI
|
15
|
-
|
16
|
-
#
|
16
|
+
# @raise [JumokuError] if the API is not completely implemented
|
17
|
+
#
|
17
18
|
def self.included(klass)
|
18
19
|
@api_methods ||= [:add_node!, :add_branch!, :remove_node!, :remove_branch!, :nodes, :terminal_nodes, :branches]
|
19
20
|
ruby_18 { @api_methods.each { |m| m.to_s } }
|
20
21
|
|
21
22
|
@api_methods.each do |meth|
|
22
|
-
raise "Must implement #{meth}" unless klass.instance_methods.include?(meth)
|
23
|
+
raise JumokuError, "Must implement #{meth}" unless klass.instance_methods.include?(meth)
|
23
24
|
end
|
24
25
|
end
|
25
|
-
|
26
26
|
end
|
27
27
|
end
|
data/lib/jumoku/version.rb
CHANGED
@@ -1,21 +1,8 @@
|
|
1
|
-
require
|
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
|
1
|
+
require 'spec_helper'
|
17
2
|
|
18
|
-
|
3
|
+
describe RawUndirectedTree do
|
4
|
+
before :each do
|
5
|
+
@tree = RawUndirectedTree.new
|
19
6
|
end
|
20
7
|
|
21
8
|
describe "#new" do
|
@@ -23,8 +10,8 @@ describe "RawTreeBuilder" do
|
|
23
10
|
@tree.should_not be_directed
|
24
11
|
@tree.should be_acyclic
|
25
12
|
@tree.should be_connected
|
26
|
-
# aka @tree.should be_valid,
|
27
|
-
|
13
|
+
# aka @tree.should be_valid, which we will use further on
|
14
|
+
@tree.should be_valid
|
28
15
|
@tree.nodes.should be_empty
|
29
16
|
end
|
30
17
|
end
|
@@ -36,7 +23,7 @@ describe "RawTreeBuilder" do
|
|
36
23
|
it "should grow up as a valid tree when adding its first node" do
|
37
24
|
@tree.nodes.size.should == 0
|
38
25
|
|
39
|
-
@tree.add_node! "root"
|
26
|
+
@tree.add_node! "root" # adding a raw string as the first node
|
40
27
|
@tree.nodes.size.should == 1
|
41
28
|
@tree.nodes.should == ["root"]
|
42
29
|
end
|
@@ -44,33 +31,34 @@ describe "RawTreeBuilder" do
|
|
44
31
|
|
45
32
|
describe "a tree with only one node" do
|
46
33
|
before :each do
|
47
|
-
|
34
|
+
# remember, this 'root' thing retain no particular meaning, it's just a raw string
|
35
|
+
# and I could have written "Joe" instead
|
36
|
+
@tree.add_node! "root"
|
48
37
|
end
|
49
38
|
|
50
|
-
it "should raise an error when trying to add a new
|
39
|
+
it "should raise an error when trying to add a new, disconnected node" do
|
40
|
+
# again, I'll use childX for the sake of this specs, as it is easy to
|
41
|
+
# remember, but the node is not really a "child" of the previous node,
|
42
|
+
# it is just connected
|
51
43
|
lambda { @tree.add_node! "child1" }.should raise_error
|
52
44
|
end
|
53
45
|
|
54
|
-
it "should grow up as a valid tree when adding new
|
46
|
+
it "should grow up as a valid tree when adding new, connected nodes" do
|
55
47
|
lambda { @tree.add_node! "child1", "root" }.should_not raise_error
|
56
48
|
|
57
49
|
@tree.add_node! "child2", "root"
|
58
50
|
@tree.add_node! "grand-child1", "child2"
|
59
|
-
@tree.add_node! Jumoku::
|
51
|
+
@tree.add_node! Jumoku::UndirectedBranch.new("grand-child2", "child2")
|
60
52
|
|
61
53
|
@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
|
54
|
+
@tree.nodes.should == ["root", "child1", "child2", "grand-child1", "grand-child2"]
|
66
55
|
|
67
56
|
@tree.add_node! "grand-grand-child1", "grand-child1"
|
68
57
|
@tree.add_node! "child3", "root"
|
69
58
|
@tree.add_node! "grand-child3", "child3"
|
70
59
|
@tree.add_node! "grand-grand-grand-child", "grand-grand-child1"
|
71
|
-
|
72
|
-
@tree.should
|
73
|
-
@tree.should be_connected
|
60
|
+
|
61
|
+
@tree.should be_valid
|
74
62
|
end
|
75
63
|
|
76
64
|
it "should raise an error when trying to form a cycle" do
|
@@ -78,34 +66,35 @@ describe "RawTreeBuilder" do
|
|
78
66
|
@tree.add_node! "child2", "root"
|
79
67
|
@tree.add_node! "grand-child", "child1"
|
80
68
|
|
81
|
-
lambda { @tree.add_node! "grand-child", "child2" }.should raise_error
|
69
|
+
lambda { @tree.add_node! "grand-child", "child2" }.should raise_error ForbiddenCycle
|
82
70
|
|
83
71
|
@tree.add_node! "grand-grand-child", "grand-child"
|
84
|
-
|
85
|
-
lambda { @tree.add_node! "grand-grand-child", "
|
72
|
+
|
73
|
+
lambda { @tree.add_node! "grand-grand-child", "child1" }.should raise_error ForbiddenCycle
|
74
|
+
lambda { @tree.add_node! "grand-grand-child", "child2" }.should raise_error ForbiddenCycle
|
86
75
|
end
|
87
76
|
end
|
88
77
|
end
|
89
78
|
|
90
79
|
describe "#add_branch!" do
|
91
80
|
describe "an empty tree" do
|
92
|
-
it "should
|
93
|
-
|
94
|
-
@tree.nodes.should == [:first, :branch]
|
81
|
+
it "should create a branch and return the updated tree" do
|
82
|
+
@tree.add_branch!(:one, :two).should be_a RawUndirectedTree
|
95
83
|
@tree.should be_valid
|
84
|
+
@tree.nodes.should == [:one, :two]
|
96
85
|
end
|
97
86
|
end
|
98
87
|
|
99
|
-
describe "a tree
|
88
|
+
describe "a tree containing a single node" do
|
100
89
|
before :each do
|
101
90
|
@tree.add_node! 1
|
102
91
|
end
|
103
92
|
|
104
|
-
it "should not allow
|
93
|
+
it "should not allow disconnected branch creation" do
|
105
94
|
lambda { @tree.add_branch! 10, 11 }.should raise_error RawTreeError
|
106
95
|
end
|
107
96
|
|
108
|
-
it "should grow up as a valid tree when populated with
|
97
|
+
it "should grow up as a valid tree when populated with connected branches" do
|
109
98
|
@tree.nodes.size.should == 1
|
110
99
|
|
111
100
|
@tree.add_branch! 1, 2
|
@@ -119,7 +108,8 @@ describe "RawTreeBuilder" do
|
|
119
108
|
|
120
109
|
@tree.add_branch! 3, 4
|
121
110
|
@tree.add_branch! 2, 5
|
122
|
-
lambda { @tree.add_branch! 5, 5 }.should raise_error
|
111
|
+
lambda { @tree.add_branch! 5, 5 }.should raise_error ForbiddenCycle
|
112
|
+
lambda { @tree.add_branch! 1, 5 }.should raise_error ForbiddenCycle
|
123
113
|
@tree.add_branch! 4, 3
|
124
114
|
@tree.add_branch! 5, 6
|
125
115
|
@tree.nodes.size.should == 6
|
@@ -132,11 +122,11 @@ describe "RawTreeBuilder" do
|
|
132
122
|
describe "#remove_node!" do
|
133
123
|
describe "an empty tree" do
|
134
124
|
it "should not allow to remove a node since there's none" do
|
135
|
-
lambda { @tree.remove_node! "
|
125
|
+
lambda { @tree.remove_node! "undefinedNode" }.should raise_error UndefinedNode
|
136
126
|
end
|
137
127
|
end
|
138
128
|
|
139
|
-
describe "a tree
|
129
|
+
describe "a tree containing a single node" do
|
140
130
|
before :each do
|
141
131
|
@tree.add_node! :last
|
142
132
|
end
|
@@ -148,12 +138,12 @@ describe "RawTreeBuilder" do
|
|
148
138
|
end
|
149
139
|
end
|
150
140
|
|
151
|
-
describe "a tree
|
141
|
+
describe "a tree containing one branch" do
|
152
142
|
before :each do
|
153
|
-
@tree1 =
|
143
|
+
@tree1 = RawUndirectedTree.new
|
154
144
|
@tree1.add_node! 1
|
155
145
|
@tree1.add_node! 2, 1
|
156
|
-
@tree2 =
|
146
|
+
@tree2 = RawUndirectedTree.new
|
157
147
|
@tree2.add_node! 1
|
158
148
|
@tree2.add_node! 2, 1
|
159
149
|
end
|
@@ -171,7 +161,7 @@ describe "RawTreeBuilder" do
|
|
171
161
|
end
|
172
162
|
end
|
173
163
|
|
174
|
-
describe "a tree
|
164
|
+
describe "a tree containing several branches" do
|
175
165
|
before :each do
|
176
166
|
# TODO: DRY this snippet
|
177
167
|
# i stands for internal, t for terminal
|
@@ -189,7 +179,7 @@ describe "RawTreeBuilder" do
|
|
189
179
|
lambda { @tree.remove_node! :t8 }.should_not raise_error
|
190
180
|
@tree.nodes.size.should == 7
|
191
181
|
@tree.nodes.should_not include :t8
|
192
|
-
lambda { @tree.remove_node! :i3 }.should raise_error
|
182
|
+
lambda { @tree.remove_node! :i3 }.should raise_error UndefinedNode
|
193
183
|
@tree.should be_valid
|
194
184
|
end
|
195
185
|
|
@@ -208,7 +198,7 @@ describe "RawTreeBuilder" do
|
|
208
198
|
end
|
209
199
|
end
|
210
200
|
|
211
|
-
describe "an tree
|
201
|
+
describe "an tree containing one node" do
|
212
202
|
before :each do
|
213
203
|
@tree.add_node! 1
|
214
204
|
end
|
@@ -218,7 +208,7 @@ describe "RawTreeBuilder" do
|
|
218
208
|
end
|
219
209
|
end
|
220
210
|
|
221
|
-
describe "a tree
|
211
|
+
describe "a tree containing several branches" do
|
222
212
|
before :each do
|
223
213
|
# TODO: DRY this snippet
|
224
214
|
# i stands for internal, t for terminal
|
@@ -240,7 +230,7 @@ describe "RawTreeBuilder" do
|
|
240
230
|
@tree.has_branch?(:i1, :t8).should be_false
|
241
231
|
@tree.should be_valid
|
242
232
|
|
243
|
-
@tree.remove_branch!
|
233
|
+
@tree.remove_branch! UndirectedBranch.new(:i5, :t7)
|
244
234
|
@tree.has_branch?(:i5, :t7).should be_false
|
245
235
|
@tree.should be_valid
|
246
236
|
end
|
@@ -254,8 +244,8 @@ describe "RawTreeBuilder" do
|
|
254
244
|
end
|
255
245
|
end
|
256
246
|
|
257
|
-
describe "a tree
|
258
|
-
it "should be aware of its
|
247
|
+
describe "a tree containing several nodes" do
|
248
|
+
it "should be aware of its nodes" do
|
259
249
|
@tree.add_node! :solo
|
260
250
|
@tree.nodes.should == [:solo]
|
261
251
|
|
@@ -274,14 +264,14 @@ describe "RawTreeBuilder" do
|
|
274
264
|
end
|
275
265
|
end
|
276
266
|
|
277
|
-
describe "a tree
|
267
|
+
describe "a tree containing one node" do
|
278
268
|
it "should have one terminal node" do
|
279
269
|
@tree.add_node! 1
|
280
270
|
@tree.terminal_nodes.should == [1]
|
281
271
|
end
|
282
272
|
end
|
283
273
|
|
284
|
-
describe "a
|
274
|
+
describe "a tree with several branches" do
|
285
275
|
before :each do
|
286
276
|
@tree.add_node! 1
|
287
277
|
@tree.add_node! 2, 1
|
@@ -305,49 +295,21 @@ describe "RawTreeBuilder" do
|
|
305
295
|
end
|
306
296
|
end
|
307
297
|
|
308
|
-
describe "a tree
|
298
|
+
describe "a tree containing one node" do
|
309
299
|
it "should not have any branch" do
|
310
300
|
@tree.add_node! :solo
|
311
301
|
@tree.branches.should be_empty
|
312
302
|
end
|
313
303
|
end
|
314
304
|
|
315
|
-
describe "a tree
|
305
|
+
describe "a tree containing one branch" do
|
316
306
|
it "should have one branch only (undirected)" do
|
317
307
|
@tree.add_node! :one
|
318
308
|
@tree.add_node! :two, :one
|
319
309
|
@tree.branches.size.should == 1
|
320
|
-
@tree.branches.first.class.should == Plexus::Edge
|
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
|
310
|
+
@tree.branches.first.class.should == Plexus::Edge
|
347
311
|
@tree.should be_valid
|
348
312
|
end
|
349
313
|
end
|
350
314
|
end
|
351
|
-
|
352
|
-
# TODO: add a final test which sums it up
|
353
315
|
end
|
data/spec/tree_spec.rb
CHANGED
@@ -1,20 +1,8 @@
|
|
1
|
-
require
|
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
|
1
|
+
require 'spec_helper'
|
16
2
|
|
17
|
-
|
3
|
+
describe Tree do
|
4
|
+
before :each do
|
5
|
+
@tree = Tree.new
|
18
6
|
end
|
19
7
|
|
20
8
|
describe "#new" do
|
@@ -24,15 +12,15 @@ describe "TreeBuilder" do
|
|
24
12
|
end
|
25
13
|
end
|
26
14
|
|
27
|
-
##
|
28
|
-
## The following tests focus on
|
15
|
+
## The core TreeAPI is tested in raw_tree_spec.rb.
|
16
|
+
## The following tests focus on methods added by TreeBuilder.
|
29
17
|
|
30
18
|
describe "#add_node" do
|
31
19
|
describe "an empty tree" do
|
32
20
|
it "should create a new, valid tree with a single node when its first node is added" do
|
33
21
|
@tree.add_node 1
|
34
|
-
@tree.should be_empty
|
35
|
-
|
22
|
+
@tree.should be_empty # the original tree is not modified
|
23
|
+
# a brand new tree is created instead, extending the original one
|
36
24
|
new_tree = @tree.add_node 1
|
37
25
|
new_tree.nodes.should == [1]
|
38
26
|
new_tree.should be_valid
|
@@ -70,7 +58,7 @@ describe "TreeBuilder" do
|
|
70
58
|
end
|
71
59
|
end
|
72
60
|
|
73
|
-
describe "a
|
61
|
+
describe "a populated tree" do
|
74
62
|
before :each do
|
75
63
|
@tree.add_branch! 1, 2
|
76
64
|
@tree.add_branch! 2, 3
|
@@ -97,7 +85,7 @@ describe "TreeBuilder" do
|
|
97
85
|
end
|
98
86
|
end
|
99
87
|
|
100
|
-
describe "a tree
|
88
|
+
describe "a tree containing one node" do
|
101
89
|
before :each do
|
102
90
|
@tree.add_node! 1
|
103
91
|
end
|
@@ -154,11 +142,11 @@ describe "TreeBuilder" do
|
|
154
142
|
@tree.nodes.should == [1, 2, 3, 4]
|
155
143
|
@tree.should be_valid
|
156
144
|
|
157
|
-
@tree.add_nodes!
|
145
|
+
@tree.add_nodes! UndirectedBranch.new(5, 2)
|
158
146
|
@tree.nodes.should == [1, 2, 3, 4, 5]
|
159
147
|
@tree.should be_valid
|
160
148
|
|
161
|
-
@tree.add_nodes! 3,4, 1,10,
|
149
|
+
@tree.add_nodes! 3,4, 1,10, UndirectedBranch.new(10, 11), -1,1
|
162
150
|
@tree.nodes.size.should == 8
|
163
151
|
@tree.should be_valid
|
164
152
|
|
@@ -181,12 +169,12 @@ describe "TreeBuilder" do
|
|
181
169
|
new_tree.nodes.should == [1, 2, 3, 4]
|
182
170
|
new_tree.should be_valid
|
183
171
|
|
184
|
-
new_tree = @tree.add_nodes
|
172
|
+
new_tree = @tree.add_nodes UndirectedBranch.new(4, 5)
|
185
173
|
@tree.should be_empty
|
186
174
|
new_tree.nodes.should == [4, 5]
|
187
175
|
new_tree.should be_valid
|
188
176
|
|
189
|
-
new_tree = @tree.add_nodes 3,4, 4,10,
|
177
|
+
new_tree = @tree.add_nodes 3,4, 4,10, UndirectedBranch.new(10, 11), -1,3
|
190
178
|
@tree.should be_empty
|
191
179
|
new_tree.nodes.size.should == 5
|
192
180
|
new_tree.should be_valid
|
@@ -204,11 +192,11 @@ describe "TreeBuilder" do
|
|
204
192
|
describe "#add_branches!" do
|
205
193
|
describe "an empty tree" do
|
206
194
|
it "should allow for adding its first branches" do
|
207
|
-
@tree.add_branches!
|
195
|
+
@tree.add_branches! UndirectedBranch.new(1, 2), 1,3, 3,4
|
208
196
|
@tree.nodes.should == [1, 2, 3, 4]
|
209
197
|
@tree.should be_valid
|
210
198
|
|
211
|
-
branch =
|
199
|
+
branch = UndirectedBranch.new(1, 4)
|
212
200
|
lambda { @tree.add_branches! branch }.should raise_error, RawTreeError
|
213
201
|
end
|
214
202
|
end
|
@@ -223,11 +211,11 @@ describe "TreeBuilder" do
|
|
223
211
|
@tree.nodes.should == [1, 2, 3]
|
224
212
|
@tree.should be_valid
|
225
213
|
|
226
|
-
@tree.add_branches!
|
214
|
+
@tree.add_branches! UndirectedBranch.new(0,1), 3,4, UndirectedBranch.new(4,5)
|
227
215
|
[0..5].all? { |n| @tree.nodes.include? n } and @tree.nodes.size.should == 5
|
228
216
|
@tree.should be_valid
|
229
217
|
|
230
|
-
lambda { @tree.add_branches!
|
218
|
+
lambda { @tree.add_branches! UndirectedBranch.new(2, 5) }.should raise_error, RawTreeError
|
231
219
|
end
|
232
220
|
end
|
233
221
|
end
|
@@ -235,7 +223,7 @@ describe "TreeBuilder" do
|
|
235
223
|
describe "add_branches" do
|
236
224
|
describe "an empty tree" do
|
237
225
|
it "should create a new, valid tree populated with its first branches" do
|
238
|
-
b1, b2, b3 =
|
226
|
+
b1, b2, b3 = UndirectedBranch.new(1, 2), UndirectedBranch.new(2, 3), UndirectedBranch.new(3, 4)
|
239
227
|
new_tree = @tree.add_branches b1, b2, b3
|
240
228
|
@tree.should be_empty
|
241
229
|
new_tree.nodes.should == [1, 2, 3, 4]
|
@@ -251,13 +239,13 @@ describe "TreeBuilder" do
|
|
251
239
|
end
|
252
240
|
|
253
241
|
it "should create a new, valid tree extended with its new branches" do
|
254
|
-
new_tree = @tree.add_branches 4, :five,
|
242
|
+
new_tree = @tree.add_branches 4, :five, UndirectedBranch.new(:five, "six")
|
255
243
|
@tree.nodes.should == (1..4).to_a
|
256
244
|
new_tree.nodes.should == [1, 2, 3, 4, :five, "six"]
|
257
245
|
new_tree.should be_valid
|
258
246
|
|
259
247
|
lambda { @tree.add_branches 10, 11 }.should raise_error, RawTreeError
|
260
|
-
lambda { @tree.add_branches
|
248
|
+
lambda { @tree.add_branches UndirectedBranch.new 1,4 }.should raise_error, RawTreeError
|
261
249
|
end
|
262
250
|
end
|
263
251
|
end
|
@@ -324,7 +312,7 @@ describe "TreeBuilder" do
|
|
324
312
|
describe "#remove_branches!" do
|
325
313
|
describe "an empty tree" do
|
326
314
|
it "should not allow for removing branches" do
|
327
|
-
lambda { @tree.remove_branches
|
315
|
+
lambda { @tree.remove_branches UndirectedBranch.new(:foo, :bar), 1,2 }.should raise_error, RawTreeError
|
328
316
|
end
|
329
317
|
end
|
330
318
|
|
@@ -344,11 +332,11 @@ describe "TreeBuilder" do
|
|
344
332
|
end
|
345
333
|
|
346
334
|
it "should allow for removing branches until it has no more branches or a sole node" do
|
347
|
-
@tree.remove_branches! 1,2,
|
335
|
+
@tree.remove_branches! 1,2, UndirectedBranch.new(2,3), 3,4
|
348
336
|
@tree.should be_empty
|
349
337
|
@tree.should be_valid
|
350
338
|
|
351
|
-
lambda { @tree.remove_branches!
|
339
|
+
lambda { @tree.remove_branches! UndirectedBranch.new(:foo, :bar), UndirectedBranch.new(1, 2) }.should raise_error, RawTreeError
|
352
340
|
end
|
353
341
|
end
|
354
342
|
end
|
@@ -356,7 +344,7 @@ describe "TreeBuilder" do
|
|
356
344
|
describe "#remove_branches" do
|
357
345
|
describe "an empty tree" do
|
358
346
|
it "should not allow for removing branches" do
|
359
|
-
lambda { @tree.remove_branches :foo, :bar,
|
347
|
+
lambda { @tree.remove_branches :foo, :bar, UndirectedBranch.new(1, 2) }.should raise_error, RawTreeError
|
360
348
|
end
|
361
349
|
end
|
362
350
|
|
@@ -376,12 +364,12 @@ describe "TreeBuilder" do
|
|
376
364
|
end
|
377
365
|
|
378
366
|
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,
|
367
|
+
new_tree = @tree.remove_branches 1,2, UndirectedBranch.new(2,3), 3,4
|
380
368
|
@tree.nodes.should == [1, 2, 3, 4]
|
381
369
|
new_tree.should be_empty
|
382
370
|
new_tree.should be_valid
|
383
371
|
|
384
|
-
lambda { @tree.remove_branches
|
372
|
+
lambda { @tree.remove_branches UndirectedBranch.new(:foo, :bar), UndirectedBranch.new(1, 2) }.should raise_error, RawTreeError
|
385
373
|
end
|
386
374
|
end
|
387
375
|
end
|
@@ -527,12 +515,12 @@ describe "TreeBuilder" do
|
|
527
515
|
describe "#add_consecutive_nodes!" do
|
528
516
|
describe "a tree" do
|
529
517
|
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,
|
531
|
-
@tree.has_branches?(1,2, 2,3,
|
532
|
-
@tree.has_branches?(1,2, 2,3,
|
533
|
-
@tree.has_branches_among?(1,2, 2,3,
|
534
|
-
@tree.has_branches_among?(1,2, 2,3,
|
535
|
-
@tree.has_branches_among?(1,2, 2,3,
|
518
|
+
@tree.add_consecutive_nodes!(1, 2, 3, :four, UndirectedBranch.new(:foo, "bar"))
|
519
|
+
@tree.has_branches?(1,2, 2,3, UndirectedBranch.new(3, :four), :four,:foo, :foo,"bar").should be_true # each specified branch exist
|
520
|
+
@tree.has_branches?(1,2, 2,3, UndirectedBranch.new(3, :four), :four,:foo).should be_true # each specified branch exist
|
521
|
+
@tree.has_branches_among?(1,2, 2,3, UndirectedBranch.new(3, :four), :four,:foo).should be_false # do not list every existing branch
|
522
|
+
@tree.has_branches_among?(1,2, 2,3, UndirectedBranch.new(3, :four), :four,:foo, :foo,"bar").should be_true # list all existing branches
|
523
|
+
@tree.has_branches_among?(1,2, 2,3, UndirectedBranch.new(3, :four), :four,:foo, :foo,"bar", Array.new, "NIL").should be_true # list all existing branches
|
536
524
|
@tree.should be_valid
|
537
525
|
end
|
538
526
|
end
|
@@ -541,10 +529,10 @@ describe "TreeBuilder" do
|
|
541
529
|
describe "#add_consecutive_nodes" do
|
542
530
|
describe "a tree" do
|
543
531
|
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,
|
532
|
+
new_tree = @tree.add_consecutive_nodes(1, 2, 3, :four, UndirectedBranch.new(:foo, "bar"))
|
545
533
|
@tree.should be_empty
|
546
|
-
new_tree.has_branches?(1,2, 2,3,
|
547
|
-
new_tree.has_branches?(1,2, 2,3,
|
534
|
+
new_tree.has_branches?(1,2, 2,3, UndirectedBranch.new(3, :four), :four,:foo, :foo,"bar").should be_true
|
535
|
+
new_tree.has_branches?(1,2, 2,3, UndirectedBranch.new(3, :four), :four,:foo).should be_true
|
548
536
|
new_tree.should be_valid
|
549
537
|
end
|
550
538
|
end
|