Browse Source

add the new unit test class

olinox14 1 year ago
parent
commit
650fe40c39
4 changed files with 129 additions and 72 deletions
  1. 10 10
      src/BuiltinProxy.php
  2. 70 61
      src/Path.php
  3. 1 1
      tests/functionnal/PathTest.php
  4. 48 0
      tests/unit/PathTest.php

+ 10 - 10
src/BuiltinProxy.php

@@ -33,12 +33,12 @@ class BuiltinProxy
         return pathinfo($path, $flags);
     }
 
-    public function opendir(string $directory, $context): false|resource
+    public function opendir(string $directory, $context = null)
     {
         return opendir($directory, $context);
     }
 
-    public function mkdir(string $directory, int $permissions = 0777, bool $recursive = false, $context): bool
+    public function mkdir(string $directory, int $permissions = 0777, bool $recursive = false, $context = null): bool
     {
         return mkdir($directory, $permissions, $recursive, $context);
     }
@@ -48,7 +48,7 @@ class BuiltinProxy
         return readdir($dir_handle);
     }
 
-    public function copy(string $from, string $to, $context ): bool
+    public function copy(string $from, string $to, $context = null): bool
     {
         return copy($from, $to, $context);
     }
@@ -58,17 +58,17 @@ class BuiltinProxy
         closedir($dir_handle);
     }
 
-    public function scandir(string $directory, int $sorting_order = 0, $context ): array|false
+    public function scandir(string $directory, int $sorting_order = 0, $context = null): array|false
     {
         return scandir($directory, $sorting_order, $context);
     }
 
-    public function unlink(string $filename, $context): bool
+    public function unlink(string $filename, $context = null): bool
     {
         return unlink($filename, $context);
     }
 
-    public function rmdir(string $directory, $context): bool
+    public function rmdir(string $directory, $context = null): bool
     {
         return rmdir($directory, $context);
     }
@@ -118,7 +118,7 @@ class BuiltinProxy
         return chdir($directory);
     }
 
-    public function rename(string $from, string $to, $context): bool
+    public function rename(string $from, string $to, $context = null): bool
     {
         return rename($from, $to, $context);
     }
@@ -138,12 +138,12 @@ class BuiltinProxy
         return dirname($path, $levels);
     }
 
-    public function file_get_contents(string $filename, bool $use_include_path = false, $context, int $offset = 0, ?int $length): false|string
+    public function file_get_contents(string $filename, bool $use_include_path = false, $context = null, int $offset = 0, ?int $length = null): false|string
     {
         return file_get_contents($filename, $use_include_path, $context, $offset, $length);
     }
 
-    public function file_put_contents(string $filename, mixed $data, int $flags = 0, $context ): false|int
+    public function file_put_contents(string $filename, mixed $data, int $flags = 0, $context = null): false|int
     {
         return file_put_contents($filename, $data, $flags, $context);
     }
@@ -183,7 +183,7 @@ class BuiltinProxy
         return glob($pattern, $flags);
     }
 
-    public function fopen(string $filename, string $mode, bool $use_include_path = false, $context ): false|resource
+    public function fopen(string $filename, string $mode, bool $use_include_path = false, $context = null)
     {
         return fopen($filename, $mode, $use_include_path, $context);
     }

+ 70 - 61
src/Path.php

@@ -36,7 +36,13 @@ class Path
     protected string $path;
 
     protected mixed $handle;
+    protected BuiltinProxy $builtin;
 
