dogviz 0.0.18 → 0.0.19

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
2
  SHA1:
3
- metadata.gz: d93013b0cc858fbd5459c5fc0794cc334df4ab7f
4
- data.tar.gz: ee353c1dfe91e9b10901d2305944806b62f3e5c8
3
+ metadata.gz: 31b3d809039b6fea6187610fe47505f1cf0639db
4
+ data.tar.gz: 7583c3283f29685564c878ed13c2ba7ede152cf5
5
5
  SHA512:
6
- metadata.gz: 76aa31f77889f81eae728587e3660ed9650b09a04a1fced9fe87699631870a73f98f62f0acfccb9af84399b7f68c380f177df846ce13aa2458e99561061c4499
7
- data.tar.gz: 7fa12c43c393cb7714e697bebdece5fb387d72df776a96aea8ec794932b56593158b906c9bb8e68e2999dd893174cea158e2e92b76c8a5968062b7cdc02e867c
6
+ metadata.gz: e4f8f6c9cd2008a5505209b94e2ce954e2b60b9aa11bcd163b99be003a1f2bc58410373715645c813ef6830db98c0a8ce244db9cc2e5db83631aad5192eba1e7
7
+ data.tar.gz: fe9f06499d86dd083df1bbaf26051e3b50876b011fbb740ade31254e97469a0e40454398c6c37f703aafc91c38450aabfae1cb1e8b18c52afbb9fc9cd9f22d65
data/.bundle/config ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ BUNDLE_PATH: "vendor/bundle"
3
+ BUNDLE_DISABLE_SHARED_GEMS: "true"
data/.gitignore CHANGED
@@ -4,3 +4,4 @@ coverage
4
4
  sys.rb
5
5
  dogviz*gem
6
6
  Gemfile.lock
7
+ vendor/
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.1.5
1
+ 2.4.1
@@ -9,7 +9,7 @@ module Dogviz
9
9
  include Parent
10
10
 
11
11
  attr_reader :parent
12
- attr_reader :name, :id, :node, :render_id, :render_type, :render_options, :children
12
+ attr_reader :name, :id, :node, :render_type, :render_options, :children
13
13
 
14
14
  def initialize(parent, name, options = {})
15
15
  @children = []
@@ -23,8 +23,9 @@ module Dogviz
23
23
  init_rollup options
24
24
 
25
25
  setup_render_attributes label: name
26
+ default_bounded_option(options)
26
27
 
27
- @render_options = options.merge inherited_render_options
28
+ @render_options = options.merge(inherited_render_options)
28
29
 
29
30
  parent.register name, self
30
31
  end
@@ -56,18 +57,12 @@ module Dogviz
56
57
 
57
58
  def do_render_subgraph(renderer)
58
59
  @render_type = :subgraph
59
- render_id = cluster_prefix + id
60
- attributes = @attributes
61
- @render_id = render_id
62
- @subgraph = renderer.render_subgraph(parent, render_id, render_options, attributes)
60
+ @subgraph = renderer.render_subgraph(parent, id, render_options.merge(@attributes))
63
61
  end
64
62
 
65
63
  def do_render_node(renderer)
66
64
  @render_type = :node
67
- @render_id = id
68
- render_id = @render_id
69
- attributes = @attributes
70
- renderer.render_node(parent, render_id, render_options, attributes)
65
+ renderer.render_node(parent, id, render_options.merge(@attributes))
71
66
  end
72
67
 
73
68
  def init_rollup(options)
@@ -76,13 +71,12 @@ module Dogviz
76
71
  options.delete(:rollup)
77
72
  end
78
73
 
79
- def cluster_prefix
80
- is_cluster = true
81
- if @render_options.has_key? :cluster
82
- is_cluster = @render_options[:cluster]
83
- @render_options.delete :cluster
74
+ def default_bounded_option(options)
75
+ bounded = true
76
+ if options.has_key? :bounded
77
+ bounded = options[:bounded]
84
78
  end
85
- cluster_prefix = (is_cluster ? 'cluster_' : '')
79
+ options[:bounded] = bounded
86
80
  end
87
81
  end
88
82
  end
