plexus 0.5.4 → 0.5.5
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 +3 -0
- data/LICENSE +37 -0
- data/README.md +208 -0
- data/Rakefile +25 -0
- data/lib/plexus.rb +90 -0
- data/lib/plexus/adjacency_graph.rb +225 -0
- data/lib/plexus/arc.rb +60 -0
- data/lib/plexus/arc_number.rb +50 -0
- data/lib/plexus/biconnected.rb +84 -0
- data/lib/plexus/chinese_postman.rb +91 -0
- data/lib/plexus/classes/graph_classes.rb +28 -0
- data/lib/plexus/common.rb +63 -0
- data/lib/plexus/comparability.rb +63 -0
- data/lib/plexus/directed_graph.rb +78 -0
- data/lib/plexus/directed_graph/algorithms.rb +95 -0
- data/lib/plexus/directed_graph/distance.rb +167 -0
- data/lib/plexus/dot.rb +94 -0
- data/lib/plexus/edge.rb +38 -0
- data/lib/plexus/ext.rb +79 -0
- data/lib/plexus/graph.rb +628 -0
- data/lib/plexus/graph_api.rb +35 -0
- data/lib/plexus/labels.rb +112 -0
- data/lib/plexus/maximum_flow.rb +77 -0
- data/lib/plexus/ruby_compatibility.rb +17 -0
- data/lib/plexus/search.rb +510 -0
- data/lib/plexus/strong_components.rb +93 -0
- data/lib/plexus/support/support.rb +9 -0
- data/lib/plexus/undirected_graph.rb +56 -0
- data/lib/plexus/undirected_graph/algorithms.rb +90 -0
- data/lib/plexus/version.rb +6 -0
- data/spec/biconnected_spec.rb +27 -0
- data/spec/chinese_postman_spec.rb +27 -0
- data/spec/community_spec.rb +44 -0
- data/spec/complement_spec.rb +27 -0
- data/spec/digraph_distance_spec.rb +121 -0
- data/spec/digraph_spec.rb +339 -0
- data/spec/dot_spec.rb +48 -0
- data/spec/edge_spec.rb +158 -0
- data/spec/inspection_spec.rb +38 -0
- data/spec/multi_edge_spec.rb +32 -0
- data/spec/neighborhood_spec.rb +36 -0
- data/spec/properties_spec.rb +146 -0
- data/spec/search_spec.rb +227 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +59 -0
- data/spec/strong_components_spec.rb +61 -0
- data/spec/triangulated_spec.rb +125 -0
- data/spec/undirected_graph_spec.rb +220 -0
- data/vendor/priority-queue/CHANGELOG +33 -0
- data/vendor/priority-queue/Makefile +140 -0
- data/vendor/priority-queue/README +133 -0
- data/vendor/priority-queue/benchmark/dijkstra.rb +171 -0
- data/vendor/priority-queue/compare_comments.rb +49 -0
- data/vendor/priority-queue/doc/c-vs-rb.png +0 -0
- data/vendor/priority-queue/doc/compare_big.gp +14 -0
- data/vendor/priority-queue/doc/compare_big.png +0 -0
- data/vendor/priority-queue/doc/compare_small.gp +15 -0
- data/vendor/priority-queue/doc/compare_small.png +0 -0
- data/vendor/priority-queue/doc/results.csv +37 -0
- data/vendor/priority-queue/ext/priority_queue/CPriorityQueue/extconf.rb +2 -0
- data/vendor/priority-queue/ext/priority_queue/CPriorityQueue/priority_queue.c +947 -0
- data/vendor/priority-queue/lib/priority_queue.rb +14 -0
- data/vendor/priority-queue/lib/priority_queue/c_priority_queue.rb +1 -0
- data/vendor/priority-queue/lib/priority_queue/poor_priority_queue.rb +46 -0
- data/vendor/priority-queue/lib/priority_queue/ruby_priority_queue.rb +526 -0
- data/vendor/priority-queue/priority_queue.so +0 -0
- data/vendor/priority-queue/setup.rb +1551 -0
- data/vendor/priority-queue/test/priority_queue_test.rb +371 -0
- data/vendor/rdot.rb +360 -0
- metadata +100 -10
@@ -0,0 +1,339 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe "Digraph" do # :nodoc:
|
4
|
+
|
5
|
+
before do
|
6
|
+
@single = Digraph[1,2, 2,3, 3,4, 1,2, 2,3, 4,4]
|
7
|
+
@dups = DirectedPseudoGraph[1,2, 2,3, 3,4, 1,2, 2,3, 4,4]
|
8
|
+
@loops = DirectedMultiGraph[1,2, 2,3, 3,4, 4,4, 1,2, 2,3]
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "new" do
|
12
|
+
it do
|
13
|
+
@single.should == Digraph[1,2, 2,3, 3,4]
|
14
|
+
@dups.should == DirectedPseudoGraph.new([1,2, 2,3, 3,4, 1,2, 2,3])
|
15
|
+
@loops.should == DirectedMultiGraph.new([1,2, 2,3, 3,4, 4,4, 1,2, 2,3])
|
16
|
+
proc { Digraph.new(:loops) }.should raise_error(ArgumentError)
|
17
|
+
proc { Digraph.new(:parallel_edges) }.should raise_error(ArgumentError)
|
18
|
+
proc { DirectedMultiGraph.new(:loops) }.should raise_error(ArgumentError)
|
19
|
+
proc { DirectedMultiGraph.new(:parallel_edges) }.should raise_error(ArgumentError)
|
20
|
+
proc { DirectedPseudoGraph.new(:loops) }.should raise_error(ArgumentError)
|
21
|
+
proc { DirectedPseudoGraph.new(:parallel_edges) }.should raise_error(ArgumentError)
|
22
|
+
proc { Digraph.new(1) }.should raise_error(ArgumentError)
|
23
|
+
Digraph.new(@single).should == @single
|
24
|
+
DirectedPseudoGraph.new(@dups).should == @dups
|
25
|
+
DirectedMultiGraph.new(@loops).should == @loops
|
26
|
+
Digraph.new(@loops).should == Digraph[1,2, 2,3, 3,4]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "edges" do
|
31
|
+
it do
|
32
|
+
@single.edges.size.should == 3
|
33
|
+
@single.edges.include?(Arc[1,2]).should be_true
|
34
|
+
@single.edges.include?(Arc[2,3]).should be_true
|
35
|
+
@single.edges.include?(Arc[3,4]).should be_true
|
36
|
+
@single.edges.include?(Arc[4,4]).should be_false
|
37
|
+
@single.edges.include?(Arc[1,2]).should be_true
|
38
|
+
@single.edges.include?(Arc[2,3]).should be_true
|
39
|
+
@single.edges.include?(Arc[1,3]).should be_false
|
40
|
+
@single.edge?(2,3).should be_true
|
41
|
+
@single.edge?(1,4).should be_false
|
42
|
+
@single.edge?(Arc[1,2]).should be_true
|
43
|
+
@single.add_edge!(5,5).edge?(5,5).should be_false
|
44
|
+
@single.remove_edge!(5,5).edge?(5,5).should be_false
|
45
|
+
|
46
|
+
@dups.edges.size.should == 5
|
47
|
+
@dups.edges.include?(MultiArc[1,2]).should be_true
|
48
|
+
@dups.edges.include?(MultiArc[2,3]).should be_true
|
49
|
+
@dups.edges.include?(MultiArc[3,4]).should be_true
|
50
|
+
@dups.edges.include?(MultiArc[4,4]).should be_false
|
51
|
+
@dups.edges.include?(MultiArc[1,2]).should be_true
|
52
|
+
@dups.edges.include?(MultiArc[2,3]).should be_true
|
53
|
+
@dups.edges.include?(MultiArc[1,3]).should be_false
|
54
|
+
@dups.edge?(2,3).should be_true
|
55
|
+
@dups.edge?(1,4).should be_false
|
56
|
+
@dups.edge?(MultiArc[1,2]).should be_true
|
57
|
+
@dups.add_edge!(5,5).edge?(5,5).should be_false
|
58
|
+
proc { @dups.remove_edge!(5,5) }.should raise_error(ArgumentError)
|
59
|
+
|
60
|
+
@dups.edges.size.should == 5
|
61
|
+
@loops.edges.include?(MultiArc[1,2]).should be_true
|
62
|
+
@loops.edges.include?(MultiArc[2,3]).should be_true
|
63
|
+
@loops.edges.include?(MultiArc[3,4]).should be_true
|
64
|
+
@loops.edges.include?(MultiArc[4,4]).should be_true
|
65
|
+
@loops.edges.include?(MultiArc[1,2]).should be_true
|
66
|
+
@loops.edges.include?(MultiArc[2,3]).should be_true
|
67
|
+
@loops.edges.include?(MultiArc[1,3]).should be_false
|
68
|
+
@loops.edge?(2,3).should be_true
|
69
|
+
@loops.edge?(1,4).should be_false
|
70
|
+
@loops.edge?(MultiArc[1,2]).should be_true
|
71
|
+
@loops.add_edge!(5,5).edge?(5,5).should be_true
|
72
|
+
proc { @loops.remove_edge!(5,5) }.should raise_error(ArgumentError)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "vertices" do
|
78
|
+
it do
|
79
|
+
@single.vertices.sort.should == [1,2,3,4]
|
80
|
+
@single.add_vertex!(5).to_a.sort.should == [1,2,3,4,5]
|
81
|
+
@single.remove_vertex!(3).to_a.sort.should == [1,2,4,5]
|
82
|
+
@single.vertex?(3).should be_false
|
83
|
+
@single.edge?(2,3).should be_false
|
84
|
+
@single.edge?(3,4).should be_false
|
85
|
+
@single.add_vertex(:bogus).vertex?(:bogus).should be_true
|
86
|
+
@single.add_vertex(:bogus).vertex?(nil).should be_false
|
87
|
+
@single.vertex?(:bogus).should be_false
|
88
|
+
@single.add_vertex!(:real)
|
89
|
+
@single.vertex?(:real).should be_true
|
90
|
+
@single.add_edge(:here, :there).edge?(Arc[:here, :there]).should be_true
|
91
|
+
@single.edge?(Arc[:here, :there]).should be_false
|
92
|
+
@single.vertex?(:here).should be_false
|
93
|
+
@single.vertex?(:there).should be_false
|
94
|
+
@single.add_edge!(:here, :there)
|
95
|
+
@single.edge?(Arc[:here, :there]).should be_true
|
96
|
+
@single.vertex?(:here).should be_true
|
97
|
+
@single.vertex?(:there).should be_true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "properties" do
|
102
|
+
it do
|
103
|
+
@single.should be_directed
|
104
|
+
@single.should_not be_empty
|
105
|
+
Digraph.new.should be_empty
|
106
|
+
@single.size.should == 4
|
107
|
+
@dups.size.should == 4
|
108
|
+
@loops.size.should == 4
|
109
|
+
@single.num_vertices.should == 4
|
110
|
+
@dups.num_vertices.should == 4
|
111
|
+
@single.num_edges.should == 3
|
112
|
+
@dups.num_edges.should == 5
|
113
|
+
@loops.num_edges.should == 6
|
114
|
+
@single.should be_oriented
|
115
|
+
@single.remove_vertex!(4)
|
116
|
+
@single.should be_oriented
|
117
|
+
@loops.oriented?.should be_false
|
118
|
+
@loops.remove_vertex!(4)
|
119
|
+
@loops.should be_oriented
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "merge" do
|
124
|
+
it do
|
125
|
+
@dups.merge(@single)
|
126
|
+
@dups.num_edges.should == 8
|
127
|
+
@dups.vertices.sort.should == [1,2,3,4]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "operators" do
|
132
|
+
it do
|
133
|
+
result = @single + Arc[3,2]
|
134
|
+
@single.size.should == 4
|
135
|
+
@single.num_edges.should == 3
|
136
|
+
result.size.should == 4
|
137
|
+
result.num_edges.should == 4
|
138
|
+
|
139
|
+
result = @single + 5
|
140
|
+
@single.size.should == 4
|
141
|
+
@single.num_edges.should == 3
|
142
|
+
result.size.should == 5
|
143
|
+
result.num_edges.should == 3
|
144
|
+
|
145
|
+
result = @single - Arc[4,4]
|
146
|
+
@single.size.should == 4
|
147
|
+
@single.num_edges.should == 3
|
148
|
+
result.size.should == 4
|
149
|
+
result.num_edges.should == 3
|
150
|
+
|
151
|
+
e = @loops.edges.detect { |e| e.source == 4 && e.target == 4 }
|
152
|
+
result = @loops - e
|
153
|
+
@single.size.should == 4
|
154
|
+
@single.num_edges.should == 3
|
155
|
+
result.size.should == 4
|
156
|
+
result.num_edges.should == 5
|
157
|
+
|
158
|
+
result = @single - 4
|
159
|
+
@single.size.should == 4
|
160
|
+
@single.num_edges.should == 3
|
161
|
+
result.size.should == 3
|
162
|
+
result.num_edges.should == 2
|
163
|
+
|
164
|
+
@single << Arc[6,1]
|
165
|
+
@single.size.should == 5
|
166
|
+
@single.num_edges.should == 4
|
167
|
+
@single.edge?(6,1).should be_true
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "reversal" do
|
172
|
+
it do
|
173
|
+
reverse = @single.add_vertex!(42).reversal
|
174
|
+
reverse.vertices.sort.should == [1,2,3,4,42]
|
175
|
+
reverse.edge?(2,1).should be_true
|
176
|
+
reverse.edge?(3,2).should be_true
|
177
|
+
reverse.edge?(4,3).should be_true
|
178
|
+
reverse.edge?(4,4).should be_false
|
179
|
+
reverse.num_edges.should == 3
|
180
|
+
reverse = @loops.reversal
|
181
|
+
reverse.edge?(4,4).should be_true
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "complement" do
|
186
|
+
it do
|
187
|
+
complement = @single.complement
|
188
|
+
complement.vertices.sort.should == [1,2,3,4]
|
189
|
+
complement.edge?(1,1).should be_false
|
190
|
+
complement.edge?(1,3).should be_true
|
191
|
+
complement.edge?(1,4).should be_true
|
192
|
+
complement.edge?(2,1).should be_true
|
193
|
+
complement.edge?(2,4).should be_true
|
194
|
+
complement.edge?(3,1).should be_true
|
195
|
+
complement.edge?(3,2).should be_true
|
196
|
+
complement.edge?(4,1).should be_true
|
197
|
+
complement.edge?(4,2).should be_true
|
198
|
+
complement.edge?(4,3).should be_true
|
199
|
+
complement.num_edges.should == 9
|
200
|
+
|
201
|
+
complement = @loops.complement
|
202
|
+
complement.vertices.sort.should == [1,2,3,4]
|
203
|
+
complement.edge?(1,1).should be_true
|
204
|
+
complement.edge?(1,3).should be_true
|
205
|
+
complement.edge?(1,4).should be_true
|
206
|
+
complement.edge?(2,1).should be_true
|
207
|
+
complement.edge?(2,2).should be_true
|
208
|
+
complement.edge?(2,4).should be_true
|
209
|
+
complement.edge?(3,1).should be_true
|
210
|
+
complement.edge?(3,2).should be_true
|
211
|
+
complement.edge?(3,3).should be_true
|
212
|
+
complement.edge?(4,1).should be_true
|
213
|
+
complement.edge?(4,2).should be_true
|
214
|
+
complement.edge?(4,3).should be_true
|
215
|
+
complement.num_edges.should == 12
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe "induced_subgraph" do
|
220
|
+
it do
|
221
|
+
induced = @single.induced_subgraph([1,2])
|
222
|
+
induced.vertices.sort.should == [1,2]
|
223
|
+
induced.edge?(1,2).should be_true
|
224
|
+
induced.num_edges.should == 1
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe "include" do
|
229
|
+
it do
|
230
|
+
@single.include?(4).should be_true
|
231
|
+
@dups.include?(4).should be_true
|
232
|
+
@dups.include?(5).should be_false
|
233
|
+
@single.include?(5).should be_false
|
234
|
+
@single.include?(Arc[1,2]).should be_true
|
235
|
+
@dups.include?(Arc[1,2]).should be_true
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe "adjacent" do
|
240
|
+
it do
|
241
|
+
|
242
|
+
@single.adjacent?(2, Arc[1,2]).should be_true
|
243
|
+
@single.adjacent(1).should == [2]
|
244
|
+
|
245
|
+
@single.adjacent(1, :type=>:edges).should == [Arc[1,2]]
|
246
|
+
@single.adjacent(1, :type=>:edges, :direction=> :out).should == [Arc[1,2]]
|
247
|
+
@single.adjacent(2, :type=>:edges, :direction=> :in).should == [Arc[1,2]]
|
248
|
+
@single.adjacent(2, :type=>:edges, :direction=> :all).sort.should == [Arc[1,2],Arc[2,3]]
|
249
|
+
|
250
|
+
[[{},1], [{:direction => :out},1], [{:direction => :in},2]].each do |h,v|
|
251
|
+
adj = @dups.adjacent(v, h.merge(:type=>:edges))
|
252
|
+
adj.size.should == 2
|
253
|
+
adj.each do |e|
|
254
|
+
e.source == 1; e.target.should == 2
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
adj = @dups.adjacent(2, {:type=>:edges,:direction=>:all})
|
259
|
+
adj.size.should == 4
|
260
|
+
adj.each do |e|
|
261
|
+
((e.source==1 and e.target==2) ||
|
262
|
+
(e.source==2 and e.target==3)).should be_true
|
263
|
+
end
|
264
|
+
|
265
|
+
@single.adjacent(1, :type=>:vertices).should == [2]
|
266
|
+
@single.adjacent(1, :type=>:vertices, :direction=> :out).should == [2]
|
267
|
+
@single.adjacent(2, :type=>:vertices, :direction=> :in).should == [1]
|
268
|
+
@single.adjacent(2, :type=>:vertices, :direction=> :all).should == [1,3]
|
269
|
+
|
270
|
+
@single.adjacent(Arc[2,3], :type=>:vertices).should == [3]
|
271
|
+
@single.adjacent(Arc[2,3], :type=>:vertices, :direction=> :out).should == [3]
|
272
|
+
@single.adjacent(Arc[2,3], :type=>:vertices, :direction=> :in).should == [2]
|
273
|
+
@single.adjacent(Arc[2,3], :type=>:vertices, :direction=> :all).should == [2,3]
|
274
|
+
|
275
|
+
@single.adjacent(Arc[2,3], :type=>:edges).should == [Arc[3,4]]
|
276
|
+
@single.adjacent(Arc[2,3], :type=>:edges, :direction=> :out).should == [Arc[3,4]]
|
277
|
+
@single.adjacent(Arc[2,3], :type=>:edges, :direction=> :in).should == [Arc[1,2]]
|
278
|
+
@single.adjacent(Arc[2,3], :type=>:edges, :direction=> :all).sort.should == [Arc[1,2],Arc[3,4]]
|
279
|
+
|
280
|
+
@dups.adjacent(MultiArc[2,3], :type=>:edges).should == [MultiArc[3,4]]
|
281
|
+
@dups.adjacent(MultiArc[2,3], :type=>:edges, :direction=> :out).should == [MultiArc[3,4]]
|
282
|
+
@dups.adjacent(MultiArc[2,3], :type=>:edges, :direction=> :in).should == [MultiArc[1,2]]*2
|
283
|
+
@dups.adjacent(MultiArc[2,3], :type=>:edges, :direction=> :all).sort.should == ([MultiArc[1,2]]*2+[MultiArc[3,4]])
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
describe "neighborhood" do
|
289
|
+
it do
|
290
|
+
@single.neighborhood(1).sort.should == [2]
|
291
|
+
@single.neighborhood(2).sort.should == [1,3]
|
292
|
+
@single.neighborhood(Arc[2,3]).sort.should == [Arc[1,2], Arc[3,4]]
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
describe "degree" do
|
297
|
+
it do
|
298
|
+
@single.in_degree(1).should == 0
|
299
|
+
@single.in_degree(2).should == 1
|
300
|
+
@single.in_degree(4).should == 1
|
301
|
+
@loops.degree(4).should == 3
|
302
|
+
@loops.in_degree(4).should == 2
|
303
|
+
@single.out_degree(1).should == 1
|
304
|
+
@single.out_degree(2).should == 1
|
305
|
+
@single.out_degree(4).should == 0
|
306
|
+
@loops.out_degree(4).should == 1
|
307
|
+
@single.add_vertex!(6).out_degree(6).should == 0
|
308
|
+
@single.add_vertex!(7).in_degree(7).should == 0
|
309
|
+
@single.add_edge!(4,2).out_degree(4).should == 1
|
310
|
+
@loops.add_edge!(4,2).out_degree(4).should == 2
|
311
|
+
@single.in_degree(2).should == 2
|
312
|
+
|
313
|
+
@single.min_in_degree.should == 0
|
314
|
+
@single.max_in_degree.should == 2
|
315
|
+
@single.min_out_degree.should == 0
|
316
|
+
@single.max_out_degree.should == 1
|
317
|
+
|
318
|
+
@loops.min_in_degree.should == 0
|
319
|
+
@loops.max_in_degree.should == 2
|
320
|
+
@loops.min_out_degree.should == 1
|
321
|
+
@loops.max_out_degree.should == 2
|
322
|
+
@loops.degree(2).should == 4
|
323
|
+
@single.degree(1).should == 1
|
324
|
+
@loops.should_not be_regular
|
325
|
+
@single.should_not be_regular
|
326
|
+
@dups.should_not be_regular
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
describe "include" do
|
331
|
+
it do
|
332
|
+
@single.include?(2).should be_true
|
333
|
+
@single.include?(23).should be_false
|
334
|
+
@single.include?(Arc[1,2]).should be_true
|
335
|
+
@single.include?(Arc[1,4]).should be_false
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
end
|
data/spec/dot_spec.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe "Dot" do # :nodoc:
|
4
|
+
|
5
|
+
DG_DOT = <<-DOT
|
6
|
+
digraph {
|
7
|
+
label = "Datacenters"
|
8
|
+
Miranda [
|
9
|
+
color = green,
|
10
|
+
style = filled,
|
11
|
+
label = "Miranda"
|
12
|
+
]
|
13
|
+
|
14
|
+
Miranda -> Hillview [
|
15
|
+
|
16
|
+
]
|
17
|
+
|
18
|
+
Miranda -> "San Francisco" [
|
19
|
+
|
20
|
+
]
|
21
|
+
|
22
|
+
Miranda -> "San Jose" [
|
23
|
+
|
24
|
+
]
|
25
|
+
|
26
|
+
Sunnyvale -> Miranda [
|
27
|
+
|
28
|
+
]
|
29
|
+
|
30
|
+
}
|
31
|
+
DOT
|
32
|
+
|
33
|
+
before do
|
34
|
+
@dg = DOT::DOTDigraph.new('label' => 'Datacenters')
|
35
|
+
@dg << DOT::DOTNode.new('name' => 'Miranda', 'color' => 'green', 'style' => 'filled')
|
36
|
+
@dg << DOT::DOTDirectedArc.new('from' => 'Miranda', 'to' => 'Hillview')
|
37
|
+
@dg << DOT::DOTDirectedArc.new('from' => 'Miranda', 'to' => '"San Francisco"')
|
38
|
+
@dg << DOT::DOTDirectedArc.new('from' => 'Miranda', 'to' => '"San Jose"')
|
39
|
+
@dg << DOT::DOTDirectedArc.new('from' => 'Sunnyvale', 'to' => 'Miranda')
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "generation" do
|
43
|
+
it do
|
44
|
+
@dg.to_s.should == DG_DOT
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/spec/edge_spec.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Arc do
|
4
|
+
before do
|
5
|
+
@e = Arc.new(1,2,'boo')
|
6
|
+
@u = Edge.new(1,2,'hoo')
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#edge_new" do
|
10
|
+
it do
|
11
|
+
proc { Arc.new }.should raise_error(ArgumentError)
|
12
|
+
proc { Arc.new(1) }.should raise_error(ArgumentError)
|
13
|
+
Arc.new(1,2).should be_a_kind_of(Arc)
|
14
|
+
Arc.new(1,2,'label').should be_a_kind_of(Arc)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#edge_getters" do
|
19
|
+
it do
|
20
|
+
@e.source.should == 1
|
21
|
+
@e.target.should == 2
|
22
|
+
@e.label.should == 'boo'
|
23
|
+
|
24
|
+
@e[0].should == 1
|
25
|
+
@e[1].should == 2
|
26
|
+
@e[2].should == 'boo'
|
27
|
+
|
28
|
+
@e[-3].should == 1
|
29
|
+
@e[-2].should == 2
|
30
|
+
@e[-1].should == 'boo'
|
31
|
+
|
32
|
+
proc { @e[-4] }.should raise_error(IndexError)
|
33
|
+
proc { @e[3] }.should raise_error(IndexError)
|
34
|
+
|
35
|
+
@e['source'].should == 1
|
36
|
+
@e['target'].should == 2
|
37
|
+
@e['label'].should == 'boo'
|
38
|
+
|
39
|
+
@e[:source].should == 1
|
40
|
+
@e[:target].should == 2
|
41
|
+
@e[:label].should == 'boo'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#edge_setters" do
|
46
|
+
it do
|
47
|
+
@e.source = 23
|
48
|
+
@e.target = 42
|
49
|
+
@e.label = 'Yabba'
|
50
|
+
@e.source.should == 23
|
51
|
+
@e.target.should == 42
|
52
|
+
@e.label.should == 'Yabba'
|
53
|
+
|
54
|
+
@e['source'] = 2
|
55
|
+
@e['target'] = 1
|
56
|
+
@e['label'] = 'Dabba'
|
57
|
+
@e.source.should == 2
|
58
|
+
@e.target.should == 1
|
59
|
+
@e.label.should == 'Dabba'
|
60
|
+
|
61
|
+
@e[:source] = 9
|
62
|
+
@e[:target] = 8
|
63
|
+
@e['label'] = 'Doooo!'
|
64
|
+
@e.source.should == 9
|
65
|
+
@e.target.should == 8
|
66
|
+
@e.label.should == 'Doooo!'
|
67
|
+
|
68
|
+
@e[0] = 'Fred'
|
69
|
+
@e[1] = 'Flintstone'
|
70
|
+
@e[2] = 'and'
|
71
|
+
@e.source.should == 'Fred'
|
72
|
+
@e.target.should == 'Flintstone'
|
73
|
+
@e.label.should == 'and'
|
74
|
+
|
75
|
+
@e[-3] = 'Barney'
|
76
|
+
@e[-2] = 'Rubble'
|
77
|
+
@e[-1] = nil
|
78
|
+
@e.source.should == 'Barney'
|
79
|
+
@e.target.should == 'Rubble'
|
80
|
+
@e.label.should == nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#edge_simple_methods" do
|
85
|
+
it do
|
86
|
+
@e.to_a.should == [1,2,'boo']
|
87
|
+
@e.to_s.should == "(1-2 'boo')"
|
88
|
+
@e.label = nil
|
89
|
+
@e.to_s.should == "(1-2)"
|
90
|
+
@e.eql?(Arc.new(1,2)).should be_true
|
91
|
+
@e.eql?(Arc.new(1,3)).should be_false
|
92
|
+
Arc.new(2,1).eql?(@e).should be_false
|
93
|
+
|
94
|
+
@e.should == Arc.new(1,2)
|
95
|
+
@e.reverse.should == Arc.new(2,1)
|
96
|
+
Arc.new(1,2).should_not == Arc.new(1,3)
|
97
|
+
Arc.new(2,1).should_not == @e
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#edge_sort" do
|
102
|
+
it do
|
103
|
+
x = [ Arc.new(2,3), Arc.new(1,3), Arc.new(1,2), Arc.new(2,1) ].sort
|
104
|
+
x.should == [Arc.new(1,2), Arc.new(1,3), Arc.new(2,1), Arc.new(2,3)]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#undirected_edge_new" do
|
109
|
+
it do
|
110
|
+
proc { Edge.new }.should raise_error(ArgumentError)
|
111
|
+
proc { Edge.new(1) }.should raise_error(ArgumentError)
|
112
|
+
Edge.new(1,2).should be_a_kind_of(Edge)
|
113
|
+
Edge.new(1,2,'label').should be_a_kind_of(Edge)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#undirected_edge_getters" do
|
118
|
+
it do
|
119
|
+
@u.source.should == 1
|
120
|
+
@u.target.should == 2
|
121
|
+
@u.to_a.should == [1,2,'hoo']
|
122
|
+
@u.to_s.should == "(1=2 'hoo')"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "#undirected_edge_methods" do
|
127
|
+
it do
|
128
|
+
@u.label = nil
|
129
|
+
@u.to_s.should == "(1=2)"
|
130
|
+
Edge.new(2,1).to_s.should == "(1=2)"
|
131
|
+
|
132
|
+
@u.should == Edge.new(2,1)
|
133
|
+
@u.should == Edge.new(2,1,'boo')
|
134
|
+
@u.should_not == Edge.new(2,3)
|
135
|
+
|
136
|
+
Edge.new(2,1).hash.should == @u.hash
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "#undirected_edge_sort" do
|
141
|
+
it do
|
142
|
+
x = [Edge.new(12, 1), Edge.new(2,11)].sort
|
143
|
+
x.should == [Edge.new(2,11), Edge.new(1,12)]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "#hash" do
|
148
|
+
it do
|
149
|
+
Arc[1,2,:c].should == Arc[1,2,:b]
|
150
|
+
Arc[1,2,:c].hash.should == Arc[1,2,:b].hash
|
151
|
+
Arc[1,2].should_not == Arc[2,1]
|
152
|
+
Arc[1,2].should_not == Edge[1,2]
|
153
|
+
Edge[1,2].should == Edge[2,1]
|
154
|
+
Edge[1,2,:a].should == Edge[2,1,:b]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|