Skip to content

Commit

Permalink
major refactoring of tests and code + remove some features + add bett…
Browse files Browse the repository at this point in the history
…er features (#1)

* major refactoring of tests and code + remove some features + add better features

* fix code quality

* Router::pathTo handles custom parameters

* allow pathTo to append extra parameters as the path query

* improve tests structure and readability

* almost completed the documentation

* Indicate data providers as annotations

* Improve exceptions

* improve project structure

* continue updating the README

* Allow conditions to return true instead of an array

* Update documentation

* Add documentation about the exceptions
  • Loading branch information
IngeniozIT committed Apr 12, 2024
1 parent d9d7a5f commit 16c9bcc
Show file tree
Hide file tree
Showing 42 changed files with 1,822 additions and 965 deletions.
460 changes: 328 additions & 132 deletions README.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions composer.json
Expand Up @@ -25,8 +25,8 @@
"infection/infection": "*",
"phpmd/phpmd": "*",
"rector/rector": "*",
"ingenioz-it/http-message": "^2.0",
"ingenioz-it/edict": "^3.1"
"ingenioz-it/http-message": "*",
"ingenioz-it/edict": "*"
},
"autoload": {
"psr-4": {
Expand All @@ -52,7 +52,7 @@
"quality:psalm": "vendor/bin/psalm --no-cache --config ./quality/psalm.xml.dist",
"quality:phan": "vendor/bin/phan --config-file ./quality/phan.php",
"quality:phan-silent": "vendor/bin/phan --no-progress-bar --config-file ./quality/phan.php",
"quality:infection": "vendor/bin/infection --configuration=./quality/infection.json.dist",
"quality:infection": "vendor/bin/infection -j$(nproc) --configuration=./quality/infection.json.dist",
"quality:phpmd": "vendor/bin/phpmd src/,tests/ text quality/phpmd.xml.dist",
"fulltest": [
"@test",
Expand Down
4 changes: 3 additions & 1 deletion quality/phpmd.xml.dist
Expand Up @@ -10,7 +10,9 @@
All default rulesets from PHPMD.
</description>
<rule ref="rulesets/codesize.xml" />
<rule ref="rulesets/cleancode.xml" />
<rule ref="rulesets/cleancode.xml">
<exclude name="StaticAccess" />
</rule>
<rule ref="rulesets/controversial.xml" />
<rule ref="rulesets/design.xml" />
<rule ref="rulesets/naming.xml" />
Expand Down
7 changes: 7 additions & 0 deletions quality/rector.php
Expand Up @@ -2,8 +2,10 @@

declare(strict_types=1);

use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\{LevelSetList, SetList};
use Rector\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
Expand All @@ -23,4 +25,9 @@
SetList::EARLY_RETURN,
SetList::INSTANCEOF,
]);

$rectorConfig->skip([
EncapsedStringsToSprintfRector::class,
BooleanInBooleanNotRuleFixerRector::class,
]);
};
11 changes: 11 additions & 0 deletions src/Condition/ConditionException.php
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace IngeniozIT\Router\Condition;

use IngeniozIT\Router\RouterException;

interface ConditionException extends RouterException
{
}
48 changes: 48 additions & 0 deletions src/Condition/ConditionHandler.php
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace IngeniozIT\Router\Condition;

use Closure;
use IngeniozIT\Router\Condition\Exception\InvalidConditionHandler;
use IngeniozIT\Router\Condition\Exception\InvalidConditionResponse;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ServerRequestInterface;

use function is_array;
use function is_bool;
use function is_callable;
use function is_string;

readonly final class ConditionHandler
{
private Closure $handler;

public function __construct(
private ContainerInterface $container,
mixed $callback,
) {
$handler = is_string($callback) ? $this->container->get($callback) : $callback;

if (!is_callable($handler)) {
throw new InvalidConditionHandler($handler);
}

$this->handler = $handler(...);
}

/**
* @return array<string, mixed>|false
*/
public function handle(ServerRequestInterface $request): array|false
{
$result = ($this->handler)($request);

if (!is_bool($result) && !is_array($result)) {
throw new InvalidConditionResponse($result);
}

return $result === true ? [] : $result;
}
}
18 changes: 18 additions & 0 deletions src/Condition/Exception/InvalidConditionHandler.php
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace IngeniozIT\Router\Condition\Exception;

