dogviz 0.0.10 → 0.0.11

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: cc41dd5fb565570c0542f852fe798a3c33bd0e92
4
- data.tar.gz: 3561e4fe3f217a3a8939de36377d0a32a0ad36da
3
+ metadata.gz: f959437590340358149cd658e36ffbe14108dcb8
4
+ data.tar.gz: 54468cd372743f2f43669a12315d9b18db7f310c
5
5
  SHA512:
6
- metadata.gz: ad9a6fe72533c4687e2cbfab4ba6cf582d2a3680890258707a13c4458bfb894a0bc6a9572b4685c23e8c351d36de78fa9069780a66cc531e541fee06abfb220b
7
- data.tar.gz: eed194cd2f1540ab35d25ef23cb41fc3ccfc5cda34f55f84c58a8709be5a440c1faa4a641029ed850dfa49c7839a6143fbee8f922935bc5c34236c72540a5c61
6
+ metadata.gz: 50303617d8055c24805c2f21c9329888a247f1c8b6a84188c11d84e094f14030cf7f6e4826e6cc4a37e00f6c29992547ac26765b5fb98281da85186046438999
7
+ data.tar.gz: fa6ac254da3d07c81bbe56526ef7cab36d037cbc2be20bd9248290c8bb7bcb8dc51e76339a047f20a93962e50814c7058a576b293850506c3ca69d56f96c8b56
@@ -0,0 +1,15 @@
1
+ require 'dogviz'
2
+
3
+ dogviz = Dogviz::System.new 'dogviz', splines: true
4
+
5
+ classes = dogviz.container('classes')
6
+ system = classes.thing('System')
7
+ thing = classes.thing('Thing')
8
+ container = classes.thing('Container')
9
+ container.points_to thing, name: 'contains'
10
+ container.points_to container, name: 'contains'
11
+ system.points_to thing, name: 'contains'
12
+ system.points_to container, name: 'contains'
13
+
14
+
15
+ dogviz.output svg: 'dogviz-generated.svg'
@@ -1,3 +1,3 @@
1
1
  module Dogviz
2
- VERSION = '0.0.10'
2
+ VERSION = '0.0.11'
3
3
  end
data/lib/dogviz.rb CHANGED
@@ -1,6 +1,20 @@
1
1
  require 'ruby-graphviz'
2
2
 
3
3
  module Dogviz
4
+ class Process
5
+ def initialize(processor, description)
6
+ @processor = processor
7
+ @description = description
8
+ end
9
+ def name
10
+ @processor.name
11
+ end
12
+ end
13
+ module Flowable
14
+ def does(action)
15
+ Process.new(self, action)
16
+ end
17
+ end
4
18
  module Common
5
19
  def create_id(name, parent)
6
20
  parts = []
@@ -72,6 +86,13 @@ module Dogviz
72
86
  end
73
87
  end
74
88
  module Parent
89
+ def nominate(names_to_values)
90
+ names_to_values.each {|name, value|
91
+ self.class.send(:define_method, name) do
92
+ value
93
+ end
94
+ }
95
+ end
75
96
  def find_all(&matcher)
76
97
  raise MissingMatchBlockError.new unless block_given?
77
98
  @by_name.find_all &matcher
@@ -104,6 +125,7 @@ module Dogviz
104
125
 
105
126
  class Thing
106
127
  include Common
128
+ include Flowable
107
129
  attr_reader :parent
108
130
  attr_reader :name, :id, :pointers, :edge_heads
109
131
 
@@ -360,6 +382,109 @@ module Dogviz
360
382
  end
361
383
  end
362
384
 
