tests/Cache/FilesystemTest.php
40555fc1
 <?php
 
2119e60c
 namespace Twig\Tests\Cache;
 
40555fc1
 /*
  * 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.
  */
 
34bdab4d
 use PHPUnit\Framework\TestCase;
1ddb8253
 use Twig\Cache\FilesystemCache;
2119e60c
 use Twig\Tests\FilesystemHelper;
1ddb8253
 
34bdab4d
 class FilesystemTest extends TestCase
40555fc1
 {
aa159678
     private $classname;
     private $directory;
     private $cache;
40555fc1
 
6a50ca06
     protected function setUp(): void
40555fc1
     {
c6601a15
         $nonce = hash('sha256', uniqid(mt_rand(), true));
         $this->classname = '__Twig_Tests_Cache_FilesystemTest_Template_'.$nonce;
         $this->directory = sys_get_temp_dir().'/twig-test';
1ddb8253
         $this->cache = new FilesystemCache($this->directory);
40555fc1
     }
 
6a50ca06
     protected function tearDown(): void
40555fc1
     {
         if (file_exists($this->directory)) {
2119e60c
             FilesystemHelper::removeDir($this->directory);
40555fc1
         }
     }
 
     public function testLoad()
     {
         $key = $this->directory.'/cache/cachefile.php';
 
98a15a89
         $dir = \dirname($key);
40555fc1
         @mkdir($dir, 0777, true);
b776e41f
         $this->assertDirectoryExists($dir);
40555fc1
         $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();
 
aa71a65f
         $this->assertFileNotExists($key);
         $this->assertFileNotExists($this->directory);
40555fc1
 
         $this->cache->write($key, $content);
 
aa71a65f
         $this->assertFileExists($this->directory);
         $this->assertFileExists($key);
40555fc1
         $this->assertSame(file_get_contents($key), $content);
     }
 
     public function testWriteFailMkdir()
     {
5ebcecf2
         $this->expectException(\RuntimeException::class);
b776e41f
         $this->expectExceptionMessage('Unable to create the cache directory');
 
98a15a89
         if (\defined('PHP_WINDOWS_VERSION_BUILD')) {
c6601a15
             $this->markTestSkipped('Read-only directories not possible on Windows.');
         }
 
40555fc1
         $key = $this->directory.'/cache/cachefile.php';
         $content = $this->generateSource();
 
52af84c1
         $this->assertFileNotExists($key);
40555fc1
 
         // Create read-only root directory.
         @mkdir($this->directory, 0555, true);
b776e41f
         $this->assertDirectoryExists($this->directory);
40555fc1
 
         $this->cache->write($key, $content);
     }
 
     public function testWriteFailDirWritable()
     {
5ebcecf2
         $this->expectException(\RuntimeException::class);
b776e41f
         $this->expectExceptionMessage('Unable to write in the cache directory');
 
98a15a89
         if (\defined('PHP_WINDOWS_VERSION_BUILD')) {
c6601a15
             $this->markTestSkipped('Read-only directories not possible on Windows.');
         }
 
40555fc1
         $key = $this->directory.'/cache/cachefile.php';
         $content = $this->generateSource();
 
52af84c1
         $this->assertFileNotExists($key);
40555fc1
 
         // Create root directory.
         @mkdir($this->directory, 0777, true);
         // Create read-only subdirectory.
c96ffc31
         @mkdir($this->directory.'/cache', 0555);
b776e41f
         $this->assertDirectoryExists($this->directory.'/cache');
40555fc1
 
         $this->cache->write($key, $content);
     }
 
     public function testWriteFailWriteFile()
     {
5ebcecf2
         $this->expectException(\RuntimeException::class);
b776e41f
         $this->expectExceptionMessage('Failed to write cache file');
 
40555fc1
         $key = $this->directory.'/cache/cachefile.php';
         $content = $this->generateSource();
 
52af84c1
         $this->assertFileNotExists($key);
40555fc1
 
         // Create a directory in the place of the cache file.
         @mkdir($key, 0777, true);
b776e41f
         $this->assertDirectoryExists($key);
40555fc1
 
         $this->cache->write($key, $content);
     }
 
     public function testGetTimestamp()
     {
         $key = $this->directory.'/cache/cachefile.php';
 
98a15a89
         $dir = \dirname($key);
40555fc1
         @mkdir($dir, 0777, true);
b776e41f
         $this->assertDirectoryExists($dir);
40555fc1
 
         // 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));
     }
 
c3ec2fb1
     /**
      * Test file cache is tolerant towards trailing (back)slashes on the configured cache directory.
      *
      * @dataProvider provideDirectories
      */
     public function testGenerateKey($expected, $input)
     {
1ddb8253
         $cache = new FilesystemCache($input);
98a15a89
         $this->assertRegExp($expected, $cache->generateKey('_test_', \get_class($this)));
c3ec2fb1
     }
 
     public function provideDirectories()
     {
         $pattern = '#a/b/[a-zA-Z0-9]+/[a-zA-Z0-9]+.php$#';
 
5c55243d
         return [
             [$pattern, 'a/b'],
             [$pattern, 'a/b/'],
             [$pattern, 'a/b\\'],
             [$pattern, 'a/b\\/'],
             [$pattern, 'a/b\\//'],
             ['#/'.substr($pattern, 1), '/a/b'],
         ];
c3ec2fb1
     }
 
40555fc1
     private function generateSource()
     {
5c55243d
         return strtr('<?php class {{classname}} {}', [
40555fc1
             '{{classname}}' => $this->classname,
5c55243d
         ]);
40555fc1
     }
 }