use IngeniozIT\Router\Condition\ConditionException;
use InvalidArgumentException;

use function get_debug_type;

final class InvalidConditionHandler extends InvalidArgumentException implements ConditionException
{
public function __construct(public mixed $handler)
{
parent::__construct('Condition handler must be a callable, ' . get_debug_type($handler) . ' given.');
}
}
20 changes: 20 additions & 0 deletions src/Condition/Exception/InvalidConditionResponse.php
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace IngeniozIT\Router\Condition\Exception;

use IngeniozIT\Router\Condition\ConditionException;
use InvalidArgumentException;

use function get_debug_type;

final class InvalidConditionResponse extends InvalidArgumentException implements ConditionException
{
public function __construct(public mixed $response)
{
parent::__construct(
'Condition must either return an array or a boolean, ' . get_debug_type($response) . ' given.'
);
}
}
6 changes: 5 additions & 1 deletion src/EmptyRouteStack.php
Expand Up @@ -6,6 +6,10 @@

use OutOfRangeException;

final class EmptyRouteStack extends OutOfRangeException
final class EmptyRouteStack extends OutOfRangeException implements RouterException
{
public function __construct()
{
parent::__construct('No routes left to process.');
}
}
11 changes: 0 additions & 11 deletions src/InvalidRoute.php

This file was deleted.

20 changes: 20 additions & 0 deletions src/Middleware/Exception/InvalidMiddlewareHandler.php
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace IngeniozIT\Router\Middleware\Exception;

use IngeniozIT\Router\Middleware\MiddlewareException;
use InvalidArgumentException;

use function get_debug_type;

final class InvalidMiddlewareHandler extends InvalidArgumentException implements MiddlewareException
{
public function __construct(public mixed $handler)
{
parent::__construct(
'Middleware handler must be a PSR Middleware or a callable, ' . get_debug_type($handler) . ' given.'
);
}
}
18 changes: 18 additions & 0 deletions src/Middleware/Exception/InvalidMiddlewareResponse.php
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace IngeniozIT\Router\Middleware\Exception;

use IngeniozIT\Router\Middleware\MiddlewareException;
use InvalidArgumentException;

use function get_debug_type;

final class InvalidMiddlewareResponse extends InvalidArgumentException implements MiddlewareException
{
public function __construct(public mixed $response)
{
parent::__construct('Middleware must return a PSR Response, ' . get_debug_type($response) . ' given.');
}
}
11 changes: 11 additions & 0 deletions src/Middleware/MiddlewareException.php
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace IngeniozIT\Router\Middleware;

use IngeniozIT\Router\RouterException;

interface MiddlewareException extends RouterException
{
}
52 changes: 52 additions & 0 deletions src/Middleware/MiddlewareHandler.php
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace IngeniozIT\Router\Middleware;

use Closure;
use IngeniozIT\Router\Middleware\Exception\InvalidMiddlewareHandler;
use IngeniozIT\Router\Middleware\Exception\InvalidMiddlewareResponse;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

use function is_callable;
use function is_string;

readonly final class MiddlewareHandler
{
private Closure $handler;

public function __construct(
private ContainerInterface $container,
mixed $callback,
) {
$handler = is_string($callback) ? $this->container->get($callback) : $callback;

if (is_callable($handler)) {
$this->handler = $handler(...);
return;
}

if ($handler instanceof MiddlewareInterface) {
$this->handler = $handler->process(...);
return;
}

throw new InvalidMiddlewareHandler($handler);
}

public function handle(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$result = ($this->handler)($request, $handler);

if (!$result instanceof ResponseInterface) {
throw new InvalidMiddlewareResponse($result);
}

return $result;
}
}

0 comments on commit 16c9bcc

Please sign in to comment.