385
+ class Flow
386
+ def initialize(sys, name)
387
+ @sys = sys
388
+ @name = name
389
+ @calls = []
390
+ end
391
+
392
+ def flows(*steps)
393
+ from = nil
394
+ to = nil
395
+ label = nil
396
+ steps.each do |step|
397
+ if from.nil?
398
+ from = ensure_is_thing(step)
399
+ elsif label.nil? && step.is_a?(String)
400
+ label = step
401
+ elsif to.nil?
402
+ to = ensure_is_thing(step)
403
+ end
404
+ unless to.nil?
405
+ calls << [from, to, label]
406
+ from = to
407
+ to = label = nil
408
+ end
409
+ end
410
+ end
411
+
412
+ def ensure_is_thing(step)
413
+ raise "Expected some thing or process: '#{step}' already got: #{calls}" unless step.is_a?(Thing) || step.is_a?(Process)
414
+ step
415
+ end
416
+
417
+ def output(type_to_file)
418
+ type = type_to_file.keys.first
419
+ raise "Only support sequence, not: '#{type}'" unless type == :sequence
420
+ render.output(type_to_file)
421
+ end
422
+
423
+ def render
424
+ renderer = SequenceRenderer.new(@name)
425
+ calls.each do |from, to, label|
426
+ renderer.render_edge from, to, {label: label}
427
+ end
428
+ renderer.rendered
429
+ end
430
+ private
431
+ attr_reader :calls
432
+ end
433
+
434
+
435
+ class RenderedSequence
436
+ def initialize(lines)
437
+ @lines = lines
438
+ end
439
+ def output(type_to_file)
440
+ text = @lines.map(&:strip).join "\n"
441
+ File.write type_to_file.values.first, text
442
+ text
443
+ end
444
+ end
445
+
446
+ class SequenceRenderer
447
+ attr_reader :lines
448
+ def initialize(title)
449
+ @lines = []
450
+ end
451
+
452
+ def render_edge(from, other, options)
453
+
454
+ detail = options[:label]
455
+ receiver_label = other.name
456
+ sender_label = from.name
457
+ if other.is_a?(Process)
458
+ receiver_label = process_start_label(receiver_label)
459
+ detail = process_annotations(detail)
460
+ elsif from.is_a?(Process)
461
+ receiver_label = process_end_label(receiver_label)
462
+ end
463
+ lines << "#{sender_label} -> #{receiver_label}: #{detail}"
464
+ end
465
+
466
+ def rendered
467
+ RenderedSequence.new lines
468
+ end
469
+
470
+ private
471
+
472
+ def process_start_label(receiver_label)
473
+ "+#{receiver_label}"
474
+ end
475
+
476
+ def process_end_label(receiver_label)
477
+ "-#{receiver_label}"
478
+ end
479
+
480
+ def process_annotations(detail)
481
+ detail = [detail,
482
+ 'note right of cook',
483
+ ' cooks burger',
484
+ 'end note'].join("\n")
485
+ end
486
+ end
487
+
363
488
  class System
364
489
  include Parent
365
490
 
@@ -382,6 +507,10 @@ module Dogviz
382
507
  out
383
508
  end
384
509
 
510
+ def flow(name)
511
+ Flow.new self, name
512
+ end
513
+
385
514
  def render(type=:graphviz)
386
515
  return @graph if @rendered
387
516
  raise "dunno bout that '#{type}', only know :graphviz" unless type == :graphviz
@@ -4,41 +4,124 @@ require_relative 'svg_graph'
4
4
  module Tests
5
5
  class TestDogvizFunctionally < Test::Unit::TestCase
6
6
 
7
- def svg_outfile
8
- '/tmp/dogviz_functional_test.svg'
7
+ def outfile(ext)
8
+ "/tmp/dogviz_functional_test.#{ext}"
9
+ end
10
+
11
+ def read_outfile(ext)
12
+ File.read outfile(ext)
9
13
  end
10
14
 
11
15
  def setup
12
- File.delete svg_outfile if File.exist?(svg_outfile)
16
+ File.delete outfile('svg') if File.exist?(outfile('svg'))
13
17
  end
14
18
 
15
19
  include Dogviz
16
- def test_outputs_svg_graph
20
+ class Family < Dogviz::System
21
+ attr_reader *%i(cat dog mum son)
22
+ def initialize
23
+ super 'family'
17
24
 
18
- sys = System.new 'family'
25
+ house = container 'household'
19
26
 
20
- house = sys.container 'household'
27
+ @cat = house.thing 'cat'
28
+ @dog = house.thing 'dog'
21
29
 
22
- cat = house.thing 'cat'
23
- dog = house.thing 'dog'
30
+ @mum = house.thing 'mum'
31
+ @son = house.thing 'son'
24
32
 
25
- mum = house.thing 'mum'
26
- son = house.thing 'son'
33
+ mum.points_to son, name: 'parents'
34
+ son.points_to mum, name: 'ignores'
27
35
 
28
- mum.points_to son, name: 'parents'
29
- son.points_to mum, name: 'respects'
36
+ cat.points_to dog, name: 'chases'
37
+ dog.points_to son, name: 'follows'
38
+ end
39
+ end
30
40
 
31
- cat.points_to dog, name: 'chases'
32
- dog.points_to son, name: 'follows'
41
+ def test_outputs_svg_graph
42
+
43
+ sys = Family.new
33
44
 
34
- sys.output svg: svg_outfile
45
+ sys.output svg: outfile('svg')
35
46
 
36
- graph = SvgGraph.parse_file svg_outfile
47
+ graph = SvgGraph.parse_file outfile('svg')
37
48
 
38
49
  assert_include graph.title, 'family'
39
50
  assert_equal ['household'], graph.names_of.containers
