rgl 0.6.2 → 0.6.4

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/lib/rgl/rdot.rb CHANGED
@@ -7,131 +7,185 @@ module RGL
7
7
  # It also supports undirected edges.
8
8
  module DOT
9
9
 
10
- # options for node declaration
10
+ # attributes due to
11
+ # https://www.graphviz.org/pdf/dotguide.pdf
12
+ # January 5, 2015
11
13
 
14
+ # options for node declaration
12
15
  NODE_OPTS = [
13
- # attributes due to
14
- # https://www.graphviz.org/Documentation/dotguide.pdf
15
- # February 23, 2008
16
- 'color', # default: black; node shape color
17
- 'comment', # any string (format-dependent)
18
- 'distortion', # default: 0.0; node distortion for shape=polygon
19
- 'fillcolor', # default: lightgrey/black; node fill color
20
- 'fixedsize', # default: false; label text has no affect on node size
21
- 'fontcolor', # default: black; type face color
22
- 'fontname', # default: Times-Roman; font family
23
- 'fontsize', #default: 14; point size of label
24
- 'group', # name of node's group
25
- 'height', # default: .5; height in inches
26
- 'label', # default: node name; any string
27
- 'layer', # default: overlay range; all, id or id:id
28
- 'orientation', # dafault: 0.0; node rotation angle
29
- 'peripheries', # shape-dependent number of node boundaries
30
- 'regular', # default: false; force polygon to be regular
31
- 'shape', # default: ellipse; node shape; see Section 2.1 and Appendix E
32
- 'shapefile', # external EPSF or SVG custom shape file
33
- 'sides', # default: 4; number of sides for shape=polygon
34
- 'skew' , # default: 0.0; skewing of node for shape=polygon
35
- 'style', # graphics options, e.g. bold, dotted, filled; cf. Section 2.3
36
- 'URL', # URL associated with node (format-dependent)
37
- 'width', # default: .75; width in inches
38
- 'z', #default: 0.0; z coordinate for VRML output
39
-
40
- # maintained for backward compatibility or rdot internal
41
- 'bottomlabel', # auxiliary label for nodes of shape M*
42
- 'bgcolor',
43
- 'rank',
44
- 'toplabel' # auxiliary label for nodes of shape M*
45
- ]
16
+ 'color', # default: black; node shape color
17
+ 'colorscheme', # default: X11; scheme for interpreting color names
18
+ 'comment', # any string (format-dependent)
19
+ 'distortion', # default: 0.0; node distortion for shape=polygon
20
+ 'fillcolor', # default: lightgrey/black; node fill color
21
+ 'fixedsize', # default: false; label text has no affect on node size
22
+ 'fontcolor', # default: black; type face color
23
+ 'fontname', # default: Times-Roman; font family
24
+ 'fontsize', # default: 14; point size of label
25
+ 'group', # name of node's group
26
+ 'height', # default: .5; height in inches
27
+ 'id', # any string (user-defined output object tags)
28
+ 'label', # default: node name; any string
29
+ 'labelloc', # default: c; node label vertical alignment
30
+ 'layer', # default: overlay range; all, id or id:id
31
+ 'margin', # default: 0.11,0.55; space around label
32
+ 'nojustify', # default: false; if true, justify to label, not node
33
+ 'orientation', # default: 0.0; node rotation angle
34
+ 'penwidth', # default: 1.0; width of pen for drawing boundaries, in points
35
+ 'peripheries', # shape-dependent number of node boundaries
36
+ 'regular', # default: false; force polygon to be regular
37
+ 'samplepoints', # default 8 or 20; number vertices to convert circle or ellipse
38
+ 'shape', # default: ellipse; node shape; see Section 2.1 and Appendix E
39
+ 'shapefile', # external EPSF or SVG custom shape file
40
+ 'sides', # default: 4; number of sides for shape=polygon
41
+ 'skew', # default: 0.0; skewing of node for shape=polygon
42
+ 'style', # graphics options, e.g. bold, dotted, filled; cf. Section 2.3
43
+ 'target', # if URL is set, determines browser window for URL
44
+ 'tooltip', # default: label, tooltip annotation for node
45
+ 'URL', # URL associated with node (format-dependent)
46
+ 'width', # default: .75; width in inches
47
+ ].freeze
48
+
49
+ # maintained for backward compatibility or rdot internal
50
+ NODE_OPTS_LGCY = [
51
+ 'bottomlabel', # auxiliary label for nodes of shape M*
52
+ 'bgcolor',
53
+ 'rank',
54
+ 'toplabel' # auxiliary label for nodes of shape M*
55
+ ].freeze
46
56
 
