diaspora-cluster-creator 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/.gitignore +1 -2
  2. data/Guardfile +1 -2
  3. data/README.md +2 -0
  4. data/TODO.todo +2 -0
  5. data/bin/diaspora-cluster +11 -8
  6. data/diaspora-cluster-creator.gemspec +2 -0
  7. data/features/cluster.feature +1 -1
  8. data/features/command_line.feature +165 -0
  9. data/features/node.feature +13 -0
  10. data/features/step_definitions/cluster_steps.rb +3 -3
  11. data/features/step_definitions/command_line_steps.rb +7 -0
  12. data/features/step_definitions/node_steps.rb +16 -0
  13. data/features/support/aruba.rb +1 -0
  14. data/features/support/world.rb +4 -8
  15. data/lib/diaspora-cluster-creator.rb +12 -9
  16. data/lib/diaspora-cluster-creator/attribute.rb +29 -0
  17. data/lib/diaspora-cluster-creator/attribute_collection_factory.rb +29 -0
  18. data/lib/diaspora-cluster-creator/cluster.rb +31 -18
  19. data/lib/diaspora-cluster-creator/edge_drawer.rb +41 -0
  20. data/lib/diaspora-cluster-creator/guarantor.rb +21 -0
  21. data/lib/diaspora-cluster-creator/node.rb +71 -0
  22. data/lib/diaspora-cluster-creator/node_attribute.rb +41 -0
  23. data/lib/diaspora-cluster-creator/node_collection_factory.rb +30 -0
  24. data/lib/diaspora-cluster-creator/template.rb +23 -16
  25. data/lib/diaspora-cluster-creator/version.rb +1 -1
  26. data/spec/diaspora-cluster-creator/attribute_collection_factory_spec.rb +31 -0
  27. data/spec/diaspora-cluster-creator/attribute_spec.rb +69 -0
  28. data/spec/diaspora-cluster-creator/cluster_spec.rb +66 -15
  29. data/spec/diaspora-cluster-creator/edge_drawer_spec.rb +21 -0
  30. data/spec/diaspora-cluster-creator/guarantor_spec.rb +54 -0
  31. data/spec/diaspora-cluster-creator/node_attribute_spec.rb +36 -0
  32. data/spec/diaspora-cluster-creator/node_collection_factory_spec.rb +27 -0
  33. data/spec/diaspora-cluster-creator/node_spec.rb +65 -0
  34. data/spec/diaspora-cluster-creator/template_integration_spec.rb +9 -10
  35. data/spec/diaspora-cluster-creator/template_spec.rb +9 -2
  36. metadata +78 -34
  37. data/features/star_system.feature +0 -13
  38. data/features/step_definitions/star_system_steps.rb +0 -16
  39. data/lib/diaspora-cluster-creator/graph.rb +0 -58
  40. data/lib/diaspora-cluster-creator/star_system.rb +0 -80
  41. data/spec/diaspora-cluster-creator/graph_spec.rb +0 -34
  42. data/spec/diaspora-cluster-creator/star_system_spec.rb +0 -103
data/.gitignore CHANGED
@@ -15,5 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
- cluster.png
19
- cluster.dot
18
+ cluster.*
data/Guardfile CHANGED
@@ -33,7 +33,7 @@ end
33
33
 
34
34
  guard 'bundler' do
35
35
  watch('Gemfile')
36
- watch('*.gemspec')
36
+ watch(%r{.*\.gemspec})
37
37
  # Uncomment next line if Gemfile contain `gemspec' command
38
38
  # watch(/^.+\.gemspec/)
39
39
  end
@@ -42,5 +42,4 @@ guard 'cucumber' do
42
42
  watch(%r{^features/.+\.feature$})
43
43
  watch(%r{^features/support/.+$}) { 'features' }
44
44
  watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
