Skip to content

Commit

Permalink
Provide PSR-16 adapter for cache
Browse files Browse the repository at this point in the history
Signed-off-by: Luís Cobucci <[email protected]>
  • Loading branch information
lcobucci committed Jan 31, 2024
1 parent 2d94d13 commit ebff3bb
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 3 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
}
],
"require": {
"php": ">=8.1.0"
"php": ">=8.1.0",
"psr/simple-cache": "^2.0 || ^3.0"
},
"require-dev": {
"lcobucci/coding-standard": "^11.0",
Expand Down
56 changes: 54 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions src/Cache/Psr16Cache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);

namespace FastRoute\Cache;

use FastRoute\Cache;
use FastRoute\DataGenerator;
use Psr\SimpleCache\CacheInterface;

use function is_array;

/** @phpstan-import-type RouteData from DataGenerator */
final class Psr16Cache implements Cache
{
public function __construct(private readonly CacheInterface $cache)
{
}

/** @inheritDoc */
public function get(string $key, callable $loader): array
{
$result = $this->cache->get($key);

if (is_array($result)) {
// @phpstan-ignore-next-line because we won´t be able to validate the array shape in a performant way
return $result;
}

$data = $loader();
$this->cache->set($key, $data);

return $data;
}
}
55 changes: 55 additions & 0 deletions test/Cache/Psr16CacheTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);

namespace FastRoute\Test\Cache;

use FastRoute\Cache\Psr16Cache;
use PHPUnit\Framework\Attributes as PHPUnit;
use PHPUnit\Framework\TestCase;
use Psr\SimpleCache\CacheInterface;

final class Psr16CacheTest extends TestCase
{
#[PHPUnit\Test]
public function cacheShouldOnlyBeSetOnMiss(): void
{
$data = [];

$generatedData = [['GET' => ['/' => ['test', []]]], []];

$adapter = new Psr16Cache($this->createDummyCache($data));
$result = $adapter->get('test', static fn () => $generatedData);

self::assertSame($generatedData, $result);
self::assertSame($generatedData, $data['test']);

// Try again, now with a different callback
$result = $adapter->get('test', static fn () => [['POST' => ['/' => ['test', []]]], []]);

self::assertSame($generatedData, $result);
}

/** @param array<string, mixed> $data */
private function createDummyCache(array &$data): CacheInterface
{
$cache = $this->createMock(CacheInterface::class);

$cache->method('get')
->willReturnCallback(
static function (string $key, mixed $default) use (&$data): mixed {
return $data[$key] ?? $default;
},
);

$cache->method('set')
->willReturnCallback(
static function (string $key, mixed $value) use (&$data): bool {
$data[$key] = $value;

return true;
},
);

return $cache;
}
}

0 comments on commit ebff3bb

Please sign in to comment.