mirror of
https://github.com/danog/Valinor.git
synced 2024-12-04 02:27:54 +01:00
2d70efbfbb
When the application runs in a development environment, the cache implementation should be decorated with `FileWatchingCache` to prevent invalid cache entries states, which can result in the library not behaving as expected (missing property value, callable with outdated signature, …). ```php $cache = new \CuyZ\Valinor\Cache\FileSystemCache('path/to/cache-dir'); if ($isApplicationInDevelopmentEnvironment) { $cache = new \CuyZ\Valinor\Cache\FileWatchingCache($cache); } (new \CuyZ\Valinor\MapperBuilder()) ->withCache($cache) ->mapper() ->map(SomeClass::class, [/* … */]); ``` This behavior now forces to explicitly inject `FileWatchingCache`, when it was done automatically before; but because it shouldn't be used in a production environment, it will increase overall performance.
150 lines
5.6 KiB
PHP
150 lines
5.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace CuyZ\Valinor\Tests\Unit\Cache;
|
|
|
|
use CuyZ\Valinor\Cache\FileSystemCache;
|
|
use CuyZ\Valinor\Definition\ClassDefinition;
|
|
use CuyZ\Valinor\Definition\FunctionDefinition;
|
|
use CuyZ\Valinor\Tests\Fake\Cache\FakeCache;
|
|
use CuyZ\Valinor\Tests\Fake\Cache\FakeFailingCache;
|
|
use CuyZ\Valinor\Tests\Fake\Definition\FakeClassDefinition;
|
|
use CuyZ\Valinor\Tests\Fake\Definition\FakeFunctionDefinition;
|
|
use org\bovigo\vfs\vfsStream;
|
|
use org\bovigo\vfs\vfsStreamDirectory;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
use function iterator_to_array;
|
|
|
|
final class FileSystemCacheTest extends TestCase
|
|
{
|
|
private vfsStreamDirectory $files;
|
|
|
|
/** @var FileSystemCache<mixed> */
|
|
private FileSystemCache $cache;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->files = vfsStream::setup('cache-dir');
|
|
$this->cache = new FileSystemCache($this->files->url());
|
|
|
|
$this->injectFakeCache();
|
|
}
|
|
|
|
public function test_cache_entries_are_handled_properly(): void
|
|
{
|
|
$classDefinition = FakeClassDefinition::new();
|
|
$functionDefinition = FakeFunctionDefinition::new();
|
|
|
|
self::assertFalse($this->cache->has('class-definition'));
|
|
self::assertFalse($this->cache->has('function-definition'));
|
|
|
|
self::assertTrue($this->cache->set('class-definition', $classDefinition));
|
|
self::assertTrue($this->cache->set('function-definition', $functionDefinition));
|
|
|
|
self::assertTrue($this->cache->has('class-definition'));
|
|
self::assertTrue($this->cache->has('function-definition'));
|
|
|
|
/** @var ClassDefinition $cachedClassDefinition */
|
|
$cachedClassDefinition = $this->cache->get('class-definition');
|
|
/** @var FunctionDefinition $cachedFunctionDefinition */
|
|
$cachedFunctionDefinition = $this->cache->get('function-definition');
|
|
|
|
self::assertSame($classDefinition->name(), $cachedClassDefinition->name());
|
|
self::assertSame($functionDefinition->signature(), $cachedFunctionDefinition->signature());
|
|
|
|
self::assertTrue($this->cache->delete('class-definition'));
|
|
self::assertTrue($this->cache->delete('function-definition'));
|
|
|
|
self::assertFalse($this->cache->has('class-definition'));
|
|
self::assertFalse($this->cache->has('function-definition'));
|
|
}
|
|
|
|
public function test_clear_cache_clears_all_caches(): void
|
|
{
|
|
$classDefinition = FakeClassDefinition::new();
|
|
$functionDefinition = FakeFunctionDefinition::new();
|
|
|
|
$this->cache->set('class-definition', $classDefinition);
|
|
$this->cache->set('function-definition', $functionDefinition);
|
|
|
|
self::assertTrue($this->cache->has('class-definition'));
|
|
self::assertTrue($this->cache->has('function-definition'));
|
|
|
|
self::assertTrue($this->cache->clear());
|
|
|
|
self::assertFalse($this->cache->has('class-definition'));
|
|
self::assertFalse($this->cache->has('function-definition'));
|
|
}
|
|
|
|
public function test_multiple_cache_entries_are_handled_properly(): void
|
|
{
|
|
$classDefinition = FakeClassDefinition::new();
|
|
$functionDefinition = FakeFunctionDefinition::new();
|
|
|
|
self::assertTrue($this->cache->setMultiple([
|
|
'class-definition' => $classDefinition,
|
|
'function-definition' => $functionDefinition,
|
|
]));
|
|
|
|
$cached = iterator_to_array($this->cache->getMultiple(['class-definition', 'function-definition']));
|
|
|
|
/** @var ClassDefinition $cachedClassDefinition */
|
|
$cachedClassDefinition = $cached['class-definition'];
|
|
/** @var FunctionDefinition $cachedFunctionDefinition */
|
|
$cachedFunctionDefinition = $cached['function-definition'];
|
|
|
|
self::assertSame($classDefinition->name(), $cachedClassDefinition->name());
|
|
self::assertSame($functionDefinition->signature(), $cachedFunctionDefinition->signature());
|
|
|
|
self::assertTrue($this->cache->deleteMultiple(['class-definition', 'function-definition']));
|
|
|
|
self::assertFalse($this->cache->has('class-definition'));
|
|
self::assertFalse($this->cache->has('function-definition'));
|
|
}
|
|
|
|
public function test_methods_returns_false_if_delegates_fail(): void
|
|
{
|
|
$this->injectFakeCache(true);
|
|
|
|
$classDefinition = FakeClassDefinition::new();
|
|
$functionDefinition = FakeFunctionDefinition::new();
|
|
|
|
self::assertTrue($this->cache->set('class-definition', $classDefinition));
|
|
self::assertFalse($this->cache->set('function-definition', $functionDefinition));
|
|
|
|
self::assertFalse($this->cache->delete('class-definition'));
|
|
self::assertFalse($this->cache->delete('function-definition'));
|
|
|
|
self::assertFalse($this->cache->clear());
|
|
|
|
self::assertFalse($this->cache->setMultiple([
|
|
'class-definition' => $classDefinition,
|
|
'function-definition' => $functionDefinition,
|
|
]));
|
|
|
|
self::assertFalse($this->cache->deleteMultiple(['class-definition', 'function-definition']));
|
|
}
|
|
|
|
public function test_get_non_existing_entry_returns_default_value(): void
|
|
{
|
|
$defaultValue = FakeClassDefinition::new();
|
|
|
|
self::assertSame($defaultValue, $this->cache->get('non-existing-entry', $defaultValue));
|
|
}
|
|
|
|
private function injectFakeCache(bool $withFailingCache = false): void
|
|
{
|
|
(function () use ($withFailingCache) {
|
|
$this->delegates = [
|
|
'*' => new FakeCache(),
|
|
ClassDefinition::class => new FakeCache(),
|
|
FunctionDefinition::class => $withFailingCache ? new FakeFailingCache() : new FakeCache(),
|
|
];
|
|
})->call($this->cache);
|
|
}
|
|
}
|