@@ -10,6 +10,7 @@ module Dogviz
10
10
  @graph[hints]
11
11
  @subgraphs = {}
12
12
  @nodes = {}
13
+ @rendered_subgraph_ids = {}
13
14
  end
14
15
 
15
16
  def render_edge(from, other, options)
@@ -20,34 +21,45 @@ module Dogviz
20
21
  edge
21
22
  end
22
23
 
23
- def render_node(parent, id, options, attributes)
24
- clean_node_options options
25
- default_options = {:shape => 'box', :style => ''}
26
- node = parent_node(parent).add_nodes(id, default_options.merge(options))
27
- apply_render_attributes node, attributes
24
+ def render_node(parent, id, attributes)
25
+ clean_node_attributes attributes
26
+ default_attributes = {:shape => 'box', :style => ''}
27
+ merged_attributes = default_attributes.merge(attributes)
28
+ node = parent_node(parent).add_nodes(id, merged_attributes)
28
29
  end
29
30
 
30
- def render_subgraph(parent, id, options, attributes)
31
- subgraph = parent_node(parent).add_graph(id, options)
32
- apply_render_attributes subgraph, attributes
31
+ def render_subgraph(parent, id, attributes)
32
+ if (attributes[:bounded] == true) then
33
+ rendered_id = 'cluster_' + id
34
+ else
35
+ rendered_id = id
36
+ end
37
+ @rendered_subgraph_ids[id] = rendered_id
38
+
39
+ subgraph = parent_node(parent).add_graph(rendered_id, clean_subgraph_attributes(attributes.clone))
33
40
  @subgraphs[id] = subgraph
34
41
  subgraph
35
42
  end
36
43
 
37
44
  private
38
45
 
39
- def clean_node_options(options)
40
- options.delete(:rank)
41
- options.delete(:cluster)
42
- options
46
+ def clean_node_attributes(attributes)
47
+ attributes.delete(:rank)
48
+ attributes.delete(:bounded)
49
+ attributes
50
+ end
51
+
52
+ def clean_subgraph_attributes(attributes)
53
+ attributes.delete(:bounded)
54
+ attributes
43
55
  end
44
56
 
45
57
  def parent_node(parent)
46
- return graph unless parent.respond_to?(:render_id)
47
- node = graph.search_node(parent.render_id)
58
+ return graph if parent.root?
59
+ node = graph.search_node(parent.id)
48
60
  return node unless node.nil?
49
- subgraph = @subgraphs[parent.render_id]
50
- raise "couldn't find node or graph: #{parent.render_id}, out of graphs: #{graph_ids}" if subgraph.nil?
61
+ subgraph = @subgraphs[parent.id]
62
+ raise "couldn't find node or graph: #{parent.id}, out of graphs: #{graph_ids}" if subgraph.nil?
51
63
  subgraph
52
64
  end
53
65
 
@@ -2,7 +2,7 @@ require_relative 'container'
2
2
  module Dogviz
3
3
  class LogicalContainer < Container
4
4
  def initialize(parent, name, options)
5
- super parent, name, options.merge(cluster: false)
5
+ super parent, name, options.merge(bounded: false)
6
6
  end
7
7
  end
8
8
  end
@@ -2,7 +2,7 @@ module Dogviz
2
2
  module Nominator
3
3
  def nominate(names_to_nominees)
4
4
  names_to_nominees.each { |name, nominee|
5
- self.class.send(:define_method, name) do
5
+ define_singleton_method name do
6
6
  nominee
7
7
  end
8
8
  }
data/lib/dogviz/parent.rb CHANGED
@@ -34,5 +34,9 @@ module Dogviz
34
34
  @children << child
35
35
  child
36
36
  end
37
+
38
+ def root?
39
+ not respond_to?(:parent)
40
+ end
37
41
  end
38
42
  end
@@ -18,8 +18,8 @@ module Dogviz
18
18
 
19
19
  def get_json_filename(type_to_filename)
20
20
  type = type_to_filename.keys.first
21
- raise StandardError.new('json output only supported') unless type == :json
21
+ raise StandardError.new("json output only supported, not #{type}") unless type == :json
22
22
  type_to_filename[type]