47
57
  # options for edge declaration
48
-
49
58
  EDGE_OPTS = [
50
- 'arrowhead', # default: normal; style of arrowhead at head end
51
- 'arrowsize', # default: 1.0; scaling factor for arrowheads
52
- 'arrowtail', # default: normal; style of arrowhead at tail end
53
- 'color', # default: black; edge stroke color
54
- 'comment', # any string (format-dependent)
55
- 'constraint', # default: true use edge to affect node ranking
56
- 'decorate', # if set, draws a line connecting labels with their edges
57
- 'dir', # default: forward; forward, back, both, or none
58
- 'fontcolor', # default: black type face color
59
- 'fontname', # default: Times-Roman; font family
60
- 'fontsize', # default: 14; point size of label
61
- 'headlabel', # label placed near head of edge
62
- 'headport', # n,ne,e,se,s,sw,w,nw
63
- 'headURL', # URL attached to head label if output format is ismap
64
- 'label', # edge label
65
- 'labelangle', # default: -25.0; angle in degrees which head or tail label is rotated off edge
66
- 'labeldistance', # default: 1.0; scaling factor for distance of head or tail label from node
67
- 'labelfloat', # default: false; lessen constraints on edge label placement
68
- 'labelfontcolor', # default: black; type face color for head and tail labels
69
- 'labelfontname', # default: Times-Roman; font family for head and tail labels
70
- 'labelfontsize', # default: 14 point size for head and tail labels
71
- 'layer', # default: overlay range; all, id or id:id
72
- 'lhead', # name of cluster to use as head of edge
73
- 'ltail', # name of cluster to use as tail of edge
74
- 'minlen', # default: 1 minimum rank distance between head and tail
75
- 'samehead', # tag for head node; edge heads with the same tag are merged onto the same port
76
- 'sametail', # tag for tail node; edge tails with the same tag are merged onto the same port
77
- 'style', # graphics options, e.g. bold, dotted, filled; cf. Section 2.3
78
- 'taillabel', # label placed near tail of edge
79
- 'tailport', # n,ne,e,se,s,sw,w,nw
80
- 'tailURL', # URL attached to tail label if output format is ismap
81
- 'weight', # default: 1; integer cost of stretching an edge
82
-
83
- # maintained for backward compatibility or rdot internal
84
- 'id'
85
- ]
59
+ 'arrowhead', # default: normal; style of arrowhead at head end
60
+ 'arrowsize', # default: 1.0; scaling factor for arrowheads
61
+ 'arrowtail', # default: normal; style of arrowhead at tail end
62
+ 'color', # default: black; edge stroke color
63
+ 'colorscheme', # default: X11; scheme for interpreting color names
64
+ 'comment', # any string (format-dependent)
65
+ 'constraint', # default: true use edge to affect node ranking
66
+ 'decorate', # if set, draws a line connecting labels with their edges
67
+ 'dir', # default: forward; forward, back, both, or none
68
+ 'edgeURL', # URL attached to non-label part of edge
69
+ 'edgehref', # synonym for edgeURL
70
+ 'edgetarget', # if URL is set, determines browser window for URL
71
+ 'edgetooltip', # default: label; tooltip annotation for non-label part of edge
72
+ 'fontcolor', # default: black type face color
73
+ 'fontname', # default: Times-Roman; font family
74
+ 'fontsize', # default: 14; point size of label
75
+ 'headclip', # default: true; if false, edge is not clipped to head node boundary
76
+ 'headhref', # synonym for headURL
77
+ 'headlabel', # default: label; placed near head of edge
78
+ 'headport', # n,ne,e,se,s,sw,w,nw
79
+ 'headtarget', # if headURL is set, determines browser window for URL
80
+ 'headtooltip', # default: label; tooltip annotation near head of edge
81
+ 'headURL', # URL attached to head label if output format is ismap
82
+ 'href', # alias for URL
83
+ 'id', # any string (user-defined output object tags)
84
+ 'label', # edge label
85
+ 'labelangle', # default: -25.0; angle in degrees which head or tail label is rotated off edge
86
+ 'labeldistance', # default: 1.0; scaling factor for distance of head or tail label from node
87
+ 'labelfloat', # default: false; lessen constraints on edge label placement
88
+ 'labelfontcolor', # default: black; type face color for head and tail labels
89
+ 'labelfontname', # default: Times-Roman; font family for head and tail labels
90
+ 'labelfontsize', # default: 14 point size for head and tail labels
91
+ 'labelhref', # synonym for labelURL
92
+ 'labelURL', # URL for label, overrides edge URL
93
+ 'labeltarget', # if URL or labelURL is set, determines browser window for URL
94
+ 'labeltooltip', # default: label; tooltip annotation near label
95
+ 'layer', # default: overlay range; all, id or id:id
96
+ 'lhead', # name of cluster to use as head of edge
97
+ 'ltail', # name of cluster to use as tail of edge
98
+ 'minlen', # default: 1 minimum rank distance between head and tail
99
+ 'penwidth', # default: 1.0; width of pen for drawing boundaries, in points
100
+ 'samehead', # tag for head node; edge heads with the same tag are merged onto the same port
101
+ 'sametail', # tag for tail node; edge tails with the same tag are merged onto the same port
102
+ 'style', # graphics options, e.g. bold, dotted, filled; cf. Section 2.3
103
+ 'weight', # default: 1; integer cost of stretching an edge
104
+ 'tailclip', # default: true; if false, edge is not clipped to tail node boundary
105
+ 'tailhref', # synonym for tailURL
106
+ 'taillabel', # label placed near tail of edge
107
+ 'tailport', # n,ne,e,se,s,sw,w,nw
108
+ 'tailtarget', # if tailURL is set, determines browser window for URL
109
+ 'tailtooltip', # default: label; tooltip annotation near tail of edge
110
+ 'tailURL', # URL attached to tail label if output format is ismap
111
+ 'target', # if URL is set, determines browser window for URL
112
+ 'tooltip' # default: label; tooltip annotation for edge
113
+ ].freeze
114
+
115
+ # maintained for backward compatibility or rdot internal
116
+ EDGE_OPTS_LGCY = [].freeze
86
117
 
