graph.njae 0.3.1 → 0.4.0

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.
data/Gemfile CHANGED
@@ -6,7 +6,8 @@ source "http://rubygems.org"
6
6
  # Add dependencies to develop your gem here.
7
7
  # Include everything needed to run rake, tests, features, etc.
8
8
  group :development do
9
- gem "rspec", "~> 2.8.0"
10
- gem "bundler", "~> 1.0.0"
11
- gem "jeweler", "~> 1.8.0"
9
+ gem "rspec" # , "~> 2.8.0"
10
+ gem "bundler" # , "~> 1.0.0"
11
+ gem "jeweler" # , "~> 1.8.0"
12
+ gem 'simplecov', :require => false, :group => :test
12
13
  end
@@ -3,28 +3,34 @@ GEM
3
3
  specs:
4
4
  diff-lcs (1.1.3)
5
5
  git (1.2.5)
6
- jeweler (1.8.3)
6
+ jeweler (1.8.4)
7
7
  bundler (~> 1.0)
8
8
  git (>= 1.2.5)
9
9
  rake
10
10
  rdoc
11
- json (1.6.5)
11
+ json (1.7.3)
12
+ multi_json (1.3.6)
12
13
  rake (0.9.2.2)
13
14
  rdoc (3.12)
14
15
  json (~> 1.4)
15
- rspec (2.8.0)
16
- rspec-core (~> 2.8.0)
17
- rspec-expectations (~> 2.8.0)
18
- rspec-mocks (~> 2.8.0)
19
- rspec-core (2.8.0)
20
- rspec-expectations (2.8.0)
21
- diff-lcs (~> 1.1.2)
22
- rspec-mocks (2.8.0)
16
+ rspec (2.11.0)
17
+ rspec-core (~> 2.11.0)
18
+ rspec-expectations (~> 2.11.0)
19
+ rspec-mocks (~> 2.11.0)
20
+ rspec-core (2.11.0)
21
+ rspec-expectations (2.11.1)
22
+ diff-lcs (~> 1.1.3)
23
+ rspec-mocks (2.11.1)
24
+ simplecov (0.6.4)
25
+ multi_json (~> 1.0)
26
+ simplecov-html (~> 0.5.3)
27
+ simplecov-html (0.5.3)
23
28
 
24
29
  PLATFORMS
25
30
  ruby
26
31
 
27
32
  DEPENDENCIES
28
- bundler (~> 1.0.0)
29
- jeweler (~> 1.8.0)
30
- rspec (~> 2.8.0)
33
+ bundler
34
+ jeweler
35
+ rspec
36
+ simplecov
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "graph.njae"
8
- s.version = "0.3.1"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Neil Smith"]
12
- s.date = "2012-05-18"
12
+ s.date = "2012-07-18"
13
13
  s.description = "A simple graph library"
14
14
  s.email = "neil.github@njae.me.uk"
