diff --git a/README.md b/README.md index 66f410a5..78851629 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,9 @@ require_once 'vendor/autoload.php'; $graph = new Graphp\Graph\Graph(); // create some cities -$rome = $graph->createVertex()->setAttribute('name', 'Rome'); -$madrid = $graph->createVertex()->setAttribute('name', 'Madrid'); -$cologne = $graph->createVertex()->setAttribute('name', 'Cologne'); +$rome = $graph->createVertex(array('name' => 'Rome')); +$madrid = $graph->createVertex(array('name' => 'Madrid')); +$cologne = $graph->createVertex(array('name' => 'Cologne')); // build some roads $graph->createEdgeDirected($cologne, $madrid); diff --git a/src/EdgeDirected.php b/src/EdgeDirected.php index 41afbaa8..9e4024ce 100644 --- a/src/EdgeDirected.php +++ b/src/EdgeDirected.php @@ -24,13 +24,14 @@ class EdgeDirected extends Edge /** * [Internal] Create a new directed Edge from Vertex $from to Vertex $to * - * @param Vertex $from start/source Vertex - * @param Vertex $to end/target Vertex + * @param Vertex $from start/source Vertex + * @param Vertex $to end/target Vertex + * @param array $attributes * @see Graph::createEdgeDirected() to create directed edges * @see Graph::createEdgeUndirected() to create undirected edges * @internal */ - public function __construct(Vertex $from, Vertex $to) + public function __construct(Vertex $from, Vertex $to, array $attributes = array()) { if ($from->getGraph() !== $to->getGraph()) { throw new InvalidArgumentException('Vertices have to be within the same graph'); @@ -38,6 +39,7 @@ public function __construct(Vertex $from, Vertex $to) $this->from = $from; $this->to = $to; + $this->attributes = $attributes; $from->getGraph()->addEdge($this); $from->addEdge($this); diff --git a/src/EdgeUndirected.php b/src/EdgeUndirected.php index c63a5d01..98d7d7ba 100644 --- a/src/EdgeUndirected.php +++ b/src/EdgeUndirected.php @@ -26,11 +26,12 @@ class EdgeUndirected extends Edge * * @param Vertex $a * @param Vertex $b + * @param array $attributes * @see Graph::createEdgeUndirected() to create undirected edges * @see Graph::createEdgeDirected() to create directed edges * @internal */ - public function __construct(Vertex $a, Vertex $b) + public function __construct(Vertex $a, Vertex $b, array $attributes = array()) { if ($a->getGraph() !== $b->getGraph()) { throw new InvalidArgumentException('Vertices have to be within the same graph'); @@ -38,6 +39,7 @@ public function __construct(Vertex $a, Vertex $b) $this->a = $a; $this->b = $b; + $this->attributes = $attributes; $a->getGraph()->addEdge($this); $a->addEdge($this); diff --git a/src/Graph.php b/src/Graph.php index 483b46eb..a5ce5e8d 100644 --- a/src/Graph.php +++ b/src/Graph.php @@ -18,12 +18,16 @@ class Graph implements DualAggregate, AttributeAware protected $edgesStorage = array(); protected $edges; - protected $attributes = array(); + protected $attributes; - public function __construct() + /** + * @param array $attributes + */ + public function __construct(array $attributes = array()) { $this->vertices = Vertices::factoryArrayReference($this->verticesStorage); $this->edges = Edges::factoryArrayReference($this->edgesStorage); + $this->attributes = $attributes; } /** @@ -49,11 +53,12 @@ public function getEdges() /** * create a new Vertex in the Graph * + * @param array $attributes * @return Vertex */ - public function createVertex() + public function createVertex(array $attributes = array()) { - return new Vertex($this); + return new Vertex($this, $attributes); } /** @@ -61,33 +66,35 @@ public function createVertex() * * @param Vertex $a * @param Vertex $b + * @param array $attributes * @return EdgeUndirected * @throws InvalidArgumentException */ - public function createEdgeUndirected(Vertex $a, Vertex $b) + public function createEdgeUndirected(Vertex $a, Vertex $b, array $attributes = array()) { if ($a->getGraph() !== $this) { throw new InvalidArgumentException('Vertices have to be within this graph'); } - return new EdgeUndirected($a, $b); + return new EdgeUndirected($a, $b, $attributes); } /** * Creates a new directed edge from the given start vertex to given target vertex * - * @param Vertex $source source vertex - * @param Vertex $target target vertex + * @param Vertex $source source vertex + * @param Vertex $target target vertex + * @param array $attributes * @return EdgeDirected * @throws InvalidArgumentException */ - public function createEdgeDirected(Vertex $source, Vertex $target) + public function createEdgeDirected(Vertex $source, Vertex $target, array $attributes = array()) { if ($source->getGraph() !== $this) { throw new InvalidArgumentException('Vertices have to be within this graph'); } - return new EdgeDirected($source, $target); + return new EdgeDirected($source, $target, $attributes); } /** @@ -171,8 +178,7 @@ public function __clone() foreach ($vertices as $originalVertex) { \assert($originalVertex instanceof Vertex); - $vertex = new Vertex($this); - $vertex->getAttributeBag()->setAttributes($originalVertex->getAttributeBag()->getAttributes()); + $vertex = new Vertex($this, $originalVertex->getAttributeBag()->getAttributes()); // create map with old vertex hash to new vertex object $map[\spl_object_hash($originalVertex)] = $vertex; @@ -188,11 +194,10 @@ public function __clone() // recreate edge and assign attributes if ($originalEdge instanceof EdgeUndirected) { - $edge = $this->createEdgeUndirected($v1, $v2); + $this->createEdgeUndirected($v1, $v2, $originalEdge->getAttributeBag()->getAttributes()); } else { - $edge = $this->createEdgeDirected($v1, $v2); + $this->createEdgeDirected($v1, $v2, $originalEdge->getAttributeBag()->getAttributes()); } - $edge->getAttributeBag()->setAttributes($originalEdge->getAttributeBag()->getAttributes()); } } diff --git a/src/Vertex.php b/src/Vertex.php index ec6b9018..933ae9ec 100644 --- a/src/Vertex.php +++ b/src/Vertex.php @@ -22,17 +22,19 @@ class Vertex implements EdgesAggregate, AttributeAware */ private $graph; - private $attributes = array(); + private $attributes; /** * Create a new Vertex * - * @param Graph $graph graph to be added to + * @param Graph $graph graph to be added to + * @param array $attributes * @see Graph::createVertex() to create new vertices */ - public function __construct(Graph $graph) + public function __construct(Graph $graph, array $attributes = array()) { $this->graph = $graph; + $this->attributes = $attributes; $graph->addVertex($this); } diff --git a/tests/EdgeBaseTest.php b/tests/EdgeBaseTest.php index 4c77f187..9a09b362 100644 --- a/tests/EdgeBaseTest.php +++ b/tests/EdgeBaseTest.php @@ -29,7 +29,7 @@ abstract class EdgeBaseTest extends AbstractAttributeAwareTest */ protected $edge; - abstract protected function createEdgeUndirected(); + abstract protected function createEdge(array $attributes = array()); /** * @return Edge @@ -42,7 +42,21 @@ public function setUp() $this->v1 = $this->graph->createVertex(); $this->v2 = $this->graph->createVertex(); - $this->edge = $this->createEdgeUndirected(); + $this->edge = $this->createEdge(); + } + + public function testEdgeConstructorDefaultHasNoAttributes() + { + $this->assertNull($this->edge->getAttribute('hello')); + $this->assertEquals('default', $this->edge->getAttribute('hello', 'default')); + $this->assertEquals(array(), $this->edge->getAttributeBag()->getAttributes()); + } + + public function testEdgeConstructorWithAttributeReturnsAttributes() + { + $edge = $this->createEdge(array('hello' => 'wörld')); + $this->assertEquals('wörld', $edge->getAttribute('hello')); + $this->assertEquals(array('hello' => 'wörld'), $edge->getAttributeBag()->getAttributes()); } public function testEdgeVertices() @@ -105,6 +119,6 @@ public function testRemoveWithLoop() protected function createAttributeAware() { - return $this->createEdgeUndirected(); + return $this->createEdge(); } } diff --git a/tests/EdgeDirectedTest.php b/tests/EdgeDirectedTest.php index 46595a97..73e7e4ab 100644 --- a/tests/EdgeDirectedTest.php +++ b/tests/EdgeDirectedTest.php @@ -4,10 +4,10 @@ class EdgeDirectedTest extends EdgeBaseTest { - protected function createEdgeUndirected() + protected function createEdge(array $attributes = array()) { // 1 -> 2 - return $this->graph->createEdgeDirected($this->v1, $this->v2); + return $this->graph->createEdgeDirected($this->v1, $this->v2, $attributes); } protected function createEdgeLoop() diff --git a/tests/EdgeUndirectedTest.php b/tests/EdgeUndirectedTest.php index 3526d33d..5691beea 100644 --- a/tests/EdgeUndirectedTest.php +++ b/tests/EdgeUndirectedTest.php @@ -4,10 +4,10 @@ class EdgeUndirectedTest extends EdgeBaseTest { - protected function createEdgeUndirected() + protected function createEdge(array $attributes = array()) { // 1 -- 2 - return $this->graph->createEdgeUndirected($this->v1, $this->v2); + return $this->graph->createEdgeUndirected($this->v1, $this->v2, $attributes); } protected function createEdgeLoop() diff --git a/tests/GraphTest.php b/tests/GraphTest.php index 735754d1..a6bec5b0 100644 --- a/tests/GraphTest.php +++ b/tests/GraphTest.php @@ -7,6 +7,21 @@ class GraphTest extends AbstractAttributeAwareTest { + public function testEmptyGraphHasNoAttributes() + { + $graph = new Graph(); + $this->assertNull($graph->getAttribute('hello')); + $this->assertEquals('default', $graph->getAttribute('hello', 'default')); + $this->assertEquals(array(), $graph->getAttributeBag()->getAttributes()); + } + + public function testEmptyGraphWithAttributeReturnsAttributes() + { + $graph = new Graph(array('hello' => 'wörld')); + $this->assertEquals('wörld', $graph->getAttribute('hello')); + $this->assertEquals(array('hello' => 'wörld'), $graph->getAttributeBag()->getAttributes()); + } + public function testCanCreateVertex() { $graph = new Graph(); @@ -186,10 +201,9 @@ public function testGraphCloneLoopGraphWithAttributes() // 1 -\ // ^ | // \--/ - $graph = new Graph(); - $graph->setAttribute('color', 'grey'); - $v = $graph->createVertex()->setAttribute('color', 'blue'); - $graph->createEdgeDirected($v, $v)->setAttribute('color', 'red'); + $graph = new Graph(array('color' => 'grey')); + $v = $graph->createVertex(array('color' => 'blue')); + $graph->createEdgeDirected($v, $v, array('color' => 'red')); $newgraph = clone $graph; diff --git a/tests/VertexTest.php b/tests/VertexTest.php index b7322465..b4322665 100644 --- a/tests/VertexTest.php +++ b/tests/VertexTest.php @@ -23,12 +23,24 @@ public function testPrecondition() $this->assertEquals(array($this->vertex), $this->graph->getVertices()->getVector()); } - public function testConstructor() + public function testConstructorWithoutAttributesHasNoAttributes() { $v2 = new Vertex($this->graph); $this->assertCount(2, $this->graph->getVertices()); $this->assertEquals(array($this->vertex, $v2), $this->graph->getVertices()->getVector()); + + $this->assertNull($v2->getAttribute('hello')); + $this->assertEquals('default', $v2->getAttribute('hello', 'default')); + $this->assertEquals(array(), $v2->getAttributeBag()->getAttributes()); + } + + public function testConstructorWithAttributesReturnsAttributes() + { + $v2 = new Vertex($this->graph, array('hello' => 'wörld')); + + $this->assertEquals('wörld', $v2->getAttribute('hello')); + $this->assertEquals(array('hello' => 'wörld'), $v2->getAttributeBag()->getAttributes()); } public function testEdges()