mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-17 14:46:00 +00:00
Introduce ChainCache and ReadOnlyFilesystemCache
Signed-off-by: Quentin Devos <4972091+Okhoshi@users.noreply.github.com>
This commit is contained in:
committed by
Quentin Devos
parent
26b1dc590c
commit
0dbe1d9f6d
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
namespace Twig\Tests\Cache;
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Twig\Cache\ChainCache;
|
||||
use Twig\Cache\FilesystemCache;
|
||||
use Twig\Tests\FilesystemHelper;
|
||||
|
||||
class ChainTest extends TestCase
|
||||
{
|
||||
private $classname;
|
||||
private $directory;
|
||||
private $cache;
|
||||
private $key;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$nonce = hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', random_bytes(32));
|
||||
$this->classname = '__Twig_Tests_Cache_ChainTest_Template_'.$nonce;
|
||||
$this->directory = sys_get_temp_dir().'/twig-test';
|
||||
$this->cache = new ChainCache([
|
||||
new FilesystemCache($this->directory.'/A'),
|
||||
new FilesystemCache($this->directory.'/B'),
|
||||
]);
|
||||
$this->key = $this->cache->generateKey('_test_', $this->classname);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
if (file_exists($this->directory)) {
|
||||
FilesystemHelper::removeDir($this->directory);
|
||||
}
|
||||
}
|
||||
|
||||
public function testLoadInA()
|
||||
{
|
||||
$cache = new FilesystemCache($this->directory.'/A');
|
||||
$key = $cache->generateKey('_test_', $this->classname);
|
||||
|
||||
$dir = \dirname($key);
|
||||
@mkdir($dir, 0777, true);
|
||||
$this->assertDirectoryExists($dir);
|
||||
$this->assertFalse(class_exists($this->classname, false));
|
||||
|
||||
$content = $this->generateSource();
|
||||
file_put_contents($key, $content);
|
||||
var_dump($key);
|
||||
|
||||
$this->cache->load($this->key);
|
||||
|
||||
$this->assertTrue(class_exists($this->classname, false));
|
||||
}
|
||||
|
||||
public function testLoadInB()
|
||||
{
|
||||
$cache = new FilesystemCache($this->directory.'/B');
|
||||
$key = $cache->generateKey('_test_', $this->classname);
|
||||
|
||||
$dir = \dirname($key);
|
||||
@mkdir($dir, 0777, true);
|
||||
$this->assertDirectoryExists($dir);
|
||||
$this->assertFalse(class_exists($this->classname, false));
|
||||
|
||||
$content = $this->generateSource();
|
||||
file_put_contents($key, $content);
|
||||
var_dump($key);
|
||||
|
||||
$this->cache->load($this->key);
|
||||
|
||||
$this->assertTrue(class_exists($this->classname, false));
|
||||
}
|
||||
|
||||
public function testLoadInBoth()
|
||||
{
|
||||
$cache = new FilesystemCache($this->directory.'/A');
|
||||
$key = $cache->generateKey('_test_', $this->classname);
|
||||
|
||||
$dir = \dirname($key);
|
||||
@mkdir($dir, 0777, true);
|
||||
$this->assertDirectoryExists($dir);
|
||||
$this->assertFalse(class_exists($this->classname, false));
|
||||
|
||||
$content = $this->generateSource();
|
||||
file_put_contents($key, $content);
|
||||
|
||||
$cache = new FilesystemCache($this->directory.'/B');
|
||||
$key = $cache->generateKey('_test_', $this->classname);
|
||||
|
||||
$dir = \dirname($key);
|
||||
@mkdir($dir, 0777, true);
|
||||
$this->assertDirectoryExists($dir);
|
||||
$this->assertFalse(class_exists($this->classname, false));
|
||||
|
||||
$content = $this->generateSource();
|
||||
file_put_contents($key, $content);
|
||||
|
||||
$this->cache->load($this->key);
|
||||
|
||||
$this->assertTrue(class_exists($this->classname, false));
|
||||
}
|
||||
|
||||
public function testLoadMissing()
|
||||
{
|
||||
$this->assertFalse(class_exists($this->classname, false));
|
||||
|
||||
$this->cache->load($this->key);
|
||||
|
||||
$this->assertFalse(class_exists($this->classname, false));
|
||||
}
|
||||
|
||||
public function testWrite()
|
||||
{
|
||||
$content = $this->generateSource();
|
||||
|
||||
$cacheA = new FilesystemCache($this->directory.'/A');
|
||||
$keyA = $cacheA->generateKey('_test_', $this->classname);
|
||||
|
||||
$this->assertFileDoesNotExist($keyA);
|
||||
$this->assertFileDoesNotExist($this->directory.'/A');
|
||||
|
||||
$cacheB = new FilesystemCache($this->directory.'/B');
|
||||
$keyB = $cacheB->generateKey('_test_', $this->classname);
|
||||
|
||||
$this->assertFileDoesNotExist($keyB);
|
||||
$this->assertFileDoesNotExist($this->directory.'/B');
|
||||
|
||||
$this->cache->write($this->key, $content);
|
||||
|
||||
$this->assertFileExists($this->directory.'/A');
|
||||
$this->assertFileExists($keyA);
|
||||
$this->assertSame(file_get_contents($keyA), $content);
|
||||
|
||||
$this->assertFileExists($this->directory.'/B');
|
||||
$this->assertFileExists($keyB);
|
||||
$this->assertSame(file_get_contents($keyB), $content);
|
||||
}
|
||||
|
||||
public function testGetTimestampInA()
|
||||
{
|
||||
$cache = new FilesystemCache($this->directory.'/A');
|
||||
$key = $cache->generateKey('_test_', $this->classname);
|
||||
|
||||
$dir = \dirname($key);
|
||||
@mkdir($dir, 0777, true);
|
||||
$this->assertDirectoryExists($dir);
|
||||
|
||||
// Create the file with a specific modification time.
|
||||
touch($key, 1234567890);
|
||||
|
||||
$this->assertSame(1234567890, $this->cache->getTimestamp($this->key));
|
||||
}
|
||||
|
||||
public function testGetTimestampInB()
|
||||
{
|
||||
$cache = new FilesystemCache($this->directory.'/B');
|
||||
$key = $cache->generateKey('_test_', $this->classname);
|
||||
|
||||
$dir = \dirname($key);
|
||||
@mkdir($dir, 0777, true);
|
||||
$this->assertDirectoryExists($dir);
|
||||
|
||||
// Create the file with a specific modification time.
|
||||
touch($key, 1234567890);
|
||||
|
||||
$this->assertSame(1234567890, $this->cache->getTimestamp($this->key));
|
||||
}
|
||||
|
||||
public function testGetTimestampInBoth()
|
||||
{
|
||||
$cacheA = new FilesystemCache($this->directory.'/A');
|
||||
$keyA = $cacheA->generateKey('_test_', $this->classname);
|
||||
|
||||
$dir = \dirname($keyA);
|
||||
@mkdir($dir, 0777, true);
|
||||
$this->assertDirectoryExists($dir);
|
||||
|
||||
// Create the file with a specific modification time.
|
||||
touch($keyA, 1234567890);
|
||||
|
||||
$cacheB = new FilesystemCache($this->directory.'/B');
|
||||
$keyB = $cacheB->generateKey('_test_', $this->classname);
|
||||
|
||||
$dir = \dirname($keyB);
|
||||
@mkdir($dir, 0777, true);
|
||||
$this->assertDirectoryExists($dir);
|
||||
|
||||
// Create the file with a specific modification time.
|
||||
touch($keyB, 1234567891);
|
||||
|
||||
$this->assertSame(1234567890, $this->cache->getTimestamp($this->key));
|
||||
}
|
||||
|
||||
public function testGetTimestampMissingFile()
|
||||
{
|
||||
$this->assertSame(0, $this->cache->getTimestamp($this->key));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideInput
|
||||
*/
|
||||
public function testGenerateKey($expected, $input)
|
||||
{
|
||||
$cache = new ChainCache([]);
|
||||
$this->assertSame($expected, $cache->generateKey($input, static::class));
|
||||
}
|
||||
|
||||
public static function provideInput()
|
||||
{
|
||||
return [
|
||||
['Twig\Tests\Cache\ChainTest#_test_', '_test_'],
|
||||
['Twig\Tests\Cache\ChainTest#_test#with#hashtag_', '_test#with#hashtag_'],
|
||||
];
|
||||
}
|
||||
|
||||
private function generateSource()
|
||||
{
|
||||
return strtr('<?php class {{classname}} {}', [
|
||||
'{{classname}}' => $this->classname,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace Twig\Tests\Cache;
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Twig\Tests\FilesystemHelper;
|
||||
use Twig\Cache\ReadOnlyFilesystemCache;
|
||||
|
||||
class ReadOnlyFilesystemTest extends TestCase
|
||||
{
|
||||
private $classname;
|
||||
private $directory;
|
||||
private $cache;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$nonce = hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', random_bytes(32));
|
||||
$this->classname = '__Twig_Tests_Cache_ReadOnlyFilesystemTest_Template_'.$nonce;
|
||||
$this->directory = sys_get_temp_dir().'/twig-test';
|
||||
$this->cache = new ReadOnlyFilesystemCache($this->directory);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
if (file_exists($this->directory)) {
|
||||
FilesystemHelper::removeDir($this->directory);
|
||||
}
|
||||
}
|
||||
|
||||
public function testLoad()
|
||||
{
|
||||
$key = $this->directory.'/cache/ro-cachefile.php';
|
||||
|
||||
$dir = \dirname($key);
|
||||
@mkdir($dir, 0777, true);
|
||||
$this->assertDirectoryExists($dir);
|
||||
$this->assertFalse(class_exists($this->classname, false));
|
||||
|
||||
$content = $this->generateSource();
|
||||
file_put_contents($key, $content);
|
||||
|
||||
$this->cache->load($key);
|
||||
|
||||
$this->assertTrue(class_exists($this->classname, false));
|
||||
}
|
||||
|
||||
public function testLoadMissing()
|
||||
{
|
||||
$key = $this->directory.'/cache/cachefile.php';
|
||||
|
||||
$this->assertFalse(class_exists($this->classname, false));
|
||||
|
||||
$this->cache->load($key);
|
||||
|
||||
$this->assertFalse(class_exists($this->classname, false));
|
||||
}
|
||||
|
||||
public function testWrite()
|
||||
{
|
||||
$key = $this->directory.'/cache/cachefile.php';
|
||||
$content = $this->generateSource();
|
||||
|
||||
$this->assertFileDoesNotExist($key);
|
||||
$this->assertFileDoesNotExist($this->directory);
|
||||
|
||||
$this->cache->write($key, $content);
|
||||
|
||||
$this->assertFileDoesNotExist($this->directory);
|
||||
$this->assertFileDoesNotExist($key);
|
||||
}
|
||||
|
||||
public function testGetTimestamp()
|
||||
{
|
||||
$key = $this->directory.'/cache/cachefile.php';
|
||||
|
||||
$dir = \dirname($key);
|
||||
@mkdir($dir, 0777, true);
|
||||
$this->assertDirectoryExists($dir);
|
||||
|
||||
// Create the file with a specific modification time.
|
||||
touch($key, 1234567890);
|
||||
|
||||
$this->assertSame(1234567890, $this->cache->getTimestamp($key));
|
||||
}
|
||||
|
||||
public function testGetTimestampMissingFile()
|
||||
{
|
||||
$key = $this->directory.'/cache/cachefile.php';
|
||||
$this->assertSame(0, $this->cache->getTimestamp($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test file cache is tolerant towards trailing (back)slashes on the configured cache directory.
|
||||
*
|
||||
* @dataProvider provideDirectories
|
||||
*/
|
||||
public function testGenerateKey($expected, $input)
|
||||
{
|
||||
$cache = new ReadOnlyFilesystemCache($input);
|
||||
$this->assertMatchesRegularExpression($expected, $cache->generateKey('_test_', static::class));
|
||||
}
|
||||
|
||||
public static function provideDirectories()
|
||||
{
|
||||
$pattern = '#a/b/[a-zA-Z0-9]+/[a-zA-Z0-9]+.php$#';
|
||||
|
||||
return [
|
||||
[$pattern, 'a/b'],
|
||||
[$pattern, 'a/b/'],
|
||||
[$pattern, 'a/b\\'],
|
||||
[$pattern, 'a/b\\/'],
|
||||
[$pattern, 'a/b\\//'],
|
||||
['#/'.substr($pattern, 1), '/a/b'],
|
||||
];
|
||||
}
|
||||
|
||||
private function generateSource()
|
||||
{
|
||||
return strtr('<?php class {{classname}} {}', [
|
||||
'{{classname}}' => $this->classname,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user