Browse Source

add unit tests for copy method

olinox14 1 year ago
parent
commit
cb21fb8961
2 changed files with 121 additions and 28 deletions
  1. 19 26
      src/Path.php
  2. 102 2
      tests/PathTest.php

+ 19 - 26
src/Path.php

@@ -64,6 +64,10 @@ class Path
         return $path;
     }
 
+    public function withFile(string|self $path, string $mode = 'r') {
+        //TODO: do a 'with open' like method
+    }
+
     /**
      * Copies a directory and its contents recursively from the source directory to the destination directory.
      *
@@ -322,17 +326,23 @@ class Path
     }
 
     /**
-     * Copies a file to a specified destination.
+     * Copies a file or directory to the specified destination.
      *
-     * @param string|Path $destination The path to the destination file or directory to copy to.
-     * @return void
-     * @throws FileNotFoundException
-     * TODO: what about the follow_symlink condition?
+     * @param string|self $destination The destination path or object to copy the file or directory to.
+     * @throws FileNotFoundException If the source file or directory does not exist.
+     * @throws FileExistsException
      */
     public function copy(string|self $destination): void
     {
         if ($this->isFile()) {
-            copy($this->path, (string)$destination);
+            $destination = (string)$destination;
+            if (is_dir($destination)) {
+                $destination = self::join($destination, $this->basename());
+            }
+            if (is_file($destination)) {
+                throw new FileExistsException("File already exists : " . $destination);
+            }
+            copy($this->path, $destination);
         } else if ($this->isDir()) {
             self::copy_dir($this, $destination);
         } else {
@@ -343,13 +353,13 @@ class Path
     /**
      * Moves a file or directory to a new location.
      *
-     * @param string $destination The new location where the file or directory should be moved to.
+     * @param string|Path $destination The new location where the file or directory should be moved to.
      *
      * @return void
      */
-    public function move($destination): void
+    public function move(string|self $destination): void
     {
-        rename($this->path, $destination);
+        rename($this->path, (string)$destination);
     }
 
     /**
@@ -758,21 +768,4 @@ class Path
 
         return str_repeat('..' . DIRECTORY_SEPARATOR, count($other_parts)) . implode(DIRECTORY_SEPARATOR, $path_parts);
     }
-
-    /**
-     * Renames this file or directory to the given target.
-     *
-     * @param string $target
-     * @return bool
-     * @throws \RuntimeException
-     */
-    public function rename(string $target): bool
-    {
-        // Check if file or directory exists
-        if (!$this->isFile() && !$this->isDir()) {
-            throw new \RuntimeException("{$this->path} does not exist");
-        }
-
-        return rename($this->path, $target);
-    }
 }

+ 102 - 2
tests/PathTest.php

@@ -11,6 +11,7 @@ use PHPUnit\Framework\TestCase;
 class PathTest extends TestCase
 {
     const TEMP_TEST_DIR = __DIR__ . "/temp";
+    // TODO: consider using sys_get_temp_dir()
 
     protected Path $pathClass;
 
@@ -80,13 +81,13 @@ class PathTest extends TestCase
         $dst = self::TEMP_TEST_DIR . "/some_other_dir";
 
         mkdir($src);
-        mkdir($dst);
         touch($srcContent);
+        mkdir($dst);
 
         Path::copy_dir($src, $dst);
 
         $this->assertTrue(
-            file_exists($srcContent)
+            file_exists($dst . DIRECTORY_SEPARATOR . "foo.txt")
         );
     }
 
@@ -609,5 +610,104 @@ class PathTest extends TestCase
         $path->delete();
     }
 
+    /**
+     * Test 'Path' class 'copy_dir' method to copy a file
+     *
+     * @return void
+     * @throws FileExistsException
+     * @throws FileNotFoundException
+     */
+    public function testCopyWithFile(): void
+    {
+        $src = self::TEMP_TEST_DIR . "/some_dir";
+        $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
+        $dst = self::TEMP_TEST_DIR . "/some_other_dir";
+
+        mkdir($src);
+        mkdir($dst);
+        touch($srcContent);
+
+        $path = new Path($srcContent);
+        $path->copy($dst);
+
+        $this->assertTrue(
+            file_exists($dst . DIRECTORY_SEPARATOR . "foo.txt")
+        );
+    }
+
+    /**
+     * Test 'Path' class 'copy_dir' method to copy a directory
+     *
+     * @return void
+     * @throws FileExistsException
+     * @throws FileNotFoundException
+     */
+    public function testCopyWithDir(): void
+    {
+        $src = self::TEMP_TEST_DIR . "/some_dir";
+        $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
+        $dst = self::TEMP_TEST_DIR . "/some_other_dir";
+
+        mkdir($src);
+        mkdir($dst);
+        touch($srcContent);
+
+        $path = new Path($src);
+        $path->copy($dst);
 
+        $this->assertTrue(
+            file_exists($srcContent)
+        );
+    }
+
+    /**
+     * Test 'Path' class 'copy' method when the source file does not exist.
+     *
+     * @return void
+     * @throws FileExistsException
+     * @throws FileNotFoundException
+     */
+    public function testCopyFileNotExists(): void
+    {
+        $src = self::TEMP_TEST_DIR . "/some_dir";
+        $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
+        $dst = self::TEMP_TEST_DIR . "/some_other_dir";
+
+        mkdir($src);
+        mkdir($dst);
+        touch($srcContent);
+
+        $path = new Path($src);
+        $path->copy($dst);
+
+        $this->assertTrue(
+            file_exists($srcContent)
+        );
+    }
+
+    /**
+     * Test 'Path' class 'copy' method when the source file does not exist.
+     *
+     * @return void
+     * @throws FileExistsException
+     * @throws FileNotFoundException
+     */
+    public function testCopyFileDestAlreadyExists(): void
+    {
+        $src = self::TEMP_TEST_DIR . "/some_dir";
+        $srcContent = $src . DIRECTORY_SEPARATOR . "foo.txt";
+        $dst = self::TEMP_TEST_DIR . "/some_other_dir";
+        $dstContent = $dst . DIRECTORY_SEPARATOR . "foo.txt";
+
+        mkdir($src);
+        touch($srcContent);
+        mkdir($dst);
+        touch($dstContent);
+
+        $this->expectException(FileExistsException::class);
+        $this->expectExceptionMessage("File already exists : " . $dstContent);
+
+        $path = new Path($srcContent);
+        $path->copy($dst);
+    }
 }