15
15
  s.extra_rdoc_files = [
@@ -38,25 +38,28 @@ Gem::Specification.new do |s|
38
38
  s.homepage = "http://github.com/NeilNjae/graph.njae"
39
39
  s.licenses = ["MIT"]
40
40
  s.require_paths = ["lib"]
41
- s.rubygems_version = "1.8.16"
41
+ s.rubygems_version = "1.8.24"
42
42
  s.summary = "A simple graph library"
43
43
 
44
44
  if s.respond_to? :specification_version then
45
45
  s.specification_version = 3
46
46
 
47
47
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
48
- s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
49
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
50
- s.add_development_dependency(%q<jeweler>, ["~> 1.8.0"])
48
+ s.add_development_dependency(%q<rspec>, [">= 0"])
49
+ s.add_development_dependency(%q<bundler>, [">= 0"])
50
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
51
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
51
52
  else
52
- s.add_dependency(%q<rspec>, ["~> 2.8.0"])
53
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
54
- s.add_dependency(%q<jeweler>, ["~> 1.8.0"])
53
+ s.add_dependency(%q<rspec>, [">= 0"])
54
+ s.add_dependency(%q<bundler>, [">= 0"])
55
+ s.add_dependency(%q<jeweler>, [">= 0"])
56
+ s.add_dependency(%q<simplecov>, [">= 0"])
55
57
  end
56
58
  else
57
- s.add_dependency(%q<rspec>, ["~> 2.8.0"])
58
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
59
- s.add_dependency(%q<jeweler>, ["~> 1.8.0"])
59
+ s.add_dependency(%q<rspec>, [">= 0"])
60
+ s.add_dependency(%q<bundler>, [">= 0"])
61
+ s.add_dependency(%q<jeweler>, [">= 0"])
62
+ s.add_dependency(%q<simplecov>, [">= 0"])
60
63
  end
61
64
  end
62
65
 
@@ -1,5 +1,7 @@
1
1
  require 'bundler/setup'
2
2
 
3
- require 'graph.njae/graph'
4
- require 'graph.njae/edge'
5
- require 'graph.njae/vertex'
3
+ require 'ostruct'
4
+
5
+ require_relative 'graph.njae/graph'
6
+ require_relative 'graph.njae/edge'
7
+ require_relative 'graph.njae/vertex'
@@ -1,5 +1,3 @@
1
- require 'ostruct'
2
-
3
1
  # A simple graph library
4
2
 
5
3
  module GraphNjae
@@ -48,6 +46,23 @@ module GraphNjae
48
46
  def to_s
49
47
  '<E: ' + self.type.to_s + ' [' + self.vertices.map {|n| n.to_s}.join(', ') + '] >'
50
48
  end
49
+
50
+ def to_dot(opts = {})
51
+ if block_given?
52
+ yield self
53
+ else
54
+ dot = self.connections[0].end.object_id.to_s + " -- " + self.connections[1].end.object_id.to_s
55
+ if opts.size > 0
56
+ dot << ' {'
57
+ dot << opts.keys.map { |k|
58
+ (k.to_s + ' = "' + self.instance_eval(opts[k].to_s).to_s) + '"'
59
+ }.join(', ')
60
+ dot << '}'
61
+ end
62
+ dot << ';'
63
+ end
64
+ end
65
+
51
66
  end
52
67
 
53
68
  # A connection between an Edge and a Vertex.The connection can have arbitrary attributes,
@@ -1,5 +1,3 @@
1
- require 'ostruct'
2
-
3
1
  require 'logger'
4
2
  $log = Logger.new(STDERR)
5
3
  $log.level = Logger::WARN
@@ -38,6 +36,31 @@ module GraphNjae
38
36
  edge << vertex1 << vertex2
39
37
  end
40
38
 
39
+ def to_dot(opts = {})
40
+ vertex_args = opts[:vertex_args] || {}
41
+ vertex_block = opts[:vertex_block] || nil
42
+ edge_args = opts[:edge_args] || {}
43
+ edge_block = opts[:edge_block] || nil
44
+ dot = "graph {\n"
45
+ self.vertices.each do |v|
46
+ if vertex_block.nil?
47
+ dot << v.to_dot(vertex_args)
48
+ else
49
+ dot << v.to_dot(&vertex_block)
50
+ end
51
+ dot << "\n"
52
+ end
53
+ self.edges.each do |e|
54
+ if edge_block.nil?
55
+ dot << e.to_dot(edge_args)
56
+ else
57
+ dot << e.to_dot(&edge_block)
58
+ end
59
+ dot << "\n"
60
+ end
61
+ dot << '}'
62
+ end
63
+
41
64
  # Form a product graph of this graph and the other.
42
65
  # Return the product graph.
43
66
  def product(other)
@@ -1,5 +1,3 @@
1
- require 'ostruct'
2
-
3
1
  # A simple graph library
4
2
 
5
3
  module GraphNjae
@@ -40,7 +38,23 @@ module GraphNjae
40
38
  end
41
39
 
42
40
  def to_s
43
- '<V: ' + self.name + '>'
41
+ '<V: ' + self.name.to_s + '>'
42
+ end
43
+
44
+ def to_dot(opts = {})
45
+ if block_given?
46
+ yield self
47
+ else
48
+ dot = self.object_id.to_s
49
+ if opts.size > 0
50
+ dot << ' {'
51
+ dot << opts.keys.map { |k|
52
+ (k.to_s + ' = "' + self.instance_eval(opts[k].to_s).to_s) + '"'
53
+ }.join(', ')
54
+ dot << '}'
55
+ end
56
+ dot << ';'
57
+ end
44
58
  end
45
59
 
46
60
  end
@@ -3,33 +3,45 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
3
  module GraphNjae
4
4
  describe Edge do
5
5
  let (:e) { Edge.new }
6
- describe "#initialize" do
7
- it "creates an empty edge" do
6
+ let(:v1) {Vertex.new :name => :v1}
7
+ let(:v2) {Vertex.new :name => :v2}
8
+ let(:v3) {Vertex.new :name => :v3}
9
+
10
+ describe '#initialize' do
11
+ it 'creates an empty edge' do
8
12
  e = Edge.new
9
13
  e.connections.should be_empty
10
14
  end
11
15
 
12
- it "creates an edge with some parameters" do
13
- e = Edge.new :value1 => 1, :value2 => "value2", :value3 => :v3
16
+ it 'creates an edge with some parameters' do
17
+ e = Edge.new :value1 => 1, :value2 => 'value2', :value3 => :v3
14
18
  e.value1.should == 1
15
- e.value2.should == "value2"
19
+ e.value2.should == 'value2'
16
20
  e.value3.should == :v3
17
21
  e.value4.should be_nil
18
22
  end
19
23
  end # #initialize
20
24
 
21
- describe "adds attribues" do
22
- it "adds then reports arbitrary attributes" do
25
+ describe 'adds attribues' do
26
+ it 'adds then reports arbitrary attributes' do
23
27
  e.score = 15
24
28
  e.score.should == 15
25
29
  end
26
30
  end # adds attributes
27
31
 
32
+ describe "#to_s" do
33
+ it "returns the string form of an edge" do
34
+ v1 = Vertex.new :name => :v1
35
+ v2 = Vertex.new :name => :v2
36
+ e.type = :test
37
+ e << v1 << v2
38
+ e.to_s.should == '<E: test [<V: v1>, <V: v2>] >'
39
+ end
40
+ end
41
+
28
42
  describe "#<<" do
29
43
  it "adds a new vertex to an edge (with a connection)" do
30
44
  e.connections.should be_empty
31
- v1 = Vertex.new :name => :v1
32
- v2 = Vertex.new :name => :v2
33
45
  e << v1
34
46
  e.should have(1).connections
35
47
  e.should have(1).vertices
@@ -43,19 +55,16 @@ module GraphNjae
43
55
  v2.edges.should include(e)
44
56
  end
45
57
 
46
- it "adds several vertices to an edge" do
58
+ it 'adds several vertices to an edge' do
47
59
  e.connections.should be_empty
48
- v1 = Vertex.new :name => :v1
49
- v2 = Vertex.new :name => :v2
50
60
  e << v1 << v2
51
61
  e.vertices.should include(v1)
52
62
  e.vertices.should include(v2)
53
63
  e.should have(2).vertices
54
64
  end
55
65
 
56
- it "adds a self-loop" do
66
+ it 'adds a self-loop' do
57
67
  e.connections.should be_empty
58
- v1 = Vertex.new
59
68
  e << v1 << v1
60
69
  e.vertices.should include(v1)
61
70
  e.should have(2).vertices
@@ -63,79 +72,85 @@ module GraphNjae
63
72
  end
64
73
  end # #<<
65
74
 
66
- describe "connection_at" do
67
- it "returns the connection that links to a vertex" do
75
+ describe 'connection_at' do
76
+ it 'returns the connection that links to a vertex' do
68
77
  e.connections.should be_empty
69
- v1 = Vertex.new :name => :v1
70
- v2 = Vertex.new :name => :v2
71
78
  e << v1 << v2
72
79
 
73
80
  e.connection_at(v1).end.should be v1
74
81
  e.connection_at(v2).end.should be v2
75
82
  end
76
83
 
77
- it "returns nil if there is no connection to that vertex" do
84
+ it 'returns nil if there is no connection to that vertex' do
78
85
  e.connections.should be_empty
79
- v1 = Vertex.new :name => :v1
80
- v2 = Vertex.new :name => :v2
81
- v3 = Vertex.new :name => :v3
82
86
  e << v1 << v2
83
87
 
84
88
  e.connection_at(v3).should be nil
85
89
  end
86
90
 
87
- it "returns the vertex for a self-loop" do
91
+ it 'returns the vertex for a self-loop' do
88
92
  e.connections.should be_empty
89
- v1 = Vertex.new :name => :v1
90
93
  e << v1 << v1
91
94
 
92
95
  e.connection_at(v1).end.should be v1
93
96
  end
94
97
  end # #connection_at
95
98
 
96
- describe "other_end" do
97
- it "returns the vertex at the other end of the given one" do
99
+ describe 'other_end' do
100
+ it 'returns the vertex at the other end of the given one' do
98
101
  e.connections.should be_empty
99
- v1 = Vertex.new :name => :v1
100
- v2 = Vertex.new :name => :v2
101
102
  e << v1 << v2
102
103
 
103
104
  e.other_end(v1).should be v2
104
105
  e.other_end(v2).should be v1
105
106
  end
106
107
 
107
- it "returns the same vertex in a self-loop" do
108
+ it 'returns the same vertex in a self-loop' do
108
109
  e.connections.should be_empty
109
- v1 = Vertex.new :name => :v1
110
110
  e << v1 << v1
111
111
 
112
112
  e.other_end(v1).should be v1
113
113
  end
114
114
 
115
- it "returns one of the connected edges if given a vertex not connected to it" do
115
+ it 'returns one of the connected edges if given a vertex not connected to it' do
116
116
  e.connections.should be_empty
117
- v1 = Vertex.new :name => :v1
118
- v2 = Vertex.new :name => :v2
119
- v3 = Vertex.new :name => :v3
120
117
  e << v1 << v2
121
118
 
122
119
  [v1, v2].should include e.other_end(v3)
123
120
  end
124
121
 
125
- it "returns nil if it can't return something sensible" do
126
- v1 = Vertex.new :name => :v1
122
+ it 'returns nil if it cannot return something sensible' do
127
123
  e.other_end(v1).should be_nil
128
124
  e << v1
129
125
  e.other_end(v1).should be_nil
130
126
  end
131
127
  end # other_end
128
+
129
+ describe '#to_dot' do
130
+ it 'describes an edge in dot notation' do
131
+ e << v1 << v2
132
+ e.to_dot.should == "#{v1.object_id.to_s} -- #{v2.object_id.to_s};"
133
+ end
134
+
135
+ it 'describes an edge in dot notation, using given attributes' do
136
+ e << v1 << v2
137
+ e.name = 'Edge name'
138
+ edot = e.to_dot :label => :name
139
+ edot.should == "#{v1.object_id.to_s} -- #{v2.object_id.to_s} {label = \"#{e.name}\"};"
140
+ end
141
+
142
+ it 'describes an edge in dot notation, given a block' do
143
+ e << v1 << v2
144
+ e.to_dot {|e| e.object_id.to_s}.should == e.object_id.to_s
145
+ end
146
+ end # dot
132
147
  end # Edge
133
148
 
134
149
  describe Connection do
135
150
  let (:c) {Connection.new }
136
151
 
137
- describe "adds attribues" do
138
- it "adds then reports arbitrary attributes" do
152
+ describe 'adds attribues' do
153
+ it 'adds then reports arbitrary attributes' do
139
154
  c.score = 15
140
155
  c.score.should == 15
141
156
  end
@@ -10,32 +10,32 @@ module GraphNjae
10
10
 
11
11
  describe Graph do
12
12
  let (:g) { Graph.new }
13
- describe "#initialize" do
14
- it "creates an empty graph" do
13
+ describe '#initialize' do
14
+ it 'creates an empty graph' do
15
15
  g = Graph.new
16
16
  g.edges.should be_empty
17
17
  g.vertices.should be_empty
18
18
  end
19
19
 
20
- it "creates a graph with some parameters" do
21
- g = Graph.new :value1 => 1, :value2 => "value2", :value3 => :v3
20
+ it 'creates a graph with some parameters' do
21
+ g = Graph.new :value1 => 1, :value2 => 'value2', :value3 => :v3
22
22
  g.value1.should == 1
23
- g.value2.should == "value2"
23
+ g.value2.should == 'value2'
24
24
  g.value3.should == :v3
25
25
  g.value4.should be_nil
26
26
  end
27
27
 
28
28
  end # #initialize
29
29
 
30
- describe "adds attributes" do
31
- it "adds then reports arbitrary attributes" do
30
+ describe 'adds attributes' do
31
+ it 'adds then reports arbitrary attributes' do
32
32
  g.score = 15
33
33
  g.score.should == 15
34
34
  end
35
35
  end # adds attributes
36
36
 
37
- describe "#<<" do
38
- it "adds a set of vertices" do
37
+ describe '#<<' do
38
+ it 'adds a set of vertices' do
39
39
  g.vertices.should be_empty
40
40
  v1 = Vertex.new
41
41
  v2 = Vertex.new
@@ -45,7 +45,7 @@ module GraphNjae
45
45
  g.vertices.should include(v2)
46
46
  end
47
47
 
48
- it "adds a set of edges" do
48
+ it 'adds a set of edges' do
49
49
  g.edges.should be_empty
50
50
  e1 = Edge.new
51
51
  e2 = Edge.new
@@ -55,7 +55,7 @@ module GraphNjae
55
55
  g.edges.should include(e2)
56
56
  end
57
57
 
58
- it "adds a mixed set of vertices and edges" do
58
+ it 'adds a mixed set of vertices and edges' do
59
59
  g.vertices.should be_empty
60
60
  g.edges.should be_empty
61
61
  v1 = Vertex.new
@@ -71,7 +71,7 @@ module GraphNjae
71
71
  g.edges.should include(e2)
72
72
  end
73
73
 
74
- it "adds a subclass of Vertex" do
74
+ it 'adds a subclass of Vertex' do
75
75
  g.vertices.should be_empty
76
76
  v1 = SVertex.new
77
77
  v2 = SVertex.new
@@ -82,8 +82,8 @@ module GraphNjae
82
82
  end
83
83
  end # #<<
84
84
 
85
- describe "connect" do
86
- it "adds and records an edge between vertices" do
85
+ describe 'connect' do
86
+ it 'adds and records an edge between vertices' do
87
87
  g.vertices.should be_empty
88
88
  g.edges.should be_empty
89
89
  v1 = Vertex.new(:name => :v1)
@@ -96,7 +96,7 @@ module GraphNjae
96
96
  g.should have(1).edges
97
97
  end
98
98
 
99
- it "adds and records an edge with attributes between vertices" do
99
+ it 'adds and records an edge with attributes between vertices' do
100
100
  g.vertices.should be_empty
101
101
  g.edges.should be_empty
102
102
  v1 = Vertex.new(:name => :v1)
@@ -111,8 +111,51 @@ module GraphNjae
111
111
  end
112
112
  end # #connect
113
113
 
114
- describe "product" do
115
- it "finds a product graph of a pair of one-vertex graphs" do
114
+ describe '#to_dot' do
115
+ it 'gives the dot notation of a simple graph' do
116
+ v1 = Vertex.new(:name => :v1)
117
+ v2 = Vertex.new(:name => :v2)
118
+ g.connect(v1, v2, :type => :edge_type)
119
+ g.to_dot.should == "graph {\n#{v1.object_id.to_s};\n#{v2.object_id.to_s};\n#{v1.object_id.to_s} -- #{v2.object_id.to_s};\n}"
120
+ end
121
+
122
+ it "gives the dot notation of a simple graph, with vertex attributes" do
123
+ v1 = Vertex.new(:name => :v1)
124
+ v2 = Vertex.new(:name => :v2)
125
+ g.connect(v1, v2, :type => :edge_type)
126
+ gdot = g.to_dot(:vertex_args => {:label => :name})
127
+ gdot.should == "graph {\n#{v1.object_id.to_s} {label = \"#{v1.name}\"};\n#{v2.object_id.to_s} {label = \"#{v2.name}\"};\n#{v1.object_id.to_s} -- #{v2.object_id.to_s};\n}"
128
+ end
129
+
130
+ it "gives the dot notation of a simple graph, with vertices generated by a block" do
131
+ v1 = Vertex.new(:name => :v1)
132
+ v2 = Vertex.new(:name => :v2)
133
+ g.connect(v1, v2, :type => :edge_type)
134
+ gdot = g.to_dot(:vertex_block => lambda {|v| v.name.to_s + ';'})
135
+ gdot.should == "graph {\n#{v1.name};\n#{v2.name};\n#{v1.object_id.to_s} -- #{v2.object_id.to_s};\n}"
136
+ end
137
+
138
+ it "gives the dot notation of a simple graph, with vertex and edge attributes" do
139
+ v1 = Vertex.new(:name => :v1)
140
+ v2 = Vertex.new(:name => :v2)
141
+ g.connect(v1, v2, :type => :edge_type)
142
+ gdot = g.to_dot(:edge_args => {:label => :type}, :vertex_args => {:label => :name})
143
+ gdot.should == "graph {\n#{v1.object_id.to_s} {label = \"#{v1.name}\"};\n#{v2.object_id.to_s} {label = \"#{v2.name}\"};\n#{v1.object_id.to_s} -- #{v2.object_id.to_s} {label = \"#{g.edges[0].type}\"};\n}"
144
+ end
145
+
146
+ it "gives the dot notation of a simple graph, with vertices and edges generated by a block" do
147
+ v1 = Vertex.new(:name => :v1)
148
+ v2 = Vertex.new(:name => :v2)
149
+ g.connect(v1, v2, :type => :edge_type)
150
+ gdot = g.to_dot(:vertex_block => lambda {|v| v.name.to_s + ';'},
151
+ :edge_block => lambda {|e| "#{e.vertices[0].name.to_s} -- #{e.vertices[1].name.to_s} {label = \"#{e.type.to_s}\"};"})
152
+ gdot.should == "graph {\n#{v1.name};\n#{v2.name};\n#{v1.name} -- #{v2.name} {label = \"#{g.edges[0].type}\"};\n}"
153
+ end
154
+
155
+ end # #to_dot
156
+
157
+ describe 'product' do
158
+ it 'finds a product graph of a pair of one-vertex graphs' do
116
159
  g1 = Graph.new
117
160
  g2 = Graph.new
118
161
  g1v1 = Vertex.new
@@ -127,7 +170,7 @@ module GraphNjae
127
170
  product.edges.should be_empty
128
171
  end
129
172
 
130
- it "finds a product graph of a pair of simple graphs" do
173
+ it 'finds a product graph of a pair of simple graphs' do
131
174
  g1 = Graph.new
132
175
  g2 = Graph.new
133
176
  g1v1 = Vertex.new(:name => :g1v1)
@@ -142,7 +185,7 @@ module GraphNjae
142
185
  pg.should have(2).edges
143
186
  end
144
187
 
145
- it "finds a product graph of not-quite-simple graph" do
188
+ it 'finds a product graph of not-quite-simple graph' do
146
189
  g1 = Graph.new
147
190
  g2 = Graph.new
148
191
  g1v1 = Vertex.new(:name => :g1v1)
@@ -161,7 +204,7 @@ module GraphNjae
161
204
  pg.should have(8).edges
162
205
  end
163
206
 
164
- it "finds a product graph of a simple graph with edge types" do
207
+ it 'finds a product graph of a simple graph with edge types' do
165
208
  g1 = Graph.new
166
209
  g2 = Graph.new
167
210
  g1v1 = Vertex.new(:name => :g1v1)
@@ -180,8 +223,8 @@ module GraphNjae
180
223
  pg.should have(4).edges
181
224
  end
182
225
 
183
- it "finds a product graph of the example graph from paper" do
184
- pending "implementation of directed graphs as operands of the product graph"
226
+ it 'finds a product graph of the example graph from paper' do
227
+ pending 'implementation of directed graphs as operands of the product graph'
185
228
  g1 = Graph.new
186
229
  g2 = Graph.new
187
230
  a = Vertex.new(:name => :a)
@@ -201,11 +244,9 @@ module GraphNjae
201
244
  pg.should have(4).edges
202
245
  pg.should have(6).vertices
203
246
  end
204
-
205
-
206
247
  end #product
207
248
 
208
- describe "initial_similarity" do
249
+ describe 'initial_similarity' do
209
250
  before(:each) do
210
251
  g1 = Graph.new
211
252
  g2 = Graph.new
@@ -222,7 +263,7 @@ module GraphNjae
222
263
  1 - n1.to_s.codepoints.to_a.delete_if {|c| n2.to_s.codepoints.to_a.include? c}.length / n1.to_s.length.to_f
223
264
  end
224
265
 
225
- it "should give all nodes an initial similarity of 1 if no block is given" do
266
+ it 'should give all nodes an initial similarity of 1 if no block is given' do
226
267
  @pg.initial_similarity
227
268
  @pg.vertices.each do |v|
228
269
  v.initial_similarity.should be_within(0.001).of(1.0)
@@ -230,7 +271,7 @@ module GraphNjae
230
271
  end
231
272
  end
232
273
 
233
- it "should give all nodes the similarity as defined by the given block" do
274
+ it 'should give all nodes the similarity as defined by the given block' do
234
275
  @pg.initial_similarity {|v| simple_name_similarity v.g1_vertex.name, v.g2_vertex.name}
235
276
  @pg.vertices.each do |v|
236
277
  v.initial_similarity.should be_within(0.001).of( simple_name_similarity v.g1_vertex.name, v.g2_vertex.name )
@@ -240,8 +281,8 @@ module GraphNjae
240
281
  end
241
282
  end #initial similarity
242
283
 
243
- describe "similarity flood" do
244
- it "similarity floods a graph of two nodes" do
284
+ describe 'similarity flood' do
285
+ it 'similarity floods a graph of two nodes' do
245
286
  g1 = Graph.new
246
287
  g2 = Graph.new
247
288
  g1v1 = Vertex.new(:name => :g1v1)
@@ -259,7 +300,7 @@ module GraphNjae
259
300
  end
260
301
  end
261
302
 
262
- it "similarity floods a graph of three nodes, a -- b -- c" do
303
+ it 'similarity floods a graph of three nodes, a -- b -- c' do
263
304
  g1 = Graph.new
264
305
  g2 = Graph.new
265
306
  g1v1 = Vertex.new(:name => :g1v1)
@@ -277,27 +318,27 @@ module GraphNjae
277
318
  pg.initial_similarity
278
319
  pg.similarity_flood
279
320
  expected_similarities = {
280
- "g1v1:g2v1" => 0.5,
281
- "g1v1:g2v2" => 0.6666666666666666,
282
- "g1v2:g2v1" => 0.6666666666666666,
283
- "g1v2:g2v2" => 1.0,
284
- "g1v2:g2v3" => 0.6666666666666666,
285
- "g1v3:g2v2" => 0.6666666666666666,
286
- "g1v3:g2v3" => 0.5}
321
+ 'g1v1:g2v1' => 0.5,
322
+ 'g1v1:g2v2' => 0.6666666666666666,
323
+ 'g1v2:g2v1' => 0.6666666666666666,
324
+ 'g1v2:g2v2' => 1.0,
325
+ 'g1v2:g2v3' => 0.6666666666666666,
326
+ 'g1v3:g2v2' => 0.6666666666666666,
327
+ 'g1v3:g2v3' => 0.5}
287
328
  pg.vertices.each do |v|