40
51
  assert_equal ['cat', 'dog', 'son', 'mum'], graph.names_of.things
41
- assert_equal ['chases', 'follows', 'parents', 'respects'], graph.names_of.edges
52
+ assert_equal ['chases', 'follows', 'parents', 'ignores'], graph.names_of.edges
53
+ end
54
+
55
+ def test_flow_generates_precise_sequence
56
+ sys = System.new 'takeaway'
57
+ eater = sys.thing 'eater'
58
+ server = sys.thing 'server'
59
+ cook = sys.thing 'cook'
60
+
61
+ order = sys.flow 'order'
62
+ order.flows eater, 'asks for burger',
63
+ server, 'passes order',
64
+ cook, server, eater
65
+
66
+ order.output sequence: outfile('seq.txt')
67
+
68
+ definition = read_outfile('seq.txt')
69
+
70
+ assert_equal [
71
+ 'eater -> server: asks for burger',
72
+ 'server -> cook: passes order',
73
+ 'cook -> server:',
74
+ 'server -> eater:',
75
+ ].join("\n"), definition
76
+ end
77
+
78
+ def test_flow_generates_precise_sequence_with_action
79
+ sys = System.new 'takeaway'
80
+ eater = sys.thing 'eater'
81
+ server = sys.thing 'server'
82
+ cook = sys.thing 'cook'
83
+
84
+ order = sys.flow 'order'
85
+ order.flows eater, 'orders',
86
+ server, 'creates order',
87
+ cook.does('cooks burger'),
88
+ 'burger', server,
89
+ 'burger', eater
90
+
91
+ order.output sequence: outfile('seq.txt')
92
+ definition = read_outfile('seq.txt')
93
+
94
+ assert_equal([
95
+ 'eater -> server: orders',
96
+ 'server -> +cook: creates order',
97
+ 'note right of cook',
98
+ ' cooks burger',
99
+ 'end note',
100
+ 'cook -> -server: burger',
101
+ 'server -> eater: burger',
102
+ ].join("\n"), definition)
103
+ end
104
+
105
+ def xtest_flows_render_sequence_diagrams_and_form_edges
106
+
107
+ sys = System.new 'service'
108
+
109
+ organisation = sys.container 'organisation'
110
+
111
+ customer = sys.thing 'customer'
112
+
113
+ support = organisation.thing 'support phone line'
114
+ ivr = organisation.thing 'ivr'
115
+ first = organisation.thing 'first level support'
116
+ second = organisation.thing 'second level support'
117
+
118
+ complaint = sys.flow 'complaint'
119
+
120
+ complain.flows customer, 'calls',
121
+ support, 'connects to',
122
+ ivr, ''
123
+
124
+
42
125
  end
43
126
 
44
127
  end
@@ -114,6 +114,19 @@ class TestDogvizGraph < Test::Unit::TestCase
114
114
  })
115
115
  end
116
116
 
117
+ class Dog
118
+ end
119
+ def test_nominate_elevates_values_as_method_on_group
120
+ group = sys.group('g')
121
+
122
+ dog = Dog.new
123
+
124
+ group.nominate foobar: :any_value, dog: dog
125
+
126
+ assert_equal :any_value, group.foobar
127
+ assert_equal dog, group.dog
128
+ end
129
+
117
130
  def test_root
118
131
  group = sys.group('g')
119
132
  nested_group = group.group('nested group')
@@ -329,6 +329,24 @@ class TestDogvizGraphvizRendering < Test::Unit::TestCase
329
329
  assert_equal('"a\nip: 1.1.1.1"', find('a')['label'].to_ruby)
330
330
  end
331
331
 
332
+ def test_nominate_reduces_need_to_find_when_piecing_together_chunks_built_in_other_methods
333
+ def build_haystack
334
+ haystack = sys.group 'haystack'
335
+ needle = haystack.group('nested').group('hidden away').thing('needle')
336
+
337
+ haystack.nominate needle: needle
338
+ haystack
339
+ end
340
+
341
+ haystack = build_haystack
342
+
343
+ thread = sys.thing 'thread'
344
+ thread.points_to haystack.needle
345
+
346
+ assert_equal('thread->haystack_nested_hidden_away_needle', connections)
347
+ end
348
+
349
+
332
350
  private
333
351
 
334
352
  def subgraph_ids
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.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - damned
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-09 00:00:00.000000000 Z
11
+ date: 2016-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,6 +108,7 @@ files:
108
108
  - README.md
109
109
  - Rakefile
110
110
  - dogviz.gemspec
111
+ - examples/dogfood.rb
111
112
  - examples/website.rb
112
113
  - examples/website_domain.rb
113
114
  - lib/dogviz.rb