Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Group entity #168

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/Graph.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ class Graph implements DualAggregate, AttributeAware

protected $attributes = array();

/**
* @var Group[]
*/
protected $groups = array();

public function __construct()
{
$this->vertices = VerticesMap::factoryArrayReference($this->verticesStorage);
Expand Down Expand Up @@ -466,4 +471,33 @@ public function getAttributeBag()
{
return new AttributeBagReference($this->attributes);
}

/**
* @param int|string $groupId
* @param bool $returnDuplicate
* @return Group
*/
public function createGroup($groupId, $returnDuplicate = false)
{
if ($returnDuplicate && isset($this->groups[$groupId])) {
return $this->groups[$groupId];
}

if (isset($this->groups[$groupId])) {
throw new OverflowException('Group already exists: ' . $groupId);
}

$group = new Group($this, $groupId);
$this->groups[$groupId] = $group;

return $group;
}

/**
* @return array|Group[]
*/
public function getGroups()
{
return array_values($this->groups);
}
}
79 changes: 79 additions & 0 deletions src/Group.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

namespace Fhaculty\Graph;

use Fhaculty\Graph\Attribute\AttributeAware;
use Fhaculty\Graph\Attribute\AttributeBagReference;
use Fhaculty\Graph\Exception\InvalidArgumentException;

class Group implements AttributeAware
{
/**
* @var int|string
*/
private $id;

/**
* @var Graph
*/
private $graph;

private $attributes = array();

public function __construct(Graph $graph, $id)
{
if (!is_int($id) && !is_string($id)) {
throw new InvalidArgumentException('Group ID has to be of type integer or string');
}

$this->id = $id;
$this->graph = $graph;
}

public function getId()
{
return $this->id;
}

public function getVerticesInGroup()
{
$thisGroup = $this;

return array_values(array_filter(
$this->graph->getVertices()->getMap(),
function (Vertex $vertex) use ($thisGroup) {
return $vertex->getGroup() instanceof Group && $vertex->getGroup()->equals($thisGroup);
}
));
}

public function getAttribute($name, $default = null)
{
return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
}

public function setAttribute($name, $value)
{
$this->attributes[$name] = $value;
}

public function removeAttribute($name)
{
unset($this->attributes[$name]);
}

public function getAttributeBag()
{
return new AttributeBagReference($this->attributes);
}

public function __toString()
{
return (string)$this->id;
}

public function equals(Group $other)
{
return $this->id === $other->id;
}
}
22 changes: 10 additions & 12 deletions src/Set/Vertices.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Fhaculty\Graph\Set;

use Fhaculty\Graph\Group;
use Fhaculty\Graph\Vertex;
use Fhaculty\Graph\Exception\InvalidArgumentException;
use Fhaculty\Graph\Exception\OutOfBoundsException;
Expand Down Expand Up @@ -511,19 +512,16 @@ private function getCallback($callback)
return $callback;
}

static $methods = array(
self::ORDER_ID => 'getId',
self::ORDER_GROUP => 'getGroup'
);

if (!is_int($callback) || !isset($methods[$callback])) {
throw new InvalidArgumentException('Invalid callback given');
if ($callback === self::ORDER_ID) {
return function (Vertex $vertex) {
return $vertex->getId();
};
} elseif ($callback === self::ORDER_GROUP) {
return function (Vertex $vertex) {
return $vertex->getGroup() instanceof Group ? $vertex->getGroup()->getId() : null;
};
}

$method = $methods[$callback];

return function (Vertex $vertex) use ($method) {
return $vertex->$method();
};
throw new InvalidArgumentException('Invalid callback given');
}
}
20 changes: 9 additions & 11 deletions src/Vertex.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ class Vertex implements EdgesAggregate, AttributeAware
private $balance;

/**
* group number
* group
*
* @var int
* @var Group|null
* @see Vertex::setGroup()
* @see Vertex::getGroup()
*/
private $group = 0;
private $group;

private $attributes = array();

Expand Down Expand Up @@ -90,26 +91,23 @@ public function setBalance($balance)
}

/**
* set group number of this vertex
* set group of this vertex
*
* @param int $group
* @param Group|null $group
* @return Vertex $this (chainable)
* @throws InvalidArgumentException if group is not numeric
*/
public function setGroup($group)
public function setGroup(Group $group = null)
{
if (!is_int($group)) {
throw new InvalidArgumentException('Invalid group number');
}
$this->group = $group;

return $this;
}