288
- name = v.g1_vertex.name.to_s + ':' + v.g2_vertex.name.to_s
329
+ name = "#{v.g1_vertex.name.to_s}:#{v.g2_vertex.name.to_s}"
289
330
  v.similarity.should be_within(0.001).of(expected_similarities[name])
290
331
  end
291
332
  end
292
333
 
293
- it "simialrity floods the sample graph from the paper" do
334
+ it 'simialrity floods the sample graph from the paper' do
294
335
  pg = Graph.new
295
- ab = Vertex.new(:name => "a:b")
296
- a1b1 = Vertex.new(:name => "a1:b1")
297
- a2b1 = Vertex.new(:name => "a2:b1")
298
- a1b2 = Vertex.new(:name => "a1:b2")
299
- a1b = Vertex.new(:name => "a1:b")
300
- a2b2 = Vertex.new(:name => "a2:b2")
336
+ ab = Vertex.new(:name => 'a:b')
337
+ a1b1 = Vertex.new(:name => 'a1:b1')
338
+ a2b1 = Vertex.new(:name => 'a2:b1')
339
+ a1b2 = Vertex.new(:name => 'a1:b2')
340
+ a1b = Vertex.new(:name => 'a1:b')
341
+ a2b2 = Vertex.new(:name => 'a2:b2')
301
342
  pg.connect(ab, a1b1, :type => :l1)
