Files
Fabien Potencier 0b6e824ea8 Merge branch '3.x' into 4.x
* 3.x:
  Add void return type hint even in tests
  Run php-cs-fixer sequentially so the void_return src-only customiser is applied
  Fix CHANGELOG
  [Intl] Add format_list filter using PHP 8.5's IntlListFormatter

# Conflicts:
#	.github/workflows/ci.yml
#	CHANGELOG
#	extra/cssinliner-extra/Tests/LegacyFunctionsTest.php
#	extra/html-extra/Tests/CvaTest.php
#	extra/html-extra/Tests/HtmlAttrMergeTest.php
#	extra/html-extra/Tests/HtmlAttrTest.php
#	extra/html-extra/Tests/LegacyFunctionsTest.php
#	extra/inky-extra/Tests/LegacyFunctionsTest.php
#	extra/markdown-extra/Tests/FunctionalTest.php
#	extra/markdown-extra/Tests/LegacyFunctionsTest.php
#	extra/twig-extra-bundle/DependencyInjection/Compiler/MissingExtensionSuggestorPass.php
#	extra/twig-extra-bundle/DependencyInjection/TwigExtraExtension.php
#	extra/twig-extra-bundle/TwigExtraBundle.php
#	src/Extension/CoreExtension.php
#	src/Extension/EscaperExtension.php
#	src/Node/CheckSecurityCallNode.php
#	src/Node/Expression/FunctionExpression.php
#	src/Node/ModuleNode.php
#	src/Node/Node.php
#	src/Node/TypesNode.php
#	src/Resources/core.php
#	src/Resources/debug.php
#	src/Test/IntegrationTestCase.php
#	tests/CustomExtensionTest.php
#	tests/EnvironmentTest.php
#	tests/ExpressionParserTest.php
#	tests/Extension/CoreTest.php
#	tests/Extension/EscaperTest.php
#	tests/Extension/LegacyDebugFunctionsTest.php
#	tests/Extension/LegacyStringLoaderFunctionsTest.php
#	tests/Extension/SandboxStateChangeTest.php
#	tests/Extension/SandboxTest.php
#	tests/LexerTest.php
#	tests/Node/Expression/CallTest.php
#	tests/Node/Expression/ConditionalTest.php
#	tests/Node/NodeTest.php
#	tests/Resources/LegacyCoreTest.php
#	tests/TemplateTest.php
#	tests/Util/CallableArgumentsExtractorTest.php
2026-07-12 13:55:37 +02:00

238 lines
7.0 KiB
PHP

<?php
/*
* 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.
*/
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\Attributes\DataProvider;
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('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(): void
{
$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);
$this->cache->load($this->key);
$this->assertTrue(class_exists($this->className, false));
}
public function testLoadInB(): void
{
$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 testLoadInBoth(): void
{
$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(): void
{
$this->assertFalse(class_exists($this->className, false));
$this->cache->load($this->key);
$this->assertFalse(class_exists($this->className, false));
}
public function testWrite(): void
{
$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(): void
{
$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(): void
{
$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(): void
{
$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(): void
{
$this->assertSame(0, $this->cache->getTimestamp($this->key));
}
#[DataProvider('provideInput')]
public function testGenerateKey($expected, $input): void
{
$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 {{class_name}} {}', [
'{{class_name}}' => $this->className,
]);
}
}