diff --git a/README.md b/README.md index 15b621c..be7ca14 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ An example of a PHPUnit test: normalizePaths($files)); } + + // Utility methods available: + /** + * @param iterable $paths + * + * @return list File real paths relative to the current temporary directory + */ + function normalizePaths(iterable $paths): array; + + static function safeChdir(string $directory): void; + static function safeGetCurrentWorkingDirectory(): string; } ``` diff --git a/UPGRADE.md b/UPGRADE.md index 205a0c9..2e640bd 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -2,6 +2,13 @@ - The class `FileSystem` was renamed `NativeFileSystem`. `FileSystem` is now an interface. +- Made explicit the dependency on `ext-mbstring`. If you do not have this dependency + met use [symfony/polyfill-mbstring](https://packagist.org/packages/symfony/polyfill-mbstring). - Deprecated the `::getFileContents()` method in favour of `::readFile()`. - Deprecated the `::isAbsolutePath()` method in favour of `Path::isAbsolute()`. - Deprecated the `::isRelativePath()` method in favour of `Path::isRelative()`. +- Deprecated the `::makeTmpDir()` method in favour of `::tmpDir()`. +- Deprecated the `::getNamespacedTmpDir()` method in favour of `::tmpDir()`. +- Deprecated the `FileSystemTestCase::getTmpDirNamespace()` has been removed. This was requiring too + much boilerplate. Instead, the temporary directory is now already thread safe although it no longer + creates one unique directory. diff --git a/infection.json.dist b/infection.json.dist index 0a7e046..9dbbcf5 100644 --- a/infection.json.dist +++ b/infection.json.dist @@ -40,5 +40,11 @@ "FunctionCallRemoval": false, "MethodCallRemoval": false, "PublicVisibility": false, + "ProtectedVisibility": false, + "UnwrapStrReplace": { + "ignore": [ + "Fidry\\FileSystem\\Test\\FileSystemTestCase::getTmpDirPrefix" + ] + } } } diff --git a/src/Test/FileSystemTestCase.php b/src/Test/FileSystemTestCase.php index ff6c037..c62c8cd 100644 --- a/src/Test/FileSystemTestCase.php +++ b/src/Test/FileSystemTestCase.php @@ -43,7 +43,6 @@ use function array_map; use function array_values; use function chdir; -use function dirname; use function getcwd; use function is_array; use function iterator_to_array; @@ -55,34 +54,18 @@ abstract class FileSystemTestCase extends TestCase { - protected static ?string $lastKnownTmpNamespace = null; - protected string $cwd = ''; protected string $tmp = ''; - /** - * To make it thread safe you cna make the namespace different on a thread basis, - * e.g. based on an environment variable which indicates the thread "ID". - */ - abstract public static function getTmpDirNamespace(): string; - - public static function tearDownAfterClass(): void - { - // Cleans up whatever was there before. Indeed, upon failure PHPUnit may fail to trigger the - // `tearDown()` method and as a result some temporary files may still remain. - if (null !== static::$lastKnownTmpNamespace) { - FS::remove(static::$lastKnownTmpNamespace); - } - } - protected function setUp(): void { + $tmpDirPrefix = $this->getTmpDirPrefix(); + $this->cwd = self::safeGetCurrentWorkingDirectory(); - $this->tmp = FS::makeTmpDir( - static::getTmpDirNamespace(), - static::class, - ); - static::$lastKnownTmpNamespace = dirname($this->tmp); + // We use the real path here as, for example, in OSX, the path returned + // is otherwise a link. + $this->tmp = FS::realPath(FS::tmpDir($tmpDirPrefix)); + self::safeChdir($this->tmp); } @@ -94,6 +77,9 @@ protected function tearDown(): void self::safeChdir($this->cwd); FS::remove($this->tmp); } + + $this->cwd = ''; + $this->tmp = ''; } /** @@ -118,7 +104,7 @@ final protected function normalizePaths(iterable $paths): array return array_values($normalizedPaths); } - private static function safeChdir(string $directory): void + final protected static function safeChdir(string $directory): void { $chdirResult = chdir($directory); @@ -132,7 +118,7 @@ private static function safeChdir(string $directory): void } } - private static function safeGetCurrentWorkingDirectory(): string + final protected static function safeGetCurrentWorkingDirectory(): string { $result = getcwd(); @@ -142,4 +128,14 @@ private static function safeGetCurrentWorkingDirectory(): string return $result; } + + /** + * If the test case is `App\Tests\MyFilesystemServiceTestCase`, the default prefix will be "App\Tests\MyFilesystemServiceTestCase". + * + * @return string + */ + protected function getTmpDirPrefix(): string + { + return str_replace('\\', '', static::class); + } } diff --git a/tests/Test/FilesystemTestCaseTest.php b/tests/Test/FilesystemTestCaseTest.php index 4a21e7e..f0d2aa6 100644 --- a/tests/Test/FilesystemTestCaseTest.php +++ b/tests/Test/FilesystemTestCaseTest.php @@ -41,8 +41,7 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Small; use Symfony\Component\Finder\Finder; -use function getenv; -use function is_string; +use function getcwd; /** * @internal @@ -51,22 +50,40 @@ #[Small] final class FilesystemTestCaseTest extends FileSystemTestCase { - public static function getTmpDirNamespace(): string + private string $cwdBeforeSetUp = ''; + + protected function setUp(): void + { + $this->cwdBeforeSetUp = getcwd(); + + parent::setUp(); + } + + protected function tearDown(): void { - $threadId = getenv('TEST_TOKEN'); + $tmpBeforeCleanup = $this->tmp; + + parent::tearDown(); - if (!is_string($threadId)) { - $threadId = ''; - } + $cwdAfterTearDown = getcwd(); - return 'FidryFilesystem'.$threadId; + // It is not very elegant to test in a teardown, but it's easier that + // way... + + self::assertSame('', $this->cwd, 'Expected the current working directory to have been reset.'); + self::assertSame('', $this->tmp, 'Expected the current temporary directory to have been reset.'); + self::assertSame($this->cwdBeforeSetUp, $cwdAfterTearDown, 'Expected the current working directory to have been restored.'); + self::assertDirectoryDoesNotExist($tmpBeforeCleanup, 'Expected the temporary directory to have been removed.'); } - public function test_it_works(): void + public function test_it_creates_a_temporary_directory_to_which_we_switch_to(): void { - self::assertNotNull($this->cwd); - self::assertNotNull($this->tmp); - self::assertNotNull(self::$lastKnownTmpNamespace); + $cwd = getcwd(); + + self::assertNotSame('', $this->cwd, 'Expected the current working directory to be set.'); + self::assertNotSame('', $this->tmp, 'Expected the current temporary directory to be set.'); + self::assertSame($this->cwdBeforeSetUp, $this->cwd, 'Expected the current working directory before setup to have been stored.'); + self::assertSame($this->tmp, $cwd, 'Expected the current working directory to be the temporary directory.'); } public function test_it_can_provide_the_relative_paths(): void