302
343
  pg.connect(ab, a2b1, :type => :l1)
303
344
  pg.connect(a2b1, a1b2, :type => :l2)
@@ -306,18 +347,18 @@ module GraphNjae
306
347
  pg.similarity_flood
307
348
 
308
349
  expected_similarities = {
309
- "a:b" => 1.0,
310
- "a2:b1" => 0.92,
311
- "a1:b2" => 0.71,
312
- "a1:b1" => 0.38,
313
- "a1:b" => 0.0,
314
- "a2:b2" => 0.0}
350
+ 'a:b' => 1.0,
351
+ 'a2:b1' => 0.92,
352
+ 'a1:b2' => 0.71,
353
+ 'a1:b1' => 0.38,
354
+ 'a1:b' => 0.0,
355
+ 'a2:b2' => 0.0}
315
356
  pg.vertices.each do |v|
316
357
  v.similarity.should be_within(0.02).of(expected_similarities[v.name])
317
358
  end
318
359
  end
319
360
 
320
- it "similarity floods a graph of three nodes, a -- b -- c, given a block that performs the default update" do
361
+ it 'similarity floods a graph of three nodes, a -- b -- c, given a block that performs the default update' do
321
362
  g1 = Graph.new
322
363
  g2 = Graph.new
323
364
  g1v1 = Vertex.new(:name => :g1v1)
