Skip to content

Commit

Permalink
Pervasive refactor of AdjacencyList family's tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
sdboyer committed Nov 3, 2013
1 parent e361dd0 commit f57d041
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 123 deletions.
33 changes: 9 additions & 24 deletions tests/Gliph/Graph/AdjacencyListBase.php
Expand Up @@ -21,29 +21,14 @@ public function setUp() {
);
}

public function doCheckVerticesEqual($vertices, AdjacencyList $graph = null) {
$found = array();
$graph = is_null($graph) ? $this->g : $graph;

$graph->eachVertex(
function ($vertex) use (&$found) {
$found[] = $vertex;
}
);

$this->assertEquals($vertices, $found);
}

public function doCheckVertexCount($count, AdjacencyList $graph = null) {
$found = array();
$graph = is_null($graph) ? $this->g : $graph;

$graph->eachVertex(
function ($vertex) use (&$found) {
$found[] = $vertex;
}
);

$this->assertCount($count, $found);
/**
* Asserts that an AdjacencyList contains the expected number of vertices.
*
* @param int $expectedCount
* @param AdjacencyList $graph
* @param string $message
*/
public function assertVertexCount($expectedCount, AdjacencyList $graph, $message = '') {
$this->assertAttributeCount($expectedCount, 'vertices', $graph);
}
}
86 changes: 54 additions & 32 deletions tests/Gliph/Graph/AdjacencyListTest.php
Expand Up @@ -2,6 +2,9 @@

namespace Gliph\Graph;

