mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 09:48:40 +00:00
impl. tests and graph
This commit is contained in:
parent
f467b598a3
commit
e98d649876
|
|
@ -194,6 +194,8 @@ class Mail
|
|||
*/
|
||||
protected ?\DateTime $messageDate = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Should confirm reading
|
||||
*
|
||||
|
|
@ -1366,6 +1368,116 @@ class Mail
|
|||
return \str_replace(' ', '_', $encoded);
|
||||
}
|
||||
|
||||
protected function hasCid(string $cid) : bool
|
||||
{
|
||||
foreach ($this->attachment as $attachment) {
|
||||
if ($attachment['disposition'] === DispositionType::INLINE && $attachment['id'] === $cid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasInlineImage() : bool
|
||||
{
|
||||
foreach ($this->attachment as $attachment) {
|
||||
if ($attachment['disposition'] === DispositionType::INLINE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasAttachment() : bool
|
||||
{
|
||||
foreach ($this->attachment as $attachmnet) {
|
||||
if ($attachment['disposition'] === DispositionType::ATTACHMENT) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasAlternative() : bool
|
||||
{
|
||||
return !empty($this->bodyAlt);
|
||||
}
|
||||
|
||||
public function clearAddresses() : void
|
||||
{
|
||||
$this->to = [];
|
||||
$this->cc = [];
|
||||
$this->bcc = [];
|
||||
}
|
||||
|
||||
public function clearAllCC() : void
|
||||
{
|
||||
$this->cc = [];
|
||||
}
|
||||
|
||||
public function clearAllTo() : void
|
||||
{
|
||||
$this->to = [];
|
||||
}
|
||||
|
||||
public function clearAllBCC() : void
|
||||
{
|
||||
$this->bcc = [];
|
||||
}
|
||||
|
||||
public function clearAttachments() : void
|
||||
{
|
||||
$this->attachment = [];
|
||||
}
|
||||
|
||||
public function clearCustomHeaders() : void
|
||||
{
|
||||
$this->header = [];
|
||||
}
|
||||
|
||||
protected function serverHostname() : string
|
||||
{
|
||||
if (!empty($this->hostname)) {
|
||||
return $this->hostname;
|
||||
} elseif (isset($_SERVER, $_SERVER['SERVER_NAME'])) {
|
||||
return $_SERVER['SERVER_NAME'];
|
||||
}
|
||||
|
||||
return ($host = \gethostname()) === false ? 'localhost.localdomain' : $host;
|
||||
}
|
||||
|
||||
public function addHeader(string $name, string $value = nulll) : bool
|
||||
{
|
||||
if ($vallue === null && \strpos($name, ':') !== false) {
|
||||
list($name, $value) = \explode(':', $name, 2);
|
||||
}
|
||||
|
||||
$name = \trim($name);
|
||||
$value = \trim($value);
|
||||
|
||||
if (empty($name) || \strbrk($name . $value, "\r\n") !== false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// todo: consider to add by name and make the name an array -> multiple values per name
|
||||
$this->header[] = [$name, $value];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHeader() : array
|
||||
{
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
public function msgHtml(string $message, string $baseDir = '') : string
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set signing files
|
||||
*
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class Edge
|
|||
* @var Node
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private $node1 = null;
|
||||
private Node $node1;
|
||||
|
||||
/**
|
||||
* Node2.
|
||||
|
|
@ -42,7 +42,7 @@ class Edge
|
|||
* @var Node
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private $node2 = null;
|
||||
private Node $node2;
|
||||
|
||||
/**
|
||||
* Is graph/edge directed
|
||||
|
|
@ -50,7 +50,7 @@ class Edge
|
|||
* @var bool
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private $isDirected = false;
|
||||
private bool $isDirected = false;
|
||||
|
||||
/**
|
||||
* Edge weight
|
||||
|
|
@ -58,7 +58,7 @@ class Edge
|
|||
* @var float
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private $weight = 0.0;
|
||||
private float $weight = 0.0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
|
@ -90,6 +90,20 @@ class Edge
|
|||
return [$this->node1, $this->node2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set weight
|
||||
*
|
||||
* @param float $weight Weight
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function setWeight(float $weight) : void
|
||||
{
|
||||
$this->weight = $weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get node of the edge.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class Graph
|
|||
* @var Node[]
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected $nodes = [];
|
||||
protected array $nodes = [];
|
||||
|
||||
/**
|
||||
* Directed
|
||||
|
|
@ -61,7 +61,7 @@ class Graph
|
|||
* @var bool
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected $isDirected = false;
|
||||
protected bool $isDirected = false;
|
||||
|
||||
/**
|
||||
* Set node to graph.
|
||||
|
|
@ -93,6 +93,21 @@ class Graph
|
|||
return $this->nodes[$key] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a relationship between two nodes
|
||||
*
|
||||
* @param Node $node1 First node
|
||||
* @param Node $node2 Second node
|
||||
*
|
||||
* @return Edge
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function setNodeRelative(Node $node1, Node $node2) : Edge
|
||||
{
|
||||
return $node1->setNodeRelative($node2, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Graph has node
|
||||
*
|
||||
|
|
@ -190,6 +205,37 @@ class Graph
|
|||
return $edges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the edge between two nodes
|
||||
*
|
||||
* @param string $id1 Node id
|
||||
* @param string $id2 Node id
|
||||
*
|
||||
* @return null|Edge
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getEdge(string $id1, string $id2) : ?Edge
|
||||
{
|
||||
foreach ($this->nodes as $node) {
|
||||
if ($node->getId() !== $id1 && $node->getId() !== $id2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$nodeEdges = $node->getEdges();
|
||||
|
||||
foreach ($nodeEdges as $edge) {
|
||||
if (($edge->getNode1()->getId() === $id1 || $edge->getNode1()->getId() === $id2)
|
||||
&& ($edge->getNode2()->getId() === $id1 || $edge->getNode2()->getId() === $id2)
|
||||
) {
|
||||
return $edge;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all bridges.
|
||||
*
|
||||
|
|
@ -289,19 +335,26 @@ class Graph
|
|||
}
|
||||
|
||||
/** @var Node $node1 */
|
||||
$node1 = $graph->hasNode($edge->getNode1()->getId()) ? $graph->getNode($edge->getNode1()->getId()) : clone $edge->getNode1();
|
||||
$node1 = $graph->hasNode($edge->getNode1()->getId())
|
||||
? $graph->getNode($edge->getNode1()->getId())
|
||||
: clone $edge->getNode1();
|
||||
|
||||
/** @var Node $node2 */
|
||||
$node2 = $graph->hasNode($edge->getNode2()->getId()) ? $graph->getNode($edge->getNode2()->getId()) : clone $edge->getNode2();
|
||||
$node2 = $graph->hasNode($edge->getNode2()->getId())
|
||||
? $graph->getNode($edge->getNode2()->getId())
|
||||
: clone $edge->getNode2();
|
||||
|
||||
$node1->setNodeRelative($node2);
|
||||
|
||||
if (!$graph->hasNode($edge->getNode1()->getId())) {
|
||||
if (!$graph->hasNode($node1->getId())) {
|
||||
$node1->removeEdges();
|
||||
$graph->setNode($node1);
|
||||
}
|
||||
|
||||
if (!$graph->hasNode($edge->getNode2()->getId())) {
|
||||
if (!$graph->hasNode($node2->getId())) {
|
||||
$node2->removeEdges();
|
||||
$graph->setNode($node2);
|
||||
}
|
||||
|
||||
$node1->setNodeRelative($node2)->setWeight($this->getEdge($node1->getId(), $node2->getId())->getWeight());
|
||||
}
|
||||
|
||||
return $graph;
|
||||
|
|
|
|||
|
|
@ -117,16 +117,17 @@ class Node
|
|||
/**
|
||||
* Set a relative undirected node.
|
||||
*
|
||||
* @param Node $node Graph node
|
||||
* @param int $key Index for absolute position
|
||||
* @param Node $node Graph node
|
||||
* @param int $key Index for absolute position
|
||||
* @param booll $isDirected Is directed
|
||||
*
|
||||
* @return Edge
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function setNodeRelative(self $node, int $key = null) : Edge
|
||||
public function setNodeRelative(self $node, int $key = null, bool $isDirected = false) : Edge
|
||||
{
|
||||
$edge = new Edge($this, $node);
|
||||
$edge = new Edge($this, $node, 0.0, $isDirected);
|
||||
$this->setEdge($edge, $key);
|
||||
|
||||
if (!$edge->isDirected()) {
|
||||
|
|
@ -183,6 +184,18 @@ class Node
|
|||
return $this->edges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all edges / neighbours from the node
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function removeEdges() : void
|
||||
{
|
||||
$this->edges = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all node neighbors.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -207,7 +207,16 @@ final class UriFactory
|
|||
}
|
||||
|
||||
if (isset($urlStructure['query'])) {
|
||||
\parse_str(\str_replace('?', '&', $urlStructure['query']), $urlStructure['query']);
|
||||
$len = \strlen($urlStructure['query']);
|
||||
for ($i = 0; $i < $len; ++$i) {
|
||||
if ($urlStructure['query'][$i] === '?') {
|
||||
$urlStructure['query'] = \substr_replace($urlStructure['query'], '&', $i, 1);
|
||||
} elseif ($urlStructure['query'][$i] === '\\') {
|
||||
++$i;
|
||||
}
|
||||
}
|
||||
|
||||
\parse_str($urlStructure['query'], $urlStructure['query']);
|
||||
}
|
||||
|
||||
$escaped =
|
||||
|
|
|
|||
|
|
@ -14,13 +14,16 @@ declare(strict_types=1);
|
|||
|
||||
namespace phpOMS\tests\Socket\Client;
|
||||
|
||||
use phpOMS\Socket\Client\NullClientConnection;
|
||||
use phpOMS\Socket\Client\ClientConnection;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class NullClientConnectionTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testPlaceholder() : void
|
||||
public function testDefault() : void
|
||||
{
|
||||
self::markTestIncomplete();
|
||||
self::assertInstanceOf(ClientConnection::class, new NullClientConnection());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,13 +51,33 @@ class EdgeTest extends \PHPUnit\Framework\TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @testdox An edge can have a weight
|
||||
* @testdox An edge weight can be set and returned
|
||||
* @covers phpOMS\Stdlib\Graph\Edge
|
||||
* @group framework
|
||||
*/
|
||||
public function testWeight() : void
|
||||
public function testWeightInputOutput() : void
|
||||
{
|
||||
$edge = new Edge(new Node('7'), new Node('8'), 1.0, true);
|
||||
self::assertEquals(1.0, $edge->getWeight());
|
||||
|
||||
$edge = new Edge(new Node('7'), new Node('8'), 1.0);
|
||||
$edge->setWeight(3.0);
|
||||
self::assertEquals(3.0, $edge->getWeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Two edge weights can be compared
|
||||
* @covers phpOMS\Stdlib\Graph\Edge
|
||||
* @group framework
|
||||
*/
|
||||
public function testWeightComparison() : void
|
||||
{
|
||||
$edge1 = new Edge(new Node('7'), new Node('8'), 1.0, true);
|
||||
$edge2 = new Edge(new Node('7'), new Node('8'), 1.0, true);
|
||||
$edge3 = new Edge(new Node('7'), new Node('8'), 2.0, true);
|
||||
|
||||
self::assertEquals(0, Edge::compare($edge1, $edge2));
|
||||
self::assertEquals(-1, Edge::compare($edge1, $edge3));
|
||||
self::assertEquals(1, Edge::compare($edge3, $edge1));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,13 @@ use phpOMS\Stdlib\Graph\Node;
|
|||
*/
|
||||
class GraphTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected Graph $graph;
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->graph = new Graph();
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The graph has the expected default values after initialization
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
|
|
@ -31,37 +38,81 @@ class GraphTest extends \PHPUnit\Framework\TestCase
|
|||
*/
|
||||
public function testDefault() : void
|
||||
{
|
||||
$graph = new Graph();
|
||||
self::assertNull($this->graph->getNode('invalid'));
|
||||
self::assertEquals([], $this->graph->getNodes());
|
||||
|
||||
self::assertNull($graph->getNode('invalid'));
|
||||
self::assertEquals([], $graph->getNodes());
|
||||
self::assertEquals(0, $this->graph->getDiameter());
|
||||
self::assertEquals(0, $this->graph->getOrder());
|
||||
self::assertEquals(0, $this->graph->getSize());
|
||||
self::assertEquals(0, $this->graph->getGirth());
|
||||
self::assertEquals(0, $this->graph->getCircuitRank());
|
||||
self::assertEquals(0, $this->graph->getNodeConnectivity());
|
||||
self::assertEquals(0, $this->graph->getEdgeConnectivity());
|
||||
|
||||
self::assertEquals(0, $graph->getDiameter());
|
||||
self::assertEquals(0, $graph->getOrder());
|
||||
self::assertEquals(0, $graph->getSize());
|
||||
self::assertEquals(0, $graph->getGirth());
|
||||
self::assertEquals(0, $graph->getCircuitRank());
|
||||
self::assertEquals(0, $graph->getNodeConnectivity());
|
||||
self::assertEquals(0, $graph->getEdgeConnectivity());
|
||||
self::assertTrue($this->graph->isConnected());
|
||||
self::assertTrue($this->graph->isBipartite());
|
||||
self::assertTrue($this->graph->isTriangleFree());
|
||||
self::assertFalse($this->graph->isDirected());
|
||||
self::assertFalse($this->graph->hasCycle());
|
||||
|
||||
self::assertTrue($graph->isConnected());
|
||||
self::assertTrue($graph->isBipartite());
|
||||
self::assertTrue($graph->isTriangleFree());
|
||||
self::assertEquals([], $this->graph->getBridges());
|
||||
self::assertEquals([], $this->graph->getFloydWarshallShortestPath());
|
||||
self::assertEquals([], $this->graph->getDijkstraShortestPath());
|
||||
self::assertEquals([], $this->graph->depthFirstTraversal());
|
||||
self::assertEquals([], $this->graph->breadthFirstTraversal());
|
||||
self::assertEquals([], $this->graph->longestPath());
|
||||
self::assertEquals([], $this->graph->longestPathBetweenNodes('invalid1', 'invalid2'));
|
||||
self::assertEquals([], $this->graph->getUnconnected());
|
||||
|
||||
self::assertEquals([], $graph->getBridges());
|
||||
self::assertEquals([], $graph->getFloydWarshallShortestPath());
|
||||
self::assertEquals([], $graph->getDijkstraShortestPath());
|
||||
self::assertEquals([], $graph->depthFirstTraversal());
|
||||
self::assertEquals([], $graph->breadthFirstTraversal());
|
||||
self::assertEquals([], $graph->longestPath());
|
||||
self::assertEquals([], $graph->longestPathBetweenNodes('invalid1', 'invalid2'));
|
||||
self::assertEquals([], $graph->getUnconnected());
|
||||
self::assertEquals(0, $this->graph->getCost());
|
||||
self::assertEquals($this->graph, $this->graph->getKruskalMinimalSpanningTree());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox A graph can ge set as directed
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testDirectedInputOutput() : void
|
||||
{
|
||||
$this->graph->setDirected(true);
|
||||
self::assertTrue($this->graph->isDirected());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox A node can be add to a graph and returned
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testNodeInputOutput() : void
|
||||
{
|
||||
$node0 = new Node('0');
|
||||
$this->graph->setNode($node0);
|
||||
|
||||
self::assertEquals($node0, $this->graph->getNode('0'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The existence of a node in a graph can be checked
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testNodeExists() : void
|
||||
{
|
||||
$node0 = new Node('0');
|
||||
$this->graph->setNode($node0);
|
||||
|
||||
self::assertTrue($this->graph->hasNode('0'));
|
||||
self::assertFalse($this->graph->hasNode('1'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox A graph can be checked for bridges
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testGraphWithBridge() : void
|
||||
{
|
||||
$graph = new Graph();
|
||||
|
||||
$node0 = new Node('0');
|
||||
$node1 = new Node('1');
|
||||
$node2 = new Node('2');
|
||||
|
|
@ -70,13 +121,13 @@ class GraphTest extends \PHPUnit\Framework\TestCase
|
|||
$node5 = new Node('5');
|
||||
$node6 = new Node('6');
|
||||
|
||||
$graph->setNode($node0);
|
||||
$graph->setNode($node1);
|
||||
$graph->setNode($node2);
|
||||
$graph->setNode($node3);
|
||||
$graph->setNode($node4);
|
||||
$graph->setNode($node5);
|
||||
$graph->setNode($node6);
|
||||
$this->graph->setNode($node0);
|
||||
$this->graph->setNode($node1);
|
||||
$this->graph->setNode($node2);
|
||||
$this->graph->setNode($node3);
|
||||
$this->graph->setNode($node4);
|
||||
$this->graph->setNode($node5);
|
||||
$this->graph->setNode($node6);
|
||||
|
||||
$node0->setNodeRelative($node1);
|
||||
$node0->setNodeRelative($node2);
|
||||
|
|
@ -87,58 +138,67 @@ class GraphTest extends \PHPUnit\Framework\TestCase
|
|||
$node3->setNodeRelative($node5);
|
||||
$node4->setNodeRelative($node5);
|
||||
|
||||
$bridges = $graph->getBridges();
|
||||
$bridges = $this->graph->getBridges();
|
||||
self::assertCount(1, $bridges);
|
||||
self::assertEquals('1', $bridges[0]->getNode1()->getId());
|
||||
self::assertEquals('6', $bridges[0]->getNode2()->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Multiple bridges are correctly identified in a graph
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testGraphWithBridges() : void
|
||||
{
|
||||
$graph = new Graph();
|
||||
|
||||
$node0 = new Node('0');
|
||||
$node1 = new Node('1');
|
||||
$node2 = new Node('2');
|
||||
$node3 = new Node('3');
|
||||
|
||||
$graph->setNode($node0);
|
||||
$graph->setNode($node1);
|
||||
$graph->setNode($node2);
|
||||
$graph->setNode($node3);
|
||||
$this->graph->setNode($node0);
|
||||
$this->graph->setNode($node1);
|
||||
$this->graph->setNode($node2);
|
||||
$this->graph->setNode($node3);
|
||||
|
||||
$node0->setNodeRelative($node1);
|
||||
$node1->setNodeRelative($node2);
|
||||
$node2->setNodeRelative($node3);
|
||||
|
||||
$bridges = $graph->getBridges();
|
||||
$bridges = $this->graph->getBridges();
|
||||
self::assertCount(3, $bridges);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox A graph without bridges is correctly classified
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testGraphWithoutBridges() : void
|
||||
{
|
||||
$graph = new Graph();
|
||||
|
||||
$node0 = new Node('0');
|
||||
$node1 = new Node('1');
|
||||
$node2 = new Node('2');
|
||||
|
||||
$graph->setNode($node0);
|
||||
$graph->setNode($node1);
|
||||
$graph->setNode($node2);
|
||||
$this->graph->setNode($node0);
|
||||
$this->graph->setNode($node1);
|
||||
$this->graph->setNode($node2);
|
||||
|
||||
$node0->setNodeRelative($node1);
|
||||
$node0->setNodeRelative($node2);
|
||||
$node1->setNodeRelative($node2);
|
||||
|
||||
$bridges = $graph->getBridges();
|
||||
$bridges = $this->graph->getBridges();
|
||||
self::assertCount(0, $bridges);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Edges can be add and returned from a graph
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testEdgesInputOutput() : void
|
||||
{
|
||||
$graph = new Graph();
|
||||
|
||||
$node0 = new Node('0');
|
||||
$node1 = new Node('1');
|
||||
$node2 = new Node('2');
|
||||
|
|
@ -147,13 +207,13 @@ class GraphTest extends \PHPUnit\Framework\TestCase
|
|||
$node5 = new Node('5');
|
||||
$node6 = new Node('6');
|
||||
|
||||
$graph->setNode($node0);
|
||||
$graph->setNode($node1);
|
||||
$graph->setNode($node2);
|
||||
$graph->setNode($node3);
|
||||
$graph->setNode($node4);
|
||||
$graph->setNode($node5);
|
||||
$graph->setNode($node6);
|
||||
$this->graph->setNode($node0);
|
||||
$this->graph->setNode($node1);
|
||||
$this->graph->setNode($node2);
|
||||
$this->graph->setNode($node3);
|
||||
$this->graph->setNode($node4);
|
||||
$this->graph->setNode($node5);
|
||||
$this->graph->setNode($node6);
|
||||
|
||||
$node0->setNodeRelative($node1);
|
||||
$node0->setNodeRelative($node2);
|
||||
|
|
@ -164,7 +224,173 @@ class GraphTest extends \PHPUnit\Framework\TestCase
|
|||
$node3->setNodeRelative($node5);
|
||||
$node4->setNodeRelative($node5);
|
||||
|
||||
$edges = $graph->getEdges();
|
||||
$edges = $this->graph->getEdges();
|
||||
self::assertCount(8, $edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox An edge can be found by two edge ids
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testEdgeInputOutput() : void
|
||||
{
|
||||
$node0 = new Node('0');
|
||||
$node1 = new Node('1');
|
||||
$node2 = new Node('2');
|
||||
$node3 = new Node('3');
|
||||
$node4 = new Node('4');
|
||||
$node5 = new Node('5');
|
||||
$node6 = new Node('6');
|
||||
|
||||
$this->graph->setNode($node0);
|
||||
$this->graph->setNode($node1);
|
||||
$this->graph->setNode($node2);
|
||||
$this->graph->setNode($node3);
|
||||
$this->graph->setNode($node4);
|
||||
$this->graph->setNode($node5);
|
||||
$this->graph->setNode($node6);
|
||||
|
||||
$node0->setNodeRelative($node1);
|
||||
$node0->setNodeRelative($node2);
|
||||
$node1->setNodeRelative($node2);
|
||||
$node1->setNodeRelative($node3);
|
||||
$node1->setNodeRelative($node4);
|
||||
$node1->setNodeRelative($node6);
|
||||
$node3->setNodeRelative($node5);
|
||||
$node4->setNodeRelative($node5);
|
||||
|
||||
self::assertEquals(
|
||||
$node1->getId(),
|
||||
$this->graph->getEdge($node1->getId(), $node3->getId())->getNode1()->getId()
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
$node3->getId(),
|
||||
$this->graph->getEdge($node1->getId(), $node3->getId())->getNode2()->getId()
|
||||
);
|
||||
|
||||
self::assertEquals(null, $this->graph->getEdge('invalid1', 'invalid2'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The existence of cycles in undirected graphs can be checked
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testUndirectedCycle() : void
|
||||
{
|
||||
$node0 = new Node('0');
|
||||
$node1 = new Node('1');
|
||||
$node2 = new Node('2');
|
||||
$node3 = new Node('3');
|
||||
|
||||
$this->graph->setNode($node0);
|
||||
$this->graph->setNode($node1);
|
||||
$this->graph->setNode($node2);
|
||||
$this->graph->setNode($node3);
|
||||
|
||||
$node0->setNodeRelative($node1);
|
||||
$node1->setNodeRelative($node2);
|
||||
$node2->setNodeRelative($node3);
|
||||
|
||||
self::assertFalse($this->graph->hasCycle());
|
||||
|
||||
$node3->setNodeRelative($node1);
|
||||
self::assertTrue($this->graph->hasCycle());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The existence of cycles in directed graphs can be checked
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testDirectedCycle() : void
|
||||
{
|
||||
$this->graph->setDirected(true);
|
||||
|
||||
$node0 = new Node('0');
|
||||
$node1 = new Node('1');
|
||||
$node2 = new Node('2');
|
||||
$node3 = new Node('3');
|
||||
|
||||
$this->graph->setNode($node0);
|
||||
$this->graph->setNode($node1);
|
||||
$this->graph->setNode($node2);
|
||||
$this->graph->setNode($node3);
|
||||
|
||||
$this->graph->setNodeRelative($node0, $node1);
|
||||
$this->graph->setNodeRelative($node1, $node2);
|
||||
$this->graph->setNodeRelative($node2, $node3);
|
||||
$this->graph->setNodeRelative($node1, $node3);
|
||||
|
||||
self::assertFalse($this->graph->hasCycle());
|
||||
|
||||
$node3->setNodeRelative($node1);
|
||||
self::assertTrue($this->graph->hasCycle());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The cost of a graph can be calculated
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testCost() : void
|
||||
{
|
||||
$node0 = new Node('0');
|
||||
$node1 = new Node('1');
|
||||
$node2 = new Node('2');
|
||||
$node3 = new Node('3');
|
||||
|
||||
$this->graph->setNode($node0);
|
||||
$this->graph->setNode($node1);
|
||||
$this->graph->setNode($node2);
|
||||
$this->graph->setNode($node3);
|
||||
|
||||
$node0->setNodeRelative($node1)->setWeight(2.0);
|
||||
$node2->setNodeRelative($node3)->setWeight(3.0);
|
||||
|
||||
self::assertEquals(5.0, $this->graph->getCost());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The Kruskal minimal spanning tree can be created
|
||||
* @covers phpOMS\Stdlib\Graph\Graph
|
||||
* @group framework
|
||||
*/
|
||||
public function testKruskalMinimalSpanningTree() : void
|
||||
{
|
||||
$node1 = new Node('1');
|
||||
$node2 = new Node('2');
|
||||
$node3 = new Node('3');
|
||||
$node4 = new Node('4');
|
||||
$node5 = new Node('5');
|
||||
$node6 = new Node('6');
|
||||
|
||||
$this->graph->setNode($node1);
|
||||
$this->graph->setNode($node2);
|
||||
$this->graph->setNode($node3);
|
||||
$this->graph->setNode($node4);
|
||||
$this->graph->setNode($node5);
|
||||
$this->graph->setNode($node6);
|
||||
|
||||
$node1->setNodeRelative($node5)->setWeight(4.0);
|
||||
$node1->setNodeRelative($node4)->setWeight(1.0);
|
||||
$node1->setNodeRelative($node2)->setWeight(2.0);
|
||||
|
||||
$node2->setNodeRelative($node3)->setWeight(3.0);
|
||||
$node2->setNodeRelative($node4)->setWeight(3.0);
|
||||
$node2->setNodeRelative($node6)->setWeight(7.0);
|
||||
|
||||
$node3->setNodeRelative($node4)->setWeight(5.0);
|
||||
$node3->setNodeRelative($node6)->setWeight(8.0);
|
||||
|
||||
$node4->setNodeRelative($node5)->setWeight(9.0);
|
||||
|
||||
$minimalSpanningTree = $this->graph->getKruskalMinimalSpanningTree();
|
||||
$nodes = $minimalSpanningTree->getNodes();
|
||||
|
||||
self::assertCount(6, $nodes);
|
||||
self::assertEquals(17.0, $minimalSpanningTree->getCost());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ declare(strict_types=1);
|
|||
namespace phpOMS\tests\Stdlib\Graph;
|
||||
|
||||
use phpOMS\Stdlib\Graph\Node;
|
||||
use phpOMS\Stdlib\Graph\Edge;
|
||||
|
||||
use function PHPUnit\Framework\assertInstanceOf;
|
||||
|
||||
/**
|
||||
* @testdox phpOMS\tests\Stdlib\Graph\NodeTest: Node in a graph
|
||||
|
|
@ -80,4 +83,83 @@ class NodeTest extends \PHPUnit\Framework\TestCase
|
|||
|
||||
self::assertFalse($node->isEqual($node2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox An edge for a node can be defined
|
||||
* @covers phpOMS\Stdlib\Graph\Node
|
||||
* @group framework
|
||||
*/
|
||||
public function testEdgeInputOutput() : void
|
||||
{
|
||||
$node = new Node('A', 1);
|
||||
$node->setEdge(new Edge($node, new Node('B')));
|
||||
|
||||
self::assertCount(1, $node->getEdges());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Edges can be removed from a node
|
||||
* @covers phpOMS\Stdlib\Graph\Node
|
||||
* @group framework
|
||||
*/
|
||||
public function testEdgeRemove() : void
|
||||
{
|
||||
$node = new Node('A', 1);
|
||||
$node->setEdge(new Edge($node, new Node('B')));
|
||||
$node->removeEdges();
|
||||
|
||||
self::assertCount(0, $node->getEdges());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox An edge for a node can be defined by key
|
||||
* @covers phpOMS\Stdlib\Graph\Node
|
||||
* @group framework
|
||||
*/
|
||||
public function testEdgeKeyInputOutput() : void
|
||||
{
|
||||
$node = new Node('A', 1);
|
||||
$node->setEdge(new Edge($node, new Node('B')), 3);
|
||||
|
||||
self::assertEquals(null, $node->getEdge(2));
|
||||
self::assertInstanceOf(Edge::class, $node->getEdge(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox A node relationship can be defined
|
||||
* @covers phpOMS\Stdlib\Graph\Node
|
||||
* @group framework
|
||||
*/
|
||||
public function testNodeRelation() : void
|
||||
{
|
||||
$node1 = new Node('A');
|
||||
$node2 = new Node('B');
|
||||
|
||||
self::assertInstanceOf(Edge::class, $edge = $node1->setNodeRelative($node2, null, false));
|
||||
self::assertCount(1, $node2->getEdges());
|
||||
self::assertFalse($edge->isDirected());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox All neighbors of a node can be returned
|
||||
* @covers phpOMS\Stdlib\Graph\Node
|
||||
* @group framework
|
||||
*
|
||||
* @todo: is there bug where directed graphs return invalid neighbors?
|
||||
*/
|
||||
public function testNeighborsInputOutput() : void
|
||||
{
|
||||
$node1 = new Node('A');
|
||||
$node2 = new Node('B');
|
||||
$node3 = new Node('C');
|
||||
$node4 = new Node('D');
|
||||
|
||||
$node3->setNodeRelative($node4);
|
||||
|
||||
$node1->setNodeRelative($node2);
|
||||
$node1->setNodeRelative($node3);
|
||||
|
||||
self::assertCount(2, $node1->getNeighbors());
|
||||
self::assertCount(1, $node4->getNeighbors());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ class UriFactoryTest extends \PHPUnit\Framework\TestCase
|
|||
|
||||
self::assertTrue(UriFactory::setQuery('/valid2', 'query4'));
|
||||
|
||||
$expected = 'www.test-uri.com?id=1&test=someString&two=PATH&hash=test&none=%23none&found=%2Fnot%3Fv%3Dquery4';
|
||||
$expected = 'www.test-uri.com?id=1&test=someString&two=PATH&hash=test&none=%23none&found=%2Fnot&v=query4';
|
||||
|
||||
self::assertEquals($expected, UriFactory::build($uri, $vars));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ class ViewTest extends \PHPUnit\Framework\TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @testdox The view data can be checked for existance
|
||||
* @testdox The view data can be checked for existence
|
||||
* @covers phpOMS\Views\View<extended>
|
||||
* @group framework
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user