@@ -344,20 +385,20 @@ module GraphNjae
344
385
  v.similarity
345
386
  end
346
387
  expected_similarities = {
347
- "g1v1:g2v1" => 0.5,
348
- "g1v1:g2v2" => 0.6666666666666666,
349
- "g1v2:g2v1" => 0.6666666666666666,
350
- "g1v2:g2v2" => 1.0,
351
- "g1v2:g2v3" => 0.6666666666666666,
352
- "g1v3:g2v2" => 0.6666666666666666,
353
- "g1v3:g2v3" => 0.5}
388
+ 'g1v1:g2v1' => 0.5,
389
+ 'g1v1:g2v2' => 0.6666666666666666,
390
+ 'g1v2:g2v1' => 0.6666666666666666,
391
+ 'g1v2:g2v2' => 1.0,
392
+ 'g1v2:g2v3' => 0.6666666666666666,
393
+ 'g1v3:g2v2' => 0.6666666666666666,
394
+ 'g1v3:g2v3' => 0.5}
354
395
  pg.vertices.each do |v|
355
- name = v.g1_vertex.name.to_s + ':' + v.g2_vertex.name.to_s
396
+ name = "#{v.g1_vertex.name.to_s}:#{v.g2_vertex.name.to_s}"
356
397
  v.similarity.should be_within(0.001).of(expected_similarities[name])
