gviz 0.0.1
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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +113 -0
- data/Rakefile +1 -0
- data/examples/arrow.dot +88 -0
- data/examples/arrows.rb +59 -0
- data/examples/color.dot +1302 -0
- data/examples/colors.rb +673 -0
- data/examples/examples.rb +71 -0
- data/examples/sample1.png +0 -0
- data/examples/sample2.png +0 -0
- data/examples/sample3.png +0 -0
- data/examples/scraper.rb +59 -0
- data/examples/shape.dot +108 -0
- data/examples/shapes.rb +79 -0
- data/gviz.gemspec +19 -0
- data/lib/gviz.rb +211 -0
- data/lib/gviz/version.rb +3 -0
- data/spec/gviz_spec.rb +395 -0
- data/spec/spec_helper.rb +9 -0
- metadata +69 -0
data/lib/gviz/version.rb
ADDED
data/spec/gviz_spec.rb
ADDED
@@ -0,0 +1,395 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
|
+
|
4
|
+
describe Gviz do
|
5
|
+
before(:each) do
|
6
|
+
@g = Gviz.new
|
7
|
+
end
|
8
|
+
|
9
|
+
context "node" do
|
10
|
+
it "add a node" do
|
11
|
+
node = @g.node(:a)
|
12
|
+
node.should be_a_instance_of Gviz::Node
|
13
|
+
node.id.should eql :a
|
14
|
+
node.attrs.should be_empty
|
15
|
+
@g.nodeset.map(&:id).should eql [:a]
|
16
|
+
end
|
17
|
+
|
18
|
+
it "add nodes" do
|
19
|
+
@g.node(:a)
|
20
|
+
@g.node(:b)
|
21
|
+
@g.nodeset.map(&:id).should eql [:a, :b]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "add a node with attrs" do
|
25
|
+
node = @g.node(:a, color:'blue', label:'hello')
|
26
|
+
node.should be_a_instance_of Gviz::Node
|
27
|
+
node.id.should eql :a
|
28
|
+
node.attrs.should == { color:'blue', label:'hello' }
|
29
|
+
@g.nodeset.map(&:attrs).should eql [node.attrs]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "update node attrs" do
|
33
|
+
@g.node(:a, color:'red', label:'hello')
|
34
|
+
@g.node(:a, color:'blue', shape:'box')
|
35
|
+
@g.nodeset.first.attrs.should == { color:'blue', label:'hello', shape:'box' }
|
36
|
+
end
|
37
|
+
|
38
|
+
it "raise an error with a string" do
|
39
|
+
->{ @g.node('a') }.should raise_error(ArgumentError)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raise an error with a symbol which include underscores" do
|
43
|
+
->{ @g.node(:a_b) }.should raise_error(ArgumentError)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "edge" do
|
48
|
+
it "add a edge" do
|
49
|
+
edge = @g.edge(:a_b)
|
50
|
+
edge.should be_a_instance_of Gviz::Edge
|
51
|
+
edge.st.should eql :a
|
52
|
+
edge.ed.should eql :b
|
53
|
+
edge.attrs.should be_empty
|
54
|
+
@g.edgeset.map(&:to_s).should eql ["a -> b"]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "add a edge with attrs" do
|
58
|
+
edge = @g.edge(:a_b, color:'red', arrowhead:'none')
|
59
|
+
edge.should be_a_instance_of Gviz::Edge
|
60
|
+
edge.st.should eql :a
|
61
|
+
edge.ed.should eql :b
|
62
|
+
edge.attrs.should == { color:'red', arrowhead:'none' }
|
63
|
+
@g.edgeset.map(&:to_s).should eql ["a -> b"]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "update edge attrs" do
|
67
|
+
@g.edge(:a_b, color:'blue', style:'bold')
|
68
|
+
@g.edge(:a_b, color:'red')
|
69
|
+
@g.edgeset.map(&:to_s).should eql ["a -> b"]
|
70
|
+
@g.edgeset.first.attrs.should == { color:'red', style:'bold' }
|
71
|
+
end
|
72
|
+
|
73
|
+
it "add different edges, but same name" do
|
74
|
+
edge1 = @g.edge(:a_b)
|
75
|
+
edge2 = @g.edge(:a_b_1)
|
76
|
+
edge1.seq.should eql 0
|
77
|
+
edge2.seq.should eql 1
|
78
|
+
@g.edgeset.map(&:to_s).should eql ["a -> b", "a -> b"]
|
79
|
+
end
|
80
|
+
|
81
|
+
it "can accept a string id" do
|
82
|
+
@g.edge('a_b')
|
83
|
+
@g.edgeset.first.to_s.should eql "a -> b"
|
84
|
+
end
|
85
|
+
|
86
|
+
it "can take ports with a string id" do
|
87
|
+
@g.edge("a:n_b:f")
|
88
|
+
edge = @g.edgeset.first
|
89
|
+
edge.st.should eql :a
|
90
|
+
edge.ed.should eql :b
|
91
|
+
edge.st_port.should eql :n
|
92
|
+
edge.ed_port.should eql :f
|
93
|
+
edge.to_s.should eql "a:n -> b:f"
|
94
|
+
end
|
95
|
+
|
96
|
+
it "can take ports with a string id 2" do
|
97
|
+
@g.add(:a => :b)
|
98
|
+
@g.edge("a:n_b:f", color:'red')
|
99
|
+
@g.edgeset.map(&:id).should eql [:a_b]
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "add" do
|
105
|
+
context "edges" do
|
106
|
+
it "one to many" do
|
107
|
+
@g.add :a => [:b, :c, :d]
|
108
|
+
@g.edgeset.map(&:to_s).should eql ['a -> b', 'a -> c', 'a -> d']
|
109
|
+
@g.nodeset.map(&:id).should eql [:a, :b, :c, :d]
|
110
|
+
end
|
111
|
+
|
112
|
+
it "many to many" do
|
113
|
+
@g.add [:main, :sub] => [:a, :b, :c]
|
114
|
+
@g.edgeset.map(&:to_s)
|
115
|
+
.should eql ['main -> a', 'main -> b', 'main -> c',
|
116
|
+
'sub -> a', 'sub -> b', 'sub -> c']
|
117
|
+
@g.nodeset.map(&:id).should eql [:main, :a, :b, :c, :sub]
|
118
|
+
end
|
119
|
+
|
120
|
+
it "sequence" do
|
121
|
+
@g.add :main => :sub, :sub => [:a, :b]
|
122
|
+
@g.edgeset.map(&:to_s)
|
123
|
+
.should eql ['main -> sub', 'sub -> a', 'sub -> b']
|
124
|
+
@g.nodeset.map(&:id).should eql [:main, :sub, :a, :b]
|
125
|
+
end
|
126
|
+
|
127
|
+
it "several sequences" do
|
128
|
+
@g.add :main => :a, :a => [:c, :d]
|
129
|
+
@g.add :main => :b, :b => [:e, :f]
|
130
|
+
@g.edgeset.map(&:to_s)
|
131
|
+
.should eql ['main -> a', 'a -> c', 'a -> d',
|
132
|
+
'main -> b', 'b -> e', 'b -> f']
|
133
|
+
@g.nodeset.map(&:id).should eql [:main, :a, :c, :d, :b, :e, :f]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "nodes" do
|
138
|
+
it "add a node" do
|
139
|
+
@g.add :a
|
140
|
+
@g.nodeset.map(&:id).should eql [:a]
|
141
|
+
end
|
142
|
+
|
143
|
+
it "add several nodes" do
|
144
|
+
@g.add :a, :b, :c
|
145
|
+
@g.nodeset.map(&:id).should eql [:a, :b, :c]
|
146
|
+
end
|
147
|
+
|
148
|
+
it "raise error with a string" do
|
149
|
+
->{ @g.add 'a' }.should raise_error(ArgumentError)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context "graph" do
|
155
|
+
it "add routes" do
|
156
|
+
@g.graph do
|
157
|
+
add :main => [:a, :b, :c]
|
158
|
+
add :a => [:d, :e]
|
159
|
+
end
|
160
|
+
@g.edgeset.map(&:to_s)
|
161
|
+
.should eql ['main -> a', 'main -> b', 'main -> c',
|
162
|
+
'a -> d', 'a -> e']
|
163
|
+
@g.nodeset.map(&:id).should eql [:main, :a, :b, :c, :d, :e]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "subgraph" do
|
168
|
+
it "add subgraph" do
|
169
|
+
sub = @g.subgraph do
|
170
|
+
add :main => [:a, :b]
|
171
|
+
end
|
172
|
+
@g.subgraphs.should eql [sub]
|
173
|
+
end
|
174
|
+
|
175
|
+
it "raise error when name is not start with 'cluster'" do
|
176
|
+
->{ @g.subgraph(:clu) {} }.should raise_error
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context "nodes" do
|
181
|
+
it "set nodes attributes globally" do
|
182
|
+
attr = { style:"filled", color:"purple" }
|
183
|
+
@g.nodes(attr)
|
184
|
+
@g.gnode_attrs.should == attr
|
185
|
+
end
|
186
|
+
|
187
|
+
it "add nodes attributes globally" do
|
188
|
+
attr = { style:"filled", color:"purple" }
|
189
|
+
attr2 = { color:"red", shape:"box" }
|
190
|
+
@g.nodes(attr)
|
191
|
+
@g.nodes(attr2)
|
192
|
+
@g.gnode_attrs.should == { style:"filled", color:"red", shape:"box" }
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context "edges" do
|
197
|
+
it "set edges attributes globally" do
|
198
|
+
attr = { style:"dotted", color:"purple" }
|
199
|
+
@g.edges(attr)
|
200
|
+
@g.gedge_attrs.should == attr
|
201
|
+
end
|
202
|
+
|
203
|
+
it "add edges attributes globally" do
|
204
|
+
attr = { style:"dotted", color:"purple" }
|
205
|
+
attr2 = { color:"red", arrowhead:"none" }
|
206
|
+
@g.edges(attr)
|
207
|
+
@g.edges(attr2)
|
208
|
+
@g.gedge_attrs.should == { style:"dotted", color:"red", arrowhead:"none" }
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context "global" do
|
213
|
+
it "set global graph attributes" do
|
214
|
+
attrs = { label:"A simple graph", rankdir:"LR" }
|
215
|
+
@g.global(attrs)
|
216
|
+
@g.graph_attrs.should == attrs
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context "rank" do
|
221
|
+
it "let nodes be same rank" do
|
222
|
+
@g.route(:a => [:b, :c], :b => [:d, :e])
|
223
|
+
@g.rank(:same, :b, :d, :e)
|
224
|
+
@g.ranks.first.should eql [:same, [:b, :d, :e]]
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
context "to_s(output dot data)" do
|
229
|
+
it "without attrs" do
|
230
|
+
@g.add :main => [:init, :parse]
|
231
|
+
@g.add :init => :printf
|
232
|
+
@g.to_s.should eql ~<<-EOS
|
233
|
+
digraph G {
|
234
|
+
main;
|
235
|
+
init;
|
236
|
+
parse;
|
237
|
+
printf;
|
238
|
+
main -> init;
|
239
|
+
main -> parse;
|
240
|
+
init -> printf;
|
241
|
+
}
|
242
|
+
EOS
|
243
|
+
end
|
244
|
+
|
245
|
+
it "with node attrs" do
|
246
|
+
@g.add :a => :b
|
247
|
+
@g.node(:a, color:'red', style:'filled')
|
248
|
+
@g.to_s.should eql ~<<-EOS
|
249
|
+
digraph G {
|
250
|
+
a[color="red",style="filled"];
|
251
|
+
b;
|
252
|
+
a -> b;
|
253
|
+
}
|
254
|
+
EOS
|
255
|
+
end
|
256
|
+
|
257
|
+
it "with edge attrs" do
|
258
|
+
@g.edge(:a_b, color:'red')
|
259
|
+
@g.to_s.should eql ~<<-EOS
|
260
|
+
digraph G {
|
261
|
+
a;
|
262
|
+
b;
|
263
|
+
a -> b[color="red"];
|
264
|
+
}
|
265
|
+
EOS
|
266
|
+
end
|
267
|
+
|
268
|
+
it "with 2 edges with different attrs" do
|
269
|
+
@g.edge(:a_b, color:'red')
|
270
|
+
@g.edge(:a_b_1, color:'blue')
|
271
|
+
@g.to_s.should eql ~<<-EOS
|
272
|
+
digraph G {
|
273
|
+
a;
|
274
|
+
b;
|
275
|
+
a -> b[color="red"];
|
276
|
+
a -> b[color="blue"];
|
277
|
+
}
|
278
|
+
EOS
|
279
|
+
end
|
280
|
+
|
281
|
+
it "with global node attributes" do
|
282
|
+
@g.nodes(shape:'box', style:'filled')
|
283
|
+
@g.add(:a => :b)
|
284
|
+
@g.to_s.should eql ~<<-EOS
|
285
|
+
digraph G {
|
286
|
+
node[shape="box",style="filled"];
|
287
|
+
a;
|
288
|
+
b;
|
289
|
+
a -> b;
|
290
|
+
}
|
291
|
+
EOS
|
292
|
+
end
|
293
|
+
|
294
|
+
it "with global edges attributes" do
|
295
|
+
@g.edges(style:'dotted', color:'red')
|
296
|
+
@g.add(:a => :b)
|
297
|
+
@g.to_s.should eql ~<<-EOS
|
298
|
+
digraph G {
|
299
|
+
edge[style="dotted",color="red"];
|
300
|
+
a;
|
301
|
+
b;
|
302
|
+
a -> b;
|
303
|
+
}
|
304
|
+
EOS
|
305
|
+
end
|
306
|
+
|
307
|
+
it "with global attributes" do
|
308
|
+
@g.global(label:"A Simple Graph", rankdir:"LR")
|
309
|
+
@g.add(:a => :b)
|
310
|
+
@g.to_s.should eql ~<<-EOS
|
311
|
+
digraph G {
|
312
|
+
label="A Simple Graph";
|
313
|
+
rankdir="LR";
|
314
|
+
a;
|
315
|
+
b;
|
316
|
+
a -> b;
|
317
|
+
}
|
318
|
+
EOS
|
319
|
+
end
|
320
|
+
|
321
|
+
it "handle newline in a label nicely" do
|
322
|
+
@g.node(:a, label:"hello\nworld")
|
323
|
+
@g.to_s.should eql ~<<-EOS
|
324
|
+
digraph G {
|
325
|
+
a[label="hello\\nworld"];
|
326
|
+
}
|
327
|
+
EOS
|
328
|
+
end
|
329
|
+
|
330
|
+
it "can handle unicode labels" do
|
331
|
+
@g.node(:a, label:"こんにちは、世界!")
|
332
|
+
@g.to_s.should eql ~<<-EOS
|
333
|
+
digraph G {
|
334
|
+
a[label="こんにちは、世界!"];
|
335
|
+
}
|
336
|
+
EOS
|
337
|
+
end
|
338
|
+
|
339
|
+
it "take port on edges" do
|
340
|
+
@g.route(:a => [:b, :c])
|
341
|
+
@g.edge("a:n_c:f")
|
342
|
+
@g.node(:a, label:"<n> a | b |<p> c")
|
343
|
+
@g.node(:c, label:"<o> d | e |<f> f")
|
344
|
+
@g.to_s.should eql ~<<-EOS
|
345
|
+
digraph G {
|
346
|
+
a[label="<n> a | b |<p> c"];
|
347
|
+
b;
|
348
|
+
c[label="<o> d | e |<f> f"];
|
349
|
+
a -> b;
|
350
|
+
a:n -> c:f;
|
351
|
+
}
|
352
|
+
EOS
|
353
|
+
end
|
354
|
+
|
355
|
+
it "with subgraph" do
|
356
|
+
@g.route(:a => :b)
|
357
|
+
@g.subgraph do
|
358
|
+
route :c => :d
|
359
|
+
end
|
360
|
+
@g.to_s.should eql ~<<-EOS
|
361
|
+
digraph G {
|
362
|
+
a;
|
363
|
+
b;
|
364
|
+
a -> b;
|
365
|
+
subgraph cluster0 {
|
366
|
+
c;
|
367
|
+
d;
|
368
|
+
c -> d;
|
369
|
+
}
|
370
|
+
}
|
371
|
+
EOS
|
372
|
+
end
|
373
|
+
|
374
|
+
it "with ranks" do
|
375
|
+
@g.route(:a => [:b, :c], :b => [:d, :e])
|
376
|
+
@g.rank(:same, :b, :d, :e)
|
377
|
+
@g.rank(:min, :c)
|
378
|
+
@g.to_s.should eql ~<<-EOS
|
379
|
+
digraph G {
|
380
|
+
a;
|
381
|
+
b;
|
382
|
+
c;
|
383
|
+
d;
|
384
|
+
e;
|
385
|
+
a -> b;
|
386
|
+
a -> c;
|
387
|
+
b -> d;
|
388
|
+
b -> e;
|
389
|
+
{ rank=same; b; d; e; }
|
390
|
+
{ rank=min; c; }
|
391
|
+
}
|
392
|
+
EOS
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gviz
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- kyoendo
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-25 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Ruby's interface of graphviz
|
15
|
+
email:
|
16
|
+
- postagie@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- LICENSE.txt
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- examples/arrow.dot
|
27
|
+
- examples/arrows.rb
|
28
|
+
- examples/color.dot
|
29
|
+
- examples/colors.rb
|
30
|
+
- examples/examples.rb
|
31
|
+
- examples/sample1.png
|
32
|
+
- examples/sample2.png
|
33
|
+
- examples/sample3.png
|
34
|
+
- examples/scraper.rb
|
35
|
+
- examples/shape.dot
|
36
|
+
- examples/shapes.rb
|
37
|
+
- gviz.gemspec
|
38
|
+
- lib/gviz.rb
|
39
|
+
- lib/gviz/version.rb
|
40
|
+
- spec/gviz_spec.rb
|
41
|
+
- spec/spec_helper.rb
|
42
|
+
homepage: https://github.com/melborne/Gviz
|
43
|
+
licenses: []
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
requirements: []
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.8.24
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: Ruby's interface of graphviz. It generate a dot file with simple ruby's syntax.
|
66
|
+
test_files:
|
67
|
+
- spec/gviz_spec.rb
|
68
|
+
- spec/spec_helper.rb
|
69
|
+
has_rdoc:
|