87
118
  # options for graph declaration
88
-
89
119
  GRAPH_OPTS = [
90
- 'bgcolor', # background color for drawing, plus initial fill color
91
- 'center', # default: false; center draing on page
92
- 'clusterrank', # default: local; may be "global" or "none"
93
- 'color', # default: black; for clusters, outline color, and fill color if
94
- # fillcolor not defined
95
- 'comment', # any string (format-dependent)
96
- 'compound', # default: false; allow edges between clusters
97
- 'concentrate', # default: false; enables edge concentrators
98
- 'fillcolor', # default: black; cluster fill color
99
- 'fontcolor', # default: black; type face color
100
- 'fontname', # default: Times-Roman; font family
101
- 'fontpath', # list of directories to search for fonts
102
- 'fontsize', # default: 14; point size of label
103
- 'label', # any string
104
- 'labeljust', # default: centered; "l" and "r" for left- and right-justified
105
- # cluster labels, respectively
106
- 'labelloc', # default: top; "t" and "b" for top- and bottom-justified
107
- # cluster labels, respectively
108
- 'layers', # id:id:id...
109
- 'margin', # default: .5; margin included in page, inches
110
- 'mclimit', # default: 1.0; scale factor for mincross iterations
111
- 'nodesep', # default: .25; separation between nodes, in inches.
112
- 'nslimit', # if set to "f", bounds network simplex iterations by
113
- # (f)(number of nodes) when setting x-coordinates
114
- 'nslimit1', # if set to "f", bounds network simplex iterations by
115
- # (f)(number of nodes) when ranking nodes
116
- 'ordering', # if "out" out edge order is preserved
117
- 'orientation', # default: portrait; if "rotate" is not used and the value is
118
- # "landscape", use landscape orientation
119
- 'page', # unit of pagination, e.g. "8.5,11"
120
- 'rank', # "same", "min", "max", "source", or "sink"
121
- 'rankdir', # default: TB; "LR" (left to right) or "TB" (top to bottom)
122
- 'ranksep', # default: .75; separation between ranks, in inches.
123
- 'ratio', # approximate aspect ratio desired, "fill" or "auto"
124
- 'samplepoints', # default: 8; number of points used to represent ellipses
125
- # and circles on output
126
- 'searchsize', # default: 30; maximum edges with negative cut values to check
127
- # when looking for a minimum one during network simplex
128
- 'size', # maximum drawing size, in inches
129
- 'style', # graphics options, e.g. "filled" for clusters
130
- 'URL', # URL associated with graph (format-dependent)
131
-
132
- # maintained for backward compatibility or rdot internal
133
- 'layerseq'
134
- ]
120
+ 'aspect', # controls aspect ratio adjustment
121
+ 'bgcolor', # background color for drawing, plus initial fill color
122
+ 'center', # default: false; center draing on page
123
+ 'clusterrank', # default: local; may be "global" or "none"
124
+ 'color', # default: black; for clusters, outline color, and fill color if
125
+ # fillcolor not defined
126
+ 'colorscheme', # default: X11; scheme for interpreting color names
127
+ 'comment', # any string (format-dependent)
128
+ 'compound', # default: false; allow edges between clusters
129
+ 'concentrate', # default: false; enables edge concentrators
130
+ 'dpi', # default: 96; dots per inch for image output
131
+ 'fillcolor', # default: black; cluster fill color
132
+ 'fontcolor', # default: black; type face color
133
+ 'fontname', # default: Times-Roman; font family
134
+ 'fontnames', # svg, ps, gd (SVG only)
135
+ 'fontpath', # list of directories to search for fonts
136
+ 'fontsize', # default: 14; point size of label
137
+ 'id', # any string (user-defined output object tags)
138
+ 'label', # any string
139
+ 'labeljust', # default: centered; "l" and "r" for left- and right-justified
140
+ # cluster labels, respectively
141
+ 'labelloc', # default: top; "t" and "b" for top- and bottom-justified
142
+ # cluster labels, respectively
143
+ 'landscape', # if true, means orientation=landscape
144
+ 'layers', # id:id:id...
145
+ 'layersep', # default: : ; specifies separator character to split layers'
146
+ 'margin', # default: .5; margin included in page, inches
147
+ 'mclimit', # default: 1.0; scale factor for mincross iterations
148
+ 'nodesep', # default: .25; separation between nodes, in inches.
149
+ 'nojustify', # default: false; if true, justify to label, not graph
150
+ 'nslimit', # if set to "f", bounds network simplex iterations by
151
+ # (f)(number of nodes) when setting x-coordinates
152
+ 'nslimit1', # if set to "f", bounds network simplex iterations by
153
+ # (f)(number of nodes) when ranking nodes
154
+ 'ordering', # if "out" out edge order is preserved
155
+ 'orientation', # default: portrait; if "rotate" is not used and the value is
156
+ # "landscape", use landscape orientation
157
+ 'outputorder', # default: breadthfirst; or nodesfirst, edgesfirst
158
+ 'page', # unit of pagination, e.g. "8.5,11"
159
+ 'pagedir', # default: BL; traversal order of pages
160
+ 'pencolor', # default: black; color for drawing cluster boundaries
161
+ 'penwidth', # default: 1.0; width of pen for drawing boundaries, in points
162
+ 'peripheries', # default: 1; shape-dependent number of node boundaries
163
+ 'rank', # "same", "min", "max", "source", or "sink"
164
+ 'rankdir', # default: TB; "LR" (left to right) or "TB" (top to bottom)
165
+ 'ranksep', # default: .75; separation between ranks, in inches.
166
+ 'ratio', # approximate aspect ratio desired, "fill" or "auto"
167
+ 'remincross', # default: true; whether to run edge crossing minimization
168
+ # a second time when there are multiple clusters
169
+ 'rotate', # If 90, set orientation to landscape
170
+ 'samplepoints', # default: 8; number of points used to represent ellipses
171
+ # and circles on output
172
+ 'searchsize', # default: 30; maximum edges with negative cut values to check
173
+ # when looking for a minimum one during network simplex
174
+ 'size', # maximum drawing size, in inches
175
+ 'splines', # draw edges as splines, polylines, lines
176
+ 'style', # graphics options, e.g. "filled" for clusters
177
+ 'stylesheet', # pathname or URL to XML style sheet for SVG
178
+ 'target', # if URL is set, determines browser window for URL
179
+ 'tooltip', # default: label; tooltip annotation for cluster
180
+ 'truecolor', # if set, force 24 bit or indexed color in image output
181
+ 'viewport', # clipping window on output
182
+ 'URL', # URL associated with graph (format-dependent)
183
+ ].freeze
184
+
185
+ # maintained for backward compatibility or rdot internal
186
+ GRAPH_OPTS_LGCY = [
187
+ 'layerseq'
188
+ ].freeze
135
189
 
