gv 0.0.3 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: df3b4f9e7e9dc7a1bb1c3f9fc0442c5032772570
4
- data.tar.gz: d74223b0a785b75df5aa6ada63c8eaf10b66a2cd
2
+ SHA256:
3
+ metadata.gz: 92d208286b90fddbf8c5c1660c0ef7a9c571c4de2c798f2329456cda47b1b375
4
+ data.tar.gz: 247302d77d98a3709826893687b518e78bbb4c59bd7e187ab46f91c8bdbe77e2
5
5
  SHA512:
6
- metadata.gz: 61070b8eac8e61b06d970495df79d49efb46f6612e425228d02ed5c364effb5e0fc9b64f22ac0915db171478f8b86e355f326eadb03e85670fcecdac3d8c24a2
7
- data.tar.gz: 8ddeec3c092d86be9f144fa83926a1251456ac7536d1d308e4638c387ef77925001226e3ef7d5ab90b18bfa1609118f5c3cf761e86c48b31f791ac54397e261f
6
+ metadata.gz: 153040bdbaed5d91e3438cb2354203b1c1dd8ba0fe9e328d7b23fb3101f7160f5cea7277f23d27ff58b434e9b175044e203a5b517316400835e9b9bf4c75d584
7
+ data.tar.gz: 34b4de2d1454cfdd059ee0fac8f989820fc39322dd3e27eb4607363f8c4966a60886e3fd52fc45442d4168bf887e2efa6122c16b97930e7ef813560bf9eb1693
data/.gemrelease ADDED
@@ -0,0 +1,2 @@
1
+ release:
2
+ tag: true
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ before_install:
2
+ - sudo add-apt-repository ppa:gviz-adm/graphviz-dev -y
3
+ - sudo apt-get -qq update
4
+ - sudo apt-get install -y libgraphviz-dev graphviz libgraphviz4
5
+ language: ruby
6
+ rvm:
7
+ - 2.3.1
8
+ - jruby-9.0.5.0
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
- # GV
1
+ [![Gem Version](https://badge.fury.io/rb/gv.svg)](https://badge.fury.io/rb/gv)
2
+ [![Inline docs](http://inch-ci.org/github/furunkel/gv.svg?branch=master)](http://inch-ci.org/github/furunkel/gv)
3
+ [![Build Status](https://travis-ci.org/furunkel/gv.svg?branch=master)](https://travis-ci.org/furunkel/gv)
2
4
 
3
- Ruby bindings for libgvc (Graphviz) using FFI.
5
+ # Graphviz FFI
6
+
7
+ Ruby bindings for libcgraph and libgvc (Graphviz) using FFI.
4
8
 
5
9
  ## Installation
6
10
 
@@ -25,8 +29,7 @@ Or install it yourself as:
25
29
  require 'gv'
26
30
 
27
31
  graph = GV::Graph.open 'g'
28
- graph.edge 'e', graph.node('A'), graph.node('B', shape: 'polygon')
29
-
32
+ graph.edge 'e', graph.node('A'), graph.node('B', shape: 'polygon', label: graph.html('<b>bold</b>'))
30
33
  # render to string
31
34
  graph.render 'png'
32
35
 
@@ -35,7 +38,7 @@ graph.write 'result.png'
35
38
  ```
36
39
 
37
40
  #### Result
38
- ![resilt](/spec/render.png)
41
+ ![Result](https://raw.githubusercontent.com/furunkel/gv/master/spec/render.png)
39
42
 
40
43
  ### Load existing graph from `.dot` file:
41
44
  ```ruby
@@ -46,6 +49,7 @@ graph = GV::Graph.load File.open('g.dot')
46
49
  # render graph
47
50
  graph.render
48
51
  ```
52
+ See the [documentation](http://www.rubydoc.info/gems/gv) for details.
49
53
 
50
54
  ## Contributing
51
55
 
data/Rakefile CHANGED
@@ -1,7 +1,14 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
+ require 'yard'
3
4
 
4
5
  Rake::TestTask.new do |t|
5
6
  t.libs.push 'lib'
6
7
  t.pattern = "spec/*_spec.rb"
7
- end
8
+ end
9
+
10
+
11
+ YARD::Rake::YardocTask.new
12
+
13
+
14
+ task :default => :test
data/gv.gemspec CHANGED
@@ -4,22 +4,25 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'gv/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "gv"
7
+ spec.name = 'gv'
8
8
  spec.version = GV::VERSION
9
- spec.authors = ["furunkel"]
10
- spec.email = ["julian@linux4you.it"]
9
+ spec.authors = ['furunkel']
10
+ spec.email = ['furunkel@polyadic.com']
11
11
  spec.summary = %q{Graphviz for Ruby, using libgvc via FFI}
12
- spec.homepage = "https://github.com/furunkel/gv"
13
- spec.license = "MIT"
12
+ spec.homepage = 'https://github.com/furunkel/gv'
13
+ spec.license = 'MIT'
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0")
16
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
- spec.require_paths = ["lib"]
18
+ spec.require_paths = ['lib']
19
19
 
20
- spec.add_development_dependency "bundler", "~> 1.7"
21
- spec.add_development_dependency "rake", "~> 10.0"
22
- spec.add_development_dependency "minitest"
20
+ spec.add_dependency 'ffi', '>= 1.11'
23
21
 
24
- spec.add_dependency "ffi"
22
+ spec.add_development_dependency 'bundler', '>= 2'
23
+ spec.add_development_dependency 'rake', '>= 10.0'
24
+ spec.add_development_dependency 'yard', '>= 0.9'
25
+ spec.add_development_dependency 'minitest', '>= 5.8'
26
+ spec.add_development_dependency 'minitest-reporters', '> 1.1'
27
+ spec.add_development_dependency 'rubocop', '>= 0.41'
25
28
  end
data/lib/gv/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module GV
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/gv.rb CHANGED
@@ -2,71 +2,80 @@ require 'gv/version'
2
2
  require 'ffi'
3
3
 
4
4
  module GV
5
+ module Libcgraph
6
+ extend FFI::Library
5
7
 
6
- module FFI
7
- extend ::FFI::Library
8
-
9
- ffi_lib 'gvc', 'cgraph', 'cgraph'
10
-
11
- class AGraph < ::FFI::ManagedStruct
12
- # dummy layout, only ever used by reference
13
- layout :_1, :int,
14
- :_2, :int
8
+ ffi_lib 'cgraph'
15
9
 
10
+ class AGraph < FFI::AutoPointer
16
11
  def self.release(ptr)
17
- FFI.agclose(ptr) unless ptr.null?
12
+ Libcgraph.agclose(ptr) unless ptr.null?
18
13
  end
19
14
  end
20
15
 
21
- typedef :pointer, :gvc
22
16
  typedef :pointer, :ag_node
23
17
  typedef :pointer, :ag_edge
24
18
 
25
- attach_function :gvContext, [], :pointer
26
- attach_function :gvFreeLayout, [:gvc, AGraph.by_ref], :int
27
- attach_function :gvLayout, [:gvc, AGraph.by_ref, :string], :int
28
-
29
- attach_function :gvRenderFilename, [:gvc, AGraph.by_ref, :string, :string], :int
30
- attach_function :gvRenderData, [:gvc, AGraph.by_ref, :string, :pointer, :pointer], :int
31
- attach_function :gvFreeRenderData, [:pointer], :void
32
-
33
- attach_function :agmemread, [:string], AGraph.by_ref
34
- attach_function :agopen, [:string, :long, :pointer], AGraph.by_ref
35
- attach_function :agclose, [AGraph.by_ref], :int
19
+ attach_function :agmemread, [:string], AGraph
20
+ attach_function :agopen, %i[string long pointer], AGraph
21
+ attach_function :agclose, [AGraph], :int
36
22
 
37
23
  attach_variable :Agundirected, :long
38
24
  attach_variable :Agstrictundirected, :long
39
25
  attach_variable :Agdirected, :long
40
26
  attach_variable :Agstrictdirected, :long
41
27
 
42
- attach_function :agnode, [AGraph.by_ref, :string, :int], :ag_node
43
- attach_function :agedge, [AGraph.by_ref, :ag_node, :ag_node, :string, :int], :ag_edge
44
- attach_function :agsubg, [AGraph.by_ref, :string, :int], :pointer
28
+ attach_function :agnode, [AGraph, :string, :int], :ag_node
29
+ attach_function :agedge, [AGraph, :ag_node, :ag_node, :string, :int], :ag_edge
30
+ attach_function :agsubg, [AGraph, :string, :int], :pointer
45
31
 
46
32
  attach_function :agnameof, [:pointer], :string
47
33
  attach_function :agraphof, [:pointer], :pointer
48
34
 
49
35
  attach_function :agtail, [:ag_edge], :ag_node
50
36
  attach_function :aghead, [:ag_edge], :ag_node
51
- attach_function :agget, [:pointer, :string], :string
37
+ attach_function :agget, %i[pointer string], :string
52
38
 
53
- attach_function :agsafeset, [:pointer, :string, :string, :string], :pointer
54
- attach_function :agstrdup_html, [AGraph.by_ref, :string], :pointer
55
- attach_function :agstrfree, [AGraph.by_ref, :pointer], :int
39
+ attach_function :agsafeset, %i[pointer string string string], :pointer
40
+ attach_function :agstrdup_html, [AGraph, :string], :pointer
41
+ attach_function :agstrfree, [AGraph, :pointer], :int
42
+
43
+ attach_function :agisdirected, [AGraph], :int
44
+ attach_function :agisstrict, [AGraph], :int
45
+ end
46
+ private_constant :Libcgraph
47
+
48
+ module Libgvc
49
+ extend FFI::Library
50
+ ffi_lib 'gvc'
51
+
52
+ typedef :pointer, :gvc
53
+
54
+ attach_function :gvContext, [], :pointer
55
+ attach_function :gvFreeLayout, [:gvc, Libcgraph::AGraph], :int
56
+ attach_function :gvLayout, [:gvc, Libcgraph::AGraph, :string], :int
56
57
 
57
- attach_function :agisdirected, [AGraph.by_ref], :int
58
- attach_function :agisstrict, [AGraph.by_ref], :int
58
+ attach_function :gvRenderFilename, [:gvc, Libcgraph::AGraph, :string, :string], :int
59
+ attach_function :gvRenderData, [:gvc, Libcgraph::AGraph, :string, :pointer, :pointer], :int
60
+ attach_function :gvFreeRenderData, [:pointer], :void
59
61
  end
62
+ private_constant :Libgvc
60
63
 
64
+ # Common super-class for edges, nodes and graphs
61
65
  class Component
62
- @@gvc = FFI.gvContext()
66
+ # @!visibility private
67
+ @@gvc = Libgvc.gvContext
63
68
 
69
+ # @return [Graph, SubGraph] the graph this component belongs to
64
70
  attr_reader :graph
65
71
 
72
+ # Creates an HTML label
73
+ # @param string [String] the HTML to parse
74
+ # @return [Object] a HTML label
66
75
  def html(string)
67
- ptr = FFI.agstrdup_html(graph.ptr, string)
76
+ ptr = Libcgraph.agstrdup_html(graph.ptr, string)
68
77
  string = ptr.read_string
69
- FFI.agstrfree graph.ptr, ptr
78
+ Libcgraph.agstrfree graph.ptr, ptr
70
79
 
71
80
  string
72
81
  end
@@ -79,62 +88,97 @@ module GV
79
88
  other.is_a?(Component) && ptr == other.ptr
80
89
  end
81
90
 
82
- alias :eql? :==
91
+ alias eql? ==
83
92
 
93
+ # @return [String] the component's name
84
94
  def name
85
- FFI.agnameof ptr
95
+ Libcgraph.agnameof ptr
86
96
  end
87
97
 
98
+ # Sets an attribute
99
+ # @param attr [Symbol, String] attribute name
100
+ # @see http://www.graphviz.org/doc/info/attrs.html Node, Edge and Graph Attributes
101
+ # @param value [Object] attribute value
88
102
  def []=(attr, value)
89
- FFI.agsafeset(ptr, attr.to_s, value.to_s, "")
103
+ Libcgraph.agsafeset(ptr, attr.to_s, value.to_s, '')
90
104
  end
91
105
 
106
+ # Retrieves the value of an attribute
107
+ # @param attr [Symbol, String] attribute name
108
+ # @see http://www.graphviz.org/doc/info/attrs.html Node, Edge and Graph Attributes
109
+ # @return [Object] the attribute value
92
110
  def [](attr)
93
- FFI.agget(ptr, attr.to_s)
111
+ Libcgraph.agget(ptr, attr.to_s)
94
112
  end
95
113
 
96
114
  protected
115
+
97
116
  attr_reader :ptr
98
117
  end
99
118
 
119
+ # Represents a node in the graph
100
120
  class Node < Component
101
121
  def initialize(graph, name_or_ptr)
102
122
  @graph = graph
103
- case name_or_ptr
104
- when String
105
- @ptr = FFI.agnode(graph.ptr, name_or_ptr, 1)
106
- else
107
- @ptr = name_or_ptr
108
- end
123
+ @ptr =
124
+ case name_or_ptr
125
+ when String
126
+ Libcgraph.agnode(graph.ptr, name_or_ptr, 1)
127
+ else
128
+ name_or_ptr
129
+ end
109
130
  end
110
131
  end
111
132
 
133
+ # Represents a connection between nodes
112
134
  class Edge < Component
113
135
  def initialize(graph, name, tail, head)
114
136
  @graph = graph
115
137
 
116
- @ptr = FFI.agedge(graph.ptr, tail.ptr, head.ptr, name, 1)
138
+ @ptr = Libcgraph.agedge(graph.ptr, tail.ptr, head.ptr, name, 1)
117
139
  end
118
140
 
141
+ # @return [Node] the head node of the edge
119
142
  def head
120
- Node.new @graph, FFI.aghead(ptr)
143
+ Node.new @graph, Libcgraph.aghead(ptr)
121
144
  end
122
145
 
146
+ # @return [Node] the tail node of the edge
123
147
  def tail
124
- Node.new @graph, FFI.agtail(ptr)
148
+ Node.new @graph, Libcgraph.agtail(ptr)
125
149
  end
126
150
  end
127
151
 
152
+ # Common super-class for graphs and sub-graphs
128
153
  class BaseGraph < Component
129
-
154
+ # Creates a new node
155
+ # @param name [String] the name (identifier) of the node
156
+ # @param attrs [Hash{String, Symbol => Object}] the attributes
157
+ # to associate with this node
158
+ # @see http://www.graphviz.org/doc/info/attrs.html Node, Edge and Graph Attributes
159
+ # @return [Node] the newly created node
130
160
  def node(name, attrs = {})
131
161
  component Node, [name], attrs
132
162
  end
133
163
 
164
+ # Creates a new edge
165
+ # @param name [String] the name (identifier) of the edge
166
+ # @param tail [Node] the edge's tail node
167
+ # @param head [Node] the edge's head node
168
+ # @param attrs [Hash{String, Symbol => Object}] the attributes
169
+ # to associate with this edge
170
+ # @see http://www.graphviz.org/doc/info/attrs.html Node, Edge and Graph Attributes
171
+ # @return [Edge] the newly created edge
134
172
  def edge(name, tail, head, attrs = {})
135
173
  component Edge, [name, tail, head], attrs
136
174
  end
137
175
 
176
+ # Creates a new sub-graph
177
+ # @param name [String] the name (identifier) of the sub-graph
178
+ # @param attrs [Hash{String, Symbol => Object}] the attributes
179
+ # to associate with this sub-graph
180
+ # @see http://www.graphviz.org/doc/info/attrs.html Node, Edge and Graph Attributes
181
+ # @return [SubGraph] the newly created sub-graph
138
182
  def sub_graph(name, attrs = {})
139
183
  graph = component SubGraph, [name], attrs
140
184
  yield graph if block_given?
@@ -142,15 +186,18 @@ module GV
142
186
  graph
143
187
  end
144
188
 
189
+ # @return whether this graph is directed
145
190
  def directed?
146
- FFI.agisdirected(ptr) == 1
191
+ Libcgraph.agisdirected(ptr) == 1
147
192
  end
148
193
 
194
+ # @return whether this graph is strict
149
195
  def strict?
150
- FFI.agisstrict(ptr) == 1
196
+ Libcgraph.agisstrict(ptr) == 1
151
197
  end
152
198
 
153
199
  private
200
+
154
201
  def component(klass, args, attrs = {})
155
202
  comp = klass.new self, *args
156
203
 
@@ -160,46 +207,58 @@ module GV
160
207
 
161
208
  comp
162
209
  end
163
-
164
210
  end
165
211
 
212
+ # Represents a sub-graph
166
213
  class SubGraph < BaseGraph
167
214
  def initialize(graph, name)
168
215
  @graph = graph
169
- @ptr = FFI.agsubg(graph.ptr, name, 1)
216
+ @ptr = Libcgraph.agsubg(graph.ptr, name, 1)
170
217
  end
171
218
  end
172
219
 
220
+ # Represents a toplevel graph
173
221
  class Graph < BaseGraph
174
-
175
222
  class << self
176
223
  private :new
177
- def open(name, type = :directed, strict = :normal)
178
- ag_type = case [type, strict]
179
- when [:directed, :normal] then FFI.Agdirected
180
- when [:undirected, :normal] then FFI.Agundirected
181
- when [:directed, :strict] then FFI.Agstrictdirected
182
- when [:undirected, :strict] then FFI.Agstrictundirected
183
- else
184
- raise ArgumentError, "invalid graph type #{[type, strict]}"
185
- end
186
-
187
- graph = new(FFI.agopen(name, ag_type, ::FFI::Pointer::NULL))
188
-
189
- if block_given?
190
- yield graph
191
- end
224
+
225
+ # Creates a new graph
226
+ # @param type [:directed, :undirected] the graphs type
227
+ # @param strictness [:strict, :normal] the graphs strict type
228
+ # @see http://www.graphviz.org/doc/info/attrs.html Node, Edge and Graph Attributes
229
+ # @yieldparam graph [Graph] the newly created graph
230
+ # @return [Graph] the newly created graph
231
+ def open(name, type = :directed, strictness = :normal)
232
+ ag_type = case [type, strictness]
233
+ when %i[directed normal]
234
+ Libcgraph.Agdirected
235
+ when %i[undirected normal]
236
+ Libcgraph.Agundirected
237
+ when %i[directed strict]
238
+ Libcgraph.Agstrictdirected
239
+ when %i[undirected strict]
240
+ Libcgraph.Agstrictundirected
241
+ else
242
+ raise ArgumentError, "invalid graph type #{[type, strictness]}"
243
+ end
244
+
245
+ graph = new(Libcgraph.agopen(name, ag_type, FFI::Pointer::NULL))
246
+
247
+ yield graph if block_given?
192
248
 
193
249
  graph
194
250
  end
195
251
 
252
+ # Loads a graph from a string of file
253
+ # @param io [IO, String] the resource to load from
254
+ # @return the newly loaded graph
196
255
  def load(io)
197
256
  data = if io.is_a? String
198
- io
199
- else
200
- io.read
201
- end
202
- new FFI.agmemread(data)
257
+ io
258
+ else
259
+ io.read
260
+ end
261
+ new Libcgraph.agmemread(data)
203
262
  end
204
263
  end
205
264
 
@@ -211,26 +270,37 @@ module GV
211
270
  self
212
271
  end
213
272
 
214
- def write(filename, format = 'png', layout = 'dot')
215
- FFI.gvLayout(@@gvc, ptr, layout.to_s)
216
- FFI.gvRenderFilename(@@gvc, ptr, format.to_s, filename);
217
- FFI.gvFreeLayout(@@gvc, ptr)
273
+ # Renders the graph to an images and saves the result to a file
274
+ # @param filename [String] the filename
275
+ # @param format [String] the image format to use, e.g. 'svg', 'pdf' etc.
276
+ # @param layout [String] the layout to use, e.g. 'dot' or 'neato' etc.
277
+ # @return [nil]
278
+ def save(filename, format = 'png', layout = 'dot')
279
+ Libgvc.gvLayout(@@gvc, ptr, layout.to_s)
280
+ Libgvc.gvRenderFilename(@@gvc, ptr, format.to_s, filename)
281
+ Libgvc.gvFreeLayout(@@gvc, ptr)
282
+
283
+ nil
218
284
  end
219
285
 
286
+ # Renders the graph to an image and returns the result as a string
287
+ # @param format [String] the image format to use, e.g. 'svg', 'pdf' etc.
288
+ # @param layout [String] the layout to use, e.g. 'dot' or 'neato' etc.
289
+ # @return [String] the rendered graph in the given format
220
290
  def render(format = 'png', layout = 'dot')
221
- FFI.gvLayout(@@gvc, ptr, layout.to_s)
291
+ Libgvc.gvLayout(@@gvc, ptr, layout.to_s)
222
292
 
223
- data_ptr = ::FFI::MemoryPointer.new(:pointer, 1)
224
- len_ptr = ::FFI::MemoryPointer.new(:int, 1)
293
+ data_ptr = FFI::MemoryPointer.new(:pointer, 1)
294
+ len_ptr = FFI::MemoryPointer.new(:int, 1)
225
295
 
226
- FFI.gvRenderData(@@gvc, ptr, format.to_s, data_ptr, len_ptr);
296
+ Libgvc.gvRenderData(@@gvc, ptr, format.to_s, data_ptr, len_ptr)
227
297
  len = len_ptr.read_uint
228
298
  data_ptr = data_ptr.read_pointer
229
-
230
- data = data_ptr.read_string_length len
231
299
 
232
- FFI.gvFreeRenderData(data_ptr)
233
- FFI.gvFreeLayout(@@gvc, ptr)
300
+ data = data_ptr.read_string len
301
+
302
+ Libgvc.gvFreeRenderData(data_ptr)
303
+ Libgvc.gvFreeLayout(@@gvc, ptr)
234
304
 
235
305
  data
236
306
  end
data/spec/graph_spec.rb CHANGED
@@ -1,36 +1,37 @@
1
1
  require_relative 'spec_helper'
2
+ require 'tmpdir'
2
3
 
3
4
  include GV
4
5
 
5
6
  describe Graph do
6
7
  describe :open do
7
- it "creates a new graph" do
8
+ it 'creates a new graph' do
8
9
  graph = Graph.open 'test'
9
- graph.directed?.must_equal true
10
- graph.strict?.must_equal false
10
+ assert graph.directed?
11
+ refute graph.strict?
11
12
 
12
13
  graph = Graph.open 'test', :directed, :strict
13
- graph.strict?.must_equal true
14
- graph.directed?.must_equal true
14
+ assert graph.strict?
15
+ assert graph.directed?
15
16
  end
16
17
 
17
- it "takes a block" do
18
- graph = Graph.open 'test' do |g|
19
- g.directed?.must_equal true
20
- g.strict?.must_equal false
18
+ it 'takes a block' do
19
+ Graph.open 'test' do |g|
20
+ assert g.directed?
21
+ refute g.strict?
21
22
  end
22
23
  end
23
24
  end
24
25
 
25
26
  describe :load do
26
- it "loads graph from file" do
27
- f = lambda do |f|
28
- graph = Graph.load f
29
- graph.directed?.must_equal true
30
- graph.strict?.must_equal false
31
- graph.name.must_equal 'g'
27
+ it 'loads graph from file' do
28
+ f = lambda do |filename|
29
+ graph = Graph.load filename
30
+ assert graph.directed?
31
+ refute graph.strict?
32
+ assert_equal 'g', graph.name
32
33
  end
33
-
34
+
34
35
  filename = File.join(__dir__, 'simple_graph.dot')
35
36
  file = File.open filename
36
37
  f.call file
@@ -45,12 +46,12 @@ describe Graph do
45
46
  @graph = Graph.open 'test'
46
47
  end
47
48
 
48
- it "creates a new node" do
49
- @graph.node('test').must_be_kind_of Node
49
+ it 'creates a new node' do
50
+ assert_kind_of Node, @graph.node('test')
50
51
  end
51
52
 
52
- it "sets given attributes" do
53
- @graph.node('test', color: 'green')[:color].must_equal 'green'
53
+ it 'sets given attributes' do
54
+ assert_equal 'green', @graph.node('test', color: 'green')[:color]
54
55
  end
55
56
  end
56
57
 
@@ -59,23 +60,22 @@ describe Graph do
59
60
  @graph = Graph.open 'test'
60
61
  end
61
62
 
62
- it "creates a new sub graph" do
63
- @graph.sub_graph('test').must_be_kind_of SubGraph
63
+ it 'creates a new sub graph' do
64
+ assert_kind_of SubGraph, @graph.sub_graph('test')
64
65
  end
65
66
 
66
- it "sets given attributes" do
67
- @graph.sub_graph('test', color: 'green')[:color].must_equal 'green'
67
+ it 'sets given attributes' do
68
+ assert_equal 'green', @graph.sub_graph('test', color: 'green')[:color]
68
69
  end
69
70
 
70
- it "takes a block" do
71
+ it 'takes a block' do
71
72
  graph = @graph.sub_graph('test') do |g|
72
73
  g[:color] = 'green'
73
74
  end
74
- graph[:color].must_equal 'green'
75
+ assert_equal 'green', graph[:color]
75
76
  end
76
77
  end
77
78
 
78
-
79
79
  describe :edge do
80
80
  before do
81
81
  @graph = Graph.open 'test'
@@ -83,35 +83,38 @@ describe Graph do
83
83
  @tail = @graph.node 'tail'
84
84
  end
85
85
 
86
- it "creates a new edge" do
87
- @graph.edge('test', @tail, @head).must_be_kind_of Edge
86
+ it 'creates a new edge' do
87
+ assert_kind_of Edge, @graph.edge('test', @tail, @head)
88
88
  end
89
89
 
90
- it "sets given attributes" do
91
- @graph.edge('test', @tail, @head, color: 'green')[:color].must_equal 'green'
90
+ it 'sets given attributes' do
91
+ assert_equal 'green', @graph.edge('test', @tail, @head, color: 'green')[:color]
92
92
  end
93
93
  end
94
94
 
95
- describe :write do
96
- it "renders the graph to the given filename" do
95
+ describe :save do
96
+ it 'renders the graph to the given filename' do
97
97
  graph = Graph.open 'test'
98
98
  graph.edge 'e', graph.node('A'), graph.node('B')
99
- filename = File.join Dir.tmpdir, Dir::Tmpname.make_tmpname(['gv_test', '.png'], nil)
100
- graph.write filename
101
- File.file?(filename).must_equal true
102
- File.unlink filename
99
+ Tempfile.create(%w(gv_test .png)) do |file|
100
+ graph.save file.path
101
+ assert_equal true, File.file?(file.path)
102
+ end
103
103
  end
104
104
  end
105
105
 
106
106
  describe :render do
107
- it "renders the graph to a string" do
107
+ it 'renders the graph to a string' do
108
108
  graph = Graph.open 'test'
109
- graph.edge 'e', graph.node('A'), graph.node('B', shape: 'polygon', label: graph.html('<b>bold</b>'))
109
+ graph.edge 'e', graph.node('A'),
110
+ graph.node('B', shape: 'polygon',
111
+ label: graph.html('<b>bold</b>'))
112
+
110
113
  data = graph.render
111
114
 
112
115
  graph = nil
113
116
  GC.start
114
- data.must_be_kind_of String
117
+ assert_kind_of String, data
115
118
 
116
119
  File.write 'spec/render.png', data
117
120
  end
@@ -127,17 +130,17 @@ describe Edge do
127
130
  end
128
131
 
129
132
  it 'gives access to head and tail' do
130
- @edge.head.must_equal @head
131
- @edge.tail.must_equal @tail
133
+ assert_equal @head, @edge.head
134
+ assert_equal @tail, @edge.tail
132
135
  end
133
136
 
134
137
  it 'gives access to name' do
135
- @edge.name.must_equal 'test'
138
+ assert_equal 'test', @edge.name
136
139
  end
137
140
 
138
141
  it 'gives access to attributes' do
139
- @edge[:color].must_equal nil
142
+ assert_nil @edge[:color]
140
143
  @edge[:color] = 'green'
141
- @edge[:color].must_equal 'green'
144
+ assert_equal 'green', @edge[:color]
142
145
  end
143
146
  end
data/spec/render.png CHANGED
Binary file
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,5 @@
1
1
  require 'gv'
2
- require 'minitest/autorun'
2
+ require 'minitest/reporters'
3
+ require 'minitest/autorun'
4
+
5
+ Minitest::Reporters.use!
metadata CHANGED
@@ -1,79 +1,123 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - furunkel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-27 00:00:00.000000000 Z
11
+ date: 2023-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - "~>"
31
+ - - ">="
18
32
  - !ruby/object:Gem::Version
19
- version: '1.7'
33
+ version: '2'
20
34
  type: :development
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - "~>"
38
+ - - ">="
25
39
  - !ruby/object:Gem::Version
26
- version: '1.7'
40
+ version: '2'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - "~>"
45
+ - - ">="
32
46
  - !ruby/object:Gem::Version
33
47
  version: '10.0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - "~>"
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0.9'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: minitest
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - ">="
46
74
  - !ruby/object:Gem::Version
47
- version: '0'
75
+ version: '5.8'
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - ">="
53
81
  - !ruby/object:Gem::Version
54
- version: '0'
82
+ version: '5.8'
55
83
  - !ruby/object:Gem::Dependency
56
- name: ffi
84
+ name: minitest-reporters
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
57
99
  requirement: !ruby/object:Gem::Requirement
58
100
  requirements:
59
101
  - - ">="
60
102
  - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
103
+ version: '0.41'
104
+ type: :development
63
105
  prerelease: false
64
106
  version_requirements: !ruby/object:Gem::Requirement
65
107
  requirements:
66
108
  - - ">="
67
109
  - !ruby/object:Gem::Version
68
- version: '0'
110
+ version: '0.41'
69
111
  description:
70
112
  email:
71
- - julian@linux4you.it
113
+ - furunkel@polyadic.com
72
114
  executables: []
73
115
  extensions: []
74
116
  extra_rdoc_files: []
75
117
  files:
118
+ - ".gemrelease"
76
119
  - ".gitignore"
120
+ - ".travis.yml"
77
121
  - Gemfile
78
122
  - LICENSE.txt
79
123
  - README.md
@@ -104,8 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
148
  - !ruby/object:Gem::Version
105
149
  version: '0'
106
150
  requirements: []
107
- rubyforge_project:
108
- rubygems_version: 2.4.5
151
+ rubygems_version: 3.3.3
109
152
  signing_key:
110
153
  specification_version: 4
111
154
  summary: Graphviz for Ruby, using libgvc via FFI