45
- watch(%r{^lib/diaspora-cluster-creator/(.+)\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
46
45
  end
data/README.md CHANGED
@@ -38,6 +38,8 @@ Or you can specify names
38
38
  Or perhaps you prefer a PNG
39
39
 
40
40
  $ diaspora-cluster filename=output.png names="Sparta [T2 E1 R3], Athens [T-2], Corinth [R3 T2 E1], Ephesus, Rhodes [T4]"
41
+
42
+ Take a look at /features/command_line.feature for better definitions.
41
43
 
42
44
  ## Contributing
43
45
 
@@ -0,0 +1,2 @@
1
+ – Allow different attributes to be passed.
2
+ – The above implies an NodeAttribute class; And a Config class as well.
@@ -5,25 +5,28 @@ require_relative '../lib/diaspora-cluster-creator'
5
5
 
6
6
  Main do
7
7
  description 'Generate a diaspora cluster'
8
- keyword('names', 'n') {
8
+ keyword('names') {
9
9
  arity(-1)
10
10
  cast :list_of_string
11
11
  description "List of cluster names, comma separated."
12
12
  }
13
- keyword('count', 'c') {
13
+ keyword('count') {
14
14
  arity 1
15
15
  cast :integer
16
16
  description "Instead of a list of names, provide a cluster count."
17
17
  }
18
- keyword('filename', 'f') {
19
- required
18
+ keyword('filename') {
20
19
  arity 1
21
- validate {|output| output =~ /\w\.(png|dot)$/i}
22
- description "filename.DOT or filename.PNG"
23
- default "cluster.dot"
20
+ validate {|output| output =~ /\w\.(png|svg|dot)$/i}
21
+ description ".png, .svg, .dot formats"
22
+ }
23
+ keyword('attributes') {
24
+ arity(-1)
25
+ cast :list_of_string
26
+ description "Instead of the default attributes, specify a different set"
24
27
  }
25
28
  def run
26
- options = {:names => params[:names].value, :count => params[:count].value, :filename => params[:filename].value}
29
+ options = {:names => params[:names].value, :count => params[:count].value, :filename => params[:filename].value, :attributes => params[:attributes].value}
27
30
  Diaspora::Cluster::Creator.run(options)
28
31
  end
29
32
  end
@@ -22,6 +22,8 @@ Gem::Specification.new do |gem|
22
22
  gem.add_development_dependency 'guard-bundler'
23
23
  gem.add_development_dependency 'guard-cucumber'
24
24
  gem.add_development_dependency 'growl'
25
+ gem.add_development_dependency 'debugger'
26
+ gem.add_development_dependency 'aruba'
25
27
 
26
28
  gem.add_runtime_dependency "ruby-graphviz"
27
29
  gem.add_runtime_dependency "main"
@@ -1,6 +1,6 @@
1
1
  Feature: Cluster creation
2
2
 
3
3
  Scenario: Cluster creation
4
- When I request a new cluster with 5 star systems
4
+ When I request a new cluster with 5 node systems
5
5
  Then the output should have 5 nodes
6
6
  And the output should have at least 4 edges
@@ -0,0 +1,165 @@
1
+ @announce
2
+ Feature: Provide tested examples of the command-line interface
3
+
4
+ Scenario: Specify without parameters
5
+ When I run `diaspora-cluster`
6
+ Then it should pass with output like:
7
+ """
8
+ graph Cluster {
9
+ A \[label = "A
10
+ T-?\d R-?\d E-?\d"\];
11
+ B \[label = "B
12
+ T-?\d R-?\d E-?\d"\];
13
+ A -- B
14
+ }
15
+ """
16
+
17
+ Scenario: Specify with names
18
+ When I run `diaspora-cluster names="Sparta{T2 E-1 R0},Athens{T1 E1 R0}"`
19
+ Then it should pass with:
20
+ """
21
+ graph Cluster {
22
+ Sparta [label = "Sparta
23
+ T2 R0 E-1"];
24
+ Athens [label = "Athens
25
+ T1 R0 E1"];
26
+ Sparta -- Athens
27
+ }
28
+ """
29
+
30
+ Scenario: Specify with technology guarantee
31
+ When I run `diaspora-cluster names="Sparta{T0 E-1 R0},Athens{T1 E1 R0},Corinth{T1 E0 R0}"`
32
+ Then it should pass with output like:
33
+ """
34
+ graph Cluster {
35
+ Sparta \[label = "Sparta
36
+ T2 R0 E-1"\];
37
+ Athens \[label = "Athens
38
+ T2 R0 E1"\];
39
+ Corinth \[label = "Corinth
40
+ T1 R0 E0"\];
41
+ Sparta -- Athens
42
+ Athens -- Corinth
43
+ }
44
+ """
45
+
46
+ Scenario: With -h
47
+ When I run `diaspora-cluster -h`
48
+ Then it should fail with output like:
49
+ """
50
+ NAME
51
+ diaspora-cluster
52
+
53
+ SYNOPSIS
54
+ diaspora-cluster \[names=names\] \[count=count\] \[filename=filename\]
55
+
56
+ DESCRIPTION
57
+ Generate a diaspora cluster
58
+
59
+ PARAMETERS
60
+ names
61
+ count
62
+ filename
63
+ --help, -h
64
+ """
65
+
66
+ Scenario Outline: I want files of different formats
67
+ When I run `diaspora-cluster filename=cluster.<FORMAT>`
68
+ Then the following files should exist:
69
+ | cluster.<FORMAT> |
70
+
71
+ Examples:
72
+ | FORMAT |
73
+ | png |
74
+ | dot |
75
+ | svg |
76
+
77
+ Scenario: Specify different attributes
78
+ When I run `diaspora-cluster attributes="Magic, Religion, Science"`
79
+ Then it should pass with output like:
80
+ """
81
+ graph Cluster {
82
+ A \[label = "A
83
+ M-?\d R-?\d S-?\d"\];
84
+ B \[label = "B
85
+ M-?\d R-?\d S-?\d"\];
86
+ C \[label = "C
87
+ M-?\d R-?\d S-?\d"\];
88
+ D \[label = "D
89
+ M-?\d R-?\d S-?\d"\];
90
+ E \[label = "E
91
+ M-?\d R-?\d S-?\d"\];
92
+ A -- B
93
+ B -- C
94
+ C -- D
95
+ D -- E
96
+ """
97
+
98
+ Scenario: Specify different attributes with prefix override
99
+ When I run `diaspora-cluster attributes="M(a)gic, Religion, Science"`
100
+ Then it should pass with output like:
101
+ """
102
+ graph Cluster {
103
+ A \[label = "A
104
+ A-?\d R-?\d S-?\d"\];
105
+ B \[label = "B
106
+ A-?\d R-?\d S-?\d"\];
107
+ C \[label = "C
108
+ A-?\d R-?\d S-?\d"\];
109
+ D \[label = "D
110
+ A-?\d R-?\d S-?\d"\];
111
+ E \[label = "E
112
+ A-?\d R-?\d S-?\d"\];
113
+ A -- B
114
+ B -- C
115
+ C -- D
116
+ D -- E
117
+ """
118
+
119
+ Scenario: Specify different attributes with default
120
+ When I run `diaspora-cluster names="Sparta{M5},Athens{R-5}" attributes="Magic, Religion, Science"`
121
+ Then it should pass with output like:
122
+ """
123
+ graph Cluster {
124
+ Sparta \[label = "Sparta
125
+ M5 R-?\d S-?\d"\];
126
+ Athens \[label = "Athens
127
+ M-?\d R-5 S-?\d"\];
128
+ Sparta -- Athens
129
+ """
130
+
131
+ Scenario: Specify with count parameters
132
+ When I run `diaspora-cluster count=10`
133
+ Then it should pass with output like:
134
+ """
135
+ graph Cluster {
136
+ A \[label = "A
137
+ T-?\d R-?\d E-?\d"\];
138
+ B \[label = "B
139
+ T-?\d R-?\d E-?\d"\];
140
+ C \[label = "C
141
+ T-?\d R-?\d E-?\d"\];
142
+ D \[label = "D
143
+ T-?\d R-?\d E-?\d"\];
144
+ E \[label = "E
145
+ T-?\d R-?\d E-?\d"\];
146
+ F \[label = "F
147
+ T-?\d R-?\d E-?\d"\];
148
+ G \[label = "G
149
+ T-?\d R-?\d E-?\d"\];
150
+ H \[label = "H
151
+ T-?\d R-?\d E-?\d"\];
152
+ I \[label = "I
153
+ T-?\d R-?\d E-?\d"\];
154
+ J \[label = "J
155
+ T-?\d R-?\d E-?\d"\];
156
+ A -- B
157
+ B -- C
158
+ C -- D
159
+ D -- E
160
+ E -- F
161
+ F -- G
162
+ H -- I
163
+ I -- J
164
+ }
165
+ """
@@ -0,0 +1,13 @@
1
+ Feature: Node Creation
2
+
3
+ Scenario: Node Creation
4
+ When I create a Node
5
+ Then it should have a technology rating
6
+ And it should have a resources rating
7
+ And it should have a environment rating
8
+
9
+ Scenario: Named Node Creation
10
+ When I create a Node with name "Sparta [T1 E-2 R3]"
11
+ Then it should have a technology rating of 1
12
+ And it should have a resources rating of 3
13
+ And it should have a environment rating of -2
@@ -1,11 +1,11 @@
1
- When /^I request a new cluster with (#{CAPTURE_INTEGER}) star systems?$/ do |count|
1
+ When /^I request a new cluster with (#{CAPTURE_INTEGER}) node systems?$/ do |count|
2
2
  set_current_cluster(['a']*count)
3
3
  end
4
4
 
5
5
  Then /^the output should have (#{CAPTURE_INTEGER}) nodes$/ do |count|
6
- current_graph.nodes.count.must_equal count
6
+ current_cluster.nodes.count.must_equal count
7
7
  end
8
8
 
9
9
  Then /^the output should have at least (#{CAPTURE_INTEGER}) edges$/ do |count|
10
- current_graph.edges.count.must_be :>=, count
10
+ current_cluster.edges.count.must_be :>=, count
11
11
  end
@@ -0,0 +1,7 @@
1
+ Then /^it should (pass|fail) with output like:$/ do |pass_or_fail, lines|
2
+ to_execute = ''
3
+ lines.split("\n").each_with_object(to_execute) do |line, mem|
4
+ mem << %(And it should #{pass_or_fail} with regex:\n"""\n#{line}\n"""\n)
5
+ end
6
+ steps to_execute
7
+ end
@@ -0,0 +1,16 @@
1
+ When /^I create a Node$/ do
2
+ current_node
3
+ end
4
+
5
+ When /^I create a Node with (?:the )?name "([^"]*)"$/ do |name|
6
+ set_current_node(name)
7
+ end
8
+
9
+ Then /^it should have an? (#{CAPTURE_SYSTEM_ATTRIBUTE}) rating$/ do |system_attribute|
10
+ current_node.send(system_attribute).must_be :<=, 4
11
+ current_node.send(system_attribute).must_be :>=, -4
12
+ end
13
+
14
+ Then /^it should have an? (#{CAPTURE_SYSTEM_ATTRIBUTE}) rating of (#{CAPTURE_INTEGER})$/ do |system_attribute, rating|
15
+ current_node.send(system_attribute).must_equal rating
16
+ end
@@ -0,0 +1 @@
1
+ require 'aruba/cucumber'
@@ -12,16 +12,12 @@ module KnowsTheDomain
12
12
  @current_roller ||= FateDice.new
13
13
  end
14
14
 
15
- def current_star_system
16
- @current_star_system ||= StarSystem.new(current_cluster, 1)
15
+ def current_node
16
+ @current_node ||= Node.new(current_cluster, 1)
17
17
  end
18
18
 
19
- def set_current_star_system(value)
20
- @current_star_system = StarSystem.new(current_cluster, value)
21
- end
22
-
23
- def current_graph
24
- @current_graph ||= Graph.new(current_cluster)
19
+ def set_current_node(value)
20
+ @current_node = Node.new(current_cluster, value)
25
21
  end
26
22
  end
27
23
 
@@ -4,21 +4,24 @@ module Diaspora
4
4
  module Cluster
5
5
  module Creator
6
6
  def self.run(params)
7
+ filename = params[:filename].to_s
7
8
  names = ('A'..'Z').to_a[0,params[:count] || 6]
8
- cluster = Cluster.new( params[:names] || names )
9
- graph = Graph.new(cluster)
10
- template = Template.new(graph)
11
- case File.extname(params[:filename])
9
+
10
+ cluster = Cluster.new(params[:names] || names, params[:attributes])
11
+ template = Template.new(cluster)
12
+
13
+ case File.extname(filename)
12
14
  when '.dot' then template.to_dot(params[:filename])
13
15
  when '.png' then template.to_png(params[:filename])
16
+ when '.svg' then template.to_svg(params[:filename])
17
+ else
18
+ STDOUT.write template.to_s
14
19
  end
15
20
  end
16
21
  end
17
22
  end
18
23
  end
19
24
 
20
- require_relative "diaspora-cluster-creator/fate_dice"
21
- require_relative "diaspora-cluster-creator/graph"
22
- require_relative "diaspora-cluster-creator/cluster"
23
- require_relative "diaspora-cluster-creator/star_system"
24
- require_relative "diaspora-cluster-creator/template"
25
+ Dir.glob(File.join(File.dirname(__FILE__),'diaspora-cluster-creator', '*')).each do |filename|
26
+ require filename
27
+ end
@@ -0,0 +1,29 @@
1
+ module Diaspora
2
+ module Cluster
3
+ module Creator
4
+ class Attribute
5
+ attr_reader :name, :prefix
6
+ def initialize(name)
7
+ if /\((?<extracted_prefix>\w)\)/ =~ name
8
+ @prefix = extracted_prefix.upcase
9
+ else
10
+ @prefix = name.slice(0).upcase
11
+ end
12
+ @name = name.gsub(/[\(\)]/,'')
13
+ end
14
+
15
+ def to_s
16
+ name
17
+ end
18
+
19
+ def to_sym
20
+ name.to_s.gsub(/\W+/,'_').downcase.to_sym
21
+ end
22
+
23
+ def label
24
+ prefix
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require 'dependency_injector'
2
+ module Diaspora
3
+ module Cluster
4
+ module Creator
5
+ class AttributeCollectionFactory
6
+ DEFAULT_ATTRIBUTE_NAMES = [
7
+ "Technology",
8
+ "Resources",
9
+ "Environment",
10
+ ].freeze
11
+ extend DependencyInjector
12
+ def_injector(:attribute_builder) { Attribute.public_method(:new) }
13
+
14
+ attr_reader :cluster
15
+ def initialize(cluster)
16
+ @cluster = cluster
17
+ end
18
+
19
+ def build_from(names = [])
20
+ from_these_names = (!names.nil? && names.any?) ? names : DEFAULT_ATTRIBUTE_NAMES
21
+ from_these_names.each_with_object([]) do |name, mem|
22
+ mem << attribute_builder.call(name)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
@@ -1,41 +1,54 @@
1
1
  require 'dependency_injector'
2
- require_relative 'star_system'
2
+ require_relative 'node_collection_factory'
3
+ require_relative 'attribute_collection_factory'
4
+ require_relative 'edge_drawer'
3
5
 
4
6
  module Diaspora
5
7
  module Cluster
6
8
  module Creator
7
9
  class Cluster
8
- include Enumerable
9
10
  extend DependencyInjector
10
- def_injector(:star_system_builder) { StarSystem.public_method(:new) }
11
- def_injector(:star_system_guarantor) { StarSystem.public_method(:guarantee!) }
11
+ def_injector(:edge_collection_builder) { lambda { EdgeDrawer.new(self).draw(nodes) } }
12
+ def_injector(:node_collection_builder) { lambda { NodeCollectionFactory.new(self).build_from(names) } }
13
+ def_injector(:attribute_collection_builder) { lambda { AttributeCollectionFactory.new(self).build_from(attribute_names) } }
12
14
 
13
15
  attr_reader :names
16
+ attr_reader :settings
17
+ attr_reader :attribute_names
14
18
 
15
- def initialize(*names)
16
- @names = names.flatten.compact
19
+ def initialize(names = [], attribute_names = [])
20
+ @names = names
21
+ @attribute_names = attribute_names
17
22
  end
18
23
 
19
- def each
20
- star_systems.each {|ss| yield(ss)}
24
+ def each_node
25
+ nodes.each { |node| yield(node) }
21
26
  end
22
27
 
23
- def star_systems
24
- @star_systems ||= build_star_systems
28
+ def each_edge
29
+ edges.each { |edge| yield(edge) }
25
30
  end
26
31
 
27
- def to_s
28
- 'Cluster'
32
+ def each_attribute
33
+ attributes.each { |attribute| yield(attribute) }
29
34
  end
30
35
 
31
- protected
32
- def build_star_systems
33
- @star_systems ||= star_system_guarantor.call(generate_first_pass)
36
+ def nodes
37
+ @nodes ||= node_collection_builder.call
34
38
  end
35
- def generate_first_pass
36
- names.each_with_object([]) {|name,mem| mem << star_system_builder.call(self, name)}
39
+
40
+ def edges
41
+ @edges ||= edge_collection_builder.call
42
+ end
43
+
44
+ def attributes
45
+ @attributes ||= attribute_collection_builder.call
46
+ end
47
+
48
+ def to_s
49
+ 'Cluster'
37
50
  end
38
51
  end
39
52
  end
40
53
  end
41
- end
54
+ end