136
190
  # Ancestor of Edge, Node, and Graph.
137
191
  #
@@ -179,16 +233,15 @@ module RGL
179
233
  # Return a quoted version of the label otherwise.
180
234
  '"' + label.split(/(\\n|\\r|\\l)/).collect do |part|
181
235
  case part
182
- when "\\n", "\\r", "\\l"
183
- part
184
- else
185
- part.gsub('\\', '\\\\\\\\').gsub('"', '\\\\"').gsub("\n", '\\n')
236
+ when "\\n", "\\r", "\\l"
237
+ part
238
+ else
239
+ part.gsub('\\', '\\\\\\\\').gsub('"', '\\\\"').gsub("\n", '\\n')
186
240
  end
187
241
  end.join + '"'
188
242
  end
189
243
  end
190
244
 
191
-
192
245
  # Ports are used when a Node instance has its `shape' option set to
193
246
  # _record_ or _Mrecord_. Ports can be nested.
194
247
  #
@@ -244,7 +297,7 @@ module RGL
244
297
  # option which, if specified, must be an Enumerable containing a list of
245
298
  # ports.
246
299
  #
247
- def initialize(params = {}, option_list = NODE_OPTS)
300
+ def initialize(params = {}, option_list = NODE_OPTS+NODE_OPTS_LGCY)
248
301
  super(params, option_list)
