abuelo 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 56d6315d3eafd194ee45e20bfa60eff9b68548c6
4
- data.tar.gz: a15a915a0c83f075c4a67495dce09628fab155f4
3
+ metadata.gz: 5fec3a84e6365d1dabdbb0a97dfaae5c5f616dfe
4
+ data.tar.gz: d687748513f8e7aabb0eae7fbfc186949dc61334
5
5
  SHA512:
6
- metadata.gz: ce7fdf584034fbe02e378dadd644c6e16dc617e3d50c7130cd97011f44bb9c9170af759b11be232f8b53d24b958ad286dda5a5a0b057075dc93d42daa619b8b5
7
- data.tar.gz: 463ff60c87536021e450664c9a9749818bf4381a1b9db69f004e8f651ca0f3fe73421eee25af210b66b843425a34a48bc1f96160f67912c880c7e1cc303add43
6
+ metadata.gz: edca527570d0e4775ebaf20458dfdfb393c3ba54e0d250eaccae09d9476d68e249c62dd7620458824d4030b0d1956e4eb09b7da4d30d7704240116d20d8b2c3f
7
+ data.tar.gz: d7bc96b07f9ded38385e0a24a1201edc4f7ce6788596c79bbf3ee7ce99c580e274c916ad972a98e2e12940f47c2f9195e8615ec3cc2e7f2ae06756c106ef71ab
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ - 2.2.4
5
+ - 2.1.8
6
+ - 2.0.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # 0.0.2 - 2016-02-21
2
+ * new possibility to build a graph: adjacency matrix
3
+ * added code of conduct
4
+ * refactoring to better meet community standards
5
+ * dropped support for Ruby < 2.0.0
6
+
7
+ # 0.0.1 - 2016-01-17
8
+ hello world
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in abuelo.gemspec
4
- gemspec
4
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abuelo (0.0.1)
4
+ abuelo (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,7 +1,14 @@
1
1
  # Abuelo
2
- Abuelo is a graph theory library that allows you to build a representation of a directed graph with its nodes and edges.
2
+ [![Build Status](https://travis-ci.org/dirkholzapfel/abuelo.svg?branch=master)](https://travis-ci.org/dirkholzapfel/abuelo)
3
+
4
+ Abuelo is a graph theory library written in Ruby that allows you to build a representation of a graph.
5
+
6
+ A graph consists of nodes (= vertices, points) and edges (= lines, arcs). The graph may be undirected or directed. For the sake of simplicity Abuelo sticks with the same vocabulary (nodes, edges) for directed and undirected graphs in contrast to theoretical graph theory.
7
+
8
+ Abuelo supports Ruby >= 2.0.0
3
9
 
4
10
  ## Examples
11
+ ### Undirected graph
5
12
  ```ruby
6
13
  graph = Abuelo::Graph.new
7
14
 
@@ -17,15 +24,109 @@ graph.add_node(node_1)
17
24
  .add_edge(edge_1)
18
25
  .add_edge(edge_2)
19
26
 
20
- graph.nodes # => [node_1, node_2, node_3]
21
- graph.has_node?(node_1) # => true
22
- graph.has_node_with_name?('foo') # => false
23
- graph.edges # => [edge_1, edge_2]
24
- graph.has_edge?(edge_1) # => true
25
- graph.find_edge(node_1, node_2) # => edge_1
26
- graph.edges_for_node(node_2) # => [edge_2]
27
+ graph.order # => 3
28
+ graph.size # => 2
29
+ graph.nodes # => [node_1, node_2, node_3]
30
+ graph.has_node?(node_1) # => true
31
+ graph.has_node_with_name?('foo') # => false
32
+ graph.find_node_by_name('node 1') # => node_1
33
+ graph.edges # => [[edge_1, edge_1.symmetric], [edge_2, edge_2.symmetric]]
34
+ graph.has_edge?(edge_1) # => true
35
+ graph.has_edge?(edge_1.symmetric) # => true
36
+ graph.find_edge(node_1, node_2) # => edge_1
37
+ graph.find_edge(node_2, node_1) # => edge_1.symmetric
38
+ graph.edges_for_node(node_2) # => [edge_1.symmetric, edge_2]
39
+
40
+ node_1.edges # => [edge_1]
41
+ node_1.neighbours # => [node_2]
27
42
  ```
28
43
 
44
+ ### Directed graph
45
+ ```ruby
46
+ graph = Abuelo::Graph.new(directed: true)
47
+
48
+ node_1 = Abuelo::Node.new('node 1')
49
+ node_2 = Abuelo::Node.new('node 2')
50
+ node_3 = Abuelo::Node.new('node 3')
51
+ edge_1 = Abuelo::Edge.new(node_1, node_2, 42)
52
+ edge_2 = Abuelo::Edge.new(node_2, node_3, 23)
53
+
54
+ graph.add_node(node_1)
55
+ .add_node(node_2)
56
+ .add_node(node_3)
57
+ .add_edge(edge_1)
58
+ .add_edge(edge_2)
59
+
60
+ graph.order # => 3
61
+ graph.size # => 2
62
+ graph.nodes # => [node_1, node_2, node_3]
63
+ graph.has_node?(node_1) # => true
64
+ graph.has_node_with_name?('foo') # => false
65
+ graph.find_node_by_name('node 1') # => node_1
66
+ graph.edges # => [edge_1, edge_2]
67
+ graph.has_edge?(edge_1) # => true
68
+ graph.has_edge?(edge_1.symmetric) # => false
69
+ graph.find_edge(node_1, node_2) # => edge_1
70
+ graph.find_edge(node_2, node_1) # => nil
71
+ graph.edges_for_node(node_2) # => [edge_2]
72
+
73
+ node_1.edges # => [edge_1]
74
+ node_1.neighbours # => [node_2]
75
+ ```
76
+
77
+ ### Initialize a graph with an adjacency matrix
78
+ The above, object oriented way to build graphs is the recommended way to work with this library.
79
+ But you can also build a graph with an [adjacency matrix](https://en.wikipedia.org/wiki/Adjacency_matrix).
80
+ That is a nice shortcut used in some tests and may be a good alternative if you use Abuelo in the console to play around.
81
+
82
+ A zero indicates there is no edge between the nodes, an Integer indicates that there is an edge with the given weight between the nodes. The nodes are automatically named, starting with "node 1".
83
+ The above example can be built like this:
84
+
85
+ #### Undirected graphs
86
+ Be aware that you have to provide all symmetric edges in an adjacency matrix for an undirected graph - the lib does not add them automatically as it happens with the `.add_edge` method.
87
+
88
+ ```ruby
89
+ adjacency_matrix = <<-matrix
90
+ 0 42 0
91
+ 42 0 23
92
+ 0 23 0
93
+ matrix
94
+
95
+ # The above matrix corresponds to this internal representation
96
+ #
97
+ # | node 1 | node 2 | node 3 |
98
+ # ------------------------------------
99
+ # node 1 | 0 | 42 | 0 |
100
+ # node 2 | 42 | 0 | 23 |
101
+ # node 3 | 0 | 23 | 0 |
102
+
103
+ graph = Abuelo::Graph.new(adjacency_matrix: adjacency_matrix)
104
+ node_1 = graph.find_node_by_name('node 1')
105
+ node_2 = graph.find_node_by_name('node 2')
106
+ graph.find_edge(node_1, node_2).weight # => 42
107
+ ```
108
+ #### Directed graphs
109
+ ```ruby
110
+ adjacency_matrix = <<-matrix
111
+ 0 42 0
112
+ 0 0 23
113
+ 0 0 0
114
+ matrix
115
+
116
+ # The above matrix corresponds to this internal representation
117
+ #
118
+ # | node 1 | node 2 | node 3 |
119
+ # ------------------------------------
120
+ # node 1 | 0 | 42 | 0 |
121
+ # node 2 | 0 | 0 | 23 |
122
+ # node 3 | 0 | 0 | 0 |
123
+
124
+ graph = Abuelo::Graph.new(adjacency_matrix: adjacency_matrix, directed: true)
125
+ ```
126
+
127
+ ## Documentation
128
+ [YARD](http://yardoc.org) documentation is available at [rubydoc](http://www.rubydoc.info/gems/abuelo).
129
+
29
130
  ## Future
30
131
  * Implement graph algorithms
31
132
  * [Kruskal's algorithm](https://en.wikipedia.org/wiki/Kruskal%27s_algorithm)
@@ -49,4 +150,9 @@ Dirk Holzapfel
49
150
 
50
151
  [cachezero.net](http://cachezero.net)
51
152
 
52
- [bitcrowd.net](http://bitcrowd.net)
153
+ [Abuelo](http://www.ronabuelopanama.com)
154
+
155
+ ### Contributors
156
+ [dirkholzapfel](https://github.com/dirkholzapfel),
157
+ [mbirman](https://github.com/mbirman),
158
+ [sergey-kintsel](https://github.com/sergey-kintsel)
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
3
 
4
- task :default => :tests
5
- task :tests => [:spec]
4
+ task default: :tests
5
+ task tests: [:spec]
6
6
 
7
7
  RSpec::Core::RakeTask.new(:spec)
data/abuelo.gemspec CHANGED
@@ -1,22 +1,22 @@
1
- $:.push File.expand_path("../lib", __FILE__)
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
2
  require 'abuelo/version'
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = 'abuelo'
6
6
  spec.version = Abuelo::VERSION
7
7
  spec.date = '2016-01-10'
8
- spec.summary = "Abuelo"
9
- spec.description = "Abuelo is a graph theory library."
10
- spec.authors = ["Dirk Holzapfel"]
11
- spec.email = 'dirk@bitcrowd.net'
8
+ spec.summary = 'Abuelo'
9
+ spec.description = 'Abuelo is a graph theory library.'
10
+ spec.authors = ['Dirk Holzapfel']
11
+ spec.email = 'cache.zero@mailbox.org'
12
12
  spec.homepage =
13
13
  'http://github.com/dirkholzapfel/abuelo'
14
14
  spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files`.split("\n")
17
17
  spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
- spec.require_paths = ["lib"]
18
+ spec.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
19
+ spec.require_paths = ['lib']
20
20
 
21
21
  # Development
22
22
  spec.add_development_dependency 'bundler', '~> 1.7'
@@ -25,4 +25,4 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  # Testing
27
27
  spec.add_development_dependency 'rspec'
28
- end
28
+ end
data/lib/abuelo.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  require 'abuelo/graph'
2
2
  require 'abuelo/node'
3
3
  require 'abuelo/edge'
4
- require 'abuelo/exceptions/exceptions'
4
+ require 'abuelo/exceptions/exceptions'
data/lib/abuelo/edge.rb CHANGED
@@ -3,16 +3,15 @@ module Abuelo
3
3
  # Class Edge provides a representation of an edge.
4
4
  # An edge connects two nodes(start-node and end-node) and has a weight.
5
5
  #
6
- # @author Dirk Holzapfel <dirk@bitcrowd.net>
6
+ # @author Dirk Holzapfel <cache.zero@mailbox.org>
7
7
  #
8
8
  class Edge
9
-
10
9
  # @return [Abuelo::Node] start-node
11
10
  attr_reader :node_1
12
11
 
13
12
  # @return [Abuelo::Node] end-node
14
13
  attr_reader :node_2
15
-
14
+
16
15
  # @return [Numeric] weight
17
16
  attr_reader :weight
18
17
 
@@ -22,8 +21,8 @@ module Abuelo
22
21
  # @param [Abuelo::Node] node_1 start-node
23
22
  # @param [Abuelo::Node] node_2 end-node
24
23
  # @param [Numeric] weight of the edge
25
- #
26
- def initialize(node_1, node_2, weight = 0)
24
+ #
25
+ def initialize(node_1, node_2, weight = 1)
27
26
  @node_1 = node_1
28
27
  @node_2 = node_2
29
28
  @weight = weight
@@ -31,41 +30,40 @@ module Abuelo
31
30
 
32
31
  #
33
32
  # @return [Abuelo::Edge] a new edge with same weight but reversed start- and end-node.
34
- #
35
- def opposite
33
+ #
34
+ def symmetric
36
35
  Abuelo::Edge.new(node_2, node_1, weight)
37
36
  end
38
37
 
39
38
  #
40
39
  # Comparison based on weight.
41
40
  #
42
- # @param [Abuelo::Edge] other_edge
41
+ # @param [Abuelo::Edge] other
42
+ #
43
+ # @return [-1, 0, +1]
43
44
  #
44
- # @return [-1, 0, +1 or ni]
45
- #
46
- def <=>(other_edge)
47
- self.weight <=> other_edge.weight
45
+ def <=>(other)
46
+ weight <=> other.weight
48
47
  end
49
48
 
50
49
  #
51
50
  # Equality check.
52
51
  #
53
- # @param [Abuelo::Edge] other_edge
52
+ # @param [Abuelo::Edge] other
54
53
  #
55
54
  # @return [Boolean] true if start-, end-node and weight of both edges are equal
56
- #
57
- def ==(other_edge)
58
- self.node_1 == other_edge.node_1 &&
59
- self.node_2 == other_edge.node_2 &&
60
- self.weight == other_edge.weight
55
+ #
56
+ def ==(other)
57
+ node_1 == other.node_1 &&
58
+ node_2 == other.node_2 &&
59
+ weight == other.weight
61
60
  end
62
61
 
63
62
  #
64
63
  # @return [String] human readable representation of edge
65
- #
64
+ #
66
65
  def to_s
67
- "#{node_1.to_s} -> #{node_2.to_s} with weight #{weight}"
66
+ "#{node_1} -> #{node_2} with weight #{weight}"
68
67
  end
69
-
70
68
  end
71
69
  end
@@ -1,11 +1,9 @@
1
1
  module Abuelo
2
2
  module Exceptions
3
-
4
3
  class NodeAlreadyExistsError < StandardError
5
4
  end
6
5
 
7
6
  class EdgeAlreadyExistsError < StandardError
8
7
  end
9
-
10
8
  end
11
- end
9
+ end
data/lib/abuelo/graph.rb CHANGED
@@ -1,17 +1,64 @@
1
1
  module Abuelo
2
2
  #
3
3
  # Class Graph provides a representation of a directed graph.
4
+ #
4
5
  # A graph consists of nodes (= vertices, points) and edges (= lines, arcs).
6
+ # The graph may be undirected or directed. For the sake of simplicity Abuelo sticks
7
+ # with the same vocabulary (nodes, edges) for directed and undirected graphs in
8
+ # contrast to theoretical graph theory.
5
9
  #
6
- # @author Dirk Holzapfel <dirk@bitcrowd.net>
10
+ # @author Dirk Holzapfel <cache.zero@mailbox.org>
7
11
  #
8
12
  class Graph
9
-
10
- def initialize
13
+ #
14
+ # @param [Hash] opts the options to create a graph with
15
+ # @option opts [Boolean] :directed defines if the graph is directed or undirected.
16
+ # (defaults to false == undirected)
17
+ # @option opts [String] :adjacency_matrix a representation of the graph in form
18
+ # of an adjacency matrix
19
+ #
20
+ # @example Build a graph with the help of an adjacency matrix
21
+ # adjacency_matrix = <<-matrix
22
+ # 0 42 0
23
+ # 42 0 23
24
+ # 0 23 0
25
+ # matrix
26
+ # graph = Abuelo::Graph.new(adjacency_matrix: adjacency_matrix)
27
+ #
28
+ def initialize(opts = {})
11
29
  @nodes = {} # @nodes = { node_name => node_object }
12
30
  @edges = {} # @edges = { node_object => { node_object => edge }}
31
+ @directed = opts.fetch(:directed, false)
32
+ init_by_adjacency_matrix(opts[:adjacency_matrix]) if opts[:adjacency_matrix]
13
33
  end
14
34
 
35
+ #
36
+ # @return [Boolean] true if the graph is directed, false if it is undirected
37
+ #
38
+ def directed?
39
+ @directed
40
+ end
41
+
42
+ #
43
+ # @return [Boolean] true if the graph is undirected, false if it is directed
44
+ #
45
+ def undirected?
46
+ !directed?
47
+ end
48
+
49
+ #
50
+ # @return [Integer] the order of the graph == the number of nodes
51
+ #
52
+ def order
53
+ nodes.count
54
+ end
55
+
56
+ #
57
+ # @return [Integer] the size of the graph == the number of edges
58
+ #
59
+ def size
60
+ edges.count
61
+ end
15
62
 
16
63
  #
17
64
  # @return [Array<Abuelo::Node>] list of nodes of the graph
@@ -29,12 +76,13 @@ module Abuelo
29
76
  #
30
77
  # @raise [Abuelo::Exceptions::NodeAlreadyExistsError] if the node is
31
78
  # already contained in the graph
32
- #
79
+ #
33
80
  def add_node(node)
34
81
  raise Abuelo::Exceptions::NodeAlreadyExistsError if has_node?(node)
35
82
 
36
83
  @nodes[node.name] = node
37
84
  node.graph = self
85
+
38
86
  self
39
87
  end
40
88
 
@@ -44,7 +92,7 @@ module Abuelo
44
92
  # @param [Abuelo::Node] node
45
93
  #
46
94
  # @return [Boolean]
47
- #
95
+ #
48
96
  def has_node?(node)
49
97
  has_node_with_name?(node.name)
50
98
  end
@@ -55,22 +103,46 @@ module Abuelo
55
103
  # @param [String] name of the node
56
104
  #
57
105
  # @return [Boolean]
58
- #
106
+ #
59
107
  def has_node_with_name?(name)
60
- @nodes[name] ? true : false
108
+ !find_node_by_name(name).nil?
61
109
  end
62
110
 
111
+ #
112
+ # Returns the node with the given name if it is contained in the graph.
113
+ #
114
+ # @param [String] name of the node
115
+ #
116
+ # @return [Abuelo::Node, nil] the node if found, otherwise nil
117
+ #
118
+ def find_node_by_name(name)
119
+ @nodes[name]
120
+ end
63
121
 
64
122
  #
65
- # @return [Array<Abuelo::Edge>] list of edges of the graph
66
- #
123
+ # @return [Array<Abuelo::Edge>, Array<Array(Abuelo::Edge, Abuelo::Edge)>]
124
+ # list of edges of the graph if directed,
125
+ # list of list of symmetric pairs of edges of the graph if undirected
126
+ #
127
+ # @example directed graph
128
+ # "graph.edges" #=> [edge_from_node_1_to_node_2]
129
+ #
130
+ # @example undirected graph
131
+ # "graph.edges" #=> [[edge_from_node_1_to_node_2, edge_from_node_2_to_node_1]]
132
+ #
67
133
  def edges
68
- edges = @edges.keys.map { |key| @edges[key].values }
69
- edges.flatten
134
+ edges = @edges.keys.flat_map { |key| @edges[key].values }
135
+
136
+ if directed?
137
+ edges
138
+ else
139
+ edges.each_slice(2).to_a
140
+ end
70
141
  end
71
142
 
72
143
  #
73
144
  # Adds an edge to the graph.
145
+ # Auto-adds the symmetric counterpart if graph is undirected.
74
146
  #
75
147
  # @param [Abuelo::Edge] edge to add
76
148
  #
@@ -78,12 +150,17 @@ module Abuelo
78
150
  #
79
151
  # @raise [Abuelo::Exceptions::EdgeAlreadyExistsError] if the edge is
80
152
  # already contained in the graph
81
- #
82
- def add_edge(edge)
153
+ #
154
+ def add_edge(edge, opts = {})
83
155
  raise Abuelo::Exceptions::EdgeAlreadyExistsError if has_edge?(edge)
84
156
 
85
157
  @edges[edge.node_1] ||= {}
86
158
  @edges[edge.node_1][edge.node_2] = edge
159
+
160
+ if undirected? && !opts[:symmetric]
161
+ add_edge(edge.symmetric, symmetric: true)
162
+ end
163
+
87
164
  self
88
165
  end
89
166
 
@@ -93,19 +170,19 @@ module Abuelo
93
170
  # @param [Abuelo::Edge] edge
94
171
  #
95
172
  # @return [Boolean]
96
- #
173
+ #
97
174
  def has_edge?(edge)
98
- find_edge(edge.node_1, edge.node_2) ? true : false
175
+ !find_edge(edge.node_1, edge.node_2).nil?
99
176
  end
100
177
 
101
178
  #
102
- # Checks if there is an edge between the two given nodes.
179
+ # Returns the edge if there is one between the two given nodes.
103
180
  #
104
181
  # @param [Abuelo::Node] node_1
105
182
  # @param [Abuelo::Node] node_2
106
183
  #
107
184
  # @return [Abuelo::Edge, nil] the edge if found, otherwise nil
108
- #
185
+ #
109
186
  def find_edge(node_1, node_2)
110
187
  @edges[node_1][node_2] if @edges[node_1]
111
188
  end
@@ -116,12 +193,30 @@ module Abuelo
116
193
  # @param [Abuelo::Node] node <description>
117
194
  #
118
195
  # @return [Array<Abuelo::Edge>] list of edges that start from the given node
119
- #
196
+ #
120
197
  def edges_for_node(node)
121
- edges = []
122
- edges += @edges[node].values.to_a if @edges[node]
123
- edges
198
+ Hash(@edges[node]).values
124
199
  end
125
200
 
201
+
202
+ private
203
+
204
+ def init_by_adjacency_matrix(adjacency_matrix)
205
+ nodes = {}
206
+ 1.upto(adjacency_matrix.lines.count) do |i|
207
+ node = Abuelo::Node.new("node #{i}")
208
+ nodes[i] = node
209
+ add_node(node)
210
+ end
211
+
212
+ adjacency_matrix.split(/\r?\n/).each_with_index do |row, row_index|
213
+ row.split(' ').map(&:to_i).each_with_index do |weight, column_index|
214
+ if weight != 0
215
+ edge = Abuelo::Edge.new(nodes[row_index+1], nodes[column_index+1], weight)
216
+ add_edge(edge, symmetric: true)
217
+ end
218
+ end
219
+ end
220
+ end
126
221
  end
127
222
  end
data/lib/abuelo/node.rb CHANGED
@@ -3,7 +3,7 @@ module Abuelo
3
3
  # Class Node provides a representation of a node.
4
4
  # A node has a name. Any object may be attached on initialization.
5
5
  #
6
- # @author Dirk Holzapfel <dirk@bitcrowd.net>
6
+ # @author Dirk Holzapfel <cache.zero@mailbox.org>
7
7
  #
8
8
  class Node
9
9
  # @return [String] name
@@ -21,7 +21,7 @@ module Abuelo
21
21
  # @param [String] name of the node
22
22
  # @param [Object] object to attach to the node.
23
23
  # This is useful on some algorithm implementations.
24
- #
24
+ #
25
25
  def initialize(name, object = nil)
26
26
  @name = name
27
27
  @object = object
@@ -29,14 +29,21 @@ module Abuelo
29
29
 
30
30
  #
31
31
  # @return [Array<Abuelo::Edge>] list of edges starting from the node
32
- #
32
+ #
33
33
  def edges
34
34
  graph.edges_for_node(self) if graph
35
35
  end
36
36
 
37
+ #
38
+ # @return [Array<Abuelo::Node>] list of nodes that are adjacent to the node
39
+ #
40
+ def neighbours
41
+ edges.map(&:node_2)
42
+ end
43
+
37
44
  #
38
45
  # @return [String] human readable representation of node
39
- #
46
+ #
40
47
  def to_s
41
48
  @name
42
49
  end
@@ -44,12 +51,12 @@ module Abuelo
44
51
  #
45
52
  # Equality check.
46
53
  #
47
- # @param [Abuelo::Node] other_node
54
+ # @param [Abuelo::Node] other
48
55
  #
49
56
  # @return [Boolean] true if name is equal
50
- #
51
- def ==(other_node)
52
- self.name == other_node.name
57
+ #
58
+ def ==(other)
59
+ name == other.name
53
60
  end
54
61
  end
55
62
  end
@@ -1,3 +1,3 @@
1
1
  module Abuelo
2
- VERSION = "0.0.1".freeze
3
- end
2
+ VERSION = '0.0.2'.freeze
3
+ end
data/spec/edge_spec.rb CHANGED
@@ -1,15 +1,14 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe Abuelo::Edge do
4
-
5
4
  let(:node_1) { Abuelo::Node.new('node 1') }
6
5
  let(:node_2) { Abuelo::Node.new('node 2') }
7
6
 
8
7
  let(:edge) { described_class.new(node_1, node_2, 3) }
9
8
 
10
9
  context 'initialization' do
11
- it 'sets the weight to 0 if not given' do
12
- expect(described_class.new(node_1, node_2).weight).to eq 0
10
+ it 'sets the weight to 1 if not given' do
11
+ expect(described_class.new(node_1, node_2).weight).to eq 1
13
12
  end
14
13
  end
15
14
 
@@ -21,12 +20,12 @@ RSpec.describe Abuelo::Edge do
21
20
  end
22
21
  end
23
22
 
24
- describe '#opposite' do
23
+ describe '#symmetric' do
25
24
  it 'returns an edge object with the same weight, but reversed nodes' do
26
- opposite = edge.opposite
27
- expect(opposite.node_1).to eq edge.node_2
28
- expect(opposite.node_2).to eq edge.node_1
29
- expect(opposite.weight).to eq edge.weight
25
+ symmetric = edge.symmetric
26
+ expect(symmetric.node_1).to eq edge.node_2
27
+ expect(symmetric.node_2).to eq edge.node_1
28
+ expect(symmetric.weight).to eq edge.weight
30
29
  end
31
30
  end
32
31
 
data/spec/graph_spec.rb CHANGED
@@ -1,130 +1,375 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe Abuelo::Graph do
4
-
5
4
  let(:node_1) { Abuelo::Node.new('node 1') }
6
5
  let(:node_2) { Abuelo::Node.new('node 2') }
7
- let(:edge) { Abuelo::Edge.new(node_1, node_2, 42) }
6
+ let(:node_3) { Abuelo::Node.new('node 3') }
7
+ let(:edge_1) { Abuelo::Edge.new(node_1, node_2, 42) }
8
+ let(:edge_2) { Abuelo::Edge.new(node_2, node_3, 23) }
9
+
10
+ let(:directed_graph) do
11
+ described_class.new(directed: true)
12
+ .add_node(node_1)
13
+ .add_node(node_2)
14
+ .add_node(node_3)
15
+ .add_edge(edge_1)
16
+ .add_edge(edge_2)
17
+ end
8
18
 
9
- let(:graph) do
10
- graph = described_class.new
11
- graph.add_node(node_1)
12
- graph.add_node(node_2)
13
- graph.add_edge(edge)
19
+ let(:undirected_graph) do
20
+ described_class.new
21
+ .add_node(node_1)
22
+ .add_node(node_2)
23
+ .add_node(node_3)
24
+ .add_edge(edge_1)
25
+ .add_edge(edge_2)
14
26
  end
15
27
 
16
- context 'nodes' do
17
- describe '#nodes' do
18
- it 'returns the nodes of the graph' do
19
- expect(graph.nodes).to match_array [node_1, node_2]
28
+ context 'directed graph' do
29
+ describe '#initialize' do
30
+ it 'can be initialized with an adjacency matrix with weights' do
31
+ adjacency_matrix = <<-matrix
32
+ 0 7 9 0 0 14
33
+ 7 0 10 15 0 0
34
+ 9 10 0 11 0 2
35
+ 0 0 11 0 6 0
36
+ 0 0 0 6 0 9
37
+ 0 0 2 0 9 0
38
+ matrix
39
+
40
+ graph = described_class.new(adjacency_matrix: adjacency_matrix, directed: true)
41
+ node_1 = graph.find_node_by_name('node 1')
42
+ node_2 = graph.find_node_by_name('node 2')
43
+ node_4 = graph.find_node_by_name('node 4')
44
+
45
+ expect(graph.order).to eq 6
46
+ expect(graph.size).to eq 16
47
+
48
+ expect(graph.has_node_with_name?('node 1')).to be true
49
+ expect(graph.has_node_with_name?('node 0')).to be false
50
+ expect(graph.has_node_with_name?('node 7')).to be false
51
+
52
+ expect(graph.find_edge(node_1, node_4)).to be nil
53
+
54
+ edge_1_2 = graph.find_edge(node_1, node_2)
55
+ expect(edge_1_2.weight).to eq 7
20
56
  end
21
57
  end
22
58
 
23
- describe '#add_node(node)' do
24
- it 'adds the node to the graph' do
25
- new_node = Abuelo::Node.new('node 3')
59
+ describe '#undirected?' do
60
+ it 'is false' do
61
+ expect(directed_graph.undirected?).to be false
62
+ end
63
+ end
26
64
 
27
- expect{
28
- graph.add_node(new_node)
29
- }.to change{ graph.nodes.count }.by 1
65
+ describe '#directed?' do
66
+ it 'is true' do
67
+ expect(directed_graph.directed?).to be true
68
+ end
69
+ end
30
70
 
31
- expect(graph.has_node?(new_node)).to be true
71
+ describe 'order' do
72
+ it 'returns the count of nodes' do
73
+ expect(directed_graph.order).to eq 3
32
74
  end
75
+ end
33
76
 
34
- it 'raises an error if a node with the same name in the graph exists' do
35
- new_node = Abuelo::Node.new('node 1')
77
+ describe 'size' do
78
+ it 'returns the count of edges' do
79
+ expect(directed_graph.size).to eq 2
80
+ end
81
+ end
36
82
 
37
- expect{
38
- graph.add_node(new_node)
39
- }.to raise_error(Abuelo::Exceptions::NodeAlreadyExistsError)
83
+ context 'nodes' do
84
+ describe '#nodes' do
85
+ it 'returns the nodes of the graph' do
86
+ expect(directed_graph.nodes).to match_array [node_1, node_2, node_3]
87
+ end
40
88
  end
41
89
 
42
- it 'sets the graph of the node to itself' do
43
- new_node = Abuelo::Node.new('node 3')
90
+ describe '#add_node(node)' do
91
+ it 'adds the node to the graph' do
92
+ new_node = Abuelo::Node.new('node 4')
93
+
94
+ expect do
95
+ directed_graph.add_node(new_node)
96
+ end.to change { directed_graph.nodes.count }.by 1
97
+
98
+ expect(directed_graph.has_node?(new_node)).to be true
99
+ end
100
+
101
+ it 'raises an error if a node with the same name in the graph exists' do
102
+ new_node = Abuelo::Node.new('node 1')
44
103
 
45
- expect{
46
- graph.add_node(new_node)
47
- }.to change{ new_node.graph }.to(graph)
104
+ expect do
105
+ directed_graph.add_node(new_node)
106
+ end.to raise_error(Abuelo::Exceptions::NodeAlreadyExistsError)
107
+ end
108
+
109
+ it 'sets the graph of the node to itself' do
110
+ new_node = Abuelo::Node.new('node 4')
111
+
112
+ expect do
113
+ directed_graph.add_node(new_node)
114
+ end.to change { new_node.graph }.to(directed_graph)
115
+ end
48
116
  end
49
- end
50
117
 
51
- describe '#has_node?(node)' do
52
- it 'returns true if node is in the graph. checks object name' do
53
- expect(graph.has_node?(node_1)).to be true
118
+ describe '#has_node?(node)' do
119
+ it 'returns true if node is in the graph. checks object name' do
120
+ expect(directed_graph.has_node?(node_1)).to be true
121
+ end
122
+
123
+ it 'returns false if node is not in the graph. checks object name' do
124
+ new_node = Abuelo::Node.new('node 99')
125
+ expect(directed_graph.has_node?(new_node)).to be false
126
+ end
54
127
  end
55
128
 
56
- it 'returns false if node is not in the graph. checks object name' do
57
- new_node = Abuelo::Node.new('node 3')
58
- expect(graph.has_node?(new_node)).to be false
129
+ describe '#has_node_with_name?(name)' do
130
+ it 'returns true if a node with the given name is in the graph' do
131
+ expect(directed_graph.has_node_with_name?('node 1')).to be true
132
+ end
133
+
134
+ it 'returns false if no node with the given name is in the graph' do
135
+ expect(directed_graph.has_node_with_name?('foo')).to be false
136
+ end
59
137
  end
60
138
  end
61
139
 
62
- describe '#has_node_with_name?(name)' do
63
- it 'returns true if a node with the given name is in the graph' do
64
- expect(graph.has_node_with_name?('node 1')).to be true
140
+ context 'edges' do
141
+ describe '#edges' do
142
+ it 'returns the edges of the graph' do
143
+ expect(directed_graph.edges).to match_array [edge_1, edge_2]
144
+ end
65
145
  end
66
146
 
67
- it 'returns fale if no node with the given name is in the graph' do
68
- expect(graph.has_node_with_name?('foo')).to be false
147
+ describe '#add_edge(edge)' do
148
+ it 'adds the edge to the graph' do
149
+ new_edge = Abuelo::Edge.new(node_2, node_1, 23)
150
+
151
+ expect do
152
+ directed_graph.add_edge(new_edge)
153
+ end.to change { directed_graph.edges.count }.by 1
154
+
155
+ expect(directed_graph.has_edge?(new_edge)).to be true
156
+ end
157
+
158
+ it 'raises an error if an edge with the same name nodes in the graph exists' do
159
+ new_edge = Abuelo::Edge.new(node_1, node_2, 23)
160
+
161
+ expect do
162
+ directed_graph.add_edge(new_edge)
163
+ end.to raise_error(Abuelo::Exceptions::EdgeAlreadyExistsError)
164
+ end
165
+ end
166
+
167
+ describe '#edges_for_node(node)' do
168
+ it 'returns all edges that start from the given node' do
169
+ expect(directed_graph.edges_for_node(node_1)).to eq [edge_1]
170
+ expect(directed_graph.edges_for_node(node_2)).to eq [edge_2]
171
+ expect(directed_graph.edges_for_node(node_3)).to eq []
172
+ end
173
+ end
174
+
175
+ describe '#has_edge?(edge)' do
176
+ it 'returns true if there is an edge with similiar nodes in the graph' do
177
+ expect(directed_graph.has_edge?(edge_1)).to be true
178
+ end
179
+
180
+ it 'does not have a symmetric edge automatically' do
181
+ expect(directed_graph.has_edge?(edge_1.symmetric)).to be false
182
+ end
183
+
184
+ it 'returns false if there is no edge with similiar nodes in the graph' do
185
+ other_edge = Abuelo::Edge.new(node_2, node_1, 23)
186
+ expect(directed_graph.has_edge?(other_edge)).to be false
187
+ end
69
188
  end
70
- end
71
- end
72
189
 
190
+ describe '#find_edge(node_1, node_2)' do
191
+ it 'returns the edge if it can be found in the graph' do
192
+ expect(directed_graph.find_edge(node_1, node_2)).to eq edge_1
193
+ end
73
194
 
74
- context 'edges' do
75
- describe '#edges' do
76
- it 'returns the edges of the graph' do
77
- expect(graph.edges).to match_array [edge]
195
+ it 'returns nil if the edge cannot be found in the graph' do
196
+ expect(directed_graph.find_edge(node_2, node_1)).to be nil
197
+ end
78
198
  end
79
199
  end
200
+ end
201
+
202
+ context 'undirected graph' do
203
+ describe '#initialize' do
204
+ it 'can be initialized with an adjacency matrix with weights' do
205
+ adjacency_matrix = <<-matrix
206
+ 0 7 9 0 0 14
207
+ 7 0 10 15 0 0
208
+ 9 10 0 11 0 2
209
+ 0 15 11 0 6 0
210
+ 0 0 0 6 0 9
211
+ 14 0 2 0 9 0
212
+ matrix
213
+
214
+ graph = described_class.new(adjacency_matrix: adjacency_matrix)
215
+ node_1 = graph.find_node_by_name('node 1')
216
+ node_2 = graph.find_node_by_name('node 2')
217
+ node_4 = graph.find_node_by_name('node 4')
80
218
 
81
- describe '#add_edge(edge)' do
82
- it 'adds the edge to the graph' do
83
- new_edge = Abuelo::Edge.new(node_2, node_1, 23)
219
+ expect(graph.order).to eq 6
220
+ expect(graph.size).to eq 9
84
221
 
85
- expect{
86
- graph.add_edge(new_edge)
87
- }.to change{ graph.edges.count }.by 1
222
+ expect(graph.has_node_with_name?('node 1')).to be true
223
+ expect(graph.has_node_with_name?('node 0')).to be false
224
+ expect(graph.has_node_with_name?('node 7')).to be false
88
225
 
89
- expect(graph.has_edge?(new_edge)).to be true
226
+ expect(graph.find_edge(node_1, node_4)).to be nil
227
+
228
+ edge_1_2 = graph.find_edge(node_1, node_2)
229
+ expect(edge_1_2.weight).to eq 7
90
230
  end
231
+ end
91
232
 
92
- it 'raises an error if an edge with the same name nodes in the graph exists' do
93
- new_edge = Abuelo::Edge.new(node_1, node_2, 23)
233
+ describe '#undirected?' do
234
+ it 'is true' do
235
+ expect(undirected_graph.undirected?).to be true
236
+ end
237
+ end
238
+
239
+ describe '#directed?' do
240
+ it 'is false' do
241
+ expect(undirected_graph.directed?).to be false
242
+ end
243
+ end
94
244
 
95
- expect{
96
- graph.add_edge(new_edge)
97
- }.to raise_error(Abuelo::Exceptions::EdgeAlreadyExistsError)
245
+ describe 'order' do
246
+ it 'returns the count of nodes' do
247
+ expect(undirected_graph.order).to eq 3
98
248
  end
99
249
  end
100
250
 
101
- describe '#edges_for_node(node)' do
102
- it 'returns all edges that start from the given node' do
103
- expect(graph.edges_for_node(node_1)).to eq [edge]
104
- expect(graph.edges_for_node(node_2)).to eq []
251
+ describe 'size' do
252
+ it 'returns the count of edges' do
253
+ expect(undirected_graph.size).to eq 2
105
254
  end
106
255
  end
107
256
 
108
- describe '#has_edge?(edge)' do
109
- it 'returns true if there is an edge with similiar nodes in the graph' do
110
- expect(graph.has_edge?(edge)).to be true
257
+ context 'nodes' do
258
+ describe '#nodes' do
259
+ it 'returns the nodes of the graph' do
260
+ expect(undirected_graph.nodes).to match_array [node_1, node_2, node_3]
261
+ end
111
262
  end
112
263
 
113
- it 'returns false if there is no edge with similiar nodes in the graph' do
114
- other_edge = Abuelo::Edge.new(node_2, node_1, 23)
115
- expect(graph.has_edge?(other_edge)).to be false
264
+ describe '#add_node(node)' do
265
+ it 'adds the node to the graph' do
266
+ new_node = Abuelo::Node.new('node 4')
267
+
268
+ expect do
269
+ undirected_graph.add_node(new_node)
270
+ end.to change { undirected_graph.nodes.count }.by 1
271
+
272
+ expect(undirected_graph.has_node?(new_node)).to be true
273
+ end
274
+
275
+ it 'raises an error if a node with the same name in the graph exists' do
276
+ new_node = Abuelo::Node.new('node 1')
277
+
278
+ expect do
279
+ undirected_graph.add_node(new_node)
280
+ end.to raise_error(Abuelo::Exceptions::NodeAlreadyExistsError)
281
+ end
282
+
283
+ it 'sets the graph of the node to itself' do
284
+ new_node = Abuelo::Node.new('node 4')
285
+
286
+ expect do
287
+ undirected_graph.add_node(new_node)
288
+ end.to change { new_node.graph }.to(undirected_graph)
289
+ end
290
+ end
291
+
292
+ describe '#has_node?(node)' do
293
+ it 'returns true if node is in the graph. checks object name' do
294
+ expect(undirected_graph.has_node?(node_1)).to be true
295
+ end
296
+
297
+ it 'returns false if node is not in the graph. checks object name' do
298
+ new_node = Abuelo::Node.new('node 4')
299
+ expect(undirected_graph.has_node?(new_node)).to be false
300
+ end
301
+ end
302
+
303
+ describe '#has_node_with_name?(name)' do
304
+ it 'returns true if a node with the given name is in the graph' do
305
+ expect(undirected_graph.has_node_with_name?('node 1')).to be true
306
+ end
307
+
308
+ it 'returns false if no node with the given name is in the graph' do
309
+ expect(undirected_graph.has_node_with_name?('foo')).to be false
310
+ end
116
311
  end
117
312
  end
118
313
 
119
- describe '#find_edge(node_1, node_2)' do
120
- it 'returns the edge if it can be found in the graph' do
121
- expect(graph.find_edge(node_1, node_2)).to eq edge
314
+ context 'edges' do
315
+ describe '#edges' do
316
+ it 'returns the edges of the graph' do
317
+ edges = [[edge_1, edge_1.symmetric], [edge_2, edge_2.symmetric]]
318
+ expect(undirected_graph.edges).to match_array edges
319
+ end
122
320
  end
123
321
 
124
- it 'returns nil if the edge cannot be found in the graph' do
125
- expect(graph.find_edge(node_2, node_1)).to be nil
322
+ describe '#add_edge(edge)' do
323
+ it 'adds the edge to the graph' do
324
+ new_edge = Abuelo::Edge.new(node_1, node_3, 23)
325
+
326
+ expect do
327
+ undirected_graph.add_edge(new_edge)
328
+ end.to change { undirected_graph.edges.count }.by 1
329
+
330
+ expect(undirected_graph.has_edge?(new_edge)).to be true
331
+ expect(undirected_graph.has_edge?(new_edge.symmetric)).to be true
332
+ end
333
+
334
+ it 'raises an error if an edge with the same name nodes in the graph exists' do
335
+ new_edge = Abuelo::Edge.new(node_1, node_2, 23)
336
+
337
+ expect do
338
+ undirected_graph.add_edge(new_edge)
339
+ end.to raise_error(Abuelo::Exceptions::EdgeAlreadyExistsError)
340
+ end
341
+ end
342
+
343
+ describe '#edges_for_node(node)' do
344
+ it 'returns all edges that start from the given node' do
345
+ expect(undirected_graph.edges_for_node(node_1)).to eq [edge_1]
346
+ expect(undirected_graph.edges_for_node(node_2)).to eq [edge_1.symmetric, edge_2]
347
+ expect(undirected_graph.edges_for_node(node_3)).to eq [edge_2.symmetric]
348
+ end
349
+ end
350
+
351
+ describe '#has_edge?(edge)' do
352
+ it 'returns true if there is an edge with similiar nodes in the graph' do
353
+ expect(undirected_graph.has_edge?(edge_1)).to be true
354
+ expect(undirected_graph.has_edge?(edge_1.symmetric)).to be true
355
+ end
356
+
357
+ it 'returns false if there is no edge with similiar nodes in the graph' do
358
+ other_edge = Abuelo::Edge.new(node_1, node_3, 23)
359
+ expect(undirected_graph.has_edge?(other_edge)).to be false
360
+ end
361
+ end
362
+
363
+ describe '#find_edge(node_1, node_2)' do
364
+ it 'returns the edge if it can be found in the graph' do
365
+ expect(undirected_graph.find_edge(node_1, node_2)).to eq edge_1
366
+ expect(undirected_graph.find_edge(node_2, node_1)).to eq edge_1.symmetric
367
+ end
368
+
369
+ it 'returns nil if the edge cannot be found in the graph' do
370
+ expect(undirected_graph.find_edge(node_1, node_3)).to be nil
371
+ end
126
372
  end
127
373
  end
128
374
  end
129
-
130
375
  end
data/spec/node_spec.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe Abuelo::Node do
4
-
5
4
  let(:node) { described_class.new('node 1') }
6
5
 
7
6
  context 'initialization' do
@@ -35,6 +34,24 @@ RSpec.describe Abuelo::Node do
35
34
  end
36
35
  end
37
36
 
37
+ describe '#neighbours' do
38
+ it 'returns an array with all nodes that are connected via an edge to the node' do
39
+ graph = Abuelo::Graph.new(directed: true, adjacency_matrix: <<-matrix
40
+ 0 1 1
41
+ 0 0 0
42
+ 0 0 0
43
+ matrix
44
+ )
45
+ node_1 = graph.find_node_by_name('node 1')
46
+ node_2 = graph.find_node_by_name('node 2')
47
+ node_3 = graph.find_node_by_name('node 3')
48
+
49
+ expect(node_1.neighbours).to match_array [node_2, node_3]
50
+ expect(node_2.neighbours).to eq []
51
+ expect(node_3.neighbours).to eq []
52
+ end
53
+ end
54
+
38
55
  describe '#to_s' do
39
56
  it 'responds with its name' do
40
57
  expect(node.to_s).to eq 'node 1'
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- $: << File.join(File.dirname(__FILE__), '/../lib')
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '/../lib')
2
2
  require "#{File.dirname(__FILE__)}/../lib/abuelo"
3
3
  require 'pry'
4
4
 
@@ -6,4 +6,4 @@ RSpec.configure do |config|
6
6
  config.run_all_when_everything_filtered = true
7
7
  config.filter_run :focus
8
8
  config.order = 'random'
9
- end
9
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abuelo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dirk Holzapfel
@@ -67,12 +67,15 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  description: Abuelo is a graph theory library.
70
- email: dirk@bitcrowd.net
70
+ email: cache.zero@mailbox.org
71
71
  executables: []
72
72
  extensions: []
73
73
  extra_rdoc_files: []
74
74
  files:
75
75
  - ".gitignore"
76
+ - ".travis.yml"
77
+ - CHANGELOG.md
78
+ - CODE_OF_CONDUCT.md
76
79
  - Gemfile
77
80
  - Gemfile.lock
78
81
  - MIT-LICENSE
@@ -118,3 +121,4 @@ test_files:
118
121
  - spec/graph_spec.rb
119
122
  - spec/node_spec.rb
120
123
  - spec/spec_helper.rb
124
+ has_rdoc: