From 145a738b924f9e3da9d6b596d4263f7c5178eb3c Mon Sep 17 00:00:00 2001 From: Michael Reichardt Date: Sat, 2 Mar 2024 22:49:06 +0100 Subject: [PATCH] test cp step --- .../Blueprints/Runner/Step/CpStepRunner.php | 57 +++- .../Runner/Step/CpStepRunnerTest.php | 244 ++++++++++++++++++ tests/Unit/CpStepTest.php | 21 -- 3 files changed, 290 insertions(+), 32 deletions(-) create mode 100644 tests/Blueprints/Runner/Step/CpStepRunnerTest.php delete mode 100644 tests/Unit/CpStepTest.php diff --git a/src/WordPress/Blueprints/Runner/Step/CpStepRunner.php b/src/WordPress/Blueprints/Runner/Step/CpStepRunner.php index d971fb5b..faa5b979 100644 --- a/src/WordPress/Blueprints/Runner/Step/CpStepRunner.php +++ b/src/WordPress/Blueprints/Runner/Step/CpStepRunner.php @@ -2,18 +2,53 @@ namespace WordPress\Blueprints\Runner\Step; +use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Filesystem; +use WordPress\Blueprints\BlueprintException; use WordPress\Blueprints\Model\DataClass\CpStep; +class CpStepRunner extends BaseStepRunner +{ + /** + * @param CpStep $input + */ + public function run(CpStep $input) + { + $resolvedFromPath = $this->getRuntime()->resolvePath($input->fromPath); + $resolvedToPath = $this->getRuntime()->resolvePath($input->toPath); -class CpStepRunner extends BaseStepRunner { - /** - * @param CpStep $input - */ - function run( CpStep $input ) { - // @TODO: Treat the input paths as relative path to the document root (unless it's absolute) - $success = copy( $input->fromPath, $input->toPath ); - if ( ! $success ) { - throw new \Exception( "Failed to copy file from {$input->fromPath} to {$input->toPath}" ); - } - } + $fileSystem = new Filesystem(); + + try { + // TODO affirm it should overwrite newer files + // Filesystem's copy requires flag `overwriteNewerFiles` set to `true` + + // TODO affirm it should copy file to directory + // copy throws an exception when $resolvedToPath is a directory - linux would handle this: + // When the program has one or more arguments of path names of files and following those an argument + // of a path to a directory, then the program copies each source file to the destination directory, + // creating any files not already existing. + + // TODO affirm it should copy all files from one directory to another (also, ponder recursivity) + // copy throws an exception when $resolvedToPath or $resolvedFromPath are directories - linux would + // handle this: + // When the program's arguments are the path names to two directories, + // cp copies all files in the source directory to the destination directory, + // creating any files or directories needed. This mode of operation requires an additional option flag, + // typically r, to indicate the recursive copying of directories. + // If the destination directory already exists, the source is copied into the destination, + // while a new directory is created if the destination does not exist. + + // TODO establish how $input->toPath should be handled + // should copy to document root when null or when ""? + + $fileSystem->copy($resolvedFromPath, $resolvedToPath, true); + } catch (IOException $exception) { + throw new BlueprintException( + "Failed to copy file from \"$resolvedFromPath\" to \"$resolvedToPath\".", + 0, + $exception + ); + } + } } diff --git a/tests/Blueprints/Runner/Step/CpStepRunnerTest.php b/tests/Blueprints/Runner/Step/CpStepRunnerTest.php new file mode 100644 index 00000000..d13731c9 --- /dev/null +++ b/tests/Blueprints/Runner/Step/CpStepRunnerTest.php @@ -0,0 +1,244 @@ +documentRoot = Path::makeAbsolute("test", sys_get_temp_dir()); + $this->runtime = new NativePHPRuntime($this->documentRoot); + + $this->step = new CpStepRunner(); + $this->step->setRuntime($this->runtime); + + $this->fileSystem = new Filesystem(); + } + + /** + * @after + */ + public function after() + { + $this->fileSystem->remove($this->documentRoot); + } + + public function testCopiesFileWhenUsingAbsolutePath(): void + { + $relativeFromPath = "fromDir/file.txt"; + $absoluteFromPath = $this->runtime->resolvePath($relativeFromPath); + $this->fileSystem->dumpFile($absoluteFromPath, "from"); + + $relativeToPath = "toDir/file.txt"; + $absoluteToPath = $this->runtime->resolvePath($relativeToPath); + + $input = new CpStep(); + $input->fromPath = $absoluteFromPath; + $input->toPath = dirname($absoluteToPath); + + $this->step->run($input); + + $this->assertFileExists($absoluteToPath); + $this->assertFileEquals($absoluteFromPath, $absoluteToPath); + } + + public function testCopiesFileWhenUsingRelativePath(): void + { + $relativeFromPath = "fromDir/file.txt"; + $absoluteFromPath = $this->runtime->resolvePath($relativeFromPath); + $this->fileSystem->dumpFile($absoluteFromPath, "from"); + + $relativeToPath = "toDir/file.txt"; + $absoluteToPath = $this->runtime->resolvePath($relativeToPath); + + $input = new CpStep(); + $input->fromPath = $relativeFromPath; + $input->toPath = dirname($relativeToPath); + + $this->step->run($input); + + $this->assertFileExists($absoluteToPath); + $this->assertFileEquals($absoluteFromPath, $absoluteToPath); + } + + public function testCopiesAndOverwritesFileWhenToFileExistsAndIsOlder(): void + { + $relativeToPath = "toDir/file.txt"; + $absoluteToPath = $this->runtime->resolvePath($relativeToPath); + $this->fileSystem->dumpFile($absoluteToPath, "to"); + + $relativeFromPath = "fromDir/file.txt"; + $absoluteFromPath = $this->runtime->resolvePath($relativeFromPath); + $this->fileSystem->dumpFile($absoluteFromPath, "from"); + + $input = new CpStep(); + $input->fromPath = $relativeFromPath; + $input->toPath = $relativeToPath; + + $this->step->run($input); + + $this->assertFileExists($absoluteToPath); + $this->assertFileEquals($absoluteFromPath, $absoluteToPath); + } + + public function testCopiesAndOverwritesFileWhenToFileExistsAndIsNewer(): void + { + $relativeFromPath = "fromDir/file.txt"; + $absoluteFromPath = $this->runtime->resolvePath($relativeFromPath); + $this->fileSystem->dumpFile($absoluteFromPath, "from"); + + $relativeToPath = "toDir/file.txt"; + $absoluteToPath = $this->runtime->resolvePath($relativeToPath); + $this->fileSystem->dumpFile($absoluteToPath, "to"); + + $input = new CpStep(); + $input->fromPath = $relativeFromPath; + $input->toPath = $relativeToPath; + + $this->step->run($input); + + $this->assertFileExists($absoluteToPath); + $this->assertFileEquals($absoluteFromPath, $absoluteToPath); + } + + public function testCopiesFilesFromOneDirectoryToAnother(): void + { + $relativeFromPath1 = "fromDir/file1.txt"; + $absoluteFromPath1 = $this->runtime->resolvePath($relativeFromPath1); + $this->fileSystem->dumpFile($absoluteFromPath1, "from1"); + + $relativeFromPath2 = "fromDir/file2.txt"; + $absoluteFromPath2 = $this->runtime->resolvePath($relativeFromPath2); + $this->fileSystem->dumpFile($absoluteFromPath2, "from2"); + + $relativeToPath1 = "toDir/file1.txt"; + $absoluteToPath1 = $this->runtime->resolvePath($relativeToPath1); + + $relativeToPath2 = "toDir/file2.txt"; + $absoluteToPath2 = $this->runtime->resolvePath($relativeToPath2); + + $input = new CpStep(); + $input->fromPath = dirname($relativeFromPath1); + $input->toPath = dirname($relativeToPath1); + + $this->step->run($input); + + $this->assertFileExists($absoluteToPath1); + $this->assertFileEquals($absoluteFromPath1, $absoluteToPath1); + + $this->assertFileExists($absoluteToPath2); + $this->assertFileEquals($absoluteFromPath2, $absoluteToPath2); + } + + public function testCopiesFilesFromOneDirectoryToAnotherRecursively(): void + { + $relativeFromPath1 = "fromDir/file1.txt"; + $absoluteFromPath1 = $this->runtime->resolvePath($relativeFromPath1); + $this->fileSystem->dumpFile($absoluteFromPath1, "from1"); + + $relativeFromPath2 = "fromDir/subDir/file2.txt"; + $absoluteFromPath2 = $this->runtime->resolvePath($relativeFromPath2); + $this->fileSystem->dumpFile($absoluteFromPath2, "from2"); + + $relativeToPath1 = "toDir/file1.txt"; + $absoluteToPath1 = $this->runtime->resolvePath($relativeToPath1); + + $relativeToPath2 = "toDir/subDir/file2.txt"; + $absoluteToPath2 = $this->runtime->resolvePath($relativeToPath2); + + $input = new CpStep(); + $input->fromPath = dirname($relativeFromPath1); + $input->toPath = dirname($relativeToPath1); + + $this->step->run($input); + + $this->assertFileExists($absoluteToPath1); + $this->assertFileEquals($absoluteFromPath1, $absoluteToPath1); + + $this->assertFileExists($absoluteToPath2); + $this->assertFileEquals($absoluteFromPath2, $absoluteToPath2); + } + + public function testCopiesFilesToRootDirectory(): void + { + $relativeFromPath = "fromDir/file.txt"; + $absoluteFromPath = $this->runtime->resolvePath($relativeFromPath); + $this->fileSystem->dumpFile($absoluteFromPath, "from"); + + + $relativeToPath = "file.txt"; + $absoluteToPath = $this->runtime->resolvePath($relativeToPath); + + $input = new CpStep(); + $input->fromPath = $relativeFromPath; + $input->toPath = ""; + + $this->step->run($input); + + $this->assertFileExists($absoluteToPath); + $this->assertFileEquals($absoluteFromPath, $absoluteToPath); + } + + public function testThrowsExceptionWhenFromPathNotFileOrDirectory(): void + { + $relativeFromPath = "fromDir/file.txt"; + $absoluteFromPath = $this->runtime->resolvePath($relativeFromPath); + $this->fileSystem->dumpFile($absoluteFromPath, "from"); + + $input = new CpStep(); + $input->fromPath = $relativeFromPath; + // $input->toPath intentionally not set + + $this->expectException(BlueprintException::class); + $this->expectExceptionMessage("Failed to copy file from \"$absoluteFromPath\" to \"$absoluteToPath\"."); + $this->step->run($input); + } + + public function testThrowsExceptionWhenToPathNull(): void + { + $relativeFromPath = "fromDir/file.txt"; + $absoluteFromPath = $this->runtime->resolvePath($relativeFromPath); + + $relativeToPath = "toDir"; + $absoluteToPath = $this->runtime->resolvePath($relativeToPath); + + $input = new CpStep(); + $input->fromPath = $relativeFromPath; + $input->toPath = $relativeToPath; + + $this->expectException(BlueprintException::class); + $this->expectExceptionMessage("Failed to copy file from \"$absoluteFromPath\" to \"$absoluteToPath\"."); + $this->step->run($input); + } +} diff --git a/tests/Unit/CpStepTest.php b/tests/Unit/CpStepTest.php deleted file mode 100644 index 60ab03fc..00000000 --- a/tests/Unit/CpStepTest.php +++ /dev/null @@ -1,21 +0,0 @@ -execute(); -// expect(file_get_contents($file1))->toBe('lorem ipsum'); -// expect(file_get_contents($file2))->toBe('lorem ipsum'); -// });