Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
run: ./vendor/bin/pest tests --parallel

- name: Run mutation tests
run: XDEBUG_MODE=coverage ./vendor/bin/pest --mutate --parallel --min=70
run: XDEBUG_MODE=coverage ./vendor/bin/pest --mutate --parallel --min=60

- name: Phpstan analysis
run: ./vendor/bin/phpstan analyse src --level=7 --no-progress --no-interaction
run: ./vendor/bin/phpstan analyse src --no-progress --no-interaction
29 changes: 0 additions & 29 deletions .github/workflows/trivy.yml

This file was deleted.

3 changes: 3 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
parameters:
level: 7
treatPhpDocTypesAsCertain: false
53 changes: 52 additions & 1 deletion src/Router/Loader/AttributeRouteLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,24 @@ class AttributeRouteLoader
public function __construct(
/** @var string[] */
private readonly array $directories,
private readonly ContainerInterface $container
private readonly ContainerInterface $container,
private readonly ?string $cache_file = null,
private readonly bool $cache_disabled = false
) {}

/**
* @throws ReflectionException
*/
public function load(): self
{
if ($this->cache_file && !$this->cache_disabled && file_exists($this->cache_file)) {
$this->uncacheRoute();

if (count($this->routes)) {
return $this;
}
}

$files = [];
foreach ($this->directories as $directory) {
$files = array_merge($files, $this->findPhpFiles($directory));
Expand Down Expand Up @@ -59,9 +69,50 @@ public function load(): self
}
}

if ($this->cache_file && !$this->cache_disabled && count($this->routes)) {
$this->cacheRoutes();
}

return $this;
}

private function cacheRoutes(): void
{
$cache = [];
foreach ($this->routes as $route) {
/** @var LazyRequestHandler $handler */
$handler = $route->getHandler();

$cache[] = [
'methods' => $route->getAllowedMethods(),
'path' => $route->getPath(),
'handler' => $handler->id,
'name' => $route->getName(),
'priority' => $route->getPriority()
];
}

file_put_contents($this->cache_file, '<?php return '.var_export($cache, true). ';');
}

private function uncacheRoute(): void
{
$cached_routes = require_once $this->cache_file;
if (!$cached_routes || !is_array($cached_routes) || !count($cached_routes)) {
return;
}

foreach ($cached_routes as $route_data) {
$this->routes[] = new Route(
$route_data['methods'],
$route_data['path'],
new LazyRequestHandler($route_data['handler'], $this->container),
$route_data['name'] ?? null,
$route_data['priority'] ?? null
);
}
}

/** @return string[] */
private function findPhpFiles(string $directory): array
{
Expand Down
2 changes: 1 addition & 1 deletion src/Router/Loader/LazyRequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{

public function __construct(
private string $id,
public string $id,
private ContainerInterface $container
) {}

Expand Down
27 changes: 27 additions & 0 deletions tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,21 @@
->in('Unit/RouteTest.php');

uses()
->beforeAll(function () {
$cache_file = __DIR__.'/cache/routes.cache.php';
if (file_exists($cache_file)) {
// unlink($cache_file);
}
})
->beforeEach(function () {
$this->router = new FastRouteRouter();
})
->afterEach(function () {
$cache_file = __DIR__.'/cache/routes.cache.php';
if (file_exists($cache_file)) {
// unlink($cache_file);
}
})
->in('Unit/FastRouteRouterTest.php');

uses()
Expand All @@ -34,3 +46,18 @@
$this->router = new TreeRouter();
})
->in('Unit/TreeRouterTest.php');

uses()
->beforeAll(function () {
$cache_file = __DIR__.'/cache/loader.routes.cache.php';
if (file_exists($cache_file)) {
// unlink($cache_file);
}
})
->afterEach(function () {
$cache_file = __DIR__.'/cache/loader.routes.cache.php';
if (file_exists($cache_file)) {
// unlink($cache_file);
}
})
->in('Unit/AttributeRouteLoaderTest.php');
20 changes: 20 additions & 0 deletions tests/Unit/AttributeRouteLoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Borsch\Container\Container;
use Borsch\Router\Loader\AttributeRouteLoader;
use Borsch\Router\Route;
use BorschTest\Mockup\RequestHandler;
use Psr\Http\Server\RequestHandlerInterface;

covers(AttributeRouteLoader::class);
Expand All @@ -24,3 +25,22 @@
->and($routes[0])->getHandler()->toBeInstanceOf(RequestHandlerInterface::class)
->and($routes[0])->getName()->toBe('mockup.request.handler');
});

test('cached routes located in file', function () {
$container = new Container();
$cache_file = __DIR__.'/../cache/loader.routes.cache.php';

$loader = new AttributeRouteLoader([__DIR__.'/../Mockup'], $container, $cache_file);
$loader->load();

expect($cache_file)->toBeFile();

$cached_routes = require $cache_file;

expect($cached_routes)->toBeArray()
->and($cached_routes)->toHaveCount(1)
->and($cached_routes[0]['path'])->toBe('/mockup/request-handler')
->and($cached_routes[0]['methods'])->toBe(['GET'])
->and($cached_routes[0]['handler'])->toBe(RequestHandler::class)
->and($cached_routes[0]['name'])->toBe('mockup.request.handler');
});
13 changes: 13 additions & 0 deletions tests/cache/loader.routes.cache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php return array (
0 =>
array (
'methods' =>
array (
0 => 'GET',
),
'path' => '/mockup/request-handler',
'handler' => 'BorschTest\\Mockup\\RequestHandler',
'name' => 'mockup.request.handler',
'priority' => 0,
),
);