249
302
  @ports = params['ports'] ? params['ports'] : []
250
303
  end
@@ -287,11 +340,10 @@ module RGL
287
340
  leader + quote_ID(@name) unless @name.nil?
288
341
  else
289
342
  leader + (@name.nil? ? '' : quote_ID(@name) + " ") + "[\n" +
290
- stringified_options + "\n" +
291
- leader + "]"
343
+ stringified_options + "\n" +
344
+ leader + "]"
292
345
  end
293
346
  end
294
-
295
347
  end # class Node
296
348
 
297
349
  # A graph representation. Whether or not it is rendered as directed or
@@ -306,7 +358,7 @@ module RGL
306
358
  # option which, if specified, must be an Enumerable containing a list of
307
359
  # nodes, edges, and/or subgraphs.
308
360
  #
309
- def initialize(params = {}, option_list = GRAPH_OPTS)
361
+ def initialize(params = {}, option_list = GRAPH_OPTS+GRAPH_OPTS_LGCY)
310
362
  super(params, option_list)
311
363
  @elements = params['elements'] ? params['elements'] : []
312
364
  @dot_string = 'graph'
@@ -368,9 +420,8 @@ module RGL
368
420
  end.join("\n\n")
369
421
 
370
422
  hdr + (options.empty? ? '' : options + "\n\n") +
371
- (elements.empty? ? '' : elements + "\n") + leader + "}"
423
+ (elements.empty? ? '' : elements + "\n") + leader + "}"
372
424
  end
373
-
374
425
  end # class Graph
375
426
 