/**
* get group number
* get group
*
* @return int
* @return Group|null
*/
public function getGroup()
{
Expand Down
42 changes: 40 additions & 2 deletions tests/GraphTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

namespace Fhaculty\Graph\Tests;

use Fhaculty\Graph\Exception\OutOfBoundsException;
use Fhaculty\Graph\Exception\OverflowException;
use Fhaculty\Graph\Exception\InvalidArgumentException;
use Fhaculty\Graph\Graph;
use Fhaculty\Graph\Group;
use Fhaculty\Graph\Tests\Attribute\AbstractAttributeAwareTest;

class GraphTest extends AbstractAttributeAwareTest
Expand All @@ -17,7 +19,7 @@ public function setup()
public function testVertexClone()
{
$graph = new Graph();
$vertex = $graph->createVertex(123)->setBalance(10)->setGroup(4);
$vertex = $graph->createVertex(123)->setBalance(10)->setGroup($graph->createGroup(4));

$newgraph = new Graph();
$newvertex = $newgraph->createVertexClone($vertex);
Expand Down Expand Up @@ -56,7 +58,7 @@ public function testGetVertexNonexistant()
public function testGraphClone()
{
$graph = new Graph();
$graph->createVertex(123)->setBalance(10)->setGroup(4);
$graph->createVertex(123)->setBalance(10)->setGroup($graph->createGroup(4));

$newgraph = $graph->createGraphClone();

Expand Down Expand Up @@ -391,6 +393,42 @@ public function testCreateGraphCloneVertices()
$this->assertEquals(1, count($graphClone->getEdges()));
}

public function testGetGroups()
{
$graph = new Graph();
$graph->createGroup(1);
$graph->createGroup(2);

$this->assertEquals(
array(
new Group($graph, 1),
new Group($graph, 2)
),
$graph->getGroups()
);
}

public function testCreateGroupReturnDuplicate()
{
$graph = new Graph();
$alreadyCreated = $graph->createGroup(1);

$this->assertSame(
$alreadyCreated,
$graph->createGroup(1, true)
);
}

/**
* @expectedException OverflowException
*/
public function testCreateGroupAlreadyExists()
{
$graph = new Graph();
$graph->createGroup(1);
$graph->createGroup(1);
}

protected function createAttributeAware()
{
return new Graph();
Expand Down
77 changes: 77 additions & 0 deletions tests/GroupTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace Fhaculty\Graph\Tests;

use Fhaculty\Graph\Exception\InvalidArgumentException;
use Fhaculty\Graph\Graph;
use Fhaculty\Graph\Group;
use Fhaculty\Graph\Tests\Attribute\AbstractAttributeAwareTest;

final class GroupTest extends AbstractAttributeAwareTest
{
public function testGroupIdCanBeAnInteger()
{
$group = new Group(new Graph(), 1);

$this->assertSame(1, $group->getId());
}

public function testGroupIdCanBeAString()
{
$group = new Group(new Graph(), 'string');

$this->assertSame('string', $group->getId());
}

/**
* @expectedException InvalidArgumentException
*/
public function testGroupIdCanNotBeSomethingElse()
{
new Group(new Graph(), null);
}

public function testGroupEquals()
{
$group = new Group(new Graph(), 1);

$this->assertTrue($group->equals(new Group(new Graph(), 1)));
}

public function testGroupIsNotEqual()
{
$group = new Group(new Graph(), 1);

$this->assertFalse($group->equals(new Group(new Graph(), 2)));
}

public function testFindAllVerticesInGroup()
{
$graph = new Graph();
$group1 = $graph->createGroup(1);
$vertex1 = $graph->createVertex(1)->setGroup($group1);
$vertex2 = $graph->createVertex(2)->setGroup($group1);
$group2 = $graph->createGroup(2);
$vertex3 = $graph->createVertex(3)->setGroup($group2);

$this->assertEquals(
array(
$vertex1,
$vertex2
),
$group1->getVerticesInGroup()
);

$this->assertEquals(
array(
$vertex3
),
$group2->getVerticesInGroup()
);
}

protected function createAttributeAware()
{
return new Group(new Graph(), 1);
}
}
20 changes: 10 additions & 10 deletions tests/Set/BaseVerticesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,26 +198,26 @@ public function returnTrue(Vertex $vertex)
public function testOrderByGroup()
{
$graph = new Graph();
$graph->createVertex()->setGroup(1);
$graph->createVertex()->setGroup(100);
$graph->createVertex()->setGroup(5);
$graph->createVertex()->setGroup(100);
$graph->createVertex()->setGroup(100);
$graph->createVertex()->setGroup(2);
$biggest = $graph->createVertex()->setGroup(200);
$graph->createVertex()->setGroup($graph->createGroup(1));
$graph->createVertex()->setGroup($graph->createGroup(100));
$graph->createVertex()->setGroup($graph->createGroup(5));
$graph->createVertex()->setGroup($graph->createGroup(100, true));
$graph->createVertex()->setGroup($graph->createGroup(100, true));
$graph->createVertex()->setGroup($graph->createGroup(2));
$biggest = $graph->createVertex()->setGroup($graph->createGroup(200));

$vertices = $graph->getVertices();
$verticesOrdered = $vertices->getVerticesOrder(Vertices::ORDER_GROUP);

$this->assertInstanceOf('Fhaculty\Graph\Set\Vertices', $verticesOrdered);
$this->assertEquals(1, $verticesOrdered->getVertexFirst()->getGroup());
$this->assertEquals(200, $verticesOrdered->getVertexLast()->getGroup());
$this->assertEquals(1, $verticesOrdered->getVertexFirst()->getGroup()->getId());
$this->assertEquals(200, $verticesOrdered->getVertexLast()->getGroup()->getId());

$this->assertSame($biggest, $verticesOrdered->getVertexLast());
$this->assertSame($biggest, $vertices->getVertexOrder(Vertices::ORDER_GROUP, true));

$sumgroups = function(Vertex $vertex) {
return $vertex->getGroup();
return $vertex->getGroup()->getId();
};
$this->assertSame(508, $vertices->getSumCallback($sumgroups));
$this->assertSame(508, $verticesOrdered->getSumCallback($sumgroups));
Expand Down
Loading