23
23
  end
24
24
  end
25
- end
25
+ end
@@ -12,8 +12,14 @@ module Dogviz
12
12
  SigmaGraphHash.new(nodes: nodes, edges: edges)
13
13
  end
14
14
 
15
- def render_node(parent, id, render_options, attributes)
15
+ def render_node(parent, id, attributes)
16
16
  @nodes << {id: id, label: id}
17
+ @edges << {
18
+ id: "#{parent.id}->#{id}",
19
+ type: 'containment',
20
+ source: parent.id,
21
+ target: id
22
+ } unless parent.root?
17
23
  end
18
24
 
19
25
  def render_edge(from, to, options)
@@ -25,8 +31,22 @@ module Dogviz
25
31
  }
26
32
  end
27
33
 
34
+ def render_subgraph(parent, id, attributes)
35
+ @nodes << {id: container_label(id), type: 'container', label: container_label(id)}
36
+ @edges << {
37
+ id: "#{container_label parent.id}->#{container_label id}",
38
+ type: 'containment',
39
+ source: container_label(parent.id),
40
+ target: container_label(id)
41
+ } unless parent.root?
42
+ end
43
+
28
44
  private
29
45
 
46
+ def container_label(id)
47
+ id
48
+ end
49
+
30
50
  attr_reader :nodes, :edges
31
51
  end
32
- end
52
+ end
data/lib/dogviz/thing.rb CHANGED
@@ -43,6 +43,9 @@ module Dogviz
43
43
  other
44
44
  end
45
45
 
46
+ alias_method :to, :points_to
47
+ alias_method :to_all, :points_to_all
48
+
46
49
  def render(renderer)
47
50
  do_render_node(renderer) unless in_rollup? || in_skip?
48
51
  end
@@ -56,9 +59,7 @@ module Dogviz
56
59
  private
57
60
 
58
61
  def do_render_node(renderer)
59
- render_options = @render_options
60
- attributes = @attributes
61
- renderer.render_node(parent, id, render_options, attributes)
62
+ renderer.render_node(parent, id, @render_options.merge(@attributes))
62
63
  end
63
64
 
64
65
  def setup_render_edge(other, options)
@@ -1,3 +1,3 @@
1
1
  module Dogviz
2
- VERSION = '0.0.18'
2
+ VERSION = '0.0.19'
3
3
  end
@@ -3,6 +3,10 @@ module GraphChecking
3
3
  subgraphs.map(&:id)
4
4
  end
5
5
 
6
+ def subgraph_ids_without_cluster_prefixes
7
+ subgraph_ids.map {|id| id.gsub /^cluster_/, '' }
8
+ end
9
+
6
10
  def subgraph(id)
7
11
  subgraphs.find {|sub| sub.id == id }
8
12
  end
@@ -30,7 +30,7 @@ module Tests
30
30
  def test_container_exposes_inherited_render_options_from_parent
31
31
  inheritable_options = {fontname: 'glyphoz'}
32
32
  parent.render_options = inheritable_options
33
- assert_equal inheritable_options, Container.new(parent, 'container').render_options
33
+ assert_equal 'glyphoz', Container.new(parent, 'container').render_options[:fontname]
34
34
  end
35
35
  end
36
36
  end
@@ -52,5 +52,16 @@ module Tests
52
52
  assert_equal ['chases', 'follows', 'parents', 'ignores'], graph.names_of.edges
53
53
  end
54
54
 
55
+ def test_allows_rank_specification
56
+ sys = Family.new
57
+ sys.logical_container 'sinker', rank: 'sink'
58
+
59
+ sys.output dot: outfile('dot')
60
+
61
+ dotspec = File.read outfile('dot')
62
+
63
+ assert_match /rank=sink/, dotspec
64
+ end
65
+
55
66
  end
56
67
  end
@@ -115,11 +115,17 @@ class TestDogvizGraph < Test::Unit::TestCase
115
115
  end
116
116
 
117
117
  class Dog
118
+ def initialize(name)
119
+ @name = name.to_s
120
+ end
121
+ def inspect
122
+ "dog #{@name}"
123
+ end
118
124
  end