+    /**
+     * Returns a new instance of the current class, initialized with the constant __DIR__ as the path.
+     *
+     * @return self A new instance of the current class.
+     */
     public static function here(): self
     {
         return new self(__DIR__);
@@ -169,6 +175,8 @@ class Path
 
     public function __construct(string $path)
     {
+        $this->builtin = new BuiltinProxy();
+        
         $this->path = $path;
         $this->handle = null;
         return $this;
@@ -221,7 +229,7 @@ class Path
      */
     public function abspath(): string
     {
-        return realpath($this->path);
+        return $this->builtin->realpath($this->path);
     }
 
     /**
@@ -239,10 +247,10 @@ class Path
     function access(int $mode): bool
     {
         return match ($mode) {
-            self::F_OK => file_exists($this->path),
-            self::R_OK => is_readable($this->path),
-            self::W_OK => is_writable($this->path),
-            self::X_OK => is_executable($this->path),
+            self::F_OK => $this->builtin->file_exists($this->path),
+            self::R_OK => $this->builtin->is_readable($this->path),
+            self::W_OK => $this->builtin->is_writable($this->path),
+            self::X_OK => $this->builtin->is_executable($this->path),
             default => throw new RuntimeException('Invalid mode'),
         };
     }
@@ -254,7 +262,7 @@ class Path
      */
     function atime(): ?string
     {
-        $time = fileatime($this->path);
+        $time = $this->builtin->fileatime($this->path);
         if ($time === false) {
             return null;
         }
@@ -268,7 +276,7 @@ class Path
      */
     function ctime(): ?string
     {
-        $time = filectime($this->path);
+        $time = $this->builtin->filectime($this->path);
         if ($time === false) {
             return null;
         }
@@ -282,7 +290,7 @@ class Path
      */
     function mtime(): ?string
     {
-        $time = filemtime($this->path);
+        $time = $this->builtin->filemtime($this->path);
         if ($time === false) {
             return null;
         }
@@ -296,7 +304,7 @@ class Path
      */
     public function isFile(): bool
     {
-        return is_file($this->path);
+        return $this->builtin->is_file($this->path);
     }
 
     /**
@@ -306,7 +314,7 @@ class Path
      */
     public function isDir(): bool
     {
-        return is_dir($this->path);
+        return $this->builtin->is_dir($this->path);
     }
 
     /**
@@ -316,7 +324,7 @@ class Path
      */
     public function ext(): string
     {
-        return pathinfo($this->path, PATHINFO_EXTENSION);
+        return $this->builtin->pathinfo($this->path, PATHINFO_EXTENSION);
     }
 
     /**
@@ -326,7 +334,7 @@ class Path
      */
     public function basename(): string
     {
-        return pathinfo($this->path, PATHINFO_BASENAME);
+        return $this->builtin->pathinfo($this->path, PATHINFO_BASENAME);
     }
 
     /**
@@ -338,7 +346,7 @@ class Path
      */
     public function cd(string|self $path): bool
     {
-        return chdir((string)$path);
+        return $this->builtin->chdir((string)$path);
     }
 
     /**
@@ -359,7 +367,7 @@ class Path
      */
     public function name(): string
     {
-        return pathinfo($this->path, PATHINFO_FILENAME);
+        return $this->builtin->pathinfo($this->path, PATHINFO_FILENAME);
     }
 
     public function normcase()
@@ -395,7 +403,7 @@ class Path
             throw new FileExistsException("A file with this name already exists : " . $this);
         }
 
-        mkdir($this->path, $mode, $recursive);
+        $this->builtin->mkdir($this->path, $mode, $recursive);
     }
 
     /**
@@ -407,9 +415,9 @@ class Path
     public function delete(): void
     {
         if ($this->isFile()) {
-            unlink($this->path);
+            $this->builtin->unlink($this->path);
         } else if ($this->isDir()) {
-            rmdir($this->path);
+            $this->builtin->rmdir($this->path);
         } else {
             throw new FileNotFoundException("File does not exist : " . $this);
         }
@@ -432,15 +440,15 @@ class Path
         }
 
         $destination = (string)$destination;
-        if (is_dir($destination)) {
+        if ($this->builtin->is_dir($destination)) {
             $destination = self::join($destination, $this->basename());
         }
 
-        if (file_exists($destination)) {
+        if ($this->builtin->file_exists($destination)) {
             throw new FileExistsException("File already exists : " . $destination);
         }
 
-        $success = copy($this->path, $destination);
+        $success = $this->builtin->copy($this->path, $destination);
         if (!$success) {
             throw new IOException("Error copying file {$this->path} to {$destination}");
         }
@@ -463,15 +471,15 @@ class Path
         // TODO: voir à faire la synthèse de copytree et https://path.readthedocs.io/en/latest/api.html#path.Path.merge_tree
         if ($this->isFile()) {
             $destination = (string)$destination;
-            if (is_dir($destination)) {
+            if ($this->builtin->is_dir($destination)) {
                 $destination = self::join($destination, $this->basename());
             }
 
-            if (file_exists($destination)) {
+            if ($this->builtin->file_exists($destination)) {
                 throw new FileExistsException("File or dir already exists : " . $destination);
             }
 
-            $success = copy($this->path, $destination);
+            $success = $this->builtin->copy($this->path, $destination);
             if (!$success) {
                 throw new IOException("Error copying file {$this->path} to {$destination}");
             }
@@ -496,13 +504,13 @@ class Path
     {
         // TODO: comparer à https://path.readthedocs.io/en/latest/api.html#path.Path.move
         $destination = (string)$destination;
-        if (is_dir($destination)) {
+        if ($this->builtin->is_dir($destination)) {
             $destination = self::join($destination, $this->basename());
         }
-        if (file_exists($destination)) {
+        if ($this->builtin->file_exists($destination)) {
             throw new FileExistsException("File or dir already exists : " . $destination);
         }
-        rename($this->path, $destination);
+        $this->builtin->rename($this->path, $destination);
     }
 
     /**
@@ -521,7 +529,7 @@ class Path
         if ($atime instanceof \DateTime) {
             $atime = $atime->getTimestamp();
         }
-        touch($this->path, $time, $atime);
+        $this->builtin->touch($this->path, $time, $atime);
     }
 
     /**
@@ -531,7 +539,7 @@ class Path
      */
     public function lastModified(): bool|int
     {
-        return filemtime($this->path);
+        return $this->builtin->filemtime($this->path);
     }
 
     /**
@@ -545,7 +553,7 @@ class Path
         if (!$this->isFile()) {
             throw new FileNotFoundException("File does not exist : " . $this->path);
         }
-        return filesize($this->path);
+        return $this->builtin->filesize($this->path);
     }
 
     /**
@@ -556,7 +564,7 @@ class Path
     public function parent(): self
     {
         // TODO: check on special cases
-        return new self(dirname($this->path));
+        return new self($this->builtin->dirname($this->path));
     }
 
     /**
@@ -581,17 +589,17 @@ class Path
      */
     public function dirs(): array
     {
-        if (!is_dir($this->path)) {
+        if (!$this->builtin->is_dir($this->path)) {
             throw new FileNotFoundException("Directory does not exist: " . $this->path);
         }
 
         $dirs = [];
 
-        foreach (scandir($this->path) as $filename) {
+        foreach ($this->builtin->scandir($this->path) as $filename) {
             if ('.' === $filename) continue;
             if ('..' === $filename) continue;
 
-            if (is_dir(self::join($this->path, $filename))) {
+            if ($this->builtin->is_dir(self::join($this->path, $filename))) {
                 $dirs[] = $filename;
             }
         }
@@ -607,17 +615,17 @@ class Path
      */
     public function files(): array
     {
-        if (!is_dir($this->path)) {
+        if (!$this->builtin->is_dir($this->path)) {
             throw new FileNotFoundException("Directory does not exist: " . $this->path);
         }
 
         $files = [];
 
-        foreach (scandir($this->path) as $filename) {
+        foreach ($this->builtin->scandir($this->path) as $filename) {
             if ('.' === $filename) continue;
             if ('..' === $filename) continue;
 
-            if (is_file(self::join($this->path, $filename))) {
+            if ($this->builtin->is_file(self::join($this->path, $filename))) {
                 $files[] = $filename;
             }
         }
@@ -641,7 +649,7 @@ class Path
         if (!$this->isFile()) {
             throw new FileNotFoundException("File does not exist : " . $this->path);
         }
-        $text = file_get_contents($this->path);
+        $text = $this->builtin->file_get_contents($this->path);
         if ($text === false) {
             throw new IOException("Error reading file {$this->path}");
         }
@@ -664,7 +672,7 @@ class Path
         // TODO: review use-cases
         // TODO: complete the input types
         // TODO: add a condition on the creation of the file if not existing
-        file_put_contents($this->path, $content);
+        $this->builtin->file_put_contents($this->path, $content);
     }
 
     public function putLines(array $lines): void
@@ -672,7 +680,7 @@ class Path
         // TODO: review use-cases
         // TODO: complete the input types
         // TODO: add a condition on the creation of the file if not existing
-        file_put_contents($this->path, implode(PHP_EOL, $lines));
+        $this->builtin->file_put_contents($this->path, implode(PHP_EOL, $lines));
     }
 
     /**
@@ -687,7 +695,7 @@ class Path
         // TODO: review use-cases
         // TODO: complete the input types
         // TODO: add a condition on the creation of the file if not existing
-        file_put_contents($this->path, $content, FILE_APPEND);
+        $this->builtin->file_put_contents($this->path, $content, FILE_APPEND);
     }
 
     /**
@@ -701,7 +709,7 @@ class Path
         if (!$this->isFile()) {
             throw new FileNotFoundException("File or dir does not exist : " . $this->path);
         }
-        return (int)substr(sprintf('%o', fileperms($this->path)), -4);
+        return (int)substr(sprintf('%o', $this->builtin->fileperms($this->path)), -4);
     }
 
     // TODO; add some more user-friendly methods to get permissions (read, write, exec...)
@@ -718,8 +726,8 @@ class Path
         if (!$this->isFile()) {
             throw new FileNotFoundException("File or dir does not exist : " . $this->path);
         }
-        clearstatcache(); // TODO: check for a better way of dealing with PHP cache
-        return chmod($this->path, $permissions);
+        $this->builtin->clearstatcache(); // TODO: check for a better way of dealing with PHP cache
+        return $this->builtin->chmod($this->path, $permissions);
     }
 
     /**
@@ -735,10 +743,10 @@ class Path
         if (!$this->isFile()) {
             throw new FileNotFoundException("File or dir does not exist : " . $this->path);
         }
-        clearstatcache(); // TODO: check for a better way of dealing with PHP cache
+        $this->builtin->clearstatcache(); // TODO: check for a better way of dealing with PHP cache
         return
-            chown($this->path, $user) &&
-            chgrp($this->path, $group);
+            $this->builtin->chown($this->path, $user) &&
+            $this->builtin->chgrp($this->path, $group);
     }
 
     public function setATime()
@@ -765,7 +773,7 @@ class Path
      */
     public function exists(): bool
     {
-        return file_exists($this->path);
+        return $this->builtin->file_exists($this->path);
     }
 
     public function samefile()
@@ -794,9 +802,10 @@ class Path
      * @param string $pattern The pattern to search for.
      * @return Generator An iterable list of objects representing files and directories that match the pattern.
      */
-    public static function glob(string $pattern): Generator
+    public function glob(string $pattern): Generator
     {
-        foreach (glob($pattern) as $filename) {
+        // TODO: concat $this->path and $pattern?
+        foreach ($this->builtin->glob($pattern) as $filename) {
             yield new static($filename);
         }
     }
@@ -817,14 +826,14 @@ class Path
      */
     public function rmdir(bool $recursive = false): void
     {
-        if (!is_dir($this->path)) {
+        if (!$this->builtin->is_dir($this->path)) {
             throw new FileNotFoundException("{$this->path} is not a directory");
         }
 
         if ($recursive) {
             self::_rrmdir($this->path);
         } else {
-            rmdir($this->path);
+            $this->builtin->rmdir($this->path);
         }
     }
 
@@ -882,7 +891,7 @@ class Path
             throw new FileNotFoundException("{$this->path} is not a file");
         }
 
-        $handle = fopen($this->path, $mode);
+        $handle = $this->builtin->fopen($this->path, $mode);
         if ($handle === false) {
             throw new IOException("Failed opening file {$this->path}");
         }
@@ -903,7 +912,7 @@ class Path
         try {
             return $callback($handle);
         } finally {
-            fclose($handle);
+            $this->builtin->fclose($handle);
         }
     }
 
@@ -920,11 +929,11 @@ class Path
     {
         $handle = $this->open('rb');
         try {
-            while (!feof($handle)) {
-                yield fread($handle, $chunk_size);
+            while (!$this->builtin->feof($handle)) {
+                yield $this->builtin->fread($handle, $chunk_size);
             }
         } finally {
-            fclose($handle);
+            $this->builtin->fclose($handle);
         }
     }
 
@@ -972,7 +981,7 @@ class Path
      */
     public function chroot(): bool
     {
-        return chroot($this->path);
+        return $this->builtin->chroot($this->path);
     }
 
     /**
@@ -982,7 +991,7 @@ class Path
      */
     public function isLink(): bool
     {
-        return is_link($this->path);
+        return $this->builtin->is_link($this->path);
     }
 
     public function isMount()
@@ -1034,7 +1043,7 @@ class Path
         if (!function_exists('link')) {
             return false;
         }
-        return link($this->path, $target);
+        return $this->builtin->link($this->path, $target);
     }
 
     /**
@@ -1044,7 +1053,7 @@ class Path
      */
     public function lstat(): bool|array
     {
-        return lstat($this->path);
+        return $this->builtin->lstat($this->path);
     }
 
     public function splitDrive()
@@ -1103,7 +1112,7 @@ class Path
         $path = $this->abspath();
         $basePath = (string)$basePath;
 
-        $realBasePath = realpath($basePath);
+        $realBasePath = $this->builtin->realpath($basePath);
         if ($realBasePath === false) {
             throw new FileNotFoundException("$basePath does not exist or unable to get a real path");
         }

+ 1 - 1
tests/PathTest.php → tests/functionnal/PathTest.php

@@ -1,6 +1,6 @@
 <?php
 
-namespace Path\Tests;
+namespace Path\Tests\functionnal;
 
 use Path\Exception\FileExistsException;
 use Path\Exception\FileNotFoundException;

+ 48 - 0
tests/unit/PathTest.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace Path\Tests\unit;
+
+use Path\BuiltinProxy;
+use Path\Path;
+use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\TestCase;
+
+class TestablePath extends Path {
+    public function setBuiltin(BuiltinProxy $builtinProxy): void
+    {
+        $this->builtin = $builtinProxy;
+    }
+}
+
+class PathTest extends TestCase
+{
+    private BuiltinProxy | MockObject $builtin;
+
+    public function setUp(): void
+    {
+        $this->builtin = $this->getMockBuilder(BuiltinProxy::class)->getMock();
+    }
+
+    public function getPathMockForMethod(string $path, string $methodName): TestablePath | MockObject
+    {
+        $mock = $this
+            ->getMockBuilder(TestablePath::class)
+            ->setConstructorArgs([$path])
+            ->setMethodsExcept(['setBuiltin', $methodName])
+            ->getMock();
+        $mock->setBuiltin($this->builtin);
+        return $mock;
+    }
+
+    public function testAbsPath(): void {
+        $path = $this->getPathMockForMethod('bar', 'absPath');
+
+        $this->builtin
+            ->expects(self::once())
+            ->method('realpath')
+            ->with('bar')
+            ->willReturn('/foo/bar');
+
+        $this->assertEquals('/foo/bar', $path->absPath());
+    }
+}