gv 0.0.3 → 0.1.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.
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