357
398
  end
358
399
  end
359
400
 
360
- it "similarity floods a graph of three nodes, a -- b -- c, given a block that performs a different update (method A)" do
401
+ it 'similarity floods a graph of three nodes, a -- b -- c, given a block that performs a different update (method A)' do
361
402
  g1 = Graph.new
362
403
  g2 = Graph.new
363
404
  g1v1 = Vertex.new(:name => :g1v1)
@@ -385,20 +426,20 @@ module GraphNjae
385
426
  v.similarity
386
427
  end
387
428
  expected_similarities = {
388
- "g1v1:g2v1" => 0.9269662921348315,
389
- "g1v1:g2v2" => 1.0,
390
- "g1v2:g2v1" => 0.6179775280898876,
391
- "g1v2:g2v2" => 1.0,
392
- "g1v2:g2v3" => 1.0,
393
- "g1v3:g2v2" => 0.6179775280898876,
394
- "g1v3:g2v3" => 0.6179775280898876}
429
+ 'g1v1:g2v1' => 0.9269662921348315,
430
+ 'g1v1:g2v2' => 1.0,
431
+ 'g1v2:g2v1' => 0.6179775280898876,
432
+ 'g1v2:g2v2' => 1.0,
433
+ 'g1v2:g2v3' => 1.0,
434
+ 'g1v3:g2v2' => 0.6179775280898876,
435
+ 'g1v3:g2v3' => 0.6179775280898876}
395
436
  pg.vertices.each do |v|
396
- name = v.g1_vertex.name.to_s + ':' + v.g2_vertex.name.to_s
437
+ name = "#{v.g1_vertex.name.to_s}:#{v.g2_vertex.name.to_s}"
397
438
  v.similarity.should be_within(0.001).of(expected_similarities[name])
398
439
  end
399
440
  end
400
441
 
401
- it "similarity floods a graph of three nodes, a -- b -- c, given a block that performs a different update (method B)" do
442
+ it 'similarity floods a graph of three nodes, a -- b -- c, given a block that performs a different update (method B)' do
402
443
  g1 = Graph.new
403
444
  g2 = Graph.new
404
445
  g1v1 = Vertex.new(:name => :g1v1)
@@ -426,20 +467,20 @@ module GraphNjae
426
467
  v.similarity
427
468
  end