376
427
  # A digraph is a directed graph representation which is the same as a Graph
@@ -385,7 +436,7 @@ module RGL
385
436
  # option which, if specified, must be an Enumerable containing a list of
386
437
  # nodes, edges, and/or subgraphs.
387
438
  #
388
- def initialize(params = {}, option_list = GRAPH_OPTS)
439
+ def initialize(params = {}, option_list = GRAPH_OPTS+GRAPH_OPTS_LGCY)
389
440
  super(params, option_list)
390
441
  @dot_string = 'digraph'
391
442
  end
@@ -404,7 +455,7 @@ module RGL
404
455
  # option which, if specified, must be an Enumerable containing a list of
405
456
  # nodes, edges, and/or subgraphs.
406
457
  #
407
- def initialize(params = {}, option_list = GRAPH_OPTS)
458
+ def initialize(params = {}, option_list = GRAPH_OPTS+GRAPH_OPTS_LGCY)
408
459
  super(params, option_list)
409
460
  @dot_string = 'subgraph'
410
461
  end
@@ -427,7 +478,7 @@ module RGL
427
478
  # edge options. The _option_list_ parameter restricts those options to the
428
479
  # list of valid names it contains.
429
480
  #
430
- def initialize(params = {}, option_list = EDGE_OPTS)
481
+ def initialize(params = {}, option_list = EDGE_OPTS+EDGE_OPTS_LGCY)
431
482
  super(params, option_list)
432
483
  @from = params['from'] ? params['from'] : nil
433
484
  @to = params['to'] ? params['to'] : nil
@@ -452,8 +503,8 @@ module RGL
452
503
  leader + quote_ID(f_s) + ' ' + edge_link + ' ' + quote_ID(t_s)
453
504
  else
454
505
  leader + quote_ID(f_s) + ' ' + edge_link + ' ' + quote_ID(t_s) + " [\n" +
455
- stringified_options + "\n" +
456
- leader + "]"
506
+ stringified_options + "\n" +
507
+ leader + "]"
457
508
  end
458
509
  end
459
510
 
data/lib/rgl/traversal.rb CHANGED
@@ -117,7 +117,9 @@ module RGL
117
117
  #
118
118
  # @return [DirectedAdjacencyGraph] which represents a BFS search tree starting at _v_.
119
119
  def bfs_search_tree_from(v)
120
- require 'rgl/adjacency'
120
+ unless defined?(DirectedAdjacencyGraph)
121
+ require 'rgl/adjacency'
122
+ end
121
123
  bfs = bfs_iterator(v)
122
124
  tree = DirectedAdjacencyGraph.new
123
125
 
@@ -0,0 +1,3 @@
1
+ module RGL
2
+ VERSION = "0.6.4".freeze
3
+ end
data/test/dot_test.rb CHANGED
@@ -13,7 +13,7 @@ class TestDot < Test::Unit::TestCase
13
13
  graph = RGL::DirectedAdjacencyGraph["a", "b"]
14
14
 
15
15
  begin
16
- dot = graph.to_dot_graph.to_s
16
+ dot = graph.to_dot_graph.to_s
17
17
 
18
18
  first_vertex_id = "a"
19
19
  second_vertex_id = "b"
@@ -29,31 +29,29 @@ class TestDot < Test::Unit::TestCase
29
29
  end
30
30
  end
31
31
 
32
- def test_to_dot_digraph_with_options
33
- graph = RGL::DirectedAdjacencyGraph["a", "b"]
32
+ def test_dot_digraph_with_complicated_options
33
+ graph = RGL::DirectedAdjacencyGraph['a','b', 'c','d', 'a','c']
34
34
 
