graph.njae 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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