428
469
  expected_similarities = {
429
- "g1v1:g2v1" => 1.0,
430
- "g1v1:g2v2" => 1.0,
431
- "g1v2:g2v1" => 0.0,
432
- "g1v2:g2v2" => 1.0,
433
- "g1v2:g2v3" => 1.0,
434
- "g1v3:g2v2" => 0.0,
435
- "g1v3:g2v3" => 0.0}
470
+ 'g1v1:g2v1' => 1.0,
471
+ 'g1v1:g2v2' => 1.0,
472
+ 'g1v2:g2v1' => 0.0,
473
+ 'g1v2:g2v2' => 1.0,
474
+ 'g1v2:g2v3' => 1.0,
475
+ 'g1v3:g2v2' => 0.0,
476
+ 'g1v3:g2v3' => 0.0}
436
477
  pg.vertices.each do |v|
437
- name = v.g1_vertex.name.to_s + ':' + v.g2_vertex.name.to_s
478
+ name = "#{v.g1_vertex.name.to_s}:#{v.g2_vertex.name.to_s}"
438
479
  v.similarity.should be_within(0.001).of(expected_similarities[name])
439
480
  end
440
481
  end
441
482
 
442
- it "similarity floods a graph of three nodes, a -- b -- c, given a block that performs a different update (method C)" do
483
+ it 'similarity floods a graph of three nodes, a -- b -- c, given a block that performs a different update (method C)' do
443
484
  g1 = Graph.new
444
485
  g2 = Graph.new
445
486
  g1v1 = Vertex.new(:name => :g1v1)
@@ -467,15 +508,15 @@ module GraphNjae
467
508
  v.similarity
468
509
  end
469
510
  expected_similarities = {
470
- "g1v1:g2v1" => 0.8282781862745098,
471
- "g1v1:g2v2" => 1.0,
472
- "g1v2:g2v1" => 0.41421568627450983,
473
- "g1v2:g2v2" => 1.0,
474
- "g1v2:g2v3" => 1.0,
475
- "g1v3:g2v2" => 0.41421568627450983,
476
- "g1v3:g2v3" => 0.41421568627450983}
511
+ 'g1v1:g2v1' => 0.8282781862745098,
512
+ 'g1v1:g2v2' => 1.0,
513
+ 'g1v2:g2v1' => 0.41421568627450983,
514
+ 'g1v2:g2v2' => 1.0,
515
+ 'g1v2:g2v3' => 1.0,
516
+ 'g1v3:g2v2' => 0.41421568627450983,
517
+ 'g1v3:g2v3' => 0.41421568627450983}
477
518
  pg.vertices.each do |v|
478
- name = v.g1_vertex.name.to_s + ':' + v.g2_vertex.name.to_s
519
+ name = "#{v.g1_vertex.name.to_s}:#{v.g2_vertex.name.to_s}"
479
520
  v.similarity.should be_within(0.001).of(expected_similarities[name])
480
521
  end
481
522
  end
@@ -4,30 +4,38 @@ module GraphNjae
4
4
  describe Vertex do
5
5
  let (:v) { Vertex.new }
6
6
 
7
- describe "#initialize" do
8
- it "creates an empty vertex" do
7
+ describe '#initialize' do
8
+ it 'creates an empty vertex' do
9
9
  v = Vertex.new
10
10
  v.edges.should be_empty
11
11
  end
12
12
 
13
- it "creates a vertex with some parameters" do
14
- v = Vertex.new :value1 => 1, :value2 => "value2", :value3 => :v3
13
+ it 'creates a vertex with some parameters' do
14
+ v = Vertex.new :value1 => 1, :value2 => 'value2', :value3 => :v3
15
15
  v.value1.should == 1
16
- v.value2.should == "value2"
16
+ v.value2.should == 'value2'
17
17
  v.value3.should == :v3
18
18
  v.value4.should be_nil
19
19
  end
20
20
  end # #initialize
21
21
 
22
- describe "adds attribues" do
23
- it "adds then reports arbitrary attributes" do
22
+ describe 'adds attribues' do
23
+ it 'adds then reports arbitrary attributes' do
24
24
  v.score = 15
25
25
  v.score.should == 15
26
26
  end
27
27
  end # adds attributes
28
+
29
+ describe "#to_s" do
30
+ it "returns the string form of a vertex" do
31
+ v.name = :v1
32
+ v.to_s.should == '<V: v1>'
33
+ end
34
+ end
35
+
28
36
 
29
- describe "#<<" do
30
- it "adds a single edge between vertices" do
37
+ describe '#<<' do
38
+ it 'adds a single edge between vertices' do
31
39
  v.neighbours.should be_empty
32
40
  v.edges.should be_empty
33
41
 
@@ -49,7 +57,7 @@ module GraphNjae
49
57
  v1.neighbours.should_not include(v1)
50
58
  end
51
59
 
52
- it "adds a single edge as a self-loop" do
60
+ it 'adds a single edge as a self-loop' do
53
61
  v.neighbours.should be_empty
54
62
  v.edges.should be_empty
55
63
 
@@ -61,8 +69,8 @@ module GraphNjae
61
69
  end
62
70
  end # #<<
63
71
 
64
- describe "connect" do
65
- it "connects two vertices" do
72
+ describe 'connect' do
73
+ it 'connects two vertices' do
66
74
  v1 = Vertex.new
67
75
  v1.id = :v1 # Need this to ensure that v != v1
68
76
 
@@ -88,14 +96,14 @@ module GraphNjae
88
96
  e.should have(2).connections
89
97
  end
90
98
 
91
- it "connects two vertices by an edge with attributes" do
99
+ it 'connects two vertices by an edge with attributes' do
92
100
  v1 = Vertex.new
93
101
  v1.id = :v1
94
102
  e = v.connect(v1, {:type => :edge_type})
95
103
  e.type.should == :edge_type
96
104
  end
97
105
 
98
- it "creates a self-connection" do
106
+ it 'creates a self-connection' do
99
107
  e = v.connect v
100
108
 
101
109
  v.should have(1).neighbours
@@ -111,21 +119,21 @@ module GraphNjae
111
119
  e.should have(2).connections
112
120
  end
113
121
 