35
- begin
36
- edge_labels = {}
37
- graph.each_edge do |b, e|
38
- key = "#{b}-#{e}"
39
- edge_labels[key] = "#{b} to #{e}"
40
- end
41
-
42
- vertex_fontcolors = {'a' => 'green', 'b' => 'blue'}
43
- vertex_fontcolor_setting = Proc.new{|v| vertex_fontcolors[v]}
44
- vertex_settings = {'fontcolor' => vertex_fontcolor_setting, 'fontsize' => 12}
45
-
46
- edge_label_setting = Proc.new{|b, e| edge_labels["#{b}-#{e}"]}
47
- edge_settings = {'color' => 'red', 'label' => edge_label_setting}
48
- dot_options = {'edge' => edge_settings,'vertex' => vertex_settings}
49
- dot = graph.to_dot_graph(dot_options).to_s
35
+ graph.set_vertex_options('a', label: 'This is A', shape: 'box3d', fontcolor: 'green', fontsize: 16)
36
+ graph.set_vertex_options('b', label: 'This is B', shape: 'tab', fontcolor: 'red', fontsize: 14)
37
+ graph.set_vertex_options('c', shape: 'tab', fontcolor: 'blue')
50
38
 
51
- assert_match(dot, /a \[\n\s*fontcolor = green,\n\s*fontsize = 12,\n\s*label = a\n\s*/)
52
- assert_match(dot, /b \[\n\s*fontcolor = blue,\n\s*fontsize = 12,\n\s*label = b\n\s*/)
53
- assert_match(dot, /a -> b \[\n\s*color = red,\n\s*fontsize = 8,\n\s*label = \"a to b\"\n/)
54
- rescue
55
- puts "Graphviz not installed?"
56
- end
39
+ graph.set_edge_options('a', 'b', label: 'NotCapitalEdge', style: 'dotted', dir: 'back', color: 'magenta')
40
+ graph.set_edge_options('a', 'c', weight: 5, color: 'blue')
41
+
42
+ graph_options = {
43
+ "rankdir" => "LR",
44
+ "labelloc" => "t",
45
+ "label" => "Graph\n (generated #{Time.now.utc})"
46
+ }
47
+
48
+ dot = graph.to_dot_graph(graph_options).to_s
49
+
50
+ assert_match(dot, /labelloc = t\n\s*/)
51
+ assert_match(dot, /rankdir = LR\n\s*/)
52
+ assert_match(dot, /a \[\n\s*fontcolor = green,\n\s*fontsize = 16,\n\s*shape = box3d,\n\s*label = "This is A"\n\s*/)
53
+ assert_match(dot, /b \[\n\s*fontcolor = red,\n\s*fontsize = 14,\n\s*shape = tab,\n\s*label = "This is B"\n\s*/)
54
+ assert_match(dot, /a -> b \[\n\s*color = magenta,\n\s*dir = back,\n\s*fontsize = 8,\n\s*label = NotCapitalEdge,\n\s*style = dotted\n\s*/)
57
55
  end
58
56
 
59
57
  def test_to_dot_graph
@@ -65,10 +63,6 @@ class TestDot < Test::Unit::TestCase
65
63
  def graph.vertex_id(v)
66
64
  "id-"+v.to_s
67
65
  end
68
- begin
69
- graph.write_to_graphic_file
70
- rescue
71
- puts "Graphviz not installed?"
72
- end
66
+ graph.write_to_graphic_file
73
67
  end
74
68
  end
@@ -0,0 +1,29 @@
1
+ require 'test/unit'
2
+
3
+ # Do not require rgl/adjacency !
4
+ require 'rgl/traversal'
5
+ require 'rgl/implicit'
6
+
7
+ include RGL
8
+
9
+ # Cyclic graph with _n_ vertices. Need a concrete graph, that is not an AdjacencyGraph
10
+ def cycle(n)
11
+ RGL::ImplicitGraph.new { |g|
12
+ g.vertex_iterator { |b| 0.upto(n - 1, &b) }
13
+ g.adjacent_iterator { |x, b| b.call((x + 1) % n) }
14
+ g.directed = true
15
+ }
16
+ end
17
+
18
+ class TestAdjacencyNotRequired < Test::Unit::TestCase
19
+
20
+ def setup
21
+ @dg = cycle(4)
22
+ end
23
+
24
+ def test_bfs_search_tree
25
+ # bfs_search_tree_from requires rgl/adjacency if not yet loaded.
26
+ assert_equal("(1-2)(2-3)(3-0)", @dg.bfs_search_tree_from(1).edges.sort.join)
27
+ end
28
+
29
+ end