/**
* @coversDefaultClass \Gliph\Graph\AdjacencyList
*/
class AdjacencyListTest extends AdjacencyListBase {

protected $v = array();
Expand All @@ -13,72 +16,91 @@ class AdjacencyListTest extends AdjacencyListBase {

public function setUp() {
parent::setUp();
$this->g = $this->getMockForAbstractClass('\\Gliph\\Graph\\AdjacencyList');
$this->g = $this->getMockForAbstractClass('Gliph\Graph\AdjacencyList');
}

/**
* Tests that an exception is thrown if a string vertex is provided.
* Data provider of non-object types for invalidation.
*
* @expectedException \Gliph\Exception\InvalidVertexTypeException
* @return array
*/
public function testAddStringVertex() {
$this->g->addVertex('a');
public function invalidVertexTypesProvider() {
return array(
array('a'),
array(1),
array((float) 1.1),
array(array()),
array(fopen(__FILE__, 'r')),
array(FALSE),
array(NULL),
);
}

/**
* Tests that an exception is thrown if an integer vertex is provided.
*
* @expectedException \Gliph\Exception\InvalidVertexTypeException
* @dataProvider invalidVertexTypesProvider
*/
public function testAddIntegerVertex() {
$this->g->addVertex(1);
public function testInvalidVertexTypes($invalid_vertex) {
$this->g->addVertex($invalid_vertex);
}

/**
* Tests that an exception is thrown if a float vertex is provided.
*
* @expectedException \Gliph\Exception\InvalidVertexTypeException
* @covers ::addVertex
*/
public function testAddFloatVertex() {
$this->g->addVertex((float) 1);
public function testAddVertex() {
extract($this->v);
$this->g->addVertex($a);

$this->assertAttributeContains($a, 'vertices', $this->g);
}

/**
* Tests that an exception is thrown if an array vertex is provided.
*
* @expectedException \Gliph\Exception\InvalidVertexTypeException
* @depends testAddVertex
* @covers ::eachVertex
* @covers ::fev
*/
public function testAddArrayVertex() {
$this->g->addVertex(array());
public function testEachVertex() {
extract($this->v);
$this->g->addVertex($a);
$this->g->addVertex($b);

$found = array();
$this->g->eachVertex(
function ($vertex) use (&$found) {
$found[] = $vertex;
}
);

$this->assertEquals(array($a, $b), $found);
}

/**
* Tests that an exception is thrown if a resource vertex is provided.
*
* @expectedException \Gliph\Exception\InvalidVertexTypeException
* @depends testAddVertex
* @covers ::hasVertex
*/
public function testAddResourceVertex() {
$this->g->addVertex(fopen(__FILE__, 'r'));
}
public function testHasVertex() {
extract($this->v);
$this->assertFalse($this->g->hasVertex($a));

public function testAddVertex() {
$this->g->addVertex($this->v['a']);

$this->assertTrue($this->g->hasVertex($this->v['a']));
$this->doCheckVertexCount(1, $this->g);
$this->g->addVertex($a);
$this->assertTrue($this->g->hasVertex($a));
}

/**
* @depends testHasVertex
* @covers ::addVertex
*/
public function testAddVertexTwice() {
// Adding a vertex twice should be a no-op.
$this->g->addVertex($this->v['a']);
$this->g->addVertex($this->v['a']);

$this->assertTrue($this->g->hasVertex($this->v['a']));
$this->doCheckVertexCount(1, $this->g);
$this->assertVertexCount(1, $this->g);
}

/**
* @expectedException Gliph\Exception\NonexistentVertexException
* @expectedException \Gliph\Exception\NonexistentVertexException
*/
public function testEachAdjacentMissingVertex() {
$this->g->eachAdjacent($this->v['a'], function() {});
Expand Down
141 changes: 100 additions & 41 deletions tests/Gliph/Graph/DirectedAdjacencyListTest.php
Expand Up @@ -2,6 +2,9 @@

namespace Gliph\Graph;

/**
* @coversDefaultClass \Gliph\Graph\DirectedAdjacencyList
*/
class DirectedAdjacencyListTest extends AdjacencyListBase {

/**
Expand All @@ -14,86 +17,135 @@ public function setUp() {
$this->g = new DirectedAdjacencyList();
}


/**
* Implicitly depends on AdjacencyList::addVertex.
*
* @covers ::addDirectedEdge
*/
public function testAddDirectedEdge() {
$this->g->addDirectedEdge($this->v['a'], $this->v['b']);
extract($this->v);
$this->g->addDirectedEdge($a, $b);

$this->doCheckVerticesEqual(array($this->v['a'], $this->v['b']), $this->g);
$this->assertAttributeContains($a, 'vertices', $this->g);
$this->assertAttributeContains($b, 'vertices', $this->g);
$this->assertVertexCount(2, $this->g);
}

public function testRemoveVertex() {
$this->g->addDirectedEdge($this->v['a'], $this->v['b']);
$this->doCheckVertexCount(2);
/**
* @depends testAddDirectedEdge
* @covers ::eachAdjacent
*/
public function testEachAdjacent() {
extract($this->v);
$this->g->addDirectedEdge($a, $b);
$this->g->addDirectedEdge($a, $c);

$this->g->removeVertex($this->v['b']);
$this->doCheckVertexCount(1);
$found = array();
$this->g->eachAdjacent($a, function($to) use (&$found) {
$found[] = $to;
});
$this->assertEquals(array($b, $c), $found);

// Ensure that b was correctly removed from a's outgoing edges
$found = array();
$this->g->eachAdjacent($this->v['a'], function($to) use (&$found) {
$this->g->eachAdjacent($b, function($to) use (&$found) {
$found[] = $to;
});
$this->assertEmpty($found);

$this->assertEquals(array(), $found);
$this->g->eachAdjacent($c, function($to) use (&$found) {
$found[] = $to;
});
$this->assertEmpty($found);
}

/**
* @depends testAddDirectedEdge
* @depends testEachAdjacent
* @covers ::removeVertex
*/
public function testRemoveVertex() {
extract($this->v);
$this->g->addDirectedEdge($a, $b);
$this->assertVertexCount(2, $this->g);

public function testRemoveEdge() {
$this->g->addDirectedEdge($this->v['a'], $this->v['b']);
$this->doCheckVerticesEqual(array($this->v['a'], $this->v['b']), $this->g);

$this->g->removeEdge($this->v['a'], $this->v['b']);
$this->doCheckVertexCount(2);

$this->assertTrue($this->g->hasVertex($this->v['a']));
$this->assertTrue($this->g->hasVertex($this->v['b']));
}

public function testEachAdjacent() {
$this->g->addDirectedEdge($this->v['a'], $this->v['b']);
$this->g->addDirectedEdge($this->v['a'], $this->v['c']);
$this->g->removeVertex($b);
$this->assertVertexCount(1, $this->g);

// Ensure that b was correctly removed from a's outgoing edges
$found = array();
$this->g->eachAdjacent($this->v['a'], function($to) use (&$found) {
$this->g->eachAdjacent($a, function($to) use (&$found) {
$found[] = $to;
});

$this->assertEquals(array($this->v['b'], $this->v['c']), $found);
$this->assertEquals(array(), $found);
}

/**
* @depends testAddDirectedEdge
* @covers ::removeEdge
*/
public function testRemoveEdge() {
extract($this->v);
$this->g->addDirectedEdge($a, $b);
$this->g->removeEdge($a, $b);

$this->assertVertexCount(2, $this->g);
}

/**
* @depends testAddDirectedEdge
* @depends testEachAdjacent
* @covers ::eachEdge
*/
public function testEachEdge() {
$this->g->addDirectedEdge($this->v['a'], $this->v['b']);
$this->g->addDirectedEdge($this->v['a'], $this->v['c']);
extract($this->v);
$this->g->addDirectedEdge($a, $b);
$this->g->addDirectedEdge($a, $c);

$found = array();
$this->g->eachEdge(function($edge) use (&$found) {
$found[] = $edge;
});

$this->assertCount(2, $found);
$this->assertEquals(array($this->v['a'], $this->v['b']), $found[0]);
$this->assertEquals(array($this->v['a'], $this->v['c']), $found[1]);
$this->assertEquals(array($a, $b), $found[0]);
$this->assertEquals(array($a, $c), $found[1]);
}

/**
* @depends testAddDirectedEdge
* @depends testEachEdge
* @covers ::transpose
*/
public function testTranspose() {
$this->g->addDirectedEdge($this->v['a'], $this->v['b']);
$this->g->addDirectedEdge($this->v['a'], $this->v['c']);
extract($this->v);
$this->g->addDirectedEdge($a, $b);
$this->g->addDirectedEdge($a, $c);

$transpose = $this->g->transpose();

$this->doCheckVertexCount(3, $transpose);
$this->doCheckVerticesEqual(array($this->v['b'], $this->v['a'], $this->v['c']), $transpose);
$this->assertVertexCount(3, $transpose);

$found = array();
$transpose->eachEdge(function($edge) use (&$found) {
$found[] = $edge;
});

$this->assertCount(2, $found);
$this->assertContains(array($b, $a), $found);
$this->assertContains(array($c, $a), $found);
}

/**
* @expectedException Gliph\Exception\NonexistentVertexException
* @expectedException \Gliph\Exception\NonexistentVertexException
* @covers ::removeVertex
*/
public function testRemoveNonexistentVertex() {
$this->g->removeVertex($this->v['a']);
}

/**
* @covers \Gliph\Graph\DirectedAdjacencyList::isAcyclic()
* @covers ::isAcyclic()
*/
public function testIsAcyclic() {
$this->g->addDirectedEdge($this->v['a'], $this->v['b']);
Expand All @@ -105,13 +157,20 @@ public function testIsAcyclic() {
}

/**
* @covers \Gliph\Graph\DirectedAdjacencyList::getCycles()
* This is primarily a test of the Tarjan SCC algo, but the coverage scoping
* ensures that we are only focused on the graph's method for returning
* correct outputs.
*
* @covers ::getCycles()
*/
public function testGetCycles() {
$this->g->addDirectedEdge($this->v['a'], $this->v['b']);
$this->g->addDirectedEdge($this->v['b'], $this->v['c']);
$this->g->addDirectedEdge($this->v['c'], $this->v['a']);
extract($this->v);
$this->g->addDirectedEdge($a, $b);
$this->g->addDirectedEdge($b, $c);

$this->assertEmpty($this->g->getCycles());

$this->g->addDirectedEdge($c, $a);
$this->assertEquals(array(array($this->v['c'], $this->v['b'], $this->v['a'])), $this->g->getCycles());
}
}

0 comments on commit f57d041

Please sign in to comment.