119
125
  def test_nominate_elevates_values_as_method_on_group
120
126
  group = sys.group('g')
121
127
 
122
- dog = Dog.new
128
+ dog = Dog.new 'a'
123
129
 
124
130
  group.nominate foobar: :any_value, dog: dog
125
131
 
@@ -127,6 +133,20 @@ class TestDogvizGraph < Test::Unit::TestCase
127
133
  assert_equal dog, group.dog
128
134
  end
129
135
 
136
+ def test_nominates_with_same_name_on_different_containers_work_together
137
+ group1 = sys.group('g1')
138
+ group2 = sys.group('g2')
139
+
140
+ dog1 = Dog.new 1
141
+ dog2 = Dog.new 2
142
+
143
+ group1.nominate dog: dog1
144
+ group2.nominate dog: dog2
145
+
146
+ assert_equal dog1, group1.dog
147
+ assert_equal dog2, group2.dog
148
+ end
149
+
130
150
  def test_nominate_from_delegates_multiple_accessors
131
151
  outer = sys.group('outer')
132
152
  nested = outer.group('nested')
@@ -56,17 +56,17 @@ class TestDogvizGraphvizRendering < Test::Unit::TestCase
56
56
 
57
57
  graph
58
58
 
59
- assert_equal([top.render_id, nested.render_id], subgraph_ids)
59
+ assert_equal([top.id, nested.id], subgraph_ids_without_cluster_prefixes)
60
60
 
61
- top_subgraph = subgraph(top.render_id)
62
- nested_subgraph = subgraph(nested.render_id)
61
+ top_subgraph = subgraph('cluster_' + top.id)
62
+ nested_subgraph = subgraph('cluster_' + nested.id)
63
63
 
64
64
  assert_equal(top_thing.id, top_subgraph.get_node(top_thing.id).id)
65
65
  assert_equal(nested_thing.id, nested_subgraph.get_node(nested_thing.id).id)
66
66
  assert_nil(top_subgraph.get_node(nested_thing.id), 'should not be in other container')
67
67
  assert_nil(nested_subgraph.get_node(top_thing.id), 'should not be in other container')
68
68
  end
69
-
69
+
70
70
  def test_point_into_target_in_container
71
71
  container = sys.container('container')
72
72
  target = container.thing('target')
@@ -348,4 +348,22 @@ class TestDogvizGraphvizRendering < Test::Unit::TestCase
348
348
  assert_equal('thread->haystack_nested_hidden_away_needle', connections)
349
349
  end
350
350
 
351
+ def test_can_use_to_method_to_point_to_things
352
+ a = sys.thing 'a'
353
+ b = sys.thing 'b'
354
+ c = sys.thing 'c'
355
+ a.to(b).to(c)
356
+
357
+ assert_equal('a->b b->c', connections)
358
+ end
359
+
360
+ def test_can_use_to_all_method_to_point_to_things
361
+ a = sys.thing 'a'
362
+ b = sys.thing 'b'
363
+ c = sys.thing 'c'
364
+ a.to_all b, c
365
+
366
+ assert_equal('a->b a->c', connections)
367
+ end
368
+
351
369
  end
@@ -23,6 +23,55 @@ class TestDogvizSigmaRendering < Test::Unit::TestCase
23
23
  assert_equal({nodes: [ { id: 'a', label: 'a' }], edges: []}, graph)
24
24
  end
25
25
 
26
+ def test_includes_containers_with_appropriate_types
27
+ sys.container('c').thing('a')
28
+
29
+ graph = sys.render(:sigma)
30
+
31
+ assert_equal({
32
+ nodes: [
33
+ { id: 'c', type: 'container', label: 'c' },
34
+ { id: 'c_a', label: 'c_a' }
35
+ ],
36
+ edges: [
37
+ {
38
+ id: 'c->c_a',
39
+ type: 'containment',
40
+ source: 'c',
41
+ target: 'c_a'
42
+ }
43
+ ]
44
+ }, graph)
45
+ end
46
+
47
+ def test_includes_nested_containers_modelled_with_containment_edges
48
+ sys.container('c').container('cc').thing('x')
49
+
50
+ graph = sys.render(:sigma)
51
+
52
+ assert_equal({
53
+ nodes: [
54
+ { id: 'c', type: 'container', label: 'c' },
55
+ { id: 'c_cc', type: 'container', label: 'c_cc' },
56
+ { id: 'c_cc_x', label: 'c_cc_x' }
57
+ ],
58
+ edges: [
59
+ {
60
+ id: 'c->c_cc',
61
+ type: 'containment',
62
+ source: 'c',
63
+ target: 'c_cc'
64
+ },
65
+ {
66
+ id: 'c_cc->c_cc_x',
67
+ type: 'containment',
68
+ source: 'c_cc',
69
+ target: 'c_cc_x'
70
+ }
71
+ ]
72
+ }, graph)
73
+ end
74
+
26
75
  def test_renders_two_linked_nodes