114
- it "creates a self-connection with an edge with attributes" do
122
+ it 'creates a self-connection with an edge with attributes' do
115
123
  e = v.connect(v, {:type => :edge_type})
116
124
  e.type.should == :edge_type
117
125
  end
118
126
 
119
127
  end # #connect
120
128
 
121
- describe "#neighbours" do
122
- it "finds neighbours of a self loop" do
129
+ describe '#neighbours' do
130
+ it 'finds neighbours of a self loop' do
123
131
  v << v
124
132
  v.should have(1).neighbours
125
133
  v.neighbours.should include v
126
134
  end
127
135
 
128
- it "finds neighbours on an edge" do
136
+ it 'finds neighbours on an edge' do
129
137
  v1 = Vertex.new
130
138
  v << v1
131
139
  v.should have(1).neighbours
@@ -134,7 +142,7 @@ module GraphNjae
134
142
  v1.neighbours.should include v
135
143
  end
136
144
 
137
- it "finds neighbours with multiple edges" do
145
+ it 'finds neighbours with multiple edges' do
138
146
  v1 = Vertex.new
139
147
  v1.id = :v1
140
148
  v << v1
@@ -147,14 +155,14 @@ module GraphNjae
147
155
  v1.neighbours.should_not include v1
148
156
  end
149
157
 
150
- it "finds neighbours with multiple self loops" do
158
+ it 'finds neighbours with multiple self loops' do
151
159
  v << v << v << v
152
160
  v.should have(3).neighbours
153
161
  v.neighbours.should include v
154
162
  v.neighbours.uniq.length.should == 1
155
163
  end
156
164
 
157
- it "finds neighbours with all sorts of edges" do
165
+ it 'finds neighbours with all sorts of edges' do
158
166
  v1 = Vertex.new ; v1.id = :v1
159
167
  v2 = Vertex.new ; v2.id = :v2
160
168
  v3 = Vertex.new ; v3.id = :v3
@@ -179,7 +187,7 @@ module GraphNjae
179
187
  v3.neighbours.should include v2
180
188
  end
181
189
 
182
- it "finds neighbours in graphs with several vertices" do
190
+ it 'finds neighbours in graphs with several vertices' do
183
191
  v1 = Vertex.new ; v1.id = :v1
184
192
  v2 = Vertex.new ; v2.id = :v2
185
193
  v3 = Vertex.new ; v3.id = :v3
@@ -211,7 +219,7 @@ module GraphNjae
211
219
  v4.neighbours.should_not include v4
212
220
  end
213
221
 
214
- it "finds neighbours with multiple edges between vertices" do
222
+ it 'finds neighbours with multiple edges between vertices' do
215
223
  v1 = Vertex.new ; v1.id = :v1
216
224
  v2 = Vertex.new ; v2.id = :v2
217
225
  v3 = Vertex.new ; v3.id = :v3
@@ -242,5 +250,27 @@ module GraphNjae
242
250
  v3.neighbours.uniq.length.should == 1
243
251
  end
244
252
  end # #neighbours
253
+
254
+ describe '#to_dot' do
255
+ it 'describes a vertex in dot notation' do
256
+ v = Vertex.new
257
+ v.to_dot.should == "#{v.object_id.to_s};"
258
+ end
259
+
260
+ it 'describes a vertex in dot notation, using given attributes' do
261
+ v = Vertex.new
262
+ v.name = 'vertex'
263
+ v.shape = 'house'
264
+ vdot = v.to_dot :label => :name, :shape => :shape
265
+ vdot.should == "#{v.object_id.to_s} {label = \"#{v.name}\", shape = \"#{v.shape}\"};"
266
+ end
267
+
268
+ it 'describes a vertex using a block' do
269
+ v = Vertex.new
270
+ v.field1 = 'f1'
271
+ vdot = v.to_dot {|v| v.field1 + ';'}
272
+ vdot.should == "#{v.field1};"
273
+ end
274
+ end # #to_dot
245
275
  end
246
276
  end
@@ -1,12 +1,4 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- $LOAD_PATH.unshift(File.dirname(__FILE__))
3
- require 'rspec'
4
- require 'graph.njae'
5
-
6
- # Requires supporting files with custom matchers and macros, etc,
7
- # in ./support/ and its subdirectories.
8
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
1
+ require 'simplecov'
2
+ SimpleCov.start
9
3
 
10
- RSpec.configure do |config|
11
-
12
- end
4
+ require 'graph.njae'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graph.njae
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,41 +9,72 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-18 00:00:00.000000000 Z
12
+ date: 2012-07-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &80307360 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 2.8.0
21
+ version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *80307360
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: bundler
27
- requirement: &80323410 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
- - - ~>
35
+ - - ! '>='
31
36
  - !ruby/object:Gem::Version
32
- version: 1.0.0
37
+ version: '0'
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *80323410
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: jeweler
38
- requirement: &80323100 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
39
57
  none: false
40
58
  requirements:
41
- - - ~>
59
+ - - ! '>='
42
60
  - !ruby/object:Gem::Version
43
- version: 1.8.0
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: simplecov
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
44
70
  type: :development
45
71
  prerelease: false
46
- version_requirements: *80323100
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
47
78
  description: A simple graph library
48
79
  email: neil.github@njae.me.uk
49
80
  executables: []
@@ -84,7 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
84
115
  version: '0'
85
116
  segments:
86
117
  - 0
87
- hash: -190252433
118
+ hash: 218522511
88
119
  required_rubygems_version: !ruby/object:Gem::Requirement
89
120
  none: false
90
121
  requirements:
@@ -93,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
124
  version: '0'
94
125
  requirements: []
95
126
  rubyforge_project:
96
- rubygems_version: 1.8.16
127
+ rubygems_version: 1.8.24
97
128
  signing_key:
98
129
  specification_version: 3
99
130
  summary: A simple graph library