From 86f77e0a5eb75a73ba4bc17c1eeea27ad65b2b2b Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 20 Nov 2019 22:27:43 +0100 Subject: [PATCH] cleanup and tests added for ci/cd --- Algorithm/Knapsack/Bounded.php | 4 +- Auth/OAuth2/AccessToken.php | 27 +++ Auth/OAuth2/Client.php | 27 +++ Auth/OAuth2/Provider.php | 27 +++ Auth/OAuth2/TokenStorageInterface.php | 27 +++ DataStorage/Database/DataMapperAbstract.php | 20 ++ .../Database/Query/Grammar/Grammar.php | 18 +- DataStorage/Database/Schema/Builder.php | 9 + Math/Matrix/Matrix.php | 4 + Math/Number/Complex.php | 20 +- .../Regression/MultipleLinearRegression.php | 37 ++- Message/Mail/Imap.php | 15 -- Message/Mail/Pop3.php | 15 -- Message/RequestAbstract.php | 4 +- Message/Socket/Header.php | 48 +++- Message/Socket/Request.php | 13 ++ Message/Socket/Response.php | 8 + Model/Html/Meta.php | 44 +++- Module/ModuleAbstract.php | 8 - Module/PackageManager.php | 8 +- Socket/Client/Client.php | 40 ++-- Socket/Client/ClientConnection.php | 88 ++++++-- Socket/Server/ClientManager.php | 46 +++- Socket/Server/Server.php | 70 ++++-- Stdlib/Base/EnumArray.php | 43 +++- Stdlib/Graph/BinaryTree.php | 15 +- Utils/StringUtils.php | 4 +- Views/View.php | 2 +- tests/Account/PermissionAbstractTest.php | 2 +- tests/Business/Finance/StockBondsTest.php | 2 +- tests/Math/Matrix/MatrixTest.php | 154 ++++++++++++- tests/Math/Matrix/VectorTest.php | 25 ++- .../CubicSplineInterpolationTest.php | 4 +- .../LagrangeInterpolationTest.php | 2 +- .../Interpolation/LinearInterpolationTest.php | 2 +- tests/Message/HeaderAbstractTest.php | 8 +- tests/Message/Http/HeaderTest.php | 30 +-- tests/Message/Http/RequestTest.php | 211 +++++++++++++++++- tests/Message/Http/ResponseTest.php | 157 ++++++++++--- tests/Message/Http/RestTest.php | 22 ++ tests/Message/ResponseAbstractTest.php | 19 +- tests/Model/Html/HeadTest.php | 129 ++++++++--- tests/Model/Html/MetaTest.php | 121 ++++++++-- tests/Module/InfoManagerTest.php | 32 ++- tests/Module/ModuleAbstractTest.php | 34 ++- tests/Module/ModuleManagerTest.php | 138 ++++++++---- tests/Module/PackageManagerTest.php | 27 ++- tests/Router/RouteVerbTest.php | 3 + tests/Router/SocketRouterTest.php | 69 ++++-- tests/Router/WebRouterTest.php | 111 +++++---- tests/Security/PhpCodeTest.php | 52 +++++ tests/Stdlib/Base/AddressTest.php | 117 ++++++++-- tests/Stdlib/Base/EnumArrayTest.php | 67 +++++- tests/Stdlib/Base/EnumTest.php | 97 +++++++- tests/Uri/UriSchemeTest.php | 3 + 55 files changed, 1924 insertions(+), 405 deletions(-) diff --git a/Algorithm/Knapsack/Bounded.php b/Algorithm/Knapsack/Bounded.php index 6893d3d1c..e1f34af79 100644 --- a/Algorithm/Knapsack/Bounded.php +++ b/Algorithm/Knapsack/Bounded.php @@ -82,7 +82,9 @@ final class Bounded $s = 0; $v = $m[$i][$j]; - for ($k = 0; $v !== $m[$i - 1][$j] + $k * ((int) $items[$i - 1]['item']->getValue()); ++$k) { + $value = (int) $items[$i - 1]['item']->getValue(); + + for ($k = 0; $v !== $m[$i - 1][$j] + $k * $value; ++$k) { $s++; $j -= (int) $items[$i - 1]['item']->getCost(); } diff --git a/Auth/OAuth2/AccessToken.php b/Auth/OAuth2/AccessToken.php index e69de29bb..3e88a2c66 100644 --- a/Auth/OAuth2/AccessToken.php +++ b/Auth/OAuth2/AccessToken.php @@ -0,0 +1,27 @@ +con->prepare($query->toSql())->execute(); } + /** + * Update conditional values + * + * @param object $obj Object to update + * @param mixed $objId Object id + * @param \ReflectionClass $refClass Reflection of the object + * @param int $relations Relations to update + * @param int $depth Depths to update + * + * @return void + * + * @since 1.0.0 + */ private static function updateConditionals(object $obj, $objId, \ReflectionClass $refClass = null, int $relations = RelationType::ALL, int $depth = 1) : void { foreach (static::$conditionals as $table => $conditional) { @@ -1720,6 +1733,13 @@ class DataMapperAbstract implements DataMapperInterface return $obj; } + /** + * Delete conditional values + * + * @param mixed $key Key to delete + * + * @since 1.0.0 + */ private static function deleteConditionals($key) : void { foreach (static::$conditionals as $table => $conditional) { diff --git a/DataStorage/Database/Query/Grammar/Grammar.php b/DataStorage/Database/Query/Grammar/Grammar.php index 492399813..649572d92 100644 --- a/DataStorage/Database/Query/Grammar/Grammar.php +++ b/DataStorage/Database/Query/Grammar/Grammar.php @@ -549,12 +549,26 @@ class Grammar extends GrammarAbstract return 'ORDER BY ' . $expression; } - protected function compileUnions() + /** + * Compile unions. + * + * @return string + * + * @since 1.0.0 + */ + protected function compileUnions() : string { return ''; } - protected function compileLock() + /** + * Compile lock. + * + * @return string + * + * @since 1.0.0 + */ + protected function compileLock() : string { return ''; } diff --git a/DataStorage/Database/Schema/Builder.php b/DataStorage/Database/Schema/Builder.php index 2df6d629c..15d0c0c9b 100644 --- a/DataStorage/Database/Schema/Builder.php +++ b/DataStorage/Database/Schema/Builder.php @@ -256,6 +256,15 @@ class Builder extends QueryBuilder return $this; } + /** + * Alter a field. + * + * @param array $column Column data + * + * @return void + * + * @since 1.0.0 + */ public function alter(array $column) : void { } diff --git a/Math/Matrix/Matrix.php b/Math/Matrix/Matrix.php index cbbdda1d3..caeed3501 100644 --- a/Math/Matrix/Matrix.php +++ b/Math/Matrix/Matrix.php @@ -518,6 +518,10 @@ class Matrix implements \ArrayAccess, \Iterator $nDim = $matrix->getN(); $mDim = $matrix->getM(); + if ($mDim !== $this->n) { + throw new InvalidDimensionException($mDim . 'x' . $nDim); + } + $matrixArr = $matrix->getMatrix(); $newMatrix = new self($this->m, $nDim); $newMatrixArr = $newMatrix->getMatrix(); diff --git a/Math/Number/Complex.php b/Math/Number/Complex.php index 75075e884..0f8eae1d7 100644 --- a/Math/Number/Complex.php +++ b/Math/Number/Complex.php @@ -161,7 +161,7 @@ final class Complex { if (\is_int($value)) { return $this->powInteger($value); - } elseif (\is_numeric($value)) { + } elseif (\is_float($value)) { return $this->powScalar($value); } elseif ($value instanceof self) { return $this->powComplex($value); @@ -170,6 +170,15 @@ final class Complex throw new \InvalidArgumentException(); } + /** + * Power with complex number + * + * @param Complex $value Power + * + * @return Complex + * + * @since 1.0.0 + */ public function powComplex(self $value) : self { @@ -195,6 +204,15 @@ final class Complex return $this->multComplex($this->powInteger(--$value)); } + /** + * Power with scalar + * + * @param int|float $value Power + * + * @return Complex + * + * @since 1.0.0 + */ public function powScalar($value) : self { diff --git a/Math/Statistic/Forecast/Regression/MultipleLinearRegression.php b/Math/Statistic/Forecast/Regression/MultipleLinearRegression.php index 2341a820d..92880d2ba 100644 --- a/Math/Statistic/Forecast/Regression/MultipleLinearRegression.php +++ b/Math/Statistic/Forecast/Regression/MultipleLinearRegression.php @@ -15,9 +15,28 @@ namespace phpOMS\Math\Statistic\Forecast\Regression; use phpOMS\Math\Matrix\Matrix; -class MultipleLinearRegression +/** + * Regression class. + * + * @package phpOMS\Math\Statistic\Forecast\Regression + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ +class MultipleLinearRegression extends RegressionAbstract { - + /** + * Get linear regression based on scatter plot. + * + * @latex y = b_{0} + b_{1} \cdot x + * + * @param array> $x Obersved x values + * @param array> $y Observed y values + * + * @return array [b0 => ?, b1 => ?] + * + * @since 1.0.0 + */ public static function getRegression(array $x, array $y) : array { $X = new Matrix(\count($x), \count($x[0])); @@ -30,19 +49,17 @@ class MultipleLinearRegression return $XT->mult($X)->inverse()->mult($XT)->mult($Y)->getMatrix(); } - public static function getVariance() : float - { - } - - public static function getPredictionInterval() : array - { - } - + /** + * {@inheritdoc} + */ public static function getSlope(float $b1, float $y, float $x) : float { return 0.0; } + /** + * {@inheritdoc} + */ public static function getElasticity(float $b1, float $y, float $x): float { return 0.0; diff --git a/Message/Mail/Imap.php b/Message/Mail/Imap.php index 94095d9ec..b4ee26f36 100644 --- a/Message/Mail/Imap.php +++ b/Message/Mail/Imap.php @@ -24,21 +24,6 @@ namespace phpOMS\Message\Mail; */ class Imap extends EmailAbstract { - /** - * Construct - * - * @param string $host Host - * @param int $port Host port - * @param int $timeout Timeout - * @param bool $ssl Use ssl - * - * @since 1.0.0 - */ - public function __construct(string $host = 'localhost', int $port = 143, int $timeout = 30, bool $ssl = false) - { - parent::__construct($host, $port, $timeout, $ssl); - } - /** * Connect to server * diff --git a/Message/Mail/Pop3.php b/Message/Mail/Pop3.php index 5c248be12..2451a44d9 100644 --- a/Message/Mail/Pop3.php +++ b/Message/Mail/Pop3.php @@ -24,21 +24,6 @@ namespace phpOMS\Message\Mail; */ class Pop3 extends EmailAbstract { - /** - * Construct - * - * @param string $host Host - * @param int $port Host port - * @param int $timeout Timeout - * @param bool $ssl Use ssl - * - * @since 1.0.0 - */ - public function __construct(string $host = 'localhost', int $port = 25, int $timeout = 30, bool $ssl = false) - { - parent::__construct($host, $port, $timeout, $ssl); - } - /** * Connect to server * diff --git a/Message/RequestAbstract.php b/Message/RequestAbstract.php index cc364824c..aeca0ee4e 100644 --- a/Message/RequestAbstract.php +++ b/Message/RequestAbstract.php @@ -89,7 +89,7 @@ abstract class RequestAbstract implements MessageInterface $json = \json_decode($this->data[$key], true); - return $json === false ? [] : $json; + return $json === false ? [] : $json ?? []; } /** @@ -169,7 +169,7 @@ abstract class RequestAbstract implements MessageInterface * * @since 1.0.0 */ - public function setData($key, $value, bool $overwrite = true) : bool + public function setData($key, $value, bool $overwrite = false) : bool { if (!$this->lock) { $key = \mb_strtolower($key); diff --git a/Message/Socket/Header.php b/Message/Socket/Header.php index 4611952ce..fadf217e4 100644 --- a/Message/Socket/Header.php +++ b/Message/Socket/Header.php @@ -64,21 +64,53 @@ class Header extends HeaderAbstract implements \Serializable */ private array $header = []; + /** + * Get the sender + * + * @return mixed + * + * @since 1.0.0 + */ public function getSendFrom() { return $this->sendFrom; } + /** + * Set sender + * + * @param mixed $sendFrom Sender + * + * @return void + * + * @since 1.0.0 + */ public function setSendFrom($sendFrom) : void { $this->sendFrom = $sendFrom; } + /** + * Get receiver + * + * @return mixed + * + * @since 1.0.0 + */ public function getSendTo() { return $this->sendTo; } + /** + * Set receiver + * + * @param mixed $sendTo Receiver + * + * @return void + * + * @since 1.0.0 + */ public function setSendTo($sendTo) : void { $this->sendTo = $sendTo; @@ -95,7 +127,9 @@ class Header extends HeaderAbstract implements \Serializable } /** - * @param int $length + * Set header length + * + * @param int $length Header length * * @return void * @@ -107,6 +141,8 @@ class Header extends HeaderAbstract implements \Serializable } /** + * Get package type + * * @return int * * @since 1.0.0 @@ -117,7 +153,9 @@ class Header extends HeaderAbstract implements \Serializable } /** - * @param int $type + * Set package type + * + * @param int $type Type * * @return void * @@ -129,6 +167,8 @@ class Header extends HeaderAbstract implements \Serializable } /** + * Get subtype + * * @return int * * @since 1.0.0 @@ -139,7 +179,9 @@ class Header extends HeaderAbstract implements \Serializable } /** - * @param int $subtype + * Set subtype + * + * @param int $subtype Subtype * * @return void * diff --git a/Message/Socket/Request.php b/Message/Socket/Request.php index 76e785abb..3a4a91fd6 100644 --- a/Message/Socket/Request.php +++ b/Message/Socket/Request.php @@ -16,8 +16,21 @@ namespace phpOMS\Message\Socket; use phpOMS\Message\RequestAbstract; +/** + * Request class. + * + * @package phpOMS\Message\Socket + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ final class Request extends RequestAbstract { + /** + * Constructor + * + * @since 1.0.0 + */ public function __construct() { $this->header = new Header(); diff --git a/Message/Socket/Response.php b/Message/Socket/Response.php index 4e5c84f59..699b393b5 100644 --- a/Message/Socket/Response.php +++ b/Message/Socket/Response.php @@ -17,6 +17,14 @@ namespace phpOMS\Message\Socket; use phpOMS\Message\ResponseAbstract; use phpOMS\Contract\RenderableInterface; +/** + * Response class. + * + * @package phpOMS\Message\Socket + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ final class Response extends ResponseAbstract implements RenderableInterface { /** diff --git a/Model/Html/Meta.php b/Model/Html/Meta.php index 9d39bceee..245012987 100644 --- a/Model/Html/Meta.php +++ b/Model/Html/Meta.php @@ -205,6 +205,20 @@ class Meta implements RenderableInterface $this->properties[$property] = $content; } + /** + * Get property. + * + * @param string $property Property + * + * @return string + * + * @since 1.0.0 + */ + public function getProperty(string $property) : string + { + return $this->properties[$property] ?? ''; + } + /** * Set itemprop. * @@ -220,10 +234,24 @@ class Meta implements RenderableInterface $this->itemprops[$itemprop] = $content; } + /** + * Get itemprop. + * + * @param string $itemprop Itemprop + * + * @return string + * + * @since 1.0.0 + */ + public function getItemprop(string $itemprop) : string + { + return $this->itemprops[$itemprop] ?? ''; + } + /** * Set name. * - * @param string $name Property + * @param string $name Name * @param string $content Content * * @return void @@ -235,6 +263,20 @@ class Meta implements RenderableInterface $this->names[$name] = $content; } + /** + * Get name. + * + * @param string $name Name + * + * @return string + * + * @since 1.0.0 + */ + public function getName(string $name) : string + { + return $this->names[$name] ?? ''; + } + /** * {@inheritdoc} */ diff --git a/Module/ModuleAbstract.php b/Module/ModuleAbstract.php index 5aa940154..d71d9ae44 100644 --- a/Module/ModuleAbstract.php +++ b/Module/ModuleAbstract.php @@ -73,14 +73,6 @@ abstract class ModuleAbstract */ protected static array $providing = []; - /** - * Localization files. - * - * @var array - * @since 1.0.0 - */ - protected static array $localization = []; - /** * Dependencies. * diff --git a/Module/PackageManager.php b/Module/PackageManager.php index 9210544d4..9c05a322e 100644 --- a/Module/PackageManager.php +++ b/Module/PackageManager.php @@ -278,7 +278,7 @@ final class PackageManager private function delete(array $components) : void { foreach ($components as $component) { - $path = StringUtils::startsWith($component, '/Package/') ? $this->extractPath . '/' . \substr($component, 9) : $this->basePath . '/' . $component; + $path = StringUtils::startsWith($component, '/Package/') ? $this->extractPath . '/' . \substr($component, 9) : $this->basePath . '/' . $component; LocalStorage::delete($path); } } @@ -295,8 +295,8 @@ final class PackageManager private function cmd(array $components) : void { foreach ($components as $component) { - $cmd = ''; - $path = StringUtils::startsWith($component, '/Package/') ? $this->extractPath . '/' . \substr($component, 9) : $this->basePath . '/' . $component; + $cmd = ''; + $path = StringUtils::startsWith($component, '/Package/') ? $this->extractPath . '/' . \substr($component, 9) : $this->basePath . '/' . $component; if (StringUtils::endsWith($component, '.php')) { // todo: maybe add a guessing method to find php path if it isn't available in the environment see Repository.php for git api @@ -308,7 +308,7 @@ final class PackageManager } if ($cmd !== '') { - $pipes = []; + $pipes = []; $resource = \proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, $this->extractPath); foreach ($pipes as $pipe) { diff --git a/Socket/Client/Client.php b/Socket/Client/Client.php index baed0e888..05a21d97f 100644 --- a/Socket/Client/Client.php +++ b/Socket/Client/Client.php @@ -73,14 +73,6 @@ class Client extends SocketAbstract $this->run = false; } - /** - * {@inheritdoc} - */ - public function create(string $ip, int $port) : void - { - parent::create($ip, $port); - } - /** * {@inheritdoc} */ @@ -142,29 +134,29 @@ class Client extends SocketAbstract $this->close(); } + /** + * Stop the socket connection to the server + * + * @return void + * + * @since 1.0.0 + */ public function shutdown() : void { $this->run = false; } + /** + * Add packet to be handeld + * + * @param mixed $packet Packet to handle + * + * @return void + * + * @since 1.0.0 + */ public function addPacket($packet) : void { $this->packets[] = $packet; } - - /** - * {@inheritdoc} - */ - public function close() : void - { - parent::close(); - } - - /** - * {@inheritdoc} - */ - public function __destruct() - { - parent::__destruct(); - } } diff --git a/Socket/Client/ClientConnection.php b/Socket/Client/ClientConnection.php index 43b44e851..6b51172d8 100644 --- a/Socket/Client/ClientConnection.php +++ b/Socket/Client/ClientConnection.php @@ -33,58 +33,118 @@ class ClientConnection private $connected = true; private Account $account; + /** + * Constructor. + * + * @param Account $account Account + * @param mixed $socket Socket connection + * + * @since 1.0.0 + */ public function __construct(Account $account, $socket) { - $this->id = $account->getId(); + $this->id = $account->getId(); $this->account = $account; - $this->socket = $socket; + $this->socket = $socket; } - public function getId() + /** + * Get client id. + * + * @return int + * + * @since 1.0.0 + */ + public function getId() : int { return $this->id; } + /** + * Get account + * + * @return Account + * + * @since 1.0.0 + */ public function getAccount() : Account { return $this->account; } + /** + * Get socket + * + * @return mixed + * + * @since 1.0.0 + */ public function getSocket() { return $this->socket; } + /** + * Set socket + * + * @param mixed $socket Socket connection + * + * @return void + * + * @since 1.0.0 + */ public function setSocket($socket) : void { $this->socket = $socket; } + /** + * Get handshake data + * + * @return mixed + * + * @sicne 1.0.0 + */ public function getHandshake() { return $this->handshake; } + /** + * Set handshake data + * + * @param mixed $handshake Handshake + * + * @return void + * + * @since 1.0.0 + */ public function setHandshake($handshake) : void { $this->handshake = $handshake; } - public function getPid() - { - return $this->pid; - } - - public function setPid($pid) : void - { - $this->pid = $pid; - } - - public function isConnected() + /** + * Is connected? + * + * @return bool + * + * @since 1.0.0 + */ + public function isConnected() : bool { return $this->connected; } + /** + * Set connected + * + * @param bool $connected Is connected? + * + * @return void + * + * @since 1.0.0 + */ public function setConnected(bool $connected) : void { $this->connected = $connected; diff --git a/Socket/Server/ClientManager.php b/Socket/Server/ClientManager.php index 19d3b6724..44827aee9 100644 --- a/Socket/Server/ClientManager.php +++ b/Socket/Server/ClientManager.php @@ -4,7 +4,7 @@ * * PHP Version 7.4 * - * @package TBD + * @package phpOMS\Socket\Server * @copyright Dennis Eichhorn * @license OMS License 1.0 * @version 1.0.0 @@ -17,20 +17,53 @@ namespace phpOMS\Socket\Server; use phpOMS\Socket\Client\ClientConnection; use phpOMS\Socket\Client\NullClientConnection; +/** + * Client manager class. + * + * @package phpOMS\Socket\Server + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class ClientManager { private $clients = []; + /** + * Add client + * + * @param ClientConnection $client Client + * + * @return void + * + * @since 1.0.0 + */ public function add(ClientConnection $client) : void { $this->clients[$client->getId()] = $client; } + /** + * Get client by id + * + * @return mixed + * + * @since 1.0.0 + */ public function get($id) { return $this->clients[$id] ?? new NullClientConnection($id, null); } + /** + * Get client by socket + * + * @param mixed $socket Socket + * + * @return mixed + * + * @since 1.0.0 + */ public function getBySocket($socket) { foreach ($this->clients as $client) { @@ -42,7 +75,16 @@ class ClientManager return new NullClientConnection($id, null); } - public function remove($id) + /** + * Remove client by id + * + * @param mixed $id Client id + * + * @return bool + * + * @since 1.0.0 + */ + public function remove($id) : bool { if (isset($this->clients[$id])) { unset($this->clients[$id]); diff --git a/Socket/Server/Server.php b/Socket/Server/Server.php index d307c036e..6378ddac3 100644 --- a/Socket/Server/Server.php +++ b/Socket/Server/Server.php @@ -127,10 +127,22 @@ class Server extends SocketAbstract $this->limit = $limit; } + /** + * Perform client-server handshake during login + * + * @param mixed $client Client + * @param mixed $headers Header + * + * @return bool + * + * @since 1.0.0 + */ public function handshake($client, $headers) : bool { // todo: different handshake for normal tcp connection - return true; + if ($client !== null) { + return true; + } if (\preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $headers, $match) === false) { return false; @@ -194,6 +206,7 @@ class Server extends SocketAbstract // socket_last_error(); // socket_strerror(socket_last_error()); // socket_clear_error(); + $a = 2; } foreach ($read as $key => $socket) { @@ -230,6 +243,15 @@ class Server extends SocketAbstract $this->close(); } + /** + * Perform server shutdown + * + * @param mixed $request Request + * + * @return void + * + * @since 1.0.0 + */ public function shutdown($request) : void { $msg = 'shutdown' . "\n"; @@ -238,15 +260,33 @@ class Server extends SocketAbstract $this->run = false; } + /** + * Connect a client + * + * @param mixed $socket Socket + * + * @return void + * + * @since 1.0.0 + */ public function connectClient($socket) : void { $this->app->logger->debug('Connecting client...'); $this->app->accountManager->add(new Account(1)); $this->clientManager->add($client = new ClientConnection(new Account(1), $socket)); - $this->conn[$client->getId()] = $socket; + $this->conn[$client->getId()] = $socket; $this->app->logger->debug('Connected client.'); } + /** + * Disconnect a client + * + * @param mixed $client Client + * + * @return void + * + * @since 1.0.0 + */ public function disconnectClient($client) : void { $this->app->logger->debug('Disconnecting client...'); @@ -264,21 +304,14 @@ class Server extends SocketAbstract } /** - * {@inheritdoc} + * Unmask payload + * + * @param mixed $payload Payload + * + * @return string + * + * @since 1.0.0 */ - public function close() : void - { - parent::close(); - } - - /** - * {@inheritdoc} - */ - public function __destruct() - { - parent::__destruct(); - } - private function unmask($payload) : string { $length = \ord($payload[1]) & 127; @@ -292,8 +325,9 @@ class Server extends SocketAbstract $masks = \substr($payload, 2, 4); $data = \substr($payload, 6); } - $text = ''; - for ($i = 0; $i < \strlen($data); ++$i) { + $text = ''; + $dataLength = \strlen($data); + for ($i = 0; $i < $dataLength; ++$i) { $text .= $data[$i] ^ $masks[$i % 4]; } diff --git a/Stdlib/Base/EnumArray.php b/Stdlib/Base/EnumArray.php index 3c01556f8..302661c97 100644 --- a/Stdlib/Base/EnumArray.php +++ b/Stdlib/Base/EnumArray.php @@ -47,9 +47,7 @@ abstract class EnumArray */ public static function isValidName(string $name) : bool { - $constants = self::getConstants(); - - return isset($constants[$name]); + return isset(static::$constants[$name]); } /** @@ -61,8 +59,7 @@ abstract class EnumArray */ public static function getConstants() : array { - /** @var array $constants */ - return (new static())::$constants; + return static::$constants; } /** @@ -78,9 +75,7 @@ abstract class EnumArray */ public static function isValidValue($value) : bool { - $constants = self::getConstants(); - - return \in_array($value, $constants, true); + return \in_array($value, static::$constants, true); } /** @@ -96,12 +91,36 @@ abstract class EnumArray */ public static function get($key) { - $constants = self::getConstants(); - - if (!isset($constants[$key])) { + if (!isset(static::$constants[$key])) { throw new \OutOfBoundsException('Key "' . $key . '" is not valid.'); } - return $constants[$key]; + return static::$constants[$key]; + } + + /** + * Count enum variables + * + * @return int + * + * @since 1.0.0 + */ + public static function count() : int + { + return \count(static::$constants); + } + + /** + * Get random enum value. + * + * @return mixed + * + * @since 1.0.0 + */ + public static function getRandom() + { + $keys = \array_keys(static::$constants); + + return static::$constants[$keys[\mt_rand(0, \count(static::$constants) - 1)]]; } } diff --git a/Stdlib/Graph/BinaryTree.php b/Stdlib/Graph/BinaryTree.php index 0d8218ac4..115f0c965 100644 --- a/Stdlib/Graph/BinaryTree.php +++ b/Stdlib/Graph/BinaryTree.php @@ -26,6 +26,13 @@ namespace phpOMS\Stdlib\Graph; */ class BinaryTree extends Tree { + /** + * Invert the tree + * + * @return BinaryTree + * + * @since 1.0.0 + */ public static function invert($list) : self { if (empty($list->getNodes())) { @@ -91,6 +98,7 @@ class BinaryTree extends Tree // todo: maybe need to add numerics to edges? } else { // todo: replace node + $a = 2; } return $this; @@ -106,7 +114,7 @@ class BinaryTree extends Tree * * @since 1.0.0 */ - public function setRight(Node $base, Node $right) /* : void */ + public function setRight(Node $base, Node $right) : self { if ($this->getRight($base) === null) { $this->addNodeRelative($base, $right); @@ -114,7 +122,10 @@ class BinaryTree extends Tree // todo: maybe need to add numerics to edges? } else { // todo: replace node + $a = 2; } + + return $this; } /** @@ -145,7 +156,7 @@ class BinaryTree extends Tree * * @since 1.0.0 */ - private function getVerticalOrder(Node $node, int $horizontalDistance = 0, array &$order) : void + private function getVerticalOrder(Node $node, int $horizontalDistance, array &$order) : void { if (!isset($order[$horizontalDistance])) { $order[$horizontalDistance] = []; diff --git a/Utils/StringUtils.php b/Utils/StringUtils.php index 761b2d514..3c76a5988 100644 --- a/Utils/StringUtils.php +++ b/Utils/StringUtils.php @@ -423,9 +423,11 @@ final class StringUtils return $element->format('Y-m-d H:i:s'); } elseif ($element instanceof RenderableInterface) { return $element->render(); - } else { + } elseif (\method_exists($element, '__toString')) { return $element->__toString(); } + + return null; } /** diff --git a/Views/View.php b/Views/View.php index 67da5e81e..c1e9ec58f 100644 --- a/Views/View.php +++ b/Views/View.php @@ -198,7 +198,7 @@ class View extends ViewAbstract /** @var string $module */ $module = $module ?? $this->module; /** @var string $theme */ - $theme = $theme ?? $this->theme; + $theme = $theme ?? $this->theme; return $this->app->l11nManager->getText($this->l11n->getLanguage() ?? 'en', $module, $theme, $translation); } diff --git a/tests/Account/PermissionAbstractTest.php b/tests/Account/PermissionAbstractTest.php index 9e2d16359..20ba1e43f 100644 --- a/tests/Account/PermissionAbstractTest.php +++ b/tests/Account/PermissionAbstractTest.php @@ -20,7 +20,7 @@ use phpOMS\Account\PermissionAbstract; use phpOMS\Account\PermissionType; /** - * @testdox phpOMS\tests\Account\PermissionAbstract: Base permission representation + * @testdox phpOMS\tests\Account\PermissionAbstractTest: Base permission representation * * @internal */ diff --git a/tests/Business/Finance/StockBondsTest.php b/tests/Business/Finance/StockBondsTest.php index 29372ce1b..dcb9b32dc 100644 --- a/tests/Business/Finance/StockBondsTest.php +++ b/tests/Business/Finance/StockBondsTest.php @@ -17,7 +17,7 @@ namespace phpOMS\tests\Business\Finance; use phpOMS\Business\Finance\StockBonds; /** - * @testdox phpOMS\tests\Business\Finance\FinanceFormulasTest: Stock & bond related formulas + * @testdox phpOMS\tests\Business\Finance\StockBondsTest: Stock & bond related formulas * * @internal */ diff --git a/tests/Math/Matrix/MatrixTest.php b/tests/Math/Matrix/MatrixTest.php index f85726e08..259bf647a 100644 --- a/tests/Math/Matrix/MatrixTest.php +++ b/tests/Math/Matrix/MatrixTest.php @@ -18,6 +18,8 @@ use phpOMS\Math\Matrix\Matrix; use phpOMS\Math\Matrix\Vector; /** + * @testdox phpOMS\tests\Math\MatrixTest: Matrix operations + * * @internal */ class MatrixTest extends \PHPUnit\Framework\TestCase @@ -44,34 +46,92 @@ class MatrixTest extends \PHPUnit\Framework\TestCase $this->C = $this->A->mult($this->B); } + /** + * @testdox A matrix can return the dimension + * @covers phpOMS\Math\Matrix\Matrix + */ public function testBase() : void { self::assertEquals(2, $this->A->getM()); self::assertEquals(3, $this->A->getN()); - // LU decomposition } - public function testMult() : void + /** + * @testdox A matrix can be right-hand multiplicated with a matrix + * @covers phpOMS\Math\Matrix\Matrix + */ + public function testMultMatrix() : void { self::assertEquals([[0, -5], [-6, -7]], $this->C->getMatrix()); + } + + /** + * @testdox A matrix can be right-hand multiplicated with a scalar + * @covers phpOMS\Math\Matrix\Matrix + */ + public function testMultMatrixScalar() : void + { self::assertEquals([[0, -10], [-12, -14]], $this->C->mult(2)->getMatrix()); } - public function testAddSub() : void + /** + * @testdox A scalar can be added to every matrix element + * @covers phpOMS\Math\Matrix\Matrix + */ + public function testAddScalar() : void + { + $A = new Matrix(); + $A->setMatrix([[1, 2], [3, 4]]); + + self::assertEquals([[1 + 2, 2 + 2], [3 + 2, 4 + 2]], $A->add(2)->toArray()); + } + + /** + * @testdox A scalar can be subtracted from every matrix element + * @covers phpOMS\Math\Matrix\Matrix + */ + public function testSubScalar() : void { $A = new Matrix(); $A->setMatrix([[1, 2], [3, 4]]); self::assertEquals([[1 - 2, 2 - 2], [3 - 2, 4 - 2]], $A->sub(2)->toArray()); - self::assertEquals([[1 + 2, 2 + 2], [3 + 2, 4 + 2]], $A->add(2)->toArray()); + } + + /** + * @testdox Two matrices can be added to each other + * @covers phpOMS\Math\Matrix\Matrix + */ + public function testAddMatrix() : void + { + $A = new Matrix(); + $A->setMatrix([[1, 2], [3, 4]]); + + $B = new Matrix(); + $B->setMatrix([[1, 2], [3, 4]]); + + self::assertEquals([[1 + 1, 2 + 2], [3 + 3, 4 + 4]], $A->add($B)->toArray()); + } + + /** + * @testdox Two matrices can be subtracted from each other + * @covers phpOMS\Math\Matrix\Matrix + */ + public function testSubMatrix() : void + { + $A = new Matrix(); + $A->setMatrix([[1, 2], [3, 4]]); $B = new Matrix(); $B->setMatrix([[1, 2], [3, 4]]); self::assertEquals([[1 - 1, 2 - 2], [3 - 3, 4 - 4]], $A->sub($B)->toArray()); - self::assertEquals([[1 + 1, 2 + 2], [3 + 3, 4 + 4]], $A->add($B)->toArray()); } + /** + * @testdox The determinant of a matrix can be calculated + * @covers phpOMS\Math\Matrix\Matrix + */ public function testDet() : void { $B = new Matrix(); @@ -84,6 +144,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase self::assertEquals(-306, $B->det()); } + /** + * @testdox A symmetric matrix can be validated for symmetry + * @covers phpOMS\Math\Matrix\Matrix + */ public function testSymmetry() : void { $B = new Matrix(); @@ -94,7 +158,14 @@ class MatrixTest extends \PHPUnit\Framework\TestCase ]); self::assertTrue($B->isSymmetric()); + } + /** + * @testdox A none-symmetric matrix cannot be validated for symmetry + * @covers phpOMS\Math\Matrix\Matrix + */ + public function testInvalidSymmetry() : void + { $C = new Matrix(); $C->setMatrix([ [1, 7, 4], @@ -105,6 +176,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase self::assertFalse($C->isSymmetric()); } + /** + * @testdox A matrix can be transposed + * @covers phpOMS\Math\Matrix\Matrix + */ public function testTranspose() : void { $B = new Matrix(); @@ -116,6 +191,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase self::assertEquals([[6, 4], [1, -2], [1, 5],], $B->transpose()->toArray()); } + /** + * @testdox A matrix equation Ax = b can be solved for x + * @covers phpOMS\Math\Matrix\Matrix + */ public function testSolve() : void { $A = new Matrix(); @@ -131,6 +210,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase self::assertEqualsWithDelta([[1], [2], [3]], $A->solve($vec)->toArray(), 0.2); } + /** + * @testdox The rank of a matrix can be calculated + * @covers phpOMS\Math\Matrix\Matrix + */ public function testRank() : void { $B = new Matrix(); @@ -189,7 +272,11 @@ class MatrixTest extends \PHPUnit\Framework\TestCase //self::assertEquals([], $this->C->diagonalize()->getMatrix()); } - public function testGetSet() : void + /** + * @testdox The matrix elements can be set and returned + * @covers phpOMS\Math\Matrix\Matrix + */ + public function testMatrixInputOutput() : void { $id = new Matrix(); $id->setMatrix([ @@ -217,6 +304,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase ); } + /** + * @testdox A matrix can be accessed like a 1-dimensional array + * @covers phpOMS\Math\Matrix\Matrix + */ public function testArrayAccess() : void { $A = new Matrix(); @@ -243,7 +334,11 @@ class MatrixTest extends \PHPUnit\Framework\TestCase self::assertFalse(isset($A[6])); } - public function testSubMatrix() : void + /** + * @testdox Sub matrices can be extracted from a matrix + * @covers phpOMS\Math\Matrix\Matrix + */ + public function testMatrixExtract() : void { $A = new Matrix(); $A->setMatrix([ @@ -274,6 +369,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase ); } + /** + * @testdox Setting a matrix element outside of the dimensions throws a InvalidDimensionException + * @covers phpOMS\Math\Matrix\Matrix + */ public function testInvalidSetIndexException() : void { self::expectException(\phpOMS\Math\Matrix\Exception\InvalidDimensionException::class); @@ -286,6 +385,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase $id->set(99, 99, 99); } + /** + * @testdox Returning a matrix element outside of the dimensions throws a InvalidDimensionException + * @covers phpOMS\Math\Matrix\Matrix + */ public function testInvalidGetIndexException() : void { self::expectException(\phpOMS\Math\Matrix\Exception\InvalidDimensionException::class); @@ -298,6 +401,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase $id->get(99, 99); } + /** + * @testdox Subtracting a invalid data type from a matrix throws a InvalidArgumentException + * @covers phpOMS\Math\Matrix\Matrix + */ public function testInvalidSub() : void { self::expectException(\InvalidArgumentException::class); @@ -311,6 +418,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase $id->sub(true); } + /** + * @testdox Adding a invalid data type from a matrix throws a InvalidArgumentException + * @covers phpOMS\Math\Matrix\Matrix + */ public function testInvalidAdd() : void { self::expectException(\InvalidArgumentException::class); @@ -324,6 +435,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase $id->add(true); } + /** + * @testdox Multiplicating a invalid data type from a matrix throws a InvalidArgumentException + * @covers phpOMS\Math\Matrix\Matrix + */ public function testInvalidMult() : void { self::expectException(\InvalidArgumentException::class); @@ -337,6 +452,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase $id->mult(true); } + /** + * @testdox Adding a matrix with a different dimension to a matrix throws a InvalidDimensionException + * @covers phpOMS\Math\Matrix\Matrix + */ public function testInvalidDimensionAdd() : void { self::expectException(\phpOMS\Math\Matrix\Exception\InvalidDimensionException::class); @@ -350,6 +469,10 @@ class MatrixTest extends \PHPUnit\Framework\TestCase $A->add($B); } + /** + * @testdox Subtracting a matrix from a different dimension to a matrix throws a InvalidDimensionException + * @covers phpOMS\Math\Matrix\Matrix + */ public function testInvalidDimensionSub() : void { self::expectException(\phpOMS\Math\Matrix\Exception\InvalidDimensionException::class); @@ -362,4 +485,21 @@ class MatrixTest extends \PHPUnit\Framework\TestCase $A->sub($B); } + + /** + * @testdox Multiplicating a matrix with a different n x m dimension to a matrix throws a InvalidDimensionException + * @covers phpOMS\Math\Matrix\Matrix + */ + public function testInvalidDimensionMult() : void + { + self::expectException(\phpOMS\Math\Matrix\Exception\InvalidDimensionException::class); + + $A = new Matrix(); + $A->setMatrix([[1, 2], [3, 4]]); + + $B = new Matrix(); + $B->setMatrix([[1, 2, 1], [3, 4, 1], [5, 6, 1]]); + + $A->mult($B); + } } diff --git a/tests/Math/Matrix/VectorTest.php b/tests/Math/Matrix/VectorTest.php index a53b6473d..8fefa3175 100644 --- a/tests/Math/Matrix/VectorTest.php +++ b/tests/Math/Matrix/VectorTest.php @@ -17,10 +17,16 @@ namespace phpOMS\tests\Math\Matrix; use phpOMS\Math\Matrix\Vector; /** + * @testdox phpOMS\tests\Math\VectorTest: Vector operations + * * @internal */ class VectorTest extends \PHPUnit\Framework\TestCase { + /** + * @testdox The vector has the expected default values after initialization + * @covers phpOMS\Math\Matrix\Vector + */ public function testDefault() : void { self::assertInstanceOf('\phpOMS\Math\Matrix\Vector', new Vector()); @@ -30,15 +36,30 @@ class VectorTest extends \PHPUnit\Framework\TestCase self::assertCount(5, $vec->toArray()); } - public function testGetSet() : void + /** + * @testdox The vector values can be set and returned + * @covers phpOMS\Math\Matrix\Vector + */ + public function testValueInputOutput() : void { $vec = new Vector(5); $vec->setMatrixV([1, 2, 3, 4, 5]); - self::assertEquals(5, $vec->getM()); self::assertEquals(2, $vec->getV(1)); $vec->setV(3, 9); self::assertEquals(9, $vec->getV(3)); } + + /** + * @testdox The vector dimension can be returned + * @covers phpOMS\Math\Matrix\Vector + */ + public function testDim() : void + { + $vec = new Vector(5); + $vec->setMatrixV([1, 2, 3, 4, 5]); + + self::assertEquals(5, $vec->getM()); + } } diff --git a/tests/Math/Numerics/Interpolation/CubicSplineInterpolationTest.php b/tests/Math/Numerics/Interpolation/CubicSplineInterpolationTest.php index dde9b4f07..d02184bab 100644 --- a/tests/Math/Numerics/Interpolation/CubicSplineInterpolationTest.php +++ b/tests/Math/Numerics/Interpolation/CubicSplineInterpolationTest.php @@ -26,7 +26,7 @@ class CubicSplineInterpolationTest extends \PHPUnit\Framework\TestCase { /** * @testdox The spline interpolation using the first derivative is correct - * @covers phpOMS\tests\Math\Numerics\Interpolation\CubicSplineInterpolation + * @covers phpOMS\Math\Numerics\Interpolation\CubicSplineInterpolation */ public function testInterpolationFirstDerivative() : void { @@ -46,7 +46,7 @@ class CubicSplineInterpolationTest extends \PHPUnit\Framework\TestCase /** * @testdox The spline interpolation using the second derivative is correct - * @covers phpOMS\tests\Math\Numerics\Interpolation\CubicSplineInterpolation + * @covers phpOMS\Math\Numerics\Interpolation\CubicSplineInterpolation */ public function testInterpolationSecondDerivative() : void { diff --git a/tests/Math/Numerics/Interpolation/LagrangeInterpolationTest.php b/tests/Math/Numerics/Interpolation/LagrangeInterpolationTest.php index e33c0121c..1f0ad5e34 100644 --- a/tests/Math/Numerics/Interpolation/LagrangeInterpolationTest.php +++ b/tests/Math/Numerics/Interpolation/LagrangeInterpolationTest.php @@ -25,7 +25,7 @@ class LagrangeInterpolationTest extends \PHPUnit\Framework\TestCase { /** * @testdox The lagrange interpolation is correct - * @covers phpOMS\tests\Math\Numerics\Interpolation\LagrangeInterpolation + * @covers phpOMS\Math\Numerics\Interpolation\LagrangeInterpolation */ public function testInterpolation() : void { diff --git a/tests/Math/Numerics/Interpolation/LinearInterpolationTest.php b/tests/Math/Numerics/Interpolation/LinearInterpolationTest.php index 232badedc..cfebfde93 100644 --- a/tests/Math/Numerics/Interpolation/LinearInterpolationTest.php +++ b/tests/Math/Numerics/Interpolation/LinearInterpolationTest.php @@ -25,7 +25,7 @@ class LinearInterpolationTest extends \PHPUnit\Framework\TestCase { /** * @testdox The linear interpolation is correct - * @covers phpOMS\tests\Math\Numerics\LinearInterpolation + * @covers phpOMS\Math\Numerics\LinearInterpolation */ public function testInterpolation() : void { diff --git a/tests/Message/HeaderAbstractTest.php b/tests/Message/HeaderAbstractTest.php index 035c9c7c1..a21a24bb8 100644 --- a/tests/Message/HeaderAbstractTest.php +++ b/tests/Message/HeaderAbstractTest.php @@ -19,6 +19,8 @@ require_once __DIR__ . '/../Autoloader.php'; use phpOMS\Message\HeaderAbstract; /** + * @testdox phpOMS\tests\Message\HeaderAbstractTest: Abstract header for requests/responses + * * @internal */ class HeaderAbstractTest extends \PHPUnit\Framework\TestCase @@ -55,7 +57,11 @@ class HeaderAbstractTest extends \PHPUnit\Framework\TestCase }; } - public function testSetGet() : void + /** + * @testdox The the status code can be set and returned + * @covers phpOMS\Message\HeaderAbstract + */ + public function testStatusCodeInputOutput() : void { $this->header->setStatusCode(2); self::assertEquals(2, $this->header->getStatusCode()); diff --git a/tests/Message/Http/HeaderTest.php b/tests/Message/Http/HeaderTest.php index 1d0f7c5be..e96dc767e 100644 --- a/tests/Message/Http/HeaderTest.php +++ b/tests/Message/Http/HeaderTest.php @@ -20,7 +20,7 @@ use phpOMS\Message\Http\RequestStatusCode; use phpOMS\System\MimeType; /** - * @testdox phpOMS\tests\Message\HeaderTest: Header for http requests/responses + * @testdox phpOMS\tests\Message\Http\HeaderTest: Header for http requests/responses * * @internal */ @@ -35,7 +35,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox The header has the expected default values after initialization - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testDefaults() : void { @@ -52,7 +52,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox Security policy headers get correctly identified - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testSecurityHeader() : void { @@ -65,7 +65,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox Header data can be set, checked for existence and returned - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testDataInputOutput() : void { @@ -76,7 +76,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox Header data can be forced to get overwritten - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testOverwrite() : void { @@ -87,7 +87,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox By default header data doesn't get overwritten - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testInvalidOverwrite() : void { @@ -98,7 +98,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox Header data can be removed - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testRemove() : void { @@ -109,7 +109,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox None-existing header data cannot be removed - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testInvalidRemove() : void { @@ -118,7 +118,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox Account data can be set and returned - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testAccountInputOutput() : void { @@ -128,7 +128,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox Data can be defined as downloadable - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testDownloadable() : void { @@ -138,7 +138,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox A header can be locked - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testLockInputOutput() : void { @@ -148,7 +148,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox A locked header cannot add new data - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testLockInvalidSet() : void { @@ -158,7 +158,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox A locked header cannot remove data - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testLockInvalidRemove() : void { @@ -168,7 +168,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox The header can generate default http headers based on status codes - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testHeaderGeneration() : void { @@ -193,7 +193,7 @@ class HeaderTest extends \PHPUnit\Framework\TestCase /** * @testdox Security header data cannot be changed once defined - * @covers phpOMS\Message\Http\Header + * @covers phpOMS\Message\Http\Header */ public function testInvalidOverwriteSecurityHeader() : void { diff --git a/tests/Message/Http/RequestTest.php b/tests/Message/Http/RequestTest.php index f945f780a..aa211ff3c 100644 --- a/tests/Message/Http/RequestTest.php +++ b/tests/Message/Http/RequestTest.php @@ -23,10 +23,16 @@ use phpOMS\Router\RouteVerb; use phpOMS\Uri\Http; /** + * @testdox phpOMS\tests\Message\Http\RequestTest: Request wrapper for http requests + * * @internal */ class RequestTest extends \PHPUnit\Framework\TestCase { + /** + * @testdox The request has the expected default values after initialization + * @covers phpOMS\Message\Http\Request + */ public function testDefault() : void { $request = new Request(); @@ -53,7 +59,23 @@ class RequestTest extends \PHPUnit\Framework\TestCase self::assertEquals('en_US', $request->getLocale()); } - public function testSetGet() : void + /** + * @testdox The OS can be set and returned + * @covers phpOMS\Message\Http\Request + */ + public function testOSInputOutput() : void + { + $request = new Request(new Http('http://www.google.com/test/path'), $l11n = new Localization()); + + $request->setOS(OSType::WINDOWS_XP); + self::assertEquals(OSType::WINDOWS_XP, $request->getOS()); + } + + /** + * @testdox The browser can be set and returned + * @covers phpOMS\Message\Http\Request + */ + public function testBrowserTypeInputOutput() : void { $request = new Request(new Http('http://www.google.com/test/path'), $l11n = new Localization()); @@ -63,20 +85,57 @@ class RequestTest extends \PHPUnit\Framework\TestCase $request->setBrowser(BrowserType::EDGE); self::assertEquals(BrowserType::EDGE, $request->getBrowser()); self::assertEquals(['browser' => BrowserType::EDGE, 'os' => OSType::WINDOWS_XP], $request->getRequestInfo()); + } + + /** + * @testdox The request method can be set and returned + * @covers phpOMS\Message\Http\Request + */ + public function testRequestMethodInputOutput() : void + { + $request = new Request(new Http('http://www.google.com/test/path'), $l11n = new Localization()); $request->setMethod(RequestMethod::PUT); self::assertEquals(RequestMethod::PUT, $request->getMethod()); self::assertEquals(RouteVerb::PUT, $request->getRouteVerb()); + } + + /** + * @testdox The route verb gets correctly infered from the request method + * @covers phpOMS\Message\Http\Request + */ + public function testRequestMethodToRouteVerb() : void + { + $request = new Request(new Http('http://www.google.com/test/path'), $l11n = new Localization()); + + $request->setMethod(RequestMethod::PUT); + self::assertEquals(RouteVerb::PUT, $request->getRouteVerb()); $request->setMethod(RequestMethod::DELETE); - self::assertEquals(RequestMethod::DELETE, $request->getMethod()); self::assertEquals(RouteVerb::DELETE, $request->getRouteVerb()); $request->setMethod(RequestMethod::POST); - self::assertEquals(RequestMethod::POST, $request->getMethod()); self::assertEquals(RouteVerb::SET, $request->getRouteVerb()); + } - self::assertEquals('http://www.google.com/test/path', $request->getUri()->__toString()); + /** + * @testdox The request is correctly constracted + * @covers phpOMS\Message\Http\Request + */ + public function testConstructInputOutput() : void + { + $request = new Request(new Http('http://www.google.com/test/path'), $l11n = new Localization()); + + self::assertEquals('http://www.google.com/test/path', $request->__toString()); + } + + /** + * @testdox The url hashes for the different paths get correctly generated + * @covers phpOMS\Message\Http\Request + */ + public function testHashingInputOutput() : void + { + $request = new Request(new Http('http://www.google.com/test/path'), $l11n = new Localization()); $request->createRequestHashs(0); self::assertEquals([ @@ -85,20 +144,65 @@ class RequestTest extends \PHPUnit\Framework\TestCase '328413d996ab9b79af9d4098af3a65b885c4ca64', ], $request->getHash()); self::assertEquals($l11n, $request->getHeader()->getL11n()); + } + + /** + * @testdox Request data can be set and returned + * @covers phpOMS\Message\Http\Request + */ + public function testDataInputOutput() : void + { + $request = new Request(new Http('http://www.google.com/test/path'), $l11n = new Localization()); self::assertTrue($request->setData('key', 'value')); - self::assertFalse($request->setData('key', 'value2', false)); self::assertEquals('value', $request->getData('key')); self::assertTrue($request->hasData('key')); self::assertEquals(['key' => 'value'], $request->getData()); + } + + /** + * @testdox Request data can be forcefully overwritten + * @covers phpOMS\Message\Http\Request + */ + public function testOverwrite() : void + { + $request = new Request(new Http('http://www.google.com/test/path'), $l11n = new Localization()); + + self::assertTrue($request->setData('key', 'value')); + self::assertTrue($request->setData('key', 'value2', true)); + self::assertEquals('value2', $request->getData('key')); + } + + /** + * @testdox Request data is not overwritten by default + * @covers phpOMS\Message\Http\Request + */ + public function testInvalidOverwrite() : void + { + $request = new Request(new Http('http://www.google.com/test/path'), $l11n = new Localization()); + + self::assertTrue($request->setData('key', 'value')); + self::assertFalse($request->setData('key', 'value2')); + self::assertEquals('value', $request->getData('key')); + } + + /** + * @testdox The uri can be changed and returned + * @covers phpOMS\Message\Http\Request + */ + public function testUriInputOutput() : void + { + $request = new Request(new Http('http://www.google.com/test/path'), $l11n = new Localization()); $request->setUri(new Http('http://www.google.com/test/path2')); - $request->createRequestHashs(0); - self::assertEquals('http://www.google.com/test/path2', $request->__toString()); } - public function testDataJson() : void + /** + * @testdox Json data can be read from the request + * @covers phpOMS\Message\Http\Request + */ + public function testDataJsonRead() : void { $request = new Request(new Http('')); @@ -110,9 +214,41 @@ class RequestTest extends \PHPUnit\Framework\TestCase $request->setData('abc', \json_encode($data)); self::assertEquals($data, $request->getDataJson('abc')); + } + + /** + * @testdox None-existing json data reads return empty data + * @covers phpOMS\Message\Http\Request + */ + public function testEmptyDataJsonRead() : void + { + $request = new Request(new Http('')); + self::assertEquals([], $request->getDataJson('def')); } + /** + * @testdox Invalid json data returns empty data + * @covers phpOMS\Message\Http\Request + */ + public function testInvalidDataJsonRead() : void + { + $request = new Request(new Http('')); + + $data = [ + 1, 2, 3, + 'a' => 'b', + 'b' => [4, 5], + ]; + + $request->setData('abc', \json_encode($data) . ','); + self::assertEquals([], $request->getDataJson('abc')); + } + + /** + * @testdox List data can be read from the request + * @covers phpOMS\Message\Http\Request + */ public function testDataList() : void { $request = new Request(new Http('')); @@ -124,9 +260,23 @@ class RequestTest extends \PHPUnit\Framework\TestCase $request->setData('abc', \implode(',', $data)); self::assertEquals($data, $request->getDataList('abc')); + } + + /** + * @testdox None-existing list data reads return empty data + * @covers phpOMS\Message\Http\Request + */ + public function testEmptyDataList() : void + { + $request = new Request(new Http('')); + self::assertEquals([], $request->getDataList('def')); } + /** + * @testdox Request data can be read with pattern matching + * @covers phpOMS\Message\Http\Request + */ public function testDataLike() : void { $request = new Request(new Http('')); @@ -136,19 +286,52 @@ class RequestTest extends \PHPUnit\Framework\TestCase $request->setData('abcde', $data); self::assertEquals(['abcde' => $data], $request->getLike('.*')); self::assertEquals(['abcde' => $data], $request->getLike('[a-z]*')); + } + + /** + * @testdox In case of no pattern matches empty data is returned + * @covers phpOMS\Message\Http\Request + */ + public function testInvalidDataLikeMatch() : void + { + $request = new Request(new Http('')); + + $data = 'this is a test'; + + $request->setData('abcde', $data); self::assertEquals([], $request->getLike('[a-z]*\d')); self::assertEquals([], $request->getLike('abcdef')); } + /** + * @testdox A request with a path can be correctly casted to a string + * @covers phpOMS\Message\Http\Request + */ public function testToString() : void { $request = new Request(new Http('http://www.google.com/test/path')); self::assertEquals('http://www.google.com/test/path', $request->__toString()); + } + + /** + * @testdox A request with a path and manually added data can be correctly casted to a string + * @covers phpOMS\Message\Http\Request + */ + public function testToStringData() : void + { + $request = new Request(new Http('http://www.google.com/test/path')); $request->setData('test', 'data'); $request->setData('test2', 3); self::assertEquals('http://www.google.com/test/path?test=data&test2=3', $request->__toString()); + } + /** + * @testdox A request with a path, query parameters and manually added data can be correctly casted to a string + * @covers phpOMS\Message\Http\Request + */ + public function testToStringGetData() : void + { $request = new Request(new Http('http://www.google.com/test/path?test=var')); self::assertEquals('http://www.google.com/test/path?test=var', $request->__toString()); @@ -157,6 +340,10 @@ class RequestTest extends \PHPUnit\Framework\TestCase self::assertEquals('http://www.google.com/test/path?test=var&test=data&test2=3', $request->__toString()); } + /** + * @testdox A rest request can be made from a request and the result can be read + * @covers phpOMS\Message\Http\Request + */ public function testRestRequest() : void { $request = new Request(new Http('https://raw.githubusercontent.com/Orange-Management/Orange-Management/develop/LICENSE.txt')); @@ -168,6 +355,10 @@ class RequestTest extends \PHPUnit\Framework\TestCase ); } + /** + * @testdox A invalid https port throws a OutOfRangeException + * @covers phpOMS\Message\Http\Request + */ public function testInvalidHttpsPort() : void { self::expectException(\OutOfRangeException::class); @@ -176,6 +367,10 @@ class RequestTest extends \PHPUnit\Framework\TestCase $request->isHttps(-1); } + /** + * @testdox A Invalid route verb throws a Exception + * @covers phpOMS\Message\Http\Request + */ public function testInvalidRouteVerb() : void { self::expectException(\Exception::class); diff --git a/tests/Message/Http/ResponseTest.php b/tests/Message/Http/ResponseTest.php index 7825d263c..0be8e2925 100644 --- a/tests/Message/Http/ResponseTest.php +++ b/tests/Message/Http/ResponseTest.php @@ -18,33 +18,70 @@ use phpOMS\Message\Http\Response; use phpOMS\System\MimeType; /** + * @testdox phpOMS\tests\Message\Http\ResponseTest: Response wrapper for http responses + * * @internal */ class ResponseTest extends \PHPUnit\Framework\TestCase { + protected Response $response; + + protected function setUp() : void + { + $this->response = new Response(); + } + + /** + * @testdox The response has the expected default values after initialization + * @covers phpOMS\Message\Http\Response + */ public function testDefault() : void { - $response = new Response(); - self::assertEquals('', $response->getBody()); - self::assertEquals('', $response->render()); - self::assertEquals([], $response->toArray()); - self::assertInstanceOf('\phpOMS\Localization\Localization', $response->getHeader()->getL11n()); - self::assertInstanceOf('\phpOMS\Message\Http\Header', $response->getHeader()); + self::assertEquals('', $this->response->getBody()); + self::assertEquals('', $this->response->render()); + self::assertEquals([], $this->response->toArray()); + self::assertInstanceOf('\phpOMS\Localization\Localization', $this->response->getHeader()->getL11n()); + self::assertInstanceOf('\phpOMS\Message\Http\Header', $this->response->getHeader()); } - public function testSetGet() : void + /** + * @testdox Response data can be set and retruned + * @covers phpOMS\Message\Http\Response + */ + public function testResponseInputOutput() : void { - $response = new Response(); - - $response->setResponse(['a' => 1]); - self::assertTrue($response->remove('a')); - self::assertFalse($response->remove('a')); + $this->response->setResponse(['a' => 1]); + self::assertEquals(1, $this->response->get('a')); } - public function testWithData() : void + /** + * @testdox Response data can be removed + * @covers phpOMS\Message\Http\Response + */ + public function testRemove() : void { - $response = new Response(); + $this->response->setResponse(['a' => 1]); + self::assertTrue($this->response->remove('a')); + } + /** + * @testdox None-existing response data cannot be removed + * @covers phpOMS\Message\Http\Response + */ + public function testInvalidRemove() : void + { + $this->response->setResponse(['a' => 1]); + $this->response->remove('a'); + + self::assertFalse($this->response->remove('a')); + } + + /** + * @testdox Response data can be turned into an array + * @covers phpOMS\Message\Http\Response + */ + public function testToArray() : void + { $data = [ ['view_string'], [1, 2, 3, 'a', 'b', [4, 5]], @@ -55,50 +92,102 @@ class ResponseTest extends \PHPUnit\Framework\TestCase 'json_string', ]; - $response->set('view', new class() extends \phpOMS\Views\View { + $this->response->set('view', new class() extends \phpOMS\Views\View { public function toArray() : array { return ['view_string']; } }); - $response->set('array', $data[1]); - $response->set('string', $data[2]); - $response->set('int', $data[3]); - $response->set('bool', $data[4]); - $response->set('float', $data[5]); - $response->set('jsonSerializable', new class() implements \JsonSerializable { + $this->response->set('array', $data[1]); + $this->response->set('string', $data[2]); + $this->response->set('int', $data[3]); + $this->response->set('bool', $data[4]); + $this->response->set('float', $data[5]); + $this->response->set('jsonSerializable', new class() implements \JsonSerializable { public function jsonSerialize() { return 'json_string'; } }); - $response->set('null', null); + $this->response->set('null', null); - self::assertEquals($data, $response->toArray()); - - $response->getHeader()->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true); - self::assertEquals(\json_encode($data), $response->render()); + self::assertEquals($data, $this->response->toArray()); } + /** + * @testdox A response with json as content-type is automatically rendered as json data + * @covers phpOMS\Message\Http\Response + */ + public function testJsonRender() : void + { + $data = [ + ['view_string'], + [1, 2, 3, 'a', 'b', [4, 5]], + 'stringVal', + 6, + false, + 1.13, + 'json_string', + ]; + + $this->response->set('view', new class() extends \phpOMS\Views\View { + public function toArray() : array + { + return ['view_string']; + } + }); + $this->response->set('array', $data[1]); + $this->response->set('string', $data[2]); + $this->response->set('int', $data[3]); + $this->response->set('bool', $data[4]); + $this->response->set('float', $data[5]); + $this->response->set('jsonSerializable', new class() implements \JsonSerializable { + public function jsonSerialize() + { + return 'json_string'; + } + }); + $this->response->set('null', null); + + $this->response->getHeader()->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true); + self::assertEquals(\json_encode($data), $this->response->render()); + } + + /** + * @testdox A response can be forced to minimize the content by removing newlines and whitespaces + * @covers phpOMS\Message\Http\Response + */ public function testMinimizedRender() : void { - $response = new Response(); - $response->set('view', new class() extends \phpOMS\Views\View { + $this->response->set('view', new class() extends \phpOMS\Views\View { public function render(...$data) : string { return " view_string with
text
that has \n whitespaces and \n\nnew lines\n "; } }); - $response->getHeader()->set('Content-Type', MimeType::M_HTML . '; charset=utf-8', true); - self::assertEquals('view_string with
text
that has whitespaces and new lines', $response->render(true)); + $this->response->getHeader()->set('Content-Type', MimeType::M_HTML . '; charset=utf-8', true); + self::assertEquals('view_string with
text
that has whitespaces and new lines', $this->response->render(true)); } - public function testInvalidResponseData() : void + /** + * @testdox Invalid response data results in an empty array + * @covers phpOMS\Message\Http\Response + */ + public function testInvalidResponseDataToArray() : void { - $response = new Response(); - $response->set('invalid', new class() {}); - self::assertEquals([], $response->toArray()); + $this->response->set('invalid', new class() {}); + self::assertEquals([], $this->response->toArray()); + } + + /** + * @testdox Invalid response data results in an empty render + * @covers phpOMS\Message\Http\Response + */ + public function testInvalidResponseDataRender() : void + { + $this->response->set('invalid', new class() {}); + self::assertEquals('', $this->response->render()); } } diff --git a/tests/Message/Http/RestTest.php b/tests/Message/Http/RestTest.php index dadc58945..a524b8dc3 100644 --- a/tests/Message/Http/RestTest.php +++ b/tests/Message/Http/RestTest.php @@ -20,10 +20,16 @@ use phpOMS\Message\Http\Rest; use phpOMS\Uri\Http; /** + * @testdox phpOMS\tests\Message\Http\RestTest: Rest request wrapper + * * @internal */ class RestTest extends \PHPUnit\Framework\TestCase { + /** + * @testdox A get request successfully returns the expected result + * @covers phpOMS\Message\Http\Rest + */ public function testRequest() : void { $request = new Request(new Http('https://raw.githubusercontent.com/Orange-Management/Orange-Management/develop/LICENSE.txt')); @@ -35,6 +41,10 @@ class RestTest extends \PHPUnit\Framework\TestCase ); } + /** + * @testdox A post request with data successfully returns the expected result + * @covers phpOMS\Message\Http\Rest + */ public function testPost() : void { $request = new Request(new Http('http://httpbin.org/post')); @@ -43,6 +53,10 @@ class RestTest extends \PHPUnit\Framework\TestCase self::assertEquals('abc', REST::request($request)->getJsonData()['form']['pdata']); } + /** + * @testdox A put request with data successfully returns the expected result + * @covers phpOMS\Message\Http\Rest + */ public function testPut() : void { $request = new Request(new Http('http://httpbin.org/put')); @@ -51,6 +65,10 @@ class RestTest extends \PHPUnit\Framework\TestCase self::assertEquals('abc', REST::request($request)->getJsonData()['form']['pdata']); } + /** + * @testdox A delete request with data successfully returns the expected result + * @covers phpOMS\Message\Http\Rest + */ public function testDelete() : void { $request = new Request(new Http('http://httpbin.org/delete')); @@ -59,6 +77,10 @@ class RestTest extends \PHPUnit\Framework\TestCase self::assertEquals('abc', REST::request($request)->getJsonData()['form']['ddata']); } + /** + * @testdox A get request with data successfully returns the expected result + * @covers phpOMS\Message\Http\Rest + */ public function testGet() : void { $request = new Request(new Http('http://httpbin.org/get')); diff --git a/tests/Message/ResponseAbstractTest.php b/tests/Message/ResponseAbstractTest.php index 308ca4c52..14f978b98 100644 --- a/tests/Message/ResponseAbstractTest.php +++ b/tests/Message/ResponseAbstractTest.php @@ -19,6 +19,8 @@ require_once __DIR__ . '/../Autoloader.php'; use phpOMS\Message\ResponseAbstract; /** + * @testdox phpOMS\tests\Message\ResponseAbstractTest: Abstract response + * * @internal */ class ResponseAbstractTest extends \PHPUnit\Framework\TestCase @@ -41,16 +43,31 @@ class ResponseAbstractTest extends \PHPUnit\Framework\TestCase }; } + /** + * @testdox The response has the expected default values after initialization + * @covers phpOMS\Message\ResponseAbstract + */ public function testDefault() : void { self::assertNull($this->response->get('asdf')); self::assertEquals('', $this->response->getBody()); } - public function testSetGet() : void + /** + * @testdox The response can be json serialized + * @covers phpOMS\Message\ResponseAbstract + */ + public function testJsonSerialize() : void { self::assertEquals([1], $this->response->jsonSerialize()); + } + /** + * @testdox Data can be set and returned for the response + * @covers phpOMS\Message\ResponseAbstract + */ + public function testDataInputOutput() : void + { $this->response->set('asdf', false); self::assertFalse($this->response->get('asdf')); } diff --git a/tests/Model/Html/HeadTest.php b/tests/Model/Html/HeadTest.php index 3a7e2b354..180ab447f 100644 --- a/tests/Model/Html/HeadTest.php +++ b/tests/Model/Html/HeadTest.php @@ -18,44 +18,88 @@ use phpOMS\Asset\AssetType; use phpOMS\Model\Html\Head; /** + * @testdox phpOMS\tests\Model\Html\HeadTest: Html head + * * @internal */ class HeadTest extends \PHPUnit\Framework\TestCase { - public function testDefault() : void + protected Head $head; + + protected function setUp() : void { - $head = new Head(); - self::assertInstanceOf('\phpOMS\Model\Html\Meta', $head->getMeta()); - self::assertEquals('', $head->getTitle()); - self::assertEquals('en', $head->getLanguage()); - self::assertEquals([], $head->getStyleAll()); - self::assertEquals([], $head->getScriptAll()); - self::assertEquals('', $head->renderStyle()); - self::assertEquals('', $head->renderScript()); - self::assertEquals('', $head->renderAssets()); - self::assertEquals('', $head->renderAssetsLate()); - self::assertEquals('', $head->render()); + $this->head = new Head(); } - public function testSetGet() : void + /** + * @testdox The head has the expected default values after initialization + * @covers phpOMS\Model\Html\Head + */ + public function testDefault() : void { - $head = new Head(); + self::assertInstanceOf('\phpOMS\Model\Html\Meta', $this->head->getMeta()); + self::assertEquals('', $this->head->getTitle()); + self::assertEquals('en', $this->head->getLanguage()); + self::assertEquals([], $this->head->getStyleAll()); + self::assertEquals([], $this->head->getScriptAll()); + self::assertEquals('', $this->head->renderStyle()); + self::assertEquals('', $this->head->renderScript()); + self::assertEquals('', $this->head->renderAssets()); + self::assertEquals('', $this->head->renderAssetsLate()); + self::assertEquals('', $this->head->render()); + } - $head->setTitle('my title'); - self::assertEquals('my title', $head->getTitle()); + /** + * @testdox The title can be set and returned + * @covers phpOMS\Model\Html\Head + */ + public function testTitleInputOutput() : void + { + $this->head->setTitle('my title'); + self::assertEquals('my title', $this->head->getTitle()); + } - $head->addAsset(AssetType::CSS, '/path/styles.css'); - $head->addAsset(AssetType::JS, '/path/logic.js'); - $head->addAsset(AssetType::JSLATE, '/path/late.js'); + /** + * @testdox The style can be set and returned + * @covers phpOMS\Model\Html\Head + */ + public function testStyleInputOutput() : void + { + $this->head->setStyle('base', '#test .class { color: #000; }'); + self::assertEquals(['base' => '#test .class { color: #000; }'], $this->head->getStyleAll()); + } - $head->setStyle('base', '#test .class { color: #000; }'); - self::assertEquals(['base' => '#test .class { color: #000; }'], $head->getStyleAll()); + /** + * @testdox The script can be set and returned + * @covers phpOMS\Model\Html\Head + */ + public function testScriptInputOutput() : void + { + $this->head->setScript('key', 'console.log("msg");'); + self::assertEquals(['key' => 'console.log("msg");'], $this->head->getScriptAll()); + } - $head->setScript('key', 'console.log("msg");'); - self::assertEquals(['key' => 'console.log("msg");'], $head->getScriptAll()); + /** + * @testdox The language can be set and returned + * @covers phpOMS\Model\Html\Head + */ + public function testLanguageInputOutput() : void + { + $this->head->setLanguage('en'); + self::assertEquals('en', $this->head->getLanguage()); + } - $head->setLanguage('en'); - self::assertEquals('en', $head->getLanguage()); + /** + * @testdox The assets can be set and rendered + * @covers phpOMS\Model\Html\Head + */ + public function testAssetRender() : void + { + $this->head->addAsset(AssetType::CSS, '/path/styles.css'); + $this->head->addAsset(AssetType::JS, '/path/logic.js'); + + $this->head->setStyle('base', '#test .class { color: #000; }'); + $this->head->setScript('key', 'console.log("msg");'); self::assertEquals( '' @@ -63,20 +107,37 @@ class HeadTest extends \PHPUnit\Framework\TestCase . '' . '' . '', - $head->render() + $this->head->render() ); - - self::assertEquals('', $head->renderAssetsLate()); } - public function testAssetWithAttribute() : void + /** + * @testdox The assets can be set and rendered at the end of the document + * @covers phpOMS\Model\Html\Head + */ + public function testAssetLateRender() : void { - $head = new Head(); + $this->head->addAsset(AssetType::JSLATE, '/path/late.js'); + self::assertEquals('', $this->head->renderAssetsLate()); + } - $head->addAsset(AssetType::JSLATE, '/path/late.js', ['testkey' => 'testvalue']); - self::assertEquals('', $head->renderAssetsLate()); + /** + * @testdox The assets can be set and rendered with attributes + * @covers phpOMS\Model\Html\Head + */ + public function testAssetRenderWithAttribute() : void + { + $this->head->addAsset(AssetType::JS, '/path/late.js', ['testkey' => 'testvalue']); + self::assertEquals('', $this->head->renderAssets()); + } - $head->addAsset(AssetType::JS, '/path/late.js', ['testkey' => 'testvalue']); - self::assertEquals('', $head->renderAssets()); + /** + * @testdox The assets can be set and rendered at the end of the document with attributes + * @covers phpOMS\Model\Html\Head + */ + public function testAssetLateRenderWithAttribute() : void + { + $this->head->addAsset(AssetType::JSLATE, '/path/late.js', ['testkey' => 'testvalue']); + self::assertEquals('', $this->head->renderAssetsLate()); } } diff --git a/tests/Model/Html/MetaTest.php b/tests/Model/Html/MetaTest.php index eb78ad691..8f6b6a8a7 100644 --- a/tests/Model/Html/MetaTest.php +++ b/tests/Model/Html/MetaTest.php @@ -17,39 +17,118 @@ namespace phpOMS\tests\Model\Html; use phpOMS\Model\Html\Meta; /** + * @testdox phpOMS\tests\Model\Html\MetaTest: Html meta data + * * @internal */ class MetaTest extends \PHPUnit\Framework\TestCase { - public function testDefault() : void + protected Meta $meta; + + protected function setUp() : void { - $meta = new Meta(); - self::assertEquals('', $meta->getDescription()); - self::assertEquals('', $meta->getCharset()); - self::assertEquals('', $meta->getAuthor()); - self::assertEquals([], $meta->getKeywords()); - self::assertEquals('', $meta->render()); + $this->meta = new Meta(); } - public function testGetSet() : void + /** + * @testdox The meta data has the expected default values after initialization + * @covers phpOMS\Model\Html\Meta + */ + public function testDefault() : void { - $meta = new Meta(); + self::assertEquals('', $this->meta->getDescription()); + self::assertEquals('', $this->meta->getCharset()); + self::assertEquals('', $this->meta->getAuthor()); + self::assertEquals('', $this->meta->getName('')); + self::assertEquals('', $this->meta->getProperty('')); + self::assertEquals('', $this->meta->getItemprop('')); + self::assertEquals([], $this->meta->getKeywords()); + self::assertEquals('', $this->meta->render()); + } - $meta->addKeyword('orange'); - self::assertEquals(['orange'], $meta->getKeywords()); + /** + * @testdox A keyword can be added and returned + * @covers phpOMS\Model\Html\Meta + */ + public function testKeywordInputOutput() : void + { + $this->meta->addKeyword('orange'); + self::assertEquals(['orange'], $this->meta->getKeywords()); + } - $meta->setAuthor('oms'); - self::assertEquals('oms', $meta->getAuthor()); + /** + * @testdox The author can be set and returned + * @covers phpOMS\Model\Html\Meta + */ + public function testAuthorInputOutput() : void + { + $this->meta->setAuthor('oms'); + self::assertEquals('oms', $this->meta->getAuthor()); + } - $meta->setCharset('utf-8'); - self::assertEquals('utf-8', $meta->getCharset()); + /** + * @testdox The charset can be set and returned + * @covers phpOMS\Model\Html\Meta + */ + public function testCharsetInputOutput() : void + { + $this->meta->setCharset('utf-8'); + self::assertEquals('utf-8', $this->meta->getCharset()); + } - $meta->setDescription('some description'); - self::assertEquals('some description', $meta->getDescription()); + /** + * @testdox The description can be set and returned + * @covers phpOMS\Model\Html\Meta + */ + public function testDescriptionInputOutput() : void + { + $this->meta->setDescription('some description'); + self::assertEquals('some description', $this->meta->getDescription()); + } - $meta->setProperty('og:title', 'TestProperty'); - $meta->setItemprop('title', 'TestItemprop'); - $meta->setName('title', 'TestName'); + /** + * @testdox A property can be set and returned + * @covers phpOMS\Model\Html\Meta + */ + public function testPropertyInputOutput() : void + { + $this->meta->setProperty('property', 'test property'); + self::assertEquals('test property', $this->meta->getProperty('property')); + } + + /** + * @testdox A itemprop can be set and returned + * @covers phpOMS\Model\Html\Meta + */ + public function testItempropInputOutput() : void + { + $this->meta->setItemprop('itemprop', 'test itemprop'); + self::assertEquals('test itemprop', $this->meta->getItemprop('itemprop')); + } + + /** + * @testdox A name can be set and returned + * @covers phpOMS\Model\Html\Meta + */ + public function testNameInputOutput() : void + { + $this->meta->setName('title', 'test title'); + self::assertEquals('test title', $this->meta->getName('title')); + } + + /** + * @testdox The meta data can be rendered + * @covers phpOMS\Model\Html\Meta + */ + public function testRender() : void + { + $this->meta->addKeyword('orange'); + $this->meta->setAuthor('oms'); + $this->meta->setCharset('utf-8'); + $this->meta->setDescription('some description'); + $this->meta->setProperty('og:title', 'TestProperty'); + $this->meta->setItemprop('title', 'TestItemprop'); + $this->meta->setName('title', 'TestName'); self::assertEquals( '' @@ -60,7 +139,7 @@ class MetaTest extends \PHPUnit\Framework\TestCase . '' . '' . '', - $meta->render() + $this->meta->render() ); } } diff --git a/tests/Module/InfoManagerTest.php b/tests/Module/InfoManagerTest.php index 2bb646dcd..aa4b7a04a 100644 --- a/tests/Module/InfoManagerTest.php +++ b/tests/Module/InfoManagerTest.php @@ -19,11 +19,17 @@ require_once __DIR__ . '/../Autoloader.php'; use phpOMS\Module\InfoManager; /** + * @testdox phpOMS\tests\Module\InfoManagerTest: Module info file manager + * * @internal */ class InfoManagerTest extends \PHPUnit\Framework\TestCase { - public function testInfoManager() : void + /** + * @testdox A info file can be correctly loaded + * @covers phpOMS\Module\InfoManager + */ + public function testLoad() : void { $info = new InfoManager(__DIR__ . '/info-test.json'); $info->load(); @@ -41,6 +47,18 @@ class InfoManagerTest extends \PHPUnit\Framework\TestCase self::assertEquals($jarray['version'], $info->getVersion()); self::assertEquals($jarray['load'], $info->getLoad()); self::assertEquals(__DIR__ . '/info-test.json', $info->getPath()); + } + + /** + * @testdox A info file can be modified + * @covers phpOMS\Module\InfoManager + */ + public function testChange() : void + { + $jarray = \json_decode(\file_get_contents(__DIR__ . '/info-test.json'), true); + + $info = new InfoManager(__DIR__ . '/info-test.json'); + $info->load(); $info->set('/name/internal', 'ABC'); self::assertEquals('ABC', $info->getInternalName()); @@ -54,6 +72,10 @@ class InfoManagerTest extends \PHPUnit\Framework\TestCase $info->update(); } + /** + * @testdox A invalid info file path load throws a PathException + * @covers phpOMS\Module\InfoManager + */ public function testInvalidPathLoad() : void { self::expectException(\phpOMS\System\File\PathException::class); @@ -62,6 +84,10 @@ class InfoManagerTest extends \PHPUnit\Framework\TestCase $info->load(); } + /** + * @testdox A invalid info file path update throws a PathException + * @covers phpOMS\Module\InfoManager + */ public function testInvalidPathUpdate() : void { self::expectException(\phpOMS\System\File\PathException::class); @@ -70,6 +96,10 @@ class InfoManagerTest extends \PHPUnit\Framework\TestCase $info->update(); } + /** + * @testdox A invalid change data throws a InvalidArgumentException + * @covers phpOMS\Module\InfoManager + */ public function testInvalidDataSet() : void { self::expectException(\InvalidArgumentException::class); diff --git a/tests/Module/ModuleAbstractTest.php b/tests/Module/ModuleAbstractTest.php index d02484b7a..53cb76d5c 100644 --- a/tests/Module/ModuleAbstractTest.php +++ b/tests/Module/ModuleAbstractTest.php @@ -22,6 +22,8 @@ use phpOMS\Module\ModuleAbstract; use phpOMS\Uri\Http; /** + * @testdox phpOMS\tests\Module\ModuleAbstractTest: Abstract module + * * @internal */ class ModuleAbstractTest extends \PHPUnit\Framework\TestCase @@ -48,14 +50,38 @@ class ModuleAbstractTest extends \PHPUnit\Framework\TestCase }; } - public function testModuleAbstract() : void + /** + * @testdox The constant values of the abstract module are overwritten by the extension + * @covers phpOMS\Module\ModuleManager + */ + public function testConstants() : void { - self::assertEquals([1, 2], $this->module->getDependencies()); self::assertEquals(2, $this->module::MODULE_ID); self::assertEquals('1.2.3', $this->module::MODULE_VERSION); + } + + /** + * @testdox The dependencies of the module can be returned + * @covers phpOMS\Module\ModuleManager + */ + public function testDependencies() : void + { + self::assertEquals([1, 2], $this->module->getDependencies()); + } + + /** + * @testdox A invalid language or theme returns in an empty localization/language dataset + * @covers phpOMS\Module\ModuleManager + */ + public function testInvalidLocalization() : void + { self::assertEquals([], $this->module::getLocalization('invalid', 'invalid')); } + /** + * @testdox The module can automatically generate a json response based on provided data for the frontend + * @covers phpOMS\Module\ModuleManager + */ public function testFillJson() : void { $request = new Request(new Http('')); @@ -74,6 +100,10 @@ class ModuleAbstractTest extends \PHPUnit\Framework\TestCase ); } + /** + * @testdox The module can automatically generate a json response based on provided data + * @covers phpOMS\Module\ModuleManager + */ public function testFillJsonRaw() : void { $request = new Request(new Http('')); diff --git a/tests/Module/ModuleManagerTest.php b/tests/Module/ModuleManagerTest.php index 07044bce0..144ebcbda 100644 --- a/tests/Module/ModuleManagerTest.php +++ b/tests/Module/ModuleManagerTest.php @@ -22,69 +22,111 @@ use phpOMS\Router\WebRouter; require_once __DIR__ . '/../Autoloader.php'; /** + * @testdox phpOMS\tests\Module\ModuleManagerTest: Manager for the module system + * * @internal */ class ModuleManagerTest extends \PHPUnit\Framework\TestCase { - protected $app = null; + protected ApplicationAbstract $app; + protected ModuleManager $moduleManager; protected function setUp() : void { $this->app = new class() extends ApplicationAbstract { protected string $appName = 'Api'; }; $this->app->appName = 'Api'; $this->app->dbPool = $GLOBALS['dbpool']; - $this->app->dispatcher = new Dispatcher($this->app); - } - - public function testAttributes() : void - { - $moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../Modules'); - self::assertInstanceOf('\phpOMS\Module\ModuleManager', $moduleManager); - - self::assertObjectHasAttribute('running', $moduleManager); - self::assertObjectHasAttribute('installed', $moduleManager); - self::assertObjectHasAttribute('active', $moduleManager); - self::assertObjectHasAttribute('all', $moduleManager); - self::assertObjectHasAttribute('uriLoad', $moduleManager); - } - - public function testUnknownModuleInit() : void - { - $moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../Modules'); - $moduleManager->initModule('doesNotExist'); - self::assertInstanceOf('\phpOMS\Module\NullModule', $moduleManager->get('doesNotExist')); - } - - public function testUnknownModuleGet() : void - { - $moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../Modules'); - self::assertInstanceOf('\phpOMS\Module\NullModule', $moduleManager->get('doesNotExist2')); - } - - public function testUnknwonModuleModification() : void - { - $moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../Modules'); - - self::assertFalse($moduleManager->activate('randomErrorTest1')); - self::assertFalse($moduleManager->deactivate('randomErrorTest1')); - } - - public function testGetSet() : void - { $this->app->router = new WebRouter(); $this->app->dispatcher = new Dispatcher($this->app); - $moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../Modules'); + $this->moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../Modules'); + } - $active = $moduleManager->getActiveModules(); - $all = $moduleManager->getAllModules(); - $installed = $moduleManager->getInstalledModules(); + /** + * @testdox The module manager has the expected attributes + * @covers phpOMS\Module\ModuleManager + */ + public function testAttributes() : void + { + self::assertInstanceOf('\phpOMS\Module\ModuleManager', $this->moduleManager); + + self::assertObjectHasAttribute('running', $this->moduleManager); + self::assertObjectHasAttribute('installed', $this->moduleManager); + self::assertObjectHasAttribute('active', $this->moduleManager); + self::assertObjectHasAttribute('all', $this->moduleManager); + self::assertObjectHasAttribute('uriLoad', $this->moduleManager); + } + + /** + * @testdox Invalid module initializations returns a null module + * @covers phpOMS\Module\ModuleManager + */ + public function testUnknownModuleInit() : void + { + $this->moduleManager->initModule('doesNotExist'); + self::assertInstanceOf('\phpOMS\Module\NullModule', $this->moduleManager->get('doesNotExist')); + } + + /** + * @testdox Unknown modules return a null module + * @covers phpOMS\Module\ModuleManager + */ + public function testUnknownModuleGet() : void + { + self::assertInstanceOf('\phpOMS\Module\NullModule', $this->moduleManager->get('doesNotExist2')); + } + + /** + * @testdox Unknown modules cannot get activested, deactivated + * @covers phpOMS\Module\ModuleManager + */ + public function testUnknwonModuleStatusChange() : void + { + self::assertFalse($this->moduleManager->activate('randomErrorTest1')); + self::assertFalse($this->moduleManager->deactivate('randomErrorTest1')); + } + + /** + * @testdox Active modules can be returned + * @covers phpOMS\Module\ModuleManager + */ + public function testActiveModules() : void + { + $active = $this->moduleManager->getActiveModules(); self::assertNotEmpty($active); - self::assertNotEmpty($all); - self::assertNotEmpty($installed); - - self::assertInstanceOf('\phpOMS\Module\ModuleAbstract', $moduleManager->get('Admin')); - self::assertInstanceOf('\Modules\Admin\Controller\ApiController', $moduleManager->get('Admin')); } + + /** + * @testdox All available modules can be returned + * @covers phpOMS\Module\ModuleManager + */ + public function testAllModules() : void + { + $all = $this->moduleManager->getAllModules(); + + self::assertNotEmpty($all); + } + + /** + * @testdox Installed modules can be returned + * @covers phpOMS\Module\ModuleManager + */ + public function testInstalledModules() : void + { + $installed = $this->moduleManager->getInstalledModules(); + + self::assertNotEmpty($installed); + } + + /** + * @testdox The valid module can be returned + * @covers phpOMS\Module\ModuleManager + */ + public function testAdminModule() : void + { + self::assertInstanceOf('\phpOMS\Module\ModuleAbstract', $this->moduleManager->get('Admin')); + self::assertInstanceOf('\Modules\Admin\Controller\ApiController', $this->moduleManager->get('Admin')); + } + } diff --git a/tests/Module/PackageManagerTest.php b/tests/Module/PackageManagerTest.php index 1d7c35b85..10191b219 100644 --- a/tests/Module/PackageManagerTest.php +++ b/tests/Module/PackageManagerTest.php @@ -17,11 +17,12 @@ namespace phpOMS\tests\Module; require_once __DIR__ . '/../Autoloader.php'; use phpOMS\Module\PackageManager; -use phpOMS\System\File\Ftp\File; use phpOMS\System\File\Local\Directory; use phpOMS\Utils\IO\Zip\Zip; /** + * @testdox phpOMS\tests\Module\PackageManagerTest: Manager for install/update packages + * * @internal */ class PackageManagerTest extends \PHPUnit\Framework\TestCase @@ -80,6 +81,10 @@ class PackageManagerTest extends \PHPUnit\Framework\TestCase ); } + /** + * @testdox A package can be installed + * @covers phpOMS\Module\PackageManager + */ public function testPackageValidInstall() : void { if (\file_exists(__DIR__ . '/dummyModule')) { @@ -133,6 +138,10 @@ class PackageManagerTest extends \PHPUnit\Framework\TestCase } } + /** + * @testdox A package which didn't get extracted cannot be loaded and throws a PathException + * @covers phpOMS\Module\PackageManager + */ public function testNotExtractedLoad() : void { self::expectException(\phpOMS\System\File\PathException::class); @@ -146,6 +155,10 @@ class PackageManagerTest extends \PHPUnit\Framework\TestCase $package->load(); } + /** + * @testdox A invalid package cannot be installed and throws a Exception + * @covers phpOMS\Module\PackageManager + */ public function testInvalidInstall() : void { self::expectException(\Exception::class); @@ -159,6 +172,10 @@ class PackageManagerTest extends \PHPUnit\Framework\TestCase $package->install(); } + /** + * @testdox A invalid package key doesn't validate the package + * @covers phpOMS\Module\PackageManager + */ public function testPackageInvalidKey() : void { $package = new PackageManager( @@ -172,6 +189,10 @@ class PackageManagerTest extends \PHPUnit\Framework\TestCase self::assertFalse($package->isValid()); } + /** + * @testdox A invalid package content doesn't validate the package + * @covers phpOMS\Module\PackageManager + */ public function testPackageInvalidContent() : void { $package = new PackageManager( @@ -186,6 +207,10 @@ class PackageManagerTest extends \PHPUnit\Framework\TestCase self::assertFalse($package->isValid()); } + /** + * @testdox The temporarily extracted package can be cleaned up + * @covers phpOMS\Module\PackageManager + */ public function testCleanup() : void { $package = new PackageManager( diff --git a/tests/Router/RouteVerbTest.php b/tests/Router/RouteVerbTest.php index a046a527d..5606672f2 100644 --- a/tests/Router/RouteVerbTest.php +++ b/tests/Router/RouteVerbTest.php @@ -35,6 +35,9 @@ class RouteVerbTest extends \PHPUnit\Framework\TestCase self::assertTrue(\defined('phpOMS\Router\RouteVerb::ANY')); } + /** + * @coversNothing + */ public function testEnumUnique() : void { $values = RouteVerb::getConstants(); diff --git a/tests/Router/SocketRouterTest.php b/tests/Router/SocketRouterTest.php index e2d65428b..aa54d1344 100644 --- a/tests/Router/SocketRouterTest.php +++ b/tests/Router/SocketRouterTest.php @@ -24,65 +24,85 @@ use phpOMS\Router\SocketRouter; require_once __DIR__ . '/../Autoloader.php'; /** + * @testdox phpOMS\tests\Router\SocketRouterTest: Router for socket requests + * * @internal */ class SocketRouterTest extends \PHPUnit\Framework\TestCase { - public function testAttributes() : void + protected SocketRouter $router; + + protected function setUp() : void { - $router = new SocketRouter(); - self::assertInstanceOf('\phpOMS\Router\SocketRouter', $router); - self::assertObjectHasAttribute('routes', $router); + $this->router = new SocketRouter(); } + /** + * @testdox The route result for an empty request is empty + * @covers phpOMS\Router\SocketRouter + */ public function testDefault() : void { - $router = new SocketRouter(); - self::assertEmpty($router->route('some_test route')); + self::assertEmpty($this->router->route('some_test route')); } + /** + * @testdox A none-existing routing file cannot be imported + * @covers phpOMS\Router\SocketRouter + */ public function testInvalidRoutingFile() : void { - $router = new SocketRouter(); - self::assertFalse($router->importFromFile(__Dir__ . '/invalidFile.php')); + self::assertFalse($this->router->importFromFile(__Dir__ . '/invalidFile.php')); } + /** + * @testdox A existing routing file can be imported + * @covers phpOMS\Router\SocketRouter + */ public function testLoadingRoutesFromFile() : void { - $router = new SocketRouter(); - self::assertTrue($router->importFromFile(__Dir__ . '/socketRouterTestFile.php')); + self::assertTrue($this->router->importFromFile(__Dir__ . '/socketRouterTestFile.php')); } + /** + * @testdox A matching route returns the destinations + * @covers phpOMS\Router\SocketRouter + */ public function testRouteMatching() : void { - $router = new SocketRouter(); - self::assertTrue($router->importFromFile(__Dir__ . '/socketRouterTestFile.php')); + self::assertTrue($this->router->importFromFile(__Dir__ . '/socketRouterTestFile.php')); self::assertEquals( [['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']], - $router->route('backend_admin -settings=general -t 123') + $this->router->route('backend_admin -settings=general -t 123') ); } + /** + * @testdox Routes can be added dynamically + * @covers phpOMS\Router\SocketRouter + */ public function testDynamicRouteAdding() : void { - $router = new SocketRouter(); self::assertNotEquals( [['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']], - $router->route('backends_admin -settings=general -t 123') + $this->router->route('backends_admin -settings=general -t 123') ); - $router->add('^.*backends_admin -settings=general.*$', 'Controller:test'); + $this->router->add('^.*backends_admin -settings=general.*$', 'Controller:test'); self::assertEquals( [['dest' => 'Controller:test']], - $router->route('backends_admin -settings=general -t 123') + $this->router->route('backends_admin -settings=general -t 123') ); } + /** + * @testdox Routes only match if the permissions match + * @covers phpOMS\Router\SocketRouter + */ public function testWithValidPermissions() : void { - $router = new SocketRouter(); - self::assertTrue($router->importFromFile(__Dir__ . '/socketRouterTestFilePermission.php')); + self::assertTrue($this->router->importFromFile(__Dir__ . '/socketRouterTestFilePermission.php')); $perm = new class( null, @@ -100,7 +120,7 @@ class SocketRouterTest extends \PHPUnit\Framework\TestCase self::assertEquals( [['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']], - $router->route('backend_admin -settings=general -t 123', + $this->router->route('backend_admin -settings=general -t 123', null, null, $account @@ -108,10 +128,13 @@ class SocketRouterTest extends \PHPUnit\Framework\TestCase ); } + /** + * @testdox Routes don't match if the permissions don't match + * @covers phpOMS\Router\SocketRouter + */ public function testWithInvalidPermissions() : void { - $router = new SocketRouter(); - self::assertTrue($router->importFromFile(__Dir__ . '/socketRouterTestFilePermission.php')); + self::assertTrue($this->router->importFromFile(__Dir__ . '/socketRouterTestFilePermission.php')); $perm2 = new class( null, @@ -153,7 +176,7 @@ class SocketRouterTest extends \PHPUnit\Framework\TestCase self::assertNotEquals( [['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']], - $router->route('backend_admin -settings=general -t 123', + $this->router->route('backend_admin -settings=general -t 123', null, null, $account2 diff --git a/tests/Router/WebRouterTest.php b/tests/Router/WebRouterTest.php index 1037a520a..c62f17845 100644 --- a/tests/Router/WebRouterTest.php +++ b/tests/Router/WebRouterTest.php @@ -27,93 +27,104 @@ use phpOMS\Uri\Http; require_once __DIR__ . '/../Autoloader.php'; /** + * @testdox phpOMS\tests\Router\WebRouterTest: Router for web requests + * * @internal */ class WebRouterTest extends \PHPUnit\Framework\TestCase { - public function testAttributes() : void + protected WebRouter $router; + + protected function setUp() : void { - $router = new WebRouter(); - self::assertInstanceOf('\phpOMS\Router\WebRouter', $router); - self::assertObjectHasAttribute('routes', $router); + $this->router = new WebRouter(); } + /** + * @testdox The route result for an empty request is empty + * @covers phpOMS\Router\WebRouter + */ public function testDefault() : void { - $router = new WebRouter(); self::assertEmpty( - $router->route( + $this->router->route( (new Request(new Http('')))->getUri()->getRoute() ) ); } + /** + * @testdox A none-existing routing file cannot be imported + * @covers phpOMS\Router\WebRouter + */ public function testInvalidRoutingFile() : void { - $router = new WebRouter(); - self::assertFalse($router->importFromFile(__Dir__ . '/invalidFile.php')); + self::assertFalse($this->router->importFromFile(__Dir__ . '/invalidFile.php')); } + /** + * @testdox A existing routing file can be imported + * @covers phpOMS\Router\WebRouter + */ public function testLoadingRoutesFromFile() : void { - $router = new WebRouter(); - self::assertTrue($router->importFromFile(__Dir__ . '/webRouterTestFile.php')); + self::assertTrue($this->router->importFromFile(__Dir__ . '/webRouterTestFile.php')); } + /** + * @testdox A matching route returns the destinations + * @covers phpOMS\Router\WebRouter + */ public function testRouteMatching() : void { - $router = new WebRouter(); - self::assertTrue($router->importFromFile(__Dir__ . '/webRouterTestFile.php')); + self::assertTrue($this->router->importFromFile(__Dir__ . '/webRouterTestFile.php')); self::assertEquals( [['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']], - $router->route( + $this->router->route( (new Request( new Http('http://test.com/backend/admin/settings/general/something?test') ))->getUri()->getRoute() ) ); - - self::assertNotEquals( - [['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']], - $router->route( - (new Request( - new Http('http://test.com/backend/admin/settings/general/something?test') - ))->getUri()->getRoute(), null, RouteVerb::PUT) - ); } + /** + * @testdox Invalid routing verbs don't match even if the route matches + * @covers phpOMS\Router\WebRouter + */ public function testRouteMissMatchingForInvalidVerbs() : void { - $router = new WebRouter(); - self::assertTrue($router->importFromFile(__Dir__ . '/webRouterTestFile.php')); + self::assertTrue($this->router->importFromFile(__Dir__ . '/webRouterTestFile.php')); self::assertNotEquals( [['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']], - $router->route( + $this->router->route( (new Request( new Http('http://test.com/backend/admin/settings/general/something?test') ))->getUri()->getRoute(), null, RouteVerb::PUT) ); } + /** + * @testdox Routes can be added dynamically + * @covers phpOMS\Router\WebRouter + */ public function testDynamicRouteAdding() : void { - $router = new WebRouter(); - self::assertNotEquals( [['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']], - $router->route( + $this->router->route( (new Request( new Http('http://test.com/backends/admin/settings/general/something?test') ))->getUri()->getRoute() ) ); - $router->add('^.*/backends/admin/settings/general.*$', 'Controller:test', RouteVerb::GET | RouteVerb::SET); + $this->router->add('^.*/backends/admin/settings/general.*$', 'Controller:test', RouteVerb::GET | RouteVerb::SET); self::assertEquals( [['dest' => 'Controller:test']], - $router->route( + $this->router->route( (new Request( new Http('http://test.com/backends/admin/settings/general/something?test') ))->getUri()->getRoute(), null, RouteVerb::ANY) @@ -121,7 +132,7 @@ class WebRouterTest extends \PHPUnit\Framework\TestCase self::assertEquals( [['dest' => 'Controller:test']], - $router->route( + $this->router->route( (new Request( new Http('http://test.com/backends/admin/settings/general/something?test') ))->getUri()->getRoute(), null, RouteVerb::SET) @@ -129,30 +140,42 @@ class WebRouterTest extends \PHPUnit\Framework\TestCase self::assertEquals( [['dest' => 'Controller:test']], - $router->route( + $this->router->route( (new Request( new Http('http://test.com/backends/admin/settings/general/something?test')))->getUri()->getRoute(), null, RouteVerb::GET) ); } + /** + * @testdox Routes which require a CSRF token can only match with a CSRF token + * @covers phpOMS\Router\WebRouter + */ public function testWithCSRF() : void { - $router = new WebRouter(); - self::assertTrue($router->importFromFile(__Dir__ . '/webRouteTestCsrf.php')); + self::assertTrue($this->router->importFromFile(__Dir__ . '/webRouteTestCsrf.php')); self::assertEquals( [['dest' => '\Modules\Admin\Controller:viewCsrf']], - $router->route( + $this->router->route( (new Request( new Http('http://test.com/backend/admin/settings/csrf/something?test') ))->getUri()->getRoute(), 'csrf_string' ) ); + } + + /** + * @testdox Routes which require a CSRF token don't match without a CSRF token + * @covers phpOMS\Router\WebRouter + */ + public function testWithoutCSRF() : void + { + self::assertTrue($this->router->importFromFile(__Dir__ . '/webRouteTestCsrf.php')); self::assertEquals( [], - $router->route( + $this->router->route( (new Request( new Http('http://test.com/backend/admin/settings/csrf/something?test') ))->getUri()->getRoute() @@ -160,10 +183,13 @@ class WebRouterTest extends \PHPUnit\Framework\TestCase ); } + /** + * @testdox Routes only match if the permissions match + * @covers phpOMS\Router\WebRouter + */ public function testWithValidPermissions() : void { - $router = new WebRouter(); - self::assertTrue($router->importFromFile(__Dir__ . '/webRouterTestFilePermission.php')); + self::assertTrue($this->router->importFromFile(__Dir__ . '/webRouterTestFilePermission.php')); $perm = new class( null, @@ -181,7 +207,7 @@ class WebRouterTest extends \PHPUnit\Framework\TestCase self::assertEquals( [['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']], - $router->route( + $this->router->route( (new Request(new Http('http://test.com/backend/admin/settings/general/something?test')))->getUri()->getRoute(), null, RouteVerb::GET, @@ -192,10 +218,13 @@ class WebRouterTest extends \PHPUnit\Framework\TestCase ); } + /** + * @testdox Routes don't match if the permissions don't match + * @covers phpOMS\Router\WebRouter + */ public function testWithInvalidPermissions() : void { - $router = new WebRouter(); - self::assertTrue($router->importFromFile(__Dir__ . '/webRouterTestFilePermission.php')); + self::assertTrue($this->router->importFromFile(__Dir__ . '/webRouterTestFilePermission.php')); $perm2 = new class( null, @@ -237,7 +266,7 @@ class WebRouterTest extends \PHPUnit\Framework\TestCase self::assertNotEquals( [['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']], - $router->route( + $this->router->route( (new Request(new Http('http://test.com/backend/admin/settings/general/something?test')))->getUri()->getRoute(), null, RouteVerb::GET, diff --git a/tests/Security/PhpCodeTest.php b/tests/Security/PhpCodeTest.php index 334db3259..d9348611a 100644 --- a/tests/Security/PhpCodeTest.php +++ b/tests/Security/PhpCodeTest.php @@ -19,10 +19,16 @@ require_once __DIR__ . '/../Autoloader.php'; use phpOMS\Security\PhpCode; /** + * @testdox phpOMS\tests\Security\PhpCodeTest: Basic php source code security inspection + * * @internal */ class RouteVerbTest extends \PHPUnit\Framework\TestCase { + /** + * @testdox A file with unicode characters gets correctly identified + * @covers phpOMS\Security\PhpCode + */ public function testHasUnicode() : void { self::assertTrue( @@ -32,7 +38,14 @@ class RouteVerbTest extends \PHPUnit\Framework\TestCase ) ) ); + } + /** + * @testdox A file with no unicode characters gets correctly identified + * @covers phpOMS\Security\PhpCode + */ + public function testHasNoUnicode() : void + { self::assertFalse( PhpCode::hasUnicode( PhpCode::normalizeSource( @@ -42,12 +55,20 @@ class RouteVerbTest extends \PHPUnit\Framework\TestCase ); } + /** + * @testdox A file with no disabled functions gets correctly identified + * @covers phpOMS\Security\PhpCode + */ public function testDisabledFunctions() : void { self::assertFalse(PhpCode::isDisabled(['file_get_contents'])); self::assertFalse(PhpCode::isDisabled(['eval', 'file_get_contents'])); } + /** + * @testdox A file with deprecated functions gets correctly identified + * @covers phpOMS\Security\PhpCode + */ public function testHasDeprecatedFunction() : void { self::assertTrue( @@ -57,7 +78,14 @@ class RouteVerbTest extends \PHPUnit\Framework\TestCase ) ) ); + } + /** + * @testdox A file with no deprecated functions gets correctly identified + * @covers phpOMS\Security\PhpCode + */ + public function testHasNoDeprecatedFunction() : void + { self::assertFalse( PhpCode::hasDeprecatedFunction( PhpCode::normalizeSource( @@ -67,15 +95,39 @@ class RouteVerbTest extends \PHPUnit\Framework\TestCase ); } + /** + * @testdox A file hash comparison is successfull if the file generates the same hash + * @covers phpOMS\Security\PhpCode + */ public function testFileIntegrity() : void { self::assertTrue(PhpCode::validateFileIntegrity(__DIR__ . '/Sample/hasDeprecated.php', \md5_file(__DIR__ . '/Sample/hasDeprecated.php'))); + } + + /** + * @testdox A file hash comparison is unsuccessfull if the file generates a different hash + * @covers phpOMS\Security\PhpCode + */ + public function testFileInvalidIntegrity() : void + { self::assertFalse(PhpCode::validateFileIntegrity(__DIR__ . '/Sample/hasUnicode.php', \md5_file(__DIR__ . '/Sample/hasDeprecated.php'))); } + /** + * @testdox Two equal strings validate as the same + * @covers phpOMS\Security\PhpCode + */ public function testStringIntegrity() : void { self::assertTrue(PhpCode::validateStringIntegrity('aa', 'aa')); + } + + /** + * @testdox Two different strings don't validate as the same + * @covers phpOMS\Security\PhpCode + */ + public function testStringInvalidIntegrity() : void + { self::assertFalse(PhpCode::validateStringIntegrity('aa', 'aA')); } } diff --git a/tests/Stdlib/Base/AddressTest.php b/tests/Stdlib/Base/AddressTest.php index 15f087ab3..13491c7bf 100644 --- a/tests/Stdlib/Base/AddressTest.php +++ b/tests/Stdlib/Base/AddressTest.php @@ -18,18 +18,34 @@ use phpOMS\Stdlib\Base\Address; use phpOMS\Stdlib\Base\Location; /** + * @testdox phpOMS\tests\Stdlib\Base\AddressTest: Address type + * * @internal */ class AddressTest extends \PHPUnit\Framework\TestCase { - public function testAttributes() : void + protected Address $address; + + protected function setUp() : void { - $address = new Address(); - self::assertObjectHasAttribute('recipient', $address); - self::assertObjectHasAttribute('fao', $address); - self::assertObjectHasAttribute('location', $address); + $this->address = new Address(); } + /** + * @testdox The address has the expected attributes + * @covers phpOMS\Stdlib\Base\Address + */ + public function testAttributes() : void + { + self::assertObjectHasAttribute('recipient', $this->address); + self::assertObjectHasAttribute('fao', $this->address); + self::assertObjectHasAttribute('location', $this->address); + } + + /** + * @testdox The address has the expected default values after initialization + * @covers phpOMS\Stdlib\Base\Address + */ public function testDefault() : void { $expected = [ @@ -48,15 +64,50 @@ class AddressTest extends \PHPUnit\Framework\TestCase ], ]; - $address = new Address(); - self::assertEquals('', $address->getRecipient()); - self::assertEquals('', $address->getFAO()); - self::assertInstanceOf('\phpOMS\Stdlib\Base\Location', $address->getLocation()); - self::assertEquals($expected, $address->toArray()); - self::assertEquals($expected, $address->jsonSerialize()); + self::assertEquals('', $this->address->getRecipient()); + self::assertEquals('', $this->address->getFAO()); + self::assertInstanceOf('\phpOMS\Stdlib\Base\Location', $this->address->getLocation()); + self::assertEquals($expected, $this->address->toArray()); + self::assertEquals($expected, $this->address->jsonSerialize()); } - public function testGetSet() : void + /** + * @testdox The fao can be set and returned + * @covers phpOMS\Stdlib\Base\Address + */ + public function testFAOInputOutput() : void + { + $this->address->setFAO('fao'); + self::assertEquals('fao', $this->address->getFAO()); + } + + /** + * @testdox The recepient can be set and returned + * @covers phpOMS\Stdlib\Base\Address + */ + public function testRecipientInputOutput() : void + { + $this->address->setRecipient('recipient'); + self::assertEquals('recipient', $this->address->getRecipient()); + } + + /** + * @testdox The location can be set and returned + * @covers phpOMS\Stdlib\Base\Address + */ + public function testLocationInputOutput() : void + { + $this->address->setLocation(new Location()); + + self::assertInstanceOf('\phpOMS\Stdlib\Base\Location', $this->address->getLocation()); + + } + + /** + * @testdox The address can be turned into array data + * @covers phpOMS\Stdlib\Base\Address + */ + public function testArray() : void { $expected = [ 'recipient' => 'recipient', @@ -74,15 +125,39 @@ class AddressTest extends \PHPUnit\Framework\TestCase ], ]; - $address = new Address(); - $address->setFAO('fao'); - $address->setRecipient('recipient'); - $address->setLocation(new Location()); + $this->address->setFAO('fao'); + $this->address->setRecipient('recipient'); + $this->address->setLocation(new Location()); - self::assertEquals('recipient', $address->getRecipient()); - self::assertEquals('fao', $address->getFAO()); - self::assertInstanceOf('\phpOMS\Stdlib\Base\Location', $address->getLocation()); - self::assertEquals($expected, $address->toArray()); - self::assertEquals($expected, $address->jsonSerialize()); + self::assertEquals($expected, $this->address->toArray()); + } + + /** + * @testdox The address can be json serialized + * @covers phpOMS\Stdlib\Base\Address + */ + public function testJsonSerialize() : void + { + $expected = [ + 'recipient' => 'recipient', + 'fao' => 'fao', + 'location' => [ + 'postal' => '', + 'city' => '', + 'country' => '', + 'address' => '', + 'state' => '', + 'geo' => [ + 'lat' => 0, + 'long' => 0, + ], + ], + ]; + + $this->address->setFAO('fao'); + $this->address->setRecipient('recipient'); + $this->address->setLocation(new Location()); + + self::assertEquals($expected, $this->address->jsonSerialize()); } } diff --git a/tests/Stdlib/Base/EnumArrayTest.php b/tests/Stdlib/Base/EnumArrayTest.php index ed4d857ea..afe9e0f20 100644 --- a/tests/Stdlib/Base/EnumArrayTest.php +++ b/tests/Stdlib/Base/EnumArrayTest.php @@ -15,29 +15,94 @@ declare(strict_types=1); namespace phpOMS\tests\Stdlib\Base; /** + * @testdox phpOMS\tests\Stdlib\Base\EnumArrayTest: Enum array type + * * @internal */ class EnumArrayTest extends \PHPUnit\Framework\TestCase { - public function testGetSet() : void + /** + * @testdox A valid enum name returns the enum value + * @covers phpOMS\Stdlib\Base\EnumArray + */ + public function testValueOutput() : void { self::assertEquals(1, EnumArrayDemo::get('ENUM1')); self::assertEquals('abc', EnumArrayDemo::get('ENUM2')); + } + /** + * @testdox A valid enum name can be validated + * @covers phpOMS\Stdlib\Base\EnumArray + */ + public function testValidateEnumName() : void + { self::assertTrue(EnumArrayDemo::isValidName('ENUM1')); + } + + /** + * @testdox A invalid enum name doesn't validate + * @covers phpOMS\Stdlib\Base\EnumArray + */ + public function testInvalidEnumNameValidation() : void + { self::assertFalse(EnumArrayDemo::isValidName('enum1')); + } + /** + * @testdox All enum name/value pairs can be returned + * @covers phpOMS\Stdlib\Base\EnumArray + */ + public function testOutputValues() : void + { self::assertEquals(['ENUM1' => 1, 'ENUM2' => 'abc'], EnumArrayDemo::getConstants()); + } + /** + * @testdox A valid enum value can be checked for existance + * @covers phpOMS\Stdlib\Base\EnumArray + */ + public function testValidateEnumValue() : void + { self::assertTrue(EnumArrayDemo::isValidValue(1)); self::assertTrue(EnumArrayDemo::isValidValue('abc')); + } + + /** + * @testdox A invalid enum value doesn't validate + * @covers phpOMS\Stdlib\Base\EnumArray + */ + public function testInvalidEnumValueValidation() : void + { self::assertFalse(EnumArrayDemo::isValidValue('e3')); } + /** + * @testdox A invalid enum name throws a OutOfBoundsException + * @covers phpOMS\Stdlib\Base\EnumArray + */ public function testInvalidConstantException() : void { self::expectException(\OutOfBoundsException::class); EnumArrayDemo::get('enum2'); } + + /** + * @testdox The amount of enum values can be returned + * @covers phpOMS\Stdlib\Base\EnumArray + */ + public function testCount() : void + { + self::assertEquals(2, EnumArrayDemo::count()); + } + + /** + * @testdox A random enum value can be returned + * @covers phpOMS\Stdlib\Base\EnumArray + */ + public function testRandomValue() : void + { + self::assertTrue(EnumDemo::isValidValue(EnumDemo::getRandom())); + } } diff --git a/tests/Stdlib/Base/EnumTest.php b/tests/Stdlib/Base/EnumTest.php index 855014c3f..c9b66c2f7 100644 --- a/tests/Stdlib/Base/EnumTest.php +++ b/tests/Stdlib/Base/EnumTest.php @@ -15,29 +15,122 @@ declare(strict_types=1); namespace phpOMS\tests\Stdlib\Base; /** + * @testdox phpOMS\tests\Stdlib\Base\EnumTest: Enum type + * * @internal */ class EnumTest extends \PHPUnit\Framework\TestCase { - public function testGetSet() : void + /** + * @testdox A valid enum name can be validated + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testValidateEnumName() : void { self::assertTrue(EnumDemo::isValidName('ENUM1')); + } + + /** + * @testdox A invalid enum name doesn't validate + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testInvalidEnumNameValidation() : void + { self::assertFalse(EnumDemo::isValidName('enum1')); + } + /** + * @testdox All enum name/value pairs can be returned + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testOutputValues() : void + { self::assertEquals(['ENUM1' => 1, 'ENUM2' => ';l'], EnumDemo::getConstants()); + } + /** + * @testdox A valid enum value can be checked for existance + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testValidateEnumValue() : void + { self::assertTrue(EnumDemo::isValidValue(1)); self::assertTrue(EnumDemo::isValidValue(';l')); + } + + /** + * @testdox A invalid enum value doesn't validate + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testInvalidEnumValueValidation() : void + { self::assertFalse(EnumDemo::isValidValue('e3')); + } + + /** + * @testdox A random enum value can be returned + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testRandomValue() : void + { self::assertTrue(EnumDemo::isValidValue(EnumDemo::getRandom())); + } + + /** + * @testdox A valid enum name returns the enum value + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testValueOutput() : void + { self::assertEquals(EnumDemo::ENUM2, EnumDemo::getByName('ENUM2')); self::assertEquals(EnumDemo::ENUM2, EnumDemo::getByName('ENUM2')); + } + + /** + * @testdox The amount of enum values can be returned + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testCount() : void + { self::assertEquals(2, EnumDemo::count()); + } + + /** + * @testdox A valid enum value returns the enum name + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testNameOutput() : void + { self::assertEquals('ENUM1', EnumDemo::getName('1')); self::assertEquals('ENUM2', EnumDemo::getName(';l')); } - public function testEmailException() : void + /** + * @testdox Binary flags validate if they are set + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testFlags() : void + { + self::assertTrue(EnumDemo::hasFlag(13, 4)); + self::assertTrue(EnumDemo::hasFlag(13, 1)); + self::assertTrue(EnumDemo::hasFlag(13, 8)); + } + + /** + * @testdox Binary flags don't validate if they are not set + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testInvalidFlags() : void + { + self::assertFalse(EnumDemo::hasFlag(13, 2)); + self::assertFalse(EnumDemo::hasFlag(13, 16)); + } + + /** + * @testdox A invalid enum name throws a OutOfBoundsException + * @covers phpOMS\Stdlib\Base\Enum + */ + public function testInvalidConstantException() : void { self::expectException(\Exception::class); diff --git a/tests/Uri/UriSchemeTest.php b/tests/Uri/UriSchemeTest.php index 35ce8362c..32a278bb8 100644 --- a/tests/Uri/UriSchemeTest.php +++ b/tests/Uri/UriSchemeTest.php @@ -45,6 +45,9 @@ class UriSchemeTest extends \PHPUnit\Framework\TestCase self::assertTrue(\defined('phpOMS\Uri\UriScheme::ITMS')); } + /** + * @coversNothing + */ public function testEnumUnique() : void { $values = UriScheme::getConstants();