27
76
  sys.thing('a').points_to sys.thing('b')
28
77
 
@@ -54,15 +103,15 @@ class TestDogvizSigmaRendering < Test::Unit::TestCase
54
103
  end
55
104
 
56
105
  def test_output_requires_type
57
- assert_raise_with_message(StandardError, /provide hash/) {
106
+ assert_raise_message(/provide hash/) {
58
107
  sys.render(:sigma).output 'file'
59
108
  }
60
109
  end
61
110
 
62
111
  def test_json_only_output
63
- assert_raise_with_message(StandardError, /json.*only/) {
112
+ assert_raise_message(/json.*only/) {
64
113
  sys.render(:sigma).output xml: 'xmlfile'
65
114
  }
66
115
  end
67
116
 
68
- end
117
+ end
data/tests/test_thing.rb CHANGED
@@ -6,9 +6,9 @@ module Tests
6
6
  include Dogviz
7
7
 
8
8
  class StubRenderer
9
- attr_reader :last_node_options, :last_edge_options
10
- def render_node(parent, id, render_options, attributes)
11
- @last_node_options = render_options.merge attributes
9
+ attr_reader :last_node_attributes, :last_edge_options
10
+ def render_node(parent, id, attributes)
11
+ @last_node_attributes = attributes
12
12
  end
13
13
  def render_edge(from, other, options)
14
14
  @last_edge_options = options
@@ -45,7 +45,7 @@ module Tests
45
45
 
46
46
  thing.render renderer
47
47
 
48
- assert_equal 'funky-font', renderer.last_node_options[:fontname]
48
+ assert_equal 'funky-font', renderer.last_node_attributes[:fontname]
49
49
  end
50
50
 
51
51
  def test_thing_edges_rendered_with_inherited_fontname
data/todo.txt CHANGED
@@ -1,7 +1,9 @@
1
- * render generic output (sigma.js json) for ingestion -> unity
2
- * move from inheritance -> better encaps
1
+ * spike 'autostrap': automatically strap-on reader methods using normalised name
2
+ * [DONE] render generic output (sigma.js json) for ingestion -> space-dog
3
3
  * sort out fore vs back color
4
- * move out any graphviz specifics from main models, e.g. colorize
4
+ * [DONE] move 'cluster_' prefix to graphviz renderer
5
5
  * clean up init options + render attributes - not v clear / overlapping
6
- * separate style from domain-specific elements (can use same view-manipulation selection mechanisms)
7
6
  * make style attributes well defined -> less leaky + explicit graphviz passthroughs
7
+ * separate style from domain-specific elements (can use same view-manipulation selection mechanisms)
8
+ * move out any graphviz specifics from main models, e.g. colorize
9
+ * move from inheritance -> better encaps
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dogviz
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.18
4
+ version: 0.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - damned
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-19 00:00:00.000000000 Z
11
+ date: 2017-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -101,6 +101,7 @@ executables: []
101
101
  extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
+ - ".bundle/config"
104
105
  - ".gitignore"
105
106
  - ".ruby-version"
106
107
  - Gemfile
@@ -167,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
168
  version: '0'
168
169
  requirements: []
169
170
  rubyforge_project:
170
- rubygems_version: 2.4.3
171
+ rubygems_version: 2.6.11
171
172
  signing_key:
172
173
  specification_version: 4
173
174
  summary: domain object graph visualisation