+require 'graph/graph'
+require 'graph/edge'
+require 'graph/vertex'
--- /dev/null
+require 'ostruct'
+
+module Graph
+ class Edge < OpenStruct
+ def initialize
+ super
+ self.connections = []
+ self
+ end
+
+ def <<(other)
+ c = Connection.new
+ c.end = other
+ self.connections << c
+ self
+ end
+
+ def vertices
+ self.connections.map {|c| c.end}
+ end
+
+ def connection_at(vertex)
+ self.connections.select {|c| c.end.equal? vertex}.first
+ end
+ end
+
+ class Connection < OpenStruct
+ def initialize
+ super
+ self
+ end
+ end
+end
--- /dev/null
+require 'ostruct'
+
+module Graph
+ class Edge < OpenStruct
+ def initialize
+ super
+ self.connections = []
+ self
+ end
+
+ def <<(other)
+ c = Connection.new
+ c.end = other
+ self.connections << c
+ self
+ end
+
+ def vertices
+ self.connections.map {|c| c.end}
+ end
+
+ def connection_at(vertex)
+ self.connections.select {|c| c.end.equal? vertex}.first
+ end
+ end
+
+ class Connection < OpenStruct
+ def initialize
+ super
+ end
+ end
+end
--- /dev/null
+require 'ostruct'
+
+module Graph
+ class Graph < OpenStruct
+ def initialize
+ super
+ self.edges = Array.new
+ self.vertices = Array.new
+ self
+ end
+
+ def <<(other)
+ if other.class == Vertex
+ self.vertices << other
+ elsif
+ self.edges << other
+ end
+ self
+ end
+ end
+end
--- /dev/null
+require 'ostruct'
+
+module Graph
+ class Graph < OpenStruct
+ def initialize
+ super
+ self.edges = Array.new
+ self.vertices = Array.new
+ end
+
+ def <<(other)
+ if other.class == Vertex
+ self.vertices << other
+ elsif
+ self.edges << other
+ end
+ self
+ end
+ end
+end
--- /dev/null
+require 'ostruct'
+
+module Graph
+ class Vertex < OpenStruct
+ def initialize
+ super
+ self.edges = []
+ self
+ end
+
+ def connect(other)
+ e = Edge.new
+ e << self << other
+ self.edges << e
+ other.edges << e unless self === other
+ e
+ end
+
+ def <<(other)
+ connect(other)
+ self
+ end
+
+ def neighbours
+ vertices = self.edges.map {|e| e.vertices}.flatten
+ vertices_to_me = vertices.select {|v| v == self}
+ other_vertices = vertices.select {|v| v != self}
+ (vertices_to_me[1..-1] || []) + other_vertices
+ end
+
+ end
+end
--- /dev/null
+require 'ostruct'
+
+module Graph
+ class Vertex < OpenStruct
+ def initialize
+ super
+ self.edges = []
+ end
+
+ def connect(other)
+ e = Edge.new
+ e << self << other
+ self.edges << e
+ other.edges << e unless self === other
+ e
+ end
+
+ def <<(other)
+ connect(other)
+ self
+ end
+
+ def neighbours
+ vertices = self.edges.map {|e| e.vertices}.flatten
+ vertices_to_me = vertices.select {|v| v == self}
+ other_vertices = vertices.select {|v| v != self}
+ (vertices_to_me[1..-1] || []) + other_vertices
+ end
+
+ end
+end
+++ /dev/null
-require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
-
-describe "Graph.njae" do
- it "fails" do
- fail "hey buddy, you should probably rename this file and start specing for real"
- end
-end
--- /dev/null
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+module Graph
+ describe Edge do
+ let (:e) { Edge.new }
+ describe "#initialize" do
+ it "creates an empty edge" do
+ e = Edge.new
+ e.connections.should be_empty
+ end
+ end # #initialize
+
+ describe "adds attribues" do
+ it "adds then reports arbitrary attributes" do
+ e.score = 15
+ e.score.should == 15
+ end
+ end # adds attributes
+
+ describe "#<<" do
+ it "adds a new vertex to an edge (with a connection)" do
+ e.connections.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ e << v1
+ e.should have(1).connections
+ e.should have(1).vertices
+ e.vertices.should include(v1)
+ e << v2
+ e.should have(2).connections
+ e.should have(2).vertices
+ e.vertices.should include(v1)
+ e.vertices.should include(v2)
+ end
+
+ it "adds several vertices to an edge" do
+ e.connections.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ e << v1 << v2
+ e.vertices.should include(v1)
+ e.vertices.should include(v2)
+ e.should have(2).vertices
+ end
+
+ it "adds a self-loop" do
+ e.connections.should be_empty
+ v1 = Vertex.new
+ e << v1 << v1
+ e.vertices.should include(v1)
+ e.should have(2).vertices
+ e.vertices.uniq.length.should == 1
+ end
+ end # #<<
+
+ describe "connection_at" do
+ it "returns the connection that links to a vertex" do
+ e.connections.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ e << v1 << v2
+
+ e.connection_at(v1).end.should be v1
+ e.connection_at(v2).end.should be v2
+ end
+
+ it "returns nil if there is no connection to that vertex" do
+ e.connections.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ v3 = Vertex.new
+ e << v1 << v2
+
+ e.connection_at(v3).should be nil
+ end
+
+ it "returns the vertex for a self-loop" do
+ e.connections.should be_empty
+ v1 = Vertex.new
+ e << v1 << v1
+
+ e.connection_at(v1).end.should be v1
+ end
+
+
+ end # #connection_at
+ end # Edge
+
+ describe Connection do
+ let (:c) {Connection.new }
+
+ describe "adds attribues" do
+ it "adds then reports arbitrary attributes" do
+ c.score = 15
+ c.score.should == 15
+ end
+ end # adds attributes
+ end # Connection
+
+end
--- /dev/null
+require 'spec_helper'
+
+module Graph
+ describe Edge do
+ let (:e) { Edge.new }
+ describe "#initialize" do
+ it "creates an empty edge" do
+ e = Edge.new
+ e.connections.should be_empty
+ end
+ end # #initialize
+
+ describe "adds attribues" do
+ it "adds then reports arbitrary attributes" do
+ e.score = 15
+ e.score.should == 15
+ end
+ end # adds attributes
+
+ describe "#<<" do
+ it "adds a new vertex to an edge (with a connection)" do
+ e.connections.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ e << v1
+ e.should have(1).connections
+ e.should have(1).vertices
+ e.vertices.should include(v1)
+ e << v2
+ e.should have(2).connections
+ e.should have(2).vertices
+ e.vertices.should include(v1)
+ e.vertices.should include(v2)
+ end
+
+ it "adds several vertices to an edge" do
+ e.connections.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ e << v1 << v2
+ e.vertices.should include(v1)
+ e.vertices.should include(v2)
+ e.should have(2).vertices
+ end
+
+ it "adds a self-loop" do
+ e.connections.should be_empty
+ v1 = Vertex.new
+ e << v1 << v1
+ e.vertices.should include(v1)
+ e.should have(2).vertices
+ e.vertices.uniq.length.should == 1
+ end
+ end # #<<
+
+ describe "connection_at" do
+ it "returns the connection that links to a vertex" do
+ e.connections.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ e << v1 << v2
+
+ e.connection_at(v1).end.should be v1
+ e.connection_at(v2).end.should be v2
+ end
+
+ it "returns nil if there is no connection to that vertex" do
+ e.connections.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ v3 = Vertex.new
+ e << v1 << v2
+
+ e.connection_at(v3).should be nil
+ end
+ end # #connection_at
+ end # Edge
+
+ describe Connection do
+ let (:c) {Connection.new }
+
+ describe "adds attribues" do
+ it "adds then reports arbitrary attributes" do
+ c.score = 15
+ c.score.should == 15
+ end
+ end # adds attributes
+ end # Connection
+
+end
\ No newline at end of file
--- /dev/null
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+module Graph
+ describe Graph do
+ let (:g) { Graph.new }
+ describe "#initialize" do
+ it "creates an empty graph" do
+ g = Graph.new
+ g.edges.should be_empty
+ g.vertices.should be_empty
+ end
+ end # #initialize
+
+ describe "adds attribues" do
+ it "adds then reports arbitrary attributes" do
+ g.score = 15
+ g.score == 15
+ end
+ end # adds attributes
+
+ describe "#<<" do
+ it "adds a set of vertices" do
+ g.vertices.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ g << v1 << v2
+ g.should have(2).vertices
+ g.vertices.should include(v1)
+ g.vertices.should include(v2)
+ end
+
+ it "adds a set of edges" do
+ g.edges.should be_empty
+ e1 = Edge.new
+ e2 = Edge.new
+ g << e1 << e2
+ g.should have(2).edges
+ g.edges.should include(e1)
+ g.edges.should include(e2)
+ end
+
+ it "adds a mixed set of vertices and edges" do
+ g.vertices.should be_empty
+ g.edges.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ e1 = Edge.new
+ e2 = Edge.new
+ g << v1 << e1 << v2 << e2
+ g.should have(2).vertices
+ g.vertices.should include(v1)
+ g.vertices.should include(v2)
+ g.should have(2).edges
+ g.edges.should include(e1)
+ g.edges.should include(e2)
+ end
+ end # #<<
+
+ describe "connect" do
+ it "adds and records an edge between vertices" do
+ end
+ end # #connect
+
+ end
+end
--- /dev/null
+require 'spec_helper'
+
+module Graph
+ describe Graph do
+ let (:g) { Graph.new }
+ describe "#initialize" do
+ it "creates an empty graph" do
+ g = Graph.new
+ g.edges.should be_empty
+ g.vertices.should be_empty
+ end
+ end # #initialize
+
+ describe "adds attribues" do
+ it "adds then reports arbitrary attributes" do
+ g.score = 15
+ g.score == 15
+ end
+ end # adds attributes
+
+ describe "#<<" do
+ it "adds a set of vertices" do
+ g.vertices.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ g << v1 << v2
+ g.should have(2).vertices
+ g.vertices.should include(v1)
+ g.vertices.should include(v2)
+ end
+
+ it "adds a set of edges" do
+ g.edges.should be_empty
+ e1 = Edge.new
+ e2 = Edge.new
+ g << e1 << e2
+ g.should have(2).edges
+ g.edges.should include(e1)
+ g.edges.should include(e2)
+ end
+
+ it "adds a mixed set of vertices and edges" do
+ g.vertices.should be_empty
+ g.edges.should be_empty
+ v1 = Vertex.new
+ v2 = Vertex.new
+ e1 = Edge.new
+ e2 = Edge.new
+ g << v1 << e1 << v2 << e2
+ g.should have(2).vertices
+ g.vertices.should include(v1)
+ g.vertices.should include(v2)
+ g.should have(2).edges
+ g.edges.should include(e1)
+ g.edges.should include(e2)
+ end
+ end # #<<
+
+ describe "connect" do
+ it "adds and records an edge between vertices" do
+ end
+ end # #connect
+
+ end
+end
\ No newline at end of file
--- /dev/null
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+module Graph
+ describe Vertex do
+ let (:v) { Vertex.new }
+
+ describe "#initialize" do
+ it "creates an empty vertex" do
+ v = Vertex.new
+ v.edges.should be_empty
+ end
+ end # #initialize
+
+ describe "adds attribues" do
+ it "adds then reports arbitrary attributes" do
+ v.score = 15
+ v.score.should == 15
+ end
+ end # adds attributes
+
+ describe "#<<" do
+ it "adds a single edge between vertices" do
+ v.neighbours.should be_empty
+ v.edges.should be_empty
+
+ v1 = Vertex.new
+ v << v1
+
+ v1.id = :v1 # Need this to ensure that v != v1
+
+ v.should have(1).edges
+ v1.should have(1).edges
+ e = v.edges[0]
+ v1.edges.should include(e)
+
+ v.should have(1).neighbours
+ v.neighbours.should include(v1)
+ v.neighbours.should_not include(v)
+ v1.should have(1).neighbours
+ v1.neighbours.should include(v)
+ v1.neighbours.should_not include(v1)
+ end
+
+ it "adds a single edge as a self-loop" do
+ v.neighbours.should be_empty
+ v.edges.should be_empty
+
+ v << v
+
+ v.should have(1).edges
+ v.should have(1).neighbours
+ v.neighbours.should include(v)
+ end
+ end # #<<
+
+ describe "connect" do
+ it "connects two vertices" do
+ v1 = Vertex.new
+ v1.id = :v1 # Need this to ensure that v != v1
+
+ e = v.connect v1
+
+ v.should have(1).neighbours
+ v.neighbours.should include(v1)
+ v.neighbours.should_not include(v)
+
+ v1.should have(1).neighbours
+ v1.neighbours.should include(v)
+ v1.neighbours.should_not include(v1)
+
+ v.should have(1).edges
+ v.edges.should include(e)
+ v1.should have(1).edges
+ v1.edges.should include(e)
+
+ e.should have(2).vertices
+ e.vertices.should include(v)
+ e.vertices.should include(v1)
+
+ e.should have(2).connections
+ end
+
+ it "creates a self-connection" do
+ e = v.connect v
+
+ v.should have(1).neighbours
+ v.neighbours.should include(v)
+
+ v.should have(1).edges
+ v.edges.should include(e)
+
+ e.should have(2).vertices
+ e.vertices.uniq.length.should == 1
+ e.vertices.should include(v)
+
+ e.should have(2).connections
+ end
+
+ end # #connect
+ end
+end
--- /dev/null
+require 'spec_helper'
+
+module Graph
+ describe Vertex do
+ let (:v) { Vertex.new }
+
+ describe "#initialize" do
+ it "creates an empty vertex" do
+ v = Vertex.new
+ v.edges.should be_empty
+ end
+ end # #initialize
+
+ describe "adds attribues" do
+ it "adds then reports arbitrary attributes" do
+ v.score = 15
+ v.score.should == 15
+ end
+ end # adds attributes
+
+ describe "#<<" do
+ it "adds a single edge between vertices" do
+ v.neighbours.should be_empty
+ v.edges.should be_empty
+
+ v1 = Vertex.new
+ v << v1
+
+ v1.id = :v1 # Need this to ensure that v != v1
+
+ v.should have(1).edges
+ v1.should have(1).edges
+ e = v.edges[0]
+ v1.edges.should include(e)
+
+ v.should have(1).neighbours
+ v.neighbours.should include(v1)
+ v.neighbours.should_not include(v)
+ v1.should have(1).neighbours
+ v1.neighbours.should include(v)
+ v1.neighbours.should_not include(v1)
+ end
+
+ it "adds a single edge as a self-loop" do
+ v.neighbours.should be_empty
+ v.edges.should be_empty
+
+ v << v
+
+ v.should have(1).edges
+ v.should have(1).neighbours
+ v.neighbours.should include(v)
+ end
+ end # #<<
+
+ describe "connect" do
+ it "connects two vertices" do
+ v1 = Vertex.new
+ v1.id = :v1 # Need this to ensure that v != v1
+
+ e = v.connect v1
+
+ v.should have(1).neighbours
+ v.neighbours.should include(v1)
+ v.neighbours.should_not include(v)
+
+ v1.should have(1).neighbours
+ v1.neighbours.should include(v)
+ v1.neighbours.should_not include(v1)
+
+ v.should have(1).edges
+ v.edges.should include(e)
+ v1.should have(1).edges
+ v1.edges.should include(e)
+
+ e.should have(2).vertices
+ e.vertices.should include(v)
+ e.vertices.should include(v1)
+
+ e.should have(2).connections
+ end
+
+ it "creates a self-connection" do
+ e = v.connect v
+
+ v.should have(1).neighbours
+ v.neighbours.should include(v)
+
+ v.should have(1).edges
+ v.edges.should include(e)
+
+ e.should have(2).vertices
+ e.vertices.uniq.length.should == 1
+ e.vertices.should include(v)
+
+ e.should have(2).connections
+ end
+
+ end # #connect
+ end
+end
\ No newline at end of file