From 23a1edcaf9950eb4053c256cc68ef595ee79dde3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=C5=A1ek=20Brychta?= Date: Mon, 23 Aug 2021 22:42:15 +0200 Subject: [PATCH 01/11] Adding IsExistingDirectory matcher Merge IsExistingDirectoryPathTest to IsExistingDirectoryTest --- README.md | 14 ++ hamcrest/Hamcrest.php | 13 ++ .../Hamcrest/File/IsExistingDirectory.php | 76 ++++++++++ hamcrest/Hamcrest/Matchers.php | 11 ++ .../Hamcrest/File/IsExistingDirectoryTest.php | 136 ++++++++++++++++++ 5 files changed, 250 insertions(+) create mode 100644 hamcrest/Hamcrest/File/IsExistingDirectory.php create mode 100644 tests/Hamcrest/File/IsExistingDirectoryTest.php diff --git a/README.md b/README.md index 52e20413a..513ebbd28 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,8 @@ Available Matchers ------------------ * [Array](../master/README.md#array) * [Collection](../master/README.md#collection) +* [Core](../master/README.md#core) +* [File](../master/README.md#file) * [Object](../master/README.md#object) * [Numbers](../master/README.md#numbers) * [Type checking](../master/README.md#type-checking) @@ -227,6 +229,18 @@ assertThat([2, 4, 6], hasItem(equalTo(2))); assertThat([1, 3, 5], hasItems(equalTo(1), equalTo(3))); ``` +### File + +All file matchers accepts `\SplFileInfo` objects or `string` paths only. + +* `anExistingDirectory` - evaluates to true if the file exists and is a directory +```php +$directory = new \SplFileInfo('/var/log'); +assertThat($directory, anExistingDirectory()); + +assertThat('/var/log', anExistingDirectory()); +``` + ### Object * `hasToString` - check `__toString` or `toString` method diff --git a/hamcrest/Hamcrest.php b/hamcrest/Hamcrest.php index 55a2dd8c5..ed7e76aa2 100644 --- a/hamcrest/Hamcrest.php +++ b/hamcrest/Hamcrest.php @@ -507,6 +507,19 @@ function notSet($property) } } +if (!function_exists('anExistingDirectory')) { + /** + * Evaluates to true if the file exists and is a directory. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsExistingDirectory + */ + function anExistingDirectory() + { + return \Hamcrest\File\IsExistingDirectory::anExistingDirectory(); + } +} + if (!function_exists('closeTo')) { /** * Matches if value is a number equal to $value within some range of diff --git a/hamcrest/Hamcrest/File/IsExistingDirectory.php b/hamcrest/Hamcrest/File/IsExistingDirectory.php new file mode 100644 index 000000000..ba9215c0d --- /dev/null +++ b/hamcrest/Hamcrest/File/IsExistingDirectory.php @@ -0,0 +1,76 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\BaseMatcher; +use Hamcrest\Description; + +class IsExistingDirectory extends BaseMatcher +{ + public function describeTo(Description $description) + { + $description->appendText('an existing directory'); + } + + final public function matches($item) + { + return $this->isSafeType($item) && $this->matchesFile($this->createSplFileInfoObjectFromPath($item)); + } + + final public function describeMismatch($item, Description $mismatchDescription) + { + if ($this->isSafeType($item)) + { + $this->describeFileMismatch($this->createSplFileInfoObjectFromPath($item), $mismatchDescription); + } + else + { + parent::describeMismatch($item, $mismatchDescription); + } + } + + private function matchesFile(\SplFileInfo $file): bool + { + return $file->isDir(); + } + + private function describeFileMismatch(\SplFileInfo $file, Description $mismatchDescription) + { + $mismatchDescription->appendValue($file)->appendText(' is not a directory'); + } + + private function isSafeType($value): bool + { + return $value instanceof \SplFileInfo || is_string($value); + } + + /** + * @param string|\SplFileInfo $item + * @return \SplFileInfo + */ + private function createSplFileInfoObjectFromPath($item): \SplFileInfo + { + if (is_string($item)) + return new \SplFileInfo($item); + + return $item; + } + + /** + * Evaluates to true if the file exists and is a directory. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsExistingDirectory + * @factory + */ + public static function anExistingDirectory() + { + return new self(); + } +} \ No newline at end of file diff --git a/hamcrest/Hamcrest/Matchers.php b/hamcrest/Hamcrest/Matchers.php index 23232e450..a8ea29143 100644 --- a/hamcrest/Hamcrest/Matchers.php +++ b/hamcrest/Hamcrest/Matchers.php @@ -411,6 +411,17 @@ public static function notSet($property) return \Hamcrest\Core\Set::notSet($property); } + /** + * Evaluates to true if the file exists and is a directory. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsExistingDirectory + */ + public static function anExistingDirectory() + { + return \Hamcrest\File\IsExistingDirectory::anExistingDirectory(); + } + /** * Matches if value is a number equal to $value within some range of * acceptable error $delta. diff --git a/tests/Hamcrest/File/IsExistingDirectoryTest.php b/tests/Hamcrest/File/IsExistingDirectoryTest.php new file mode 100644 index 000000000..49461de1f --- /dev/null +++ b/tests/Hamcrest/File/IsExistingDirectoryTest.php @@ -0,0 +1,136 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\AbstractMatcherTest; + +class IsExistingDirectoryTest extends AbstractMatcherTest +{ + private static $EXISTING_DIRECTORY_PATH; + private static $NON_EXISTING_DIRECTORY_PATH; + private static $EXISTING_FILE_PATH; + + private static $EXISTING_DIRECTORY; + private static $NON_EXISTING_DIRECTORY; + private static $EXISTING_FILE; + + /** + * @beforeClass + */ + public static function initializeFiles() + { + self::$EXISTING_DIRECTORY_PATH = __DIR__; + self::$NON_EXISTING_DIRECTORY_PATH = __DIR__ . '/does-not-exist'; + self::$EXISTING_FILE_PATH = __FILE__; + + self::$EXISTING_DIRECTORY = new \SplFileInfo(self::$EXISTING_DIRECTORY_PATH); + self::$NON_EXISTING_DIRECTORY = new \SplFileInfo(self::$NON_EXISTING_DIRECTORY_PATH); + self::$EXISTING_FILE = new \SplFileInfo(self::$EXISTING_FILE_PATH); + } + + protected function createMatcher() + { + return IsExistingDirectory::anExistingDirectory(); + } + + public function testMatchesAnExistingDirectory() + { + $this->assertMatches( + $this->createMatcher(), + self::$EXISTING_DIRECTORY, + "should match a directory that actualy exists" + ); + } + + public function testMatchesAnExistingDirectoryPath() + { + $this->assertMatches( + $this->createMatcher(), + self::$EXISTING_DIRECTORY_PATH, + "should match a path to directory that actualy exists" + ); + } + + public function testDoesNotMatchADirectoryThatDoesNotExist() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$NON_EXISTING_DIRECTORY, + "should not match a directory that does not exist" + ); + } + + public function testDoesNotMatchADirectoryPathThatDoesNotExist() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$NON_EXISTING_DIRECTORY_PATH, + "should not match a path to directory that does not exist" + ); + } + + public function testDoesNotMatchAnExistingFileThatIsNotADirectory() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$EXISTING_FILE, + "should not match an existing file that is not a directory" + ); + } + + public function testDoesNotMatchAnExistingFilePathThatIsNotADirectory() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$EXISTING_FILE_PATH, + "should not match a path to existing file that is not a directory" + ); + } + + public function testDoesNotMatchNull() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + null, + 'should not match null' + ); + } + + public function testHasAReadableDescription() + { + $this->assertDescription('an existing directory', $this->createMatcher()); + } + + public function testHasAReadableMissmatchDescription() + { + $this->assertMismatchDescription( + '<' . self::$NON_EXISTING_DIRECTORY . '> is not a directory', + $this->createMatcher(), + self::$NON_EXISTING_DIRECTORY + ); + } + + public function testHasAReadableMissmatchDescriptionForPath() + { + $this->assertMismatchDescription( + '<' . self::$NON_EXISTING_DIRECTORY_PATH . '> is not a directory', + $this->createMatcher(), + self::$NON_EXISTING_DIRECTORY_PATH + ); + } + + public function testHasAReadableTypeMissmatchDescription() + { + $this->assertMismatchDescription( + 'was ', + $this->createMatcher(), + new \stdClass() + ); + } +} \ No newline at end of file From de2beb5502ae40f136ee155eda27c03e5f6ea9a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=C5=A1ek=20Brychta?= Date: Mon, 23 Aug 2021 22:47:26 +0200 Subject: [PATCH 02/11] Adding IsExistingFile matcher Merge IsExistingFilePathTest to IsExistingFileTest --- README.md | 8 ++ hamcrest/Hamcrest.php | 13 ++ hamcrest/Hamcrest/File/IsExistingFile.php | 76 ++++++++++++ hamcrest/Hamcrest/Matchers.php | 11 ++ tests/Hamcrest/File/IsExistingFileTest.php | 136 +++++++++++++++++++++ 5 files changed, 244 insertions(+) create mode 100644 hamcrest/Hamcrest/File/IsExistingFile.php create mode 100644 tests/Hamcrest/File/IsExistingFileTest.php diff --git a/README.md b/README.md index 513ebbd28..52d96de2d 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,14 @@ assertThat($directory, anExistingDirectory()); assertThat('/var/log', anExistingDirectory()); ``` +* `anExistingFile` - evaluates to true if the file exists and is a regular file +```php +$file = new \SplFileInfo('/var/log/php-fpm.log'); +assertThat($file, anExistingFile()); + +assertThat('/var/log/php-fpm.log', anExistingFile()); +``` + ### Object * `hasToString` - check `__toString` or `toString` method diff --git a/hamcrest/Hamcrest.php b/hamcrest/Hamcrest.php index ed7e76aa2..b4edf9b40 100644 --- a/hamcrest/Hamcrest.php +++ b/hamcrest/Hamcrest.php @@ -520,6 +520,19 @@ function anExistingDirectory() } } +if (!function_exists('anExistingFile')) { + /** + * Evaluates to true if the file exists and is a regular file. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsExistingFile + */ + function anExistingFile() + { + return \Hamcrest\File\IsExistingFile::anExistingFile(); + } +} + if (!function_exists('closeTo')) { /** * Matches if value is a number equal to $value within some range of diff --git a/hamcrest/Hamcrest/File/IsExistingFile.php b/hamcrest/Hamcrest/File/IsExistingFile.php new file mode 100644 index 000000000..ccf1b7fb3 --- /dev/null +++ b/hamcrest/Hamcrest/File/IsExistingFile.php @@ -0,0 +1,76 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\BaseMatcher; +use Hamcrest\Description; + +class IsExistingFile extends BaseMatcher +{ + public function describeTo(Description $description) + { + $description->appendText('an existing file'); + } + + final public function matches($item) + { + return $this->isSafeType($item) && $this->matchesFile($this->createSplFileInfoObjectFromPath($item)); + } + + final public function describeMismatch($item, Description $mismatchDescription) + { + if ($this->isSafeType($item)) + { + $this->describeFileMismatch($this->createSplFileInfoObjectFromPath($item), $mismatchDescription); + } + else + { + parent::describeMismatch($item, $mismatchDescription); + } + } + + private function matchesFile(\SplFileInfo $file): bool + { + return $file->isFile(); + } + + private function describeFileMismatch(\SplFileInfo $file, Description $mismatchDescription) + { + $mismatchDescription->appendValue($file)->appendText(' is not a file'); + } + + private function isSafeType($value): bool + { + return $value instanceof \SplFileInfo || is_string($value); + } + + /** + * @param string|\SplFileInfo $item + * @return \SplFileInfo + */ + private function createSplFileInfoObjectFromPath($item): \SplFileInfo + { + if (is_string($item)) + return new \SplFileInfo($item); + + return $item; + } + + /** + * Evaluates to true if the file exists and is a regular file. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsExistingFile + * @factory + */ + public static function anExistingFile() + { + return new self(); + } +} \ No newline at end of file diff --git a/hamcrest/Hamcrest/Matchers.php b/hamcrest/Hamcrest/Matchers.php index a8ea29143..0d66ff154 100644 --- a/hamcrest/Hamcrest/Matchers.php +++ b/hamcrest/Hamcrest/Matchers.php @@ -422,6 +422,17 @@ public static function anExistingDirectory() return \Hamcrest\File\IsExistingDirectory::anExistingDirectory(); } + /** + * Evaluates to true if the file exists and is a regular file. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsExistingFile + */ + public static function anExistingFile() + { + return \Hamcrest\File\IsExistingFile::anExistingFile(); + } + /** * Matches if value is a number equal to $value within some range of * acceptable error $delta. diff --git a/tests/Hamcrest/File/IsExistingFileTest.php b/tests/Hamcrest/File/IsExistingFileTest.php new file mode 100644 index 000000000..1a8801222 --- /dev/null +++ b/tests/Hamcrest/File/IsExistingFileTest.php @@ -0,0 +1,136 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\AbstractMatcherTest; + +class IsExistingFileTest extends AbstractMatcherTest +{ + private static $EXISTING_FILE_PATH; + private static $NON_EXISTING_FILE_PATH; + private static $EXISTING_DIRECTORY_PATH; + + private static $EXISTING_FILE; + private static $NON_EXISTING_FILE; + private static $EXISTING_DIRECTORY; + + /** + * @beforeClass + */ + public static function initializeFiles() + { + self::$EXISTING_FILE_PATH = __FILE__; + self::$NON_EXISTING_FILE_PATH = __DIR__ . '/does-not-exist'; + self::$EXISTING_DIRECTORY_PATH = __DIR__; + + self::$EXISTING_FILE = new \SplFileInfo(self::$EXISTING_FILE_PATH); + self::$NON_EXISTING_FILE = new \SplFileInfo(self::$NON_EXISTING_FILE_PATH); + self::$EXISTING_DIRECTORY = new \SplFileInfo(self::$EXISTING_DIRECTORY_PATH); + } + + protected function createMatcher() + { + return IsExistingFile::anExistingFile(); + } + + public function testMatchesAnExistingFile() + { + $this->assertMatches( + $this->createMatcher(), + self::$EXISTING_FILE, + "should match a file that actualy exists" + ); + } + + public function testMatchesAnExistingFilePath() + { + $this->assertMatches( + $this->createMatcher(), + self::$EXISTING_FILE_PATH, + "should match a path to file that actualy exists" + ); + } + + public function testDoesNotMatchAFileThatDoesNotExist() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$NON_EXISTING_FILE, + "should not match a file that does not exist" + ); + } + + public function testDoesNotMatchAFilePathThatDoesNotExist() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$NON_EXISTING_FILE_PATH, + "should not match a path to file that does not exist" + ); + } + + public function testDoesNotMatchAnExistingDirectory() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$EXISTING_DIRECTORY, + "should not match an existing directory" + ); + } + + public function testDoesNotMatchAnExistingDirectoryPath() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$EXISTING_DIRECTORY_PATH, + "should not match a path to existing directory" + ); + } + + public function testDoesNotMatchNull() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + null, + 'should not match null' + ); + } + + public function testHasAReadableDescription() + { + $this->assertDescription('an existing file', $this->createMatcher()); + } + + public function testHasAReadableMissmatchDescription() + { + $this->assertMismatchDescription( + '<' . self::$NON_EXISTING_FILE . '> is not a file', + $this->createMatcher(), + self::$NON_EXISTING_FILE + ); + } + + public function testHasAReadableMissmatchDescriptionForPath() + { + $this->assertMismatchDescription( + '<' . self::$NON_EXISTING_FILE_PATH . '> is not a file', + $this->createMatcher(), + self::$NON_EXISTING_FILE_PATH + ); + } + + public function testHasAReadableTypeMissmatchDescription() + { + $this->assertMismatchDescription( + 'was ', + $this->createMatcher(), + new \stdClass() + ); + } +} \ No newline at end of file From 0576f7335d466b1ef3493bc2d417cd1c6c84c00d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=C5=A1ek=20Brychta?= Date: Mon, 23 Aug 2021 22:55:26 +0200 Subject: [PATCH 03/11] Extracting common file matchers behavior to FileMatcher class --- hamcrest/Hamcrest/File/FileMatcher.php | 76 +++++++++++++++++++ .../Hamcrest/File/IsExistingDirectory.php | 50 +----------- hamcrest/Hamcrest/File/IsExistingFile.php | 47 +----------- 3 files changed, 84 insertions(+), 89 deletions(-) create mode 100644 hamcrest/Hamcrest/File/FileMatcher.php diff --git a/hamcrest/Hamcrest/File/FileMatcher.php b/hamcrest/Hamcrest/File/FileMatcher.php new file mode 100644 index 000000000..eb592a042 --- /dev/null +++ b/hamcrest/Hamcrest/File/FileMatcher.php @@ -0,0 +1,76 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\BaseMatcher; +use Hamcrest\Description; + +abstract class FileMatcher extends BaseMatcher +{ + /** @var string */ + private $ownDescription; + /** @var string */ + private $failureDescription; + + /** + * @param string $ownDescription + * @param string $failureDescription + */ + public function __construct($ownDescription, $failureDescription) + { + $this->ownDescription = $ownDescription; + $this->failureDescription = $failureDescription; + } + + public function describeTo(Description $description) + { + $description->appendText($this->ownDescription); + } + + final public function matches($item) + { + return $this->isSafeType($item) && $this->matchesFile($this->createSplFileInfoObjectFromPath($item)); + } + + final public function describeMismatch($item, Description $mismatchDescription) + { + if ($this->isSafeType($item)) + { + $this->describeFileMismatch($this->createSplFileInfoObjectFromPath($item), $mismatchDescription); + } + else + { + parent::describeMismatch($item, $mismatchDescription); + } + } + + abstract protected function matchesFile(\SplFileInfo $file): bool; + + protected function describeFileMismatch(\SplFileInfo $file, Description $mismatchDescription) + { + $mismatchDescription->appendValue($file)->appendText(' ')->appendText($this->failureDescription); + } + + private function isSafeType($value): bool + { + return $value instanceof \SplFileInfo || is_string($value); + } + + /** + * @param string|\SplFileInfo $item + * @return \SplFileInfo + */ + private function createSplFileInfoObjectFromPath($item): \SplFileInfo + { + if (is_string($item)) + return new \SplFileInfo($item); + + return $item; + } +} \ No newline at end of file diff --git a/hamcrest/Hamcrest/File/IsExistingDirectory.php b/hamcrest/Hamcrest/File/IsExistingDirectory.php index ba9215c0d..a17bba895 100644 --- a/hamcrest/Hamcrest/File/IsExistingDirectory.php +++ b/hamcrest/Hamcrest/File/IsExistingDirectory.php @@ -8,60 +8,18 @@ namespace Hamcrest\File; -use Hamcrest\BaseMatcher; -use Hamcrest\Description; - -class IsExistingDirectory extends BaseMatcher +class IsExistingDirectory extends FileMatcher { - public function describeTo(Description $description) - { - $description->appendText('an existing directory'); - } - - final public function matches($item) - { - return $this->isSafeType($item) && $this->matchesFile($this->createSplFileInfoObjectFromPath($item)); - } - - final public function describeMismatch($item, Description $mismatchDescription) + public function __construct() { - if ($this->isSafeType($item)) - { - $this->describeFileMismatch($this->createSplFileInfoObjectFromPath($item), $mismatchDescription); - } - else - { - parent::describeMismatch($item, $mismatchDescription); - } + parent::__construct('an existing directory', 'is not a directory'); } - private function matchesFile(\SplFileInfo $file): bool + protected function matchesFile(\SplFileInfo $file): bool { return $file->isDir(); } - private function describeFileMismatch(\SplFileInfo $file, Description $mismatchDescription) - { - $mismatchDescription->appendValue($file)->appendText(' is not a directory'); - } - - private function isSafeType($value): bool - { - return $value instanceof \SplFileInfo || is_string($value); - } - - /** - * @param string|\SplFileInfo $item - * @return \SplFileInfo - */ - private function createSplFileInfoObjectFromPath($item): \SplFileInfo - { - if (is_string($item)) - return new \SplFileInfo($item); - - return $item; - } - /** * Evaluates to true if the file exists and is a directory. * Accepts only \SplFileInfo objects or string paths. diff --git a/hamcrest/Hamcrest/File/IsExistingFile.php b/hamcrest/Hamcrest/File/IsExistingFile.php index ccf1b7fb3..046196b3c 100644 --- a/hamcrest/Hamcrest/File/IsExistingFile.php +++ b/hamcrest/Hamcrest/File/IsExistingFile.php @@ -11,57 +11,18 @@ use Hamcrest\BaseMatcher; use Hamcrest\Description; -class IsExistingFile extends BaseMatcher +class IsExistingFile extends FileMatcher { - public function describeTo(Description $description) + public function __construct() { - $description->appendText('an existing file'); + parent::__construct('an existing file', 'is not a file'); } - final public function matches($item) - { - return $this->isSafeType($item) && $this->matchesFile($this->createSplFileInfoObjectFromPath($item)); - } - - final public function describeMismatch($item, Description $mismatchDescription) - { - if ($this->isSafeType($item)) - { - $this->describeFileMismatch($this->createSplFileInfoObjectFromPath($item), $mismatchDescription); - } - else - { - parent::describeMismatch($item, $mismatchDescription); - } - } - - private function matchesFile(\SplFileInfo $file): bool + protected function matchesFile(\SplFileInfo $file): bool { return $file->isFile(); } - private function describeFileMismatch(\SplFileInfo $file, Description $mismatchDescription) - { - $mismatchDescription->appendValue($file)->appendText(' is not a file'); - } - - private function isSafeType($value): bool - { - return $value instanceof \SplFileInfo || is_string($value); - } - - /** - * @param string|\SplFileInfo $item - * @return \SplFileInfo - */ - private function createSplFileInfoObjectFromPath($item): \SplFileInfo - { - if (is_string($item)) - return new \SplFileInfo($item); - - return $item; - } - /** * Evaluates to true if the file exists and is a regular file. * Accepts only \SplFileInfo objects or string paths. From 7d90e18615722fa22faed47febe49744eb351080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=C5=A1ek=20Brychta?= Date: Mon, 6 Sep 2021 21:57:14 +0200 Subject: [PATCH 04/11] Making the code PHP 5.3 compatible --- hamcrest/Hamcrest/File/FileMatcher.php | 19 ++++++++++++++----- .../Hamcrest/File/IsExistingDirectory.php | 4 +--- hamcrest/Hamcrest/File/IsExistingFile.php | 7 +------ .../Hamcrest/File/IsExistingDirectoryTest.php | 2 -- tests/Hamcrest/File/IsExistingFileTest.php | 2 -- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/hamcrest/Hamcrest/File/FileMatcher.php b/hamcrest/Hamcrest/File/FileMatcher.php index eb592a042..cf4e20c0c 100644 --- a/hamcrest/Hamcrest/File/FileMatcher.php +++ b/hamcrest/Hamcrest/File/FileMatcher.php @@ -1,7 +1,5 @@ */ @@ -50,14 +48,25 @@ final public function describeMismatch($item, Description $mismatchDescription) } } - abstract protected function matchesFile(\SplFileInfo $file): bool; + /** + * Implement this method to provide the actual functionality of the matcher. + * It is guaranteed that the {@link $file} parameter is always {@code \SplFileInfo}. + * + * @param \SplFileInfo $file + * @return bool + */ + abstract protected function matchesFile(\SplFileInfo $file); protected function describeFileMismatch(\SplFileInfo $file, Description $mismatchDescription) { $mismatchDescription->appendValue($file)->appendText(' ')->appendText($this->failureDescription); } - private function isSafeType($value): bool + /** + * @param $value + * @return bool + */ + private function isSafeType($value) { return $value instanceof \SplFileInfo || is_string($value); } @@ -66,7 +75,7 @@ private function isSafeType($value): bool * @param string|\SplFileInfo $item * @return \SplFileInfo */ - private function createSplFileInfoObjectFromPath($item): \SplFileInfo + private function createSplFileInfoObjectFromPath($item) { if (is_string($item)) return new \SplFileInfo($item); diff --git a/hamcrest/Hamcrest/File/IsExistingDirectory.php b/hamcrest/Hamcrest/File/IsExistingDirectory.php index a17bba895..0cfd95385 100644 --- a/hamcrest/Hamcrest/File/IsExistingDirectory.php +++ b/hamcrest/Hamcrest/File/IsExistingDirectory.php @@ -1,7 +1,5 @@ */ @@ -15,7 +13,7 @@ public function __construct() parent::__construct('an existing directory', 'is not a directory'); } - protected function matchesFile(\SplFileInfo $file): bool + protected function matchesFile(\SplFileInfo $file) { return $file->isDir(); } diff --git a/hamcrest/Hamcrest/File/IsExistingFile.php b/hamcrest/Hamcrest/File/IsExistingFile.php index 046196b3c..ed15e84b2 100644 --- a/hamcrest/Hamcrest/File/IsExistingFile.php +++ b/hamcrest/Hamcrest/File/IsExistingFile.php @@ -1,16 +1,11 @@ */ namespace Hamcrest\File; -use Hamcrest\BaseMatcher; -use Hamcrest\Description; - class IsExistingFile extends FileMatcher { public function __construct() @@ -18,7 +13,7 @@ public function __construct() parent::__construct('an existing file', 'is not a file'); } - protected function matchesFile(\SplFileInfo $file): bool + protected function matchesFile(\SplFileInfo $file) { return $file->isFile(); } diff --git a/tests/Hamcrest/File/IsExistingDirectoryTest.php b/tests/Hamcrest/File/IsExistingDirectoryTest.php index 49461de1f..8b6ef6112 100644 --- a/tests/Hamcrest/File/IsExistingDirectoryTest.php +++ b/tests/Hamcrest/File/IsExistingDirectoryTest.php @@ -1,7 +1,5 @@ */ diff --git a/tests/Hamcrest/File/IsExistingFileTest.php b/tests/Hamcrest/File/IsExistingFileTest.php index 1a8801222..2606ce905 100644 --- a/tests/Hamcrest/File/IsExistingFileTest.php +++ b/tests/Hamcrest/File/IsExistingFileTest.php @@ -1,7 +1,5 @@ */ From c992e71c8b525e851ed3c6b6a04578d2b2463ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=C5=A1ek=20Brychta?= Date: Mon, 6 Sep 2021 21:58:24 +0200 Subject: [PATCH 05/11] Reformatting to maintain project code style --- hamcrest/Hamcrest/File/FileMatcher.php | 22 ++++++++++++------- .../Hamcrest/File/IsExistingDirectory.php | 2 +- hamcrest/Hamcrest/File/IsExistingFile.php | 2 +- .../Hamcrest/File/IsExistingDirectoryTest.php | 2 +- tests/Hamcrest/File/IsExistingFileTest.php | 2 +- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/hamcrest/Hamcrest/File/FileMatcher.php b/hamcrest/Hamcrest/File/FileMatcher.php index cf4e20c0c..dc9d5857a 100644 --- a/hamcrest/Hamcrest/File/FileMatcher.php +++ b/hamcrest/Hamcrest/File/FileMatcher.php @@ -11,9 +11,18 @@ abstract class FileMatcher extends BaseMatcher { - /** @var string */ + /** + * Description of the matcher that will be returned from the {@link describeTo()} method. + * + * @var string + */ private $ownDescription; - /** @var string */ + + /** + * Description of a mismatch for the matcher, it will be prepended by the actual value that does not match. + * + * @var string + */ private $failureDescription; /** @@ -38,12 +47,9 @@ final public function matches($item) final public function describeMismatch($item, Description $mismatchDescription) { - if ($this->isSafeType($item)) - { + if ($this->isSafeType($item)) { $this->describeFileMismatch($this->createSplFileInfoObjectFromPath($item), $mismatchDescription); - } - else - { + } else { parent::describeMismatch($item, $mismatchDescription); } } @@ -82,4 +88,4 @@ private function createSplFileInfoObjectFromPath($item) return $item; } -} \ No newline at end of file +} diff --git a/hamcrest/Hamcrest/File/IsExistingDirectory.php b/hamcrest/Hamcrest/File/IsExistingDirectory.php index 0cfd95385..d8e39ba0e 100644 --- a/hamcrest/Hamcrest/File/IsExistingDirectory.php +++ b/hamcrest/Hamcrest/File/IsExistingDirectory.php @@ -29,4 +29,4 @@ public static function anExistingDirectory() { return new self(); } -} \ No newline at end of file +} diff --git a/hamcrest/Hamcrest/File/IsExistingFile.php b/hamcrest/Hamcrest/File/IsExistingFile.php index ed15e84b2..3dc20685c 100644 --- a/hamcrest/Hamcrest/File/IsExistingFile.php +++ b/hamcrest/Hamcrest/File/IsExistingFile.php @@ -29,4 +29,4 @@ public static function anExistingFile() { return new self(); } -} \ No newline at end of file +} diff --git a/tests/Hamcrest/File/IsExistingDirectoryTest.php b/tests/Hamcrest/File/IsExistingDirectoryTest.php index 8b6ef6112..01929402e 100644 --- a/tests/Hamcrest/File/IsExistingDirectoryTest.php +++ b/tests/Hamcrest/File/IsExistingDirectoryTest.php @@ -131,4 +131,4 @@ public function testHasAReadableTypeMissmatchDescription() new \stdClass() ); } -} \ No newline at end of file +} diff --git a/tests/Hamcrest/File/IsExistingFileTest.php b/tests/Hamcrest/File/IsExistingFileTest.php index 2606ce905..574c96554 100644 --- a/tests/Hamcrest/File/IsExistingFileTest.php +++ b/tests/Hamcrest/File/IsExistingFileTest.php @@ -131,4 +131,4 @@ public function testHasAReadableTypeMissmatchDescription() new \stdClass() ); } -} \ No newline at end of file +} From 900240fbbe0498fe7837c76c0f1d05f7948c29bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=C5=A1ek=20Brychta?= Date: Fri, 24 Sep 2021 21:28:06 +0200 Subject: [PATCH 06/11] Adding IsExistingFileOrDirectory matcher --- README.md | 11 ++ hamcrest/Hamcrest.php | 13 ++ .../File/IsExistingFileOrDirectory.php | 32 +++++ hamcrest/Hamcrest/Matchers.php | 11 ++ .../File/IsExistingFileOrDirectoryTest.php | 134 ++++++++++++++++++ 5 files changed, 201 insertions(+) create mode 100644 hamcrest/Hamcrest/File/IsExistingFileOrDirectory.php create mode 100644 tests/Hamcrest/File/IsExistingFileOrDirectoryTest.php diff --git a/README.md b/README.md index 52d96de2d..3a10a6b26 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,17 @@ assertThat($file, anExistingFile()); assertThat('/var/log/php-fpm.log', anExistingFile()); ``` +* `anExistingFileOrDirectory` - evaluates to true if the file exists and is a regular file or a directory +```php +$directory = new \SplFileInfo('/var/log'); +$file = new \SplFileInfo('/var/log/php-fpm.log'); +assertThat($directory, anExistingFileOrDirectory()); +assertThat($file, anExistingFileOrDirectory()); + +assertThat('/var/log', anExistingFileOrDirectory()); +assertThat('/var/log/php-fpm.log', anExistingFileOrDirectory()); +``` + ### Object * `hasToString` - check `__toString` or `toString` method diff --git a/hamcrest/Hamcrest.php b/hamcrest/Hamcrest.php index b4edf9b40..38e2ae462 100644 --- a/hamcrest/Hamcrest.php +++ b/hamcrest/Hamcrest.php @@ -533,6 +533,19 @@ function anExistingFile() } } +if (!function_exists('anExistingFileOrDirectory')) { + /** + * Evaluates to true if the file exists and is a regular file or a directory. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsExistingFileOrDirectory + */ + function anExistingFileOrDirectory() + { + return \Hamcrest\File\IsExistingFileOrDirectory::anExistingFileOrDirectory(); + } +} + if (!function_exists('closeTo')) { /** * Matches if value is a number equal to $value within some range of diff --git a/hamcrest/Hamcrest/File/IsExistingFileOrDirectory.php b/hamcrest/Hamcrest/File/IsExistingFileOrDirectory.php new file mode 100644 index 000000000..d7ae8ec6b --- /dev/null +++ b/hamcrest/Hamcrest/File/IsExistingFileOrDirectory.php @@ -0,0 +1,32 @@ + + */ + +namespace Hamcrest\File; + +class IsExistingFileOrDirectory extends FileMatcher +{ + public function __construct() + { + parent::__construct('an existing file or directory', 'does not exist'); + } + + protected function matchesFile(\SplFileInfo $file) + { + return $file->isFile() || $file->isDir(); + } + + /** + * Evaluates to true if the file exists and is a regular file or a directory. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsExistingFileOrDirectory + * @factory + */ + public static function anExistingFileOrDirectory() + { + return new self(); + } +} diff --git a/hamcrest/Hamcrest/Matchers.php b/hamcrest/Hamcrest/Matchers.php index 0d66ff154..117dd5765 100644 --- a/hamcrest/Hamcrest/Matchers.php +++ b/hamcrest/Hamcrest/Matchers.php @@ -433,6 +433,17 @@ public static function anExistingFile() return \Hamcrest\File\IsExistingFile::anExistingFile(); } + /** + * Evaluates to true if the file exists and is a regular file or a directory. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsExistingFileOrDirectory + */ + public static function anExistingFileOrDirectory() + { + return \Hamcrest\File\IsExistingFileOrDirectory::anExistingFileOrDirectory(); + } + /** * Matches if value is a number equal to $value within some range of * acceptable error $delta. diff --git a/tests/Hamcrest/File/IsExistingFileOrDirectoryTest.php b/tests/Hamcrest/File/IsExistingFileOrDirectoryTest.php new file mode 100644 index 000000000..6bf2e2d7a --- /dev/null +++ b/tests/Hamcrest/File/IsExistingFileOrDirectoryTest.php @@ -0,0 +1,134 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\AbstractMatcherTest; + +class IsExistingFileOrDirectoryTest extends AbstractMatcherTest +{ + private static $EXISTING_FILE_PATH; + private static $EXISTING_DIRECTORY_PATH; + private static $NON_EXISTING_FILE_PATH; + + private static $EXISTING_FILE; + private static $EXISTING_DIRECTORY; + private static $NON_EXISTING_FILE; + + /** + * @beforeClass + */ + public static function initializeFiles() + { + self::$EXISTING_FILE_PATH = __FILE__; + self::$EXISTING_DIRECTORY_PATH = __DIR__; + self::$NON_EXISTING_FILE_PATH = __DIR__ . '/does-not-exist'; + + self::$EXISTING_FILE = new \SplFileInfo(self::$EXISTING_FILE_PATH); + self::$EXISTING_DIRECTORY = new \SplFileInfo(self::$EXISTING_DIRECTORY_PATH); + self::$NON_EXISTING_FILE = new \SplFileInfo(self::$NON_EXISTING_FILE_PATH); + } + + protected function createMatcher() + { + return IsExistingFileOrDirectory::anExistingFileOrDirectory(); + } + + public function testMatchesAnExistingFile() + { + $this->assertMatches( + $this->createMatcher(), + self::$EXISTING_FILE, + "should match a file that actualy exists" + ); + } + + public function testMatchesAnExistingFilePath() + { + $this->assertMatches( + $this->createMatcher(), + self::$EXISTING_FILE_PATH, + "should match a path to file that actualy exists" + ); + } + + public function testMatchesAnExistingDirectory() + { + $this->assertMatches( + $this->createMatcher(), + self::$EXISTING_DIRECTORY, + "should match an existing directory" + ); + } + + public function testMatchesAnExistingDirectoryPath() + { + $this->assertMatches( + $this->createMatcher(), + self::$EXISTING_DIRECTORY_PATH, + "should match a path to existing directory" + ); + } + + public function testDoesNotMatchAFileThatDoesNotExist() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$NON_EXISTING_FILE, + "should not match a file that does not exist" + ); + } + + public function testDoesNotMatchAFilePathThatDoesNotExist() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$NON_EXISTING_FILE_PATH, + "should not match a path to file that does not exist" + ); + } + + public function testDoesNotMatchNull() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + null, + 'should not match null' + ); + } + + public function testHasAReadableDescription() + { + $this->assertDescription('an existing file or directory', $this->createMatcher()); + } + + public function testHasAReadableMissmatchDescription() + { + $this->assertMismatchDescription( + '<' . self::$NON_EXISTING_FILE . '> does not exist', + $this->createMatcher(), + self::$NON_EXISTING_FILE + ); + } + + public function testHasAReadableMissmatchDescriptionForPath() + { + $this->assertMismatchDescription( + '<' . self::$NON_EXISTING_FILE_PATH . '> does not exist', + $this->createMatcher(), + self::$NON_EXISTING_FILE_PATH + ); + } + + public function testHasAReadableTypeMissmatchDescription() + { + $this->assertMismatchDescription( + 'was ', + $this->createMatcher(), + new \stdClass() + ); + } +} From f857e2e7aa2754e2a0c622948fb694bb38010262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=C5=A1ek=20Brychta?= Date: Fri, 24 Sep 2021 21:39:26 +0200 Subject: [PATCH 07/11] Adding IsReadableFile matcher --- README.md | 8 ++ hamcrest/Hamcrest.php | 13 +++ hamcrest/Hamcrest/File/IsReadableFile.php | 32 +++++++ hamcrest/Hamcrest/Matchers.php | 11 +++ tests/Hamcrest/File/IsReadableFileTest.php | 98 ++++++++++++++++++++++ 5 files changed, 162 insertions(+) create mode 100644 hamcrest/Hamcrest/File/IsReadableFile.php create mode 100644 tests/Hamcrest/File/IsReadableFileTest.php diff --git a/README.md b/README.md index 3a10a6b26..ae5638ffb 100644 --- a/README.md +++ b/README.md @@ -260,6 +260,14 @@ assertThat('/var/log', anExistingFileOrDirectory()); assertThat('/var/log/php-fpm.log', anExistingFileOrDirectory()); ``` +* `aReadableFile` - evaluates to true if the file is readable +```php +$file = new \SplFileInfo('/var/log/php-fpm.log'); +assertThat($file, aReadableFile()); + +assertThat('/var/log/php-fpm.log', aReadableFile()); +``` + ### Object * `hasToString` - check `__toString` or `toString` method diff --git a/hamcrest/Hamcrest.php b/hamcrest/Hamcrest.php index 38e2ae462..fb0935d19 100644 --- a/hamcrest/Hamcrest.php +++ b/hamcrest/Hamcrest.php @@ -546,6 +546,19 @@ function anExistingFileOrDirectory() } } +if (!function_exists('aReadableFile')) { + /** + * Evaluates to true if the file is readable. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsReadableFile + */ + function aReadableFile() + { + return \Hamcrest\File\IsReadableFile::aReadableFile(); + } +} + if (!function_exists('closeTo')) { /** * Matches if value is a number equal to $value within some range of diff --git a/hamcrest/Hamcrest/File/IsReadableFile.php b/hamcrest/Hamcrest/File/IsReadableFile.php new file mode 100644 index 000000000..54ce4d125 --- /dev/null +++ b/hamcrest/Hamcrest/File/IsReadableFile.php @@ -0,0 +1,32 @@ + + */ + +namespace Hamcrest\File; + +class IsReadableFile extends FileMatcher +{ + public function __construct() + { + parent::__construct('a readable file', 'cannot be read'); + } + + protected function matchesFile(\SplFileInfo $file) + { + return $file->isReadable(); + } + + /** + * Evaluates to true if the file is readable. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsReadableFile + * @factory + */ + public static function aReadableFile() + { + return new self(); + } +} diff --git a/hamcrest/Hamcrest/Matchers.php b/hamcrest/Hamcrest/Matchers.php index 117dd5765..bfeae8520 100644 --- a/hamcrest/Hamcrest/Matchers.php +++ b/hamcrest/Hamcrest/Matchers.php @@ -444,6 +444,17 @@ public static function anExistingFileOrDirectory() return \Hamcrest\File\IsExistingFileOrDirectory::anExistingFileOrDirectory(); } + /** + * Evaluates to true if the file is readable. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsReadableFile + */ + public static function aReadableFile() + { + return \Hamcrest\File\IsReadableFile::aReadableFile(); + } + /** * Matches if value is a number equal to $value within some range of * acceptable error $delta. diff --git a/tests/Hamcrest/File/IsReadableFileTest.php b/tests/Hamcrest/File/IsReadableFileTest.php new file mode 100644 index 000000000..ac8954a1c --- /dev/null +++ b/tests/Hamcrest/File/IsReadableFileTest.php @@ -0,0 +1,98 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\AbstractMatcherTest; + +class IsReadableFileTest extends AbstractMatcherTest +{ + private static $READABLE_FILE_PATH; + + private static $READABLE_FILE; + private static $NON_READABLE_FILE; + + /** + * @beforeClass + */ + public static function initializeFiles() + { + self::$READABLE_FILE_PATH = __FILE__; + + self::$READABLE_FILE = new \SplFileInfo(self::$READABLE_FILE_PATH); + + self::$NON_READABLE_FILE = new class('/tmp/non-readable') extends \SplFileInfo { + public function isReadable() + { + return false; + } + }; + } + + protected function createMatcher() + { + return IsReadableFile::aReadableFile(); + } + + public function testMatchesAReadableFile() + { + $this->assertMatches( + $this->createMatcher(), + self::$READABLE_FILE, + "should match a file that is readable" + ); + } + + public function testMatchesAReadableFilePath() + { + $this->assertMatches( + $this->createMatcher(), + self::$READABLE_FILE_PATH, + "should match a path to file that is readable" + ); + } + + public function testDoesNotMatchAFileThatIsNotReadable() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$NON_READABLE_FILE, + "should not match a file that is not readable" + ); + } + + public function testDoesNotMatchNull() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + null, + 'should not match null' + ); + } + + public function testHasAReadableDescription() + { + $this->assertDescription('a readable file', $this->createMatcher()); + } + + public function testHasAReadableMissmatchDescription() + { + $this->assertMismatchDescription( + '<' . self::$NON_READABLE_FILE . '> cannot be read', + $this->createMatcher(), + self::$NON_READABLE_FILE + ); + } + + public function testHasAReadableTypeMissmatchDescription() + { + $this->assertMismatchDescription( + 'was ', + $this->createMatcher(), + new \stdClass() + ); + } +} From 38958e968ec46db5da52e00c2a530c2dd8e0a133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=C5=A1ek=20Brychta?= Date: Fri, 24 Sep 2021 21:44:46 +0200 Subject: [PATCH 08/11] Adding IsWritableFile matcher --- README.md | 8 ++ hamcrest/Hamcrest.php | 13 +++ hamcrest/Hamcrest/File/IsWritableFile.php | 32 +++++++ hamcrest/Hamcrest/Matchers.php | 11 +++ tests/Hamcrest/File/IsWritableFileTest.php | 98 ++++++++++++++++++++++ 5 files changed, 162 insertions(+) create mode 100644 hamcrest/Hamcrest/File/IsWritableFile.php create mode 100644 tests/Hamcrest/File/IsWritableFileTest.php diff --git a/README.md b/README.md index ae5638ffb..2e98d5923 100644 --- a/README.md +++ b/README.md @@ -268,6 +268,14 @@ assertThat($file, aReadableFile()); assertThat('/var/log/php-fpm.log', aReadableFile()); ``` +* `aWritableFile` - evaluates to true if the file is writable +```php +$file = new \SplFileInfo('/var/log/php-fpm.log'); +assertThat($file, aWritableFile()); + +assertThat('/var/log/php-fpm.log', aWritableFile()); +``` + ### Object * `hasToString` - check `__toString` or `toString` method diff --git a/hamcrest/Hamcrest.php b/hamcrest/Hamcrest.php index fb0935d19..5981de8a1 100644 --- a/hamcrest/Hamcrest.php +++ b/hamcrest/Hamcrest.php @@ -559,6 +559,19 @@ function aReadableFile() } } +if (!function_exists('aWritableFile')) { + /** + * Evaluates to true if the file is writable. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsWritableFile + */ + function aWritableFile() + { + return \Hamcrest\File\IsWritableFile::aWritableFile(); + } +} + if (!function_exists('closeTo')) { /** * Matches if value is a number equal to $value within some range of diff --git a/hamcrest/Hamcrest/File/IsWritableFile.php b/hamcrest/Hamcrest/File/IsWritableFile.php new file mode 100644 index 000000000..9603f79af --- /dev/null +++ b/hamcrest/Hamcrest/File/IsWritableFile.php @@ -0,0 +1,32 @@ + + */ + +namespace Hamcrest\File; + +class IsWritableFile extends FileMatcher +{ + public function __construct() + { + parent::__construct('a writable file', 'cannot be written to'); + } + + protected function matchesFile(\SplFileInfo $file) + { + return $file->isWritable(); + } + + /** + * Evaluates to true if the file is writable. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsWritableFile + * @factory + */ + public static function aWritableFile() + { + return new self(); + } +} diff --git a/hamcrest/Hamcrest/Matchers.php b/hamcrest/Hamcrest/Matchers.php index bfeae8520..a115785a5 100644 --- a/hamcrest/Hamcrest/Matchers.php +++ b/hamcrest/Hamcrest/Matchers.php @@ -455,6 +455,17 @@ public static function aReadableFile() return \Hamcrest\File\IsReadableFile::aReadableFile(); } + /** + * Evaluates to true if the file is writable. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\File\IsWritableFile + */ + public static function aWritableFile() + { + return \Hamcrest\File\IsWritableFile::aWritableFile(); + } + /** * Matches if value is a number equal to $value within some range of * acceptable error $delta. diff --git a/tests/Hamcrest/File/IsWritableFileTest.php b/tests/Hamcrest/File/IsWritableFileTest.php new file mode 100644 index 000000000..686a420b6 --- /dev/null +++ b/tests/Hamcrest/File/IsWritableFileTest.php @@ -0,0 +1,98 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\AbstractMatcherTest; + +class IsWritableFileTest extends AbstractMatcherTest +{ + private static $WRITABLE_FILE_PATH; + + private static $WRITABLE_FILE; + private static $NON_WRITABLE_FILE; + + /** + * @beforeClass + */ + public static function initializeFiles() + { + self::$WRITABLE_FILE_PATH = __FILE__; + + self::$WRITABLE_FILE = new \SplFileInfo(self::$WRITABLE_FILE_PATH); + + self::$NON_WRITABLE_FILE = new class('/tmp/non-writable') extends \SplFileInfo { + public function isWritable() + { + return false; + } + }; + } + + protected function createMatcher() + { + return IsWritableFile::aWritableFile(); + } + + public function testMatchesAWritableFile() + { + $this->assertMatches( + $this->createMatcher(), + self::$WRITABLE_FILE, + "should match a file that is writable" + ); + } + + public function testMatchesAWritableFilePath() + { + $this->assertMatches( + $this->createMatcher(), + self::$WRITABLE_FILE_PATH, + "should match a path to file that is writable" + ); + } + + public function testDoesNotMatchAFileThatIsNotWritable() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + self::$NON_WRITABLE_FILE, + "should not match a file that is not writable" + ); + } + + public function testDoesNotMatchNull() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + null, + 'should not match null' + ); + } + + public function testHasAReadableDescription() + { + $this->assertDescription('a writable file', $this->createMatcher()); + } + + public function testHasAReadableMissmatchDescription() + { + $this->assertMismatchDescription( + '<' . self::$NON_WRITABLE_FILE . '> cannot be written to', + $this->createMatcher(), + self::$NON_WRITABLE_FILE + ); + } + + public function testHasAReadableTypeMissmatchDescription() + { + $this->assertMismatchDescription( + 'was ', + $this->createMatcher(), + new \stdClass() + ); + } +} From 4234a1e9dce4b8602587dfb5e32bef99cb5c87d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=C5=A1ek=20Brychta?= Date: Fri, 24 Sep 2021 23:18:23 +0200 Subject: [PATCH 09/11] Adding IsFileWithSize matcher --- README.md | 26 +++ hamcrest/Hamcrest.php | 41 +++++ hamcrest/Hamcrest/Core/DescribedAs.php | 5 + hamcrest/Hamcrest/File/FileMatcher.php | 2 +- hamcrest/Hamcrest/File/IsFileWithSize.php | 92 ++++++++++ hamcrest/Hamcrest/Matchers.php | 35 ++++ tests/Hamcrest/File/IsFileWithSizeTest.php | 204 +++++++++++++++++++++ 7 files changed, 404 insertions(+), 1 deletion(-) create mode 100644 hamcrest/Hamcrest/File/IsFileWithSize.php create mode 100644 tests/Hamcrest/File/IsFileWithSizeTest.php diff --git a/README.md b/README.md index 2e98d5923..e143ad8d7 100644 --- a/README.md +++ b/README.md @@ -276,6 +276,32 @@ assertThat($file, aWritableFile()); assertThat('/var/log/php-fpm.log', aWritableFile()); ``` +* `aFileWithSize` - evaluates to true if the file size is equal to given value or the provided matcher matches the file size +```php +$file = new \SplFileInfo('/var/log/php-fpm.log'); +assertThat($file, aFileWithSize(42)); +assertThat($file, aFileWithSize(greaterThan(42))); + +assertThat('/var/log/php-fpm.log', aFileWithSize(42)); +assertThat('/var/log/php-fpm.log', aFileWithSize(greaterThan(42))); +``` + +* `anEmptyFile` - evaluates to true if the file is empty +```php +$file = new \SplFileInfo('/var/log/php-fpm.log'); +assertThat($file, anEmptyFile()); + +assertThat('/var/log/php-fpm.log', anEmptyFile()); +``` + +* `aNonEmptyFile` - evaluates to true if the file is not empty +```php +$file = new \SplFileInfo('/var/log/php-fpm.log'); +assertThat($file, aNonEmptyFile()); + +assertThat('/var/log/php-fpm.log', aNonEmptyFile()); +``` + ### Object * `hasToString` - check `__toString` or `toString` method diff --git a/hamcrest/Hamcrest.php b/hamcrest/Hamcrest.php index 5981de8a1..39e8ad432 100644 --- a/hamcrest/Hamcrest.php +++ b/hamcrest/Hamcrest.php @@ -546,6 +546,47 @@ function anExistingFileOrDirectory() } } +if (!function_exists('aFileWithSize')) { + /** + * Does file size satisfy a given matcher? + * Accepts only \SplFileInfo objects or string paths. + * + * @param \Hamcrest\Matcher|int $size as a {@link \Hamcrest\Matcher} or a value. + * + * @return \Hamcrest\File\IsFileWithSize + */ + function aFileWithSize($size) + { + return \Hamcrest\File\IsFileWithSize::aFileWithSize($size); + } +} + +if (!function_exists('anEmptyFile')) { + /** + * Matches an empty file. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\Core\DescribedAs + */ + function anEmptyFile() + { + return \Hamcrest\File\IsFileWithSize::anEmptyFile(); + } +} + +if (!function_exists('aNonEmptyFile')) { + /** + * Matches a non-empty file. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\Core\DescribedAs + */ + function aNonEmptyFile() + { + return \Hamcrest\File\IsFileWithSize::aNonEmptyFile(); + } +} + if (!function_exists('aReadableFile')) { /** * Evaluates to true if the file is readable. diff --git a/hamcrest/Hamcrest/Core/DescribedAs.php b/hamcrest/Hamcrest/Core/DescribedAs.php index 5b2583fa7..3d917d221 100644 --- a/hamcrest/Hamcrest/Core/DescribedAs.php +++ b/hamcrest/Hamcrest/Core/DescribedAs.php @@ -51,6 +51,11 @@ public function describeTo(Description $description) } } + public function describeMismatch($item, Description $description) + { + $this->_matcher->describeMismatch($item, $description); + } + /** * Wraps an existing matcher and overrides the description when it fails. * diff --git a/hamcrest/Hamcrest/File/FileMatcher.php b/hamcrest/Hamcrest/File/FileMatcher.php index dc9d5857a..24d1e1a27 100644 --- a/hamcrest/Hamcrest/File/FileMatcher.php +++ b/hamcrest/Hamcrest/File/FileMatcher.php @@ -29,7 +29,7 @@ abstract class FileMatcher extends BaseMatcher * @param string $ownDescription * @param string $failureDescription */ - public function __construct($ownDescription, $failureDescription) + public function __construct($ownDescription = '', $failureDescription = '') { $this->ownDescription = $ownDescription; $this->failureDescription = $failureDescription; diff --git a/hamcrest/Hamcrest/File/IsFileWithSize.php b/hamcrest/Hamcrest/File/IsFileWithSize.php new file mode 100644 index 000000000..6535a6ac0 --- /dev/null +++ b/hamcrest/Hamcrest/File/IsFileWithSize.php @@ -0,0 +1,92 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\Core\DescribedAs; +use Hamcrest\Core\IsNot; +use Hamcrest\Description; +use Hamcrest\Matcher; +use Hamcrest\Util; + +class IsFileWithSize extends FileMatcher +{ + /** + * Matcher that will match the actual size of the file. + * + * @var Matcher + */ + private $sizeMatcher; + + public function __construct(Matcher $sizeMatcher) + { + parent::__construct(); + $this->sizeMatcher = $sizeMatcher; + } + + final public function describeTo(Description $description) + { + $description->appendText('a file with size ')->appendDescriptionOf($this->sizeMatcher); + } + + protected function matchesFile(\SplFileInfo $file) + { + $fileSize = $file->getSize(); + + return $this->sizeMatcher->matches($fileSize); + } + + protected function describeFileMismatch(\SplFileInfo $file, Description $mismatchDescription) + { + $fileSize = $file->getSize(); + $mismatchDescription->appendText('size was ')->appendValue($fileSize); + } + + + /** + * Does file size satisfy a given matcher? + * Accepts only \SplFileInfo objects or string paths. + * + * @param \Hamcrest\Matcher|int $size as a {@link \Hamcrest\Matcher} or a value. + * + * @return \Hamcrest\File\IsFileWithSize + * @factory + */ + public static function aFileWithSize($size) + { + return new self(Util::wrapValueWithIsEqual($size)); + } + + /** + * Matches an empty file. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\Core\DescribedAs + * @factory + */ + public static function anEmptyFile() + { + return DescribedAs::describedAs( + 'an empty file', + self::aFileWithSize(0) + ); + } + + /** + * Matches a non-empty file. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\Core\DescribedAs + * @factory + */ + public static function aNonEmptyFile() + { + return DescribedAs::describedAs( + 'a non-empty file', + self::aFileWithSize(IsNot::not(0)) + ); + } +} diff --git a/hamcrest/Hamcrest/Matchers.php b/hamcrest/Hamcrest/Matchers.php index a115785a5..ff7e26d1c 100644 --- a/hamcrest/Hamcrest/Matchers.php +++ b/hamcrest/Hamcrest/Matchers.php @@ -444,6 +444,41 @@ public static function anExistingFileOrDirectory() return \Hamcrest\File\IsExistingFileOrDirectory::anExistingFileOrDirectory(); } + /** + * Does file size satisfy a given matcher? + * Accepts only \SplFileInfo objects or string paths. + * + * @param \Hamcrest\Matcher|int $size as a {@link \Hamcrest\Matcher} or a value. + * + * @return \Hamcrest\File\IsFileWithSize + */ + public static function aFileWithSize($size) + { + return \Hamcrest\File\IsFileWithSize::aFileWithSize($size); + } + + /** + * Matches an empty file. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\Core\DescribedAs + */ + public static function anEmptyFile() + { + return \Hamcrest\File\IsFileWithSize::anEmptyFile(); + } + + /** + * Matches a non-empty file. + * Accepts only \SplFileInfo objects or string paths. + * + * @return \Hamcrest\Core\DescribedAs + */ + public static function aNonEmptyFile() + { + return \Hamcrest\File\IsFileWithSize::aNonEmptyFile(); + } + /** * Evaluates to true if the file is readable. * Accepts only \SplFileInfo objects or string paths. diff --git a/tests/Hamcrest/File/IsFileWithSizeTest.php b/tests/Hamcrest/File/IsFileWithSizeTest.php new file mode 100644 index 000000000..bdae67c83 --- /dev/null +++ b/tests/Hamcrest/File/IsFileWithSizeTest.php @@ -0,0 +1,204 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\AbstractMatcherTest; + +class IsFileWithSizeTest extends AbstractMatcherTest +{ + private static $FILE_PATH; + private static $FILE; + private static $ACTUAL_SIZE; + + private static $EMPTY_FILE; + + /** + * @beforeClass + */ + public static function initializeFiles() + { + self::$FILE_PATH = __FILE__; + self::$FILE = new \SplFileInfo(self::$FILE_PATH); + self::$ACTUAL_SIZE = filesize(self::$FILE_PATH); + + self::$EMPTY_FILE = new class('/tmp/empty') extends \SplFileInfo { + public function getSize() + { + return 0; + } + }; + } + + protected function createMatcher() + { + return IsFileWithSize::aFileWithSize(not(anything())); + } + + public function testMatchesAFileWithEqualSize() + { + $this->assertMatches( + aFileWithSize(self::$ACTUAL_SIZE), + self::$FILE, + "should match a file that has equal size" + ); + } + + public function testMatchesAFilePathWithEqualSize() + { + $this->assertMatches( + aFileWithSize(self::$ACTUAL_SIZE), + self::$FILE_PATH, + "should match a file path that has equal size" + ); + } + + public function testDoesNotMatchAFileWithDifferentSize() + { + $this->assertDoesNotMatch( + aFileWithSize(self::$ACTUAL_SIZE + 1), + self::$FILE, + "should not match a file that has a different size" + ); + } + + public function testDoesNotMatchAFilePathWithDifferentSize() + { + $this->assertDoesNotMatch( + aFileWithSize(self::$ACTUAL_SIZE + 1), + self::$FILE_PATH, + "should not match a file path that has a different size" + ); + } + + public function testMatchesAFileWithSizeMatchedByAnotherMatcher() + { + $this->assertMatches( + aFileWithSize(greaterThan(self::$ACTUAL_SIZE - 1)), + self::$FILE, + "should match a file with size that is matched by another matcher" + ); + } + + public function testMatchesAFilePathWithSizeMatchedByAnotherMatcher() + { + $this->assertMatches( + aFileWithSize(greaterThan(self::$ACTUAL_SIZE - 1)), + self::$FILE_PATH, + "should match a file path with size that is matched by another matcher" + ); + } + + public function testDoesNotMatchAFileWithSizeNotMatchedByAnotherMatcher() + { + $this->assertDoesNotMatch( + aFileWithSize(greaterThan(self::$ACTUAL_SIZE)), + self::$FILE, + "should not match a file with size that is not matched by another matcher" + ); + } + + public function testEmptyFileMatcherMatchesEmptyFile() + { + $this->assertMatches( + anEmptyFile(), + self::$EMPTY_FILE, + "should match an empty file" + ); + } + + public function testEmptyFileMatcherDoesNotMatchNonEmptyFile() + { + $this->assertDoesNotMatch( + anEmptyFile(), + self::$FILE, + "should not match non-empty file" + ); + } + + public function testNonEmptyFileMatcherMatchesNonEmptyFile() + { + $this->assertMatches( + aNonEmptyFile(), + self::$FILE, + "should match a non-empty file" + ); + } + + public function testNonEmptyFileMatcherDoesNotMatchEmptyFile() + { + $this->assertDoesNotMatch( + aNonEmptyFile(), + self::$EMPTY_FILE, + "should not match empty file" + ); + } + + public function testDoesNotMatchNull() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + null, + 'should not match null' + ); + } + + public function testHasAReadableDescription() + { + $this->assertDescription('a file with size <42>', aFileWithSize(42)); + } + + public function testHasAReadableDescriptionWithAnotherMatcher() + { + $this->assertDescription('a file with size a value greater than <42>', aFileWithSize(greaterThan(42))); + } + + public function testEmptyFileMatcherHasAReadableDescription() + { + $this->assertDescription('an empty file', anEmptyFile()); + } + + public function testNonEmptyFileMatcherHasAReadableDescription() + { + $this->assertDescription('a non-empty file', aNonEmptyFile()); + } + + public function testHasAReadableMissmatchDescription() + { + $this->assertMismatchDescription( + 'size was <' . self::$ACTUAL_SIZE . '>', + $this->createMatcher(), + self::$FILE + ); + } + + public function testEmptyFileMatcherHasAReadableMissmatchDescription() + { + $this->assertMismatchDescription( + 'size was <' . self::$ACTUAL_SIZE . '>', + anEmptyFile(), + self::$FILE + ); + } + + public function testNonEmptyFileMatcherHasAReadableMissmatchDescription() + { + $this->assertMismatchDescription( + 'size was <0>', + aNonEmptyFile(), + self::$EMPTY_FILE + ); + } + + public function testHasAReadableTypeMissmatchDescription() + { + $this->assertMismatchDescription( + 'was ', + $this->createMatcher(), + new \stdClass() + ); + } +} From 8cb405b47f740b6b509b7d3a1f67b90568d42e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=C5=A1ek=20Brychta?= Date: Mon, 6 Jun 2022 14:20:59 +0200 Subject: [PATCH 10/11] Adding IsFileNamed matcher --- README.md | 10 ++ hamcrest/Hamcrest.php | 15 +++ hamcrest/Hamcrest/File/IsFileNamed.php | 60 +++++++++++ hamcrest/Hamcrest/Matchers.php | 13 +++ tests/Hamcrest/File/IsFileNamedTest.php | 133 ++++++++++++++++++++++++ 5 files changed, 231 insertions(+) create mode 100644 hamcrest/Hamcrest/File/IsFileNamed.php create mode 100644 tests/Hamcrest/File/IsFileNamedTest.php diff --git a/README.md b/README.md index e143ad8d7..c6d4b83a0 100644 --- a/README.md +++ b/README.md @@ -302,6 +302,16 @@ assertThat($file, aNonEmptyFile()); assertThat('/var/log/php-fpm.log', aNonEmptyFile()); ``` +* `aFileNamed` - evaluates to true if the file name is equal to given value or the provided matcher matches the file name +```php +$file = new \SplFileInfo('/var/log/php-fpm.log'); +assertThat($file, aFileNamed('php-fpm.log')); +assertThat($file, aFileNamed(startsWith('php'))); + +assertThat('/var/log/php-fpm.log', aFileNamed('php-fpm.log')); +assertThat('/var/log/php-fpm.log', aFileNamed(startsWith('php'))); +``` + ### Object * `hasToString` - check `__toString` or `toString` method diff --git a/hamcrest/Hamcrest.php b/hamcrest/Hamcrest.php index 39e8ad432..479ae08c8 100644 --- a/hamcrest/Hamcrest.php +++ b/hamcrest/Hamcrest.php @@ -546,6 +546,21 @@ function anExistingFileOrDirectory() } } +if (!function_exists('aFileNamed')) { + /** + * Does file name satisfy a given matcher? + * Accepts only \SplFileInfo objects or string paths. + * + * @param \Hamcrest\Matcher|string $name as a {@link \Hamcrest\Matcher} or a value. + * + * @return \Hamcrest\File\IsFileNamed + */ + function aFileNamed($name) + { + return \Hamcrest\File\IsFileNamed::aFileNamed($name); + } +} + if (!function_exists('aFileWithSize')) { /** * Does file size satisfy a given matcher? diff --git a/hamcrest/Hamcrest/File/IsFileNamed.php b/hamcrest/Hamcrest/File/IsFileNamed.php new file mode 100644 index 000000000..13b2b19b8 --- /dev/null +++ b/hamcrest/Hamcrest/File/IsFileNamed.php @@ -0,0 +1,60 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\Description; +use Hamcrest\Matcher; +use Hamcrest\Util; + +class IsFileNamed extends FileMatcher +{ + /** + * Matcher that will match the actual name of the file. + * + * @var Matcher + */ + private $nameMatcher; + + public function __construct(Matcher $nameMatcher) + { + parent::__construct(); + $this->nameMatcher = $nameMatcher; + } + + final public function describeTo(Description $description) + { + $description->appendText('a file with name ')->appendDescriptionOf($this->nameMatcher); + } + + protected function matchesFile(\SplFileInfo $file) + { + $fileName = $file->getFilename(); + + return $this->nameMatcher->matches($fileName); + } + + protected function describeFileMismatch(\SplFileInfo $file, Description $mismatchDescription) + { + $fileName = $file->getFilename(); + $mismatchDescription->appendText('name was ')->appendValue($fileName); + } + + + /** + * Does file name satisfy a given matcher? + * Accepts only \SplFileInfo objects or string paths. + * + * @param \Hamcrest\Matcher|string $name as a {@link \Hamcrest\Matcher} or a value. + * + * @return \Hamcrest\File\IsFileNamed + * @factory + */ + public static function aFileNamed($name) + { + return new self(Util::wrapValueWithIsEqual($name)); + } +} diff --git a/hamcrest/Hamcrest/Matchers.php b/hamcrest/Hamcrest/Matchers.php index ff7e26d1c..2159a4d2a 100644 --- a/hamcrest/Hamcrest/Matchers.php +++ b/hamcrest/Hamcrest/Matchers.php @@ -444,6 +444,19 @@ public static function anExistingFileOrDirectory() return \Hamcrest\File\IsExistingFileOrDirectory::anExistingFileOrDirectory(); } + /** + * Does file name satisfy a given matcher? + * Accepts only \SplFileInfo objects or string paths. + * + * @param \Hamcrest\Matcher|string $name as a {@link \Hamcrest\Matcher} or a value. + * + * @return \Hamcrest\File\IsFileNamed + */ + public static function aFileNamed($name) + { + return \Hamcrest\File\IsFileNamed::aFileNamed($name); + } + /** * Does file size satisfy a given matcher? * Accepts only \SplFileInfo objects or string paths. diff --git a/tests/Hamcrest/File/IsFileNamedTest.php b/tests/Hamcrest/File/IsFileNamedTest.php new file mode 100644 index 000000000..0c06d6cc7 --- /dev/null +++ b/tests/Hamcrest/File/IsFileNamedTest.php @@ -0,0 +1,133 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\AbstractMatcherTest; + +class IsFileNamedTest extends AbstractMatcherTest +{ + private static $FILE_PATH; + private static $FILE; + private static $ACTUAL_NAME; + private static $ACTUAL_NAME_START; + + /** + * @beforeClass + */ + public static function initializeFiles() + { + self::$FILE_PATH = __FILE__; + self::$FILE = new \SplFileInfo(self::$FILE_PATH); + self::$ACTUAL_NAME = pathinfo(self::$FILE_PATH, PATHINFO_BASENAME); + self::$ACTUAL_NAME_START = substr(self::$ACTUAL_NAME, 0, 5); + } + + protected function createMatcher() + { + return IsFileNamed::aFileNamed(not(anything())); + } + + public function testMatchesAFileWithEqualName() + { + $this->assertMatches( + aFileNamed(self::$ACTUAL_NAME), + self::$FILE, + 'should match a file that has equal name' + ); + } + + public function testMatchesAFilePathWithEqualName() + { + $this->assertMatches( + aFileNamed(self::$ACTUAL_NAME), + self::$FILE_PATH, + 'should match a file path that has equal name' + ); + } + + public function testDoesNotMatchAFileWithDifferentName() + { + $this->assertDoesNotMatch( + aFileNamed(self::$ACTUAL_NAME . '_suffix'), + self::$FILE, + 'should not match a file that has a different name' + ); + } + + public function testDoesNotMatchAFilePathWithDifferentName() + { + $this->assertDoesNotMatch( + aFileNamed(self::$ACTUAL_NAME . '_suffix'), + self::$FILE_PATH, + 'should not match a file path that has a different file name' + ); + } + + public function testMatchesAFileWithNameMatchedByAnotherMatcher() + { + $this->assertMatches( + aFileNamed(startsWith(self::$ACTUAL_NAME_START)), + self::$FILE, + 'should match a file with name that is matched by another matcher' + ); + } + + public function testMatchesAFilePathWithNameMatchedByAnotherMatcher() + { + $this->assertMatches( + aFileNamed(startsWith(self::$ACTUAL_NAME_START)), + self::$FILE_PATH, + 'should match a file path with name that is matched by another matcher' + ); + } + + public function testDoesNotMatchAFileWithNameNotMatchedByAnotherMatcher() + { + $this->assertDoesNotMatch( + aFileNamed(endsWith(self::$ACTUAL_NAME_START)), + self::$FILE, + 'should not match a file with name that is not matched by another matcher' + ); + } + + public function testDoesNotMatchNull() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + null, + 'should not match null' + ); + } + + public function testHasAReadableDescription() + { + $this->assertDescription('a file with name "my-file.txt"', aFileNamed('my-file.txt')); + } + + public function testHasAReadableDescriptionWithAnotherMatcher() + { + $this->assertDescription('a file with name a string starting with "my-file"', aFileNamed(startsWith('my-file'))); + } + + public function testHasAReadableMissmatchDescription() + { + $this->assertMismatchDescription( + 'name was "' . self::$ACTUAL_NAME . '"', + $this->createMatcher(), + self::$FILE + ); + } + + public function testHasAReadableTypeMissmatchDescription() + { + $this->assertMismatchDescription( + 'was ', + $this->createMatcher(), + new \stdClass() + ); + } +} From 5b57f058edd31378706daaf19088ab2296023b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=C5=A1ek=20Brychta?= Date: Mon, 6 Jun 2022 15:41:27 +0200 Subject: [PATCH 11/11] Adding IsFileWithCanonicalPath matcher --- README.md | 10 ++ hamcrest/Hamcrest.php | 15 ++ .../Hamcrest/File/IsFileWithCanonicalPath.php | 60 ++++++++ hamcrest/Hamcrest/Matchers.php | 13 ++ .../File/IsFileWithCanonicalPathTest.php | 137 ++++++++++++++++++ 5 files changed, 235 insertions(+) create mode 100644 hamcrest/Hamcrest/File/IsFileWithCanonicalPath.php create mode 100644 tests/Hamcrest/File/IsFileWithCanonicalPathTest.php diff --git a/README.md b/README.md index c6d4b83a0..a8fb62baa 100644 --- a/README.md +++ b/README.md @@ -312,6 +312,16 @@ assertThat('/var/log/php-fpm.log', aFileNamed('php-fpm.log')); assertThat('/var/log/php-fpm.log', aFileNamed(startsWith('php'))); ``` +* `aFileWithCanonicalPath` - evaluates to true if the file canonical path is equal to given value or the provided matcher matches the canonical path of the file +```php +$file = new \SplFileInfo('/var/log/./php-fpm.log'); +assertThat($file, aFileWithCanonicalPath('/var/log/php-fpm.log')); +assertThat($file, aFileWithCanonicalPath(endsWith('log/php-fpm.log'))); + +assertThat('/var/log/./php-fpm.log', aFileWithCanonicalPath('/var/log/php-fpm.log')); +assertThat('/var/log/./php-fpm.log', aFileWithCanonicalPath(endsWith('log/php-fpm.log'))); +``` + ### Object * `hasToString` - check `__toString` or `toString` method diff --git a/hamcrest/Hamcrest.php b/hamcrest/Hamcrest.php index 479ae08c8..bf11dac6f 100644 --- a/hamcrest/Hamcrest.php +++ b/hamcrest/Hamcrest.php @@ -561,6 +561,21 @@ function aFileNamed($name) } } +if (!function_exists('aFileWithCanonicalPath')) { + /** + * Does canonical path satisfy a given matcher? + * Accepts only \SplFileInfo objects or string paths. + * + * @param \Hamcrest\Matcher|string $path as a {@link \Hamcrest\Matcher} or a value. + * + * @return \Hamcrest\File\IsFileWithCanonicalPath + */ + function aFileWithCanonicalPath($path) + { + return \Hamcrest\File\IsFileWithCanonicalPath::aFileWithCanonicalPath($path); + } +} + if (!function_exists('aFileWithSize')) { /** * Does file size satisfy a given matcher? diff --git a/hamcrest/Hamcrest/File/IsFileWithCanonicalPath.php b/hamcrest/Hamcrest/File/IsFileWithCanonicalPath.php new file mode 100644 index 000000000..a9e0987a6 --- /dev/null +++ b/hamcrest/Hamcrest/File/IsFileWithCanonicalPath.php @@ -0,0 +1,60 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\Description; +use Hamcrest\Matcher; +use Hamcrest\Util; + +class IsFileWithCanonicalPath extends FileMatcher +{ + /** + * Matcher that will match the actual canonical path of the file. + * + * @var Matcher + */ + private $pathMatcher; + + public function __construct(Matcher $pathMatcher) + { + parent::__construct(); + $this->pathMatcher = $pathMatcher; + } + + final public function describeTo(Description $description) + { + $description->appendText('a file with canonical path ')->appendDescriptionOf($this->pathMatcher); + } + + protected function matchesFile(\SplFileInfo $file) + { + $realPath = $file->getRealPath(); + + return $this->pathMatcher->matches($realPath); + } + + protected function describeFileMismatch(\SplFileInfo $file, Description $mismatchDescription) + { + $realPath = $file->getRealPath(); + $mismatchDescription->appendText('canonical path was ')->appendValue($realPath); + } + + + /** + * Does canonical path satisfy a given matcher? + * Accepts only \SplFileInfo objects or string paths. + * + * @param \Hamcrest\Matcher|string $path as a {@link \Hamcrest\Matcher} or a value. + * + * @return \Hamcrest\File\IsFileWithCanonicalPath + * @factory + */ + public static function aFileWithCanonicalPath($path) + { + return new self(Util::wrapValueWithIsEqual($path)); + } +} diff --git a/hamcrest/Hamcrest/Matchers.php b/hamcrest/Hamcrest/Matchers.php index 2159a4d2a..70251d6ba 100644 --- a/hamcrest/Hamcrest/Matchers.php +++ b/hamcrest/Hamcrest/Matchers.php @@ -457,6 +457,19 @@ public static function aFileNamed($name) return \Hamcrest\File\IsFileNamed::aFileNamed($name); } + /** + * Does canonical path satisfy a given matcher? + * Accepts only \SplFileInfo objects or string paths. + * + * @param \Hamcrest\Matcher|string $path as a {@link \Hamcrest\Matcher} or a value. + * + * @return \Hamcrest\File\IsFileWithCanonicalPath + */ + public static function aFileWithCanonicalPath($path) + { + return \Hamcrest\File\IsFileWithCanonicalPath::aFileWithCanonicalPath($path); + } + /** * Does file size satisfy a given matcher? * Accepts only \SplFileInfo objects or string paths. diff --git a/tests/Hamcrest/File/IsFileWithCanonicalPathTest.php b/tests/Hamcrest/File/IsFileWithCanonicalPathTest.php new file mode 100644 index 000000000..2a98f1943 --- /dev/null +++ b/tests/Hamcrest/File/IsFileWithCanonicalPathTest.php @@ -0,0 +1,137 @@ + + */ + +namespace Hamcrest\File; + +use Hamcrest\AbstractMatcherTest; + +class IsFileWithCanonicalPathTest extends AbstractMatcherTest +{ + private static $CANONICAL_PATH; + private static $FILENAME; + private static $FILE_PATH; + private static $FILE; + + private static $DIFFERENT_CANONICAL_PATH; + + /** + * @beforeClass + */ + public static function initializeFiles() + { + self::$CANONICAL_PATH = __FILE__; + self::$FILENAME = pathinfo(__FILE__, PATHINFO_BASENAME); + self::$FILE_PATH = __DIR__ . '/./' . self::$FILENAME; + self::$FILE = new \SplFileInfo(self::$FILE_PATH); + + self::$DIFFERENT_CANONICAL_PATH = __DIR__ . '/different-file.txt'; + } + + protected function createMatcher() + { + return IsFileWithCanonicalPath::aFileWithCanonicalPath(not(anything())); + } + + public function testMatchesAFileWithEqualCanonicalPath() + { + $this->assertMatches( + aFileWithCanonicalPath(self::$CANONICAL_PATH), + self::$FILE, + 'should match a file that has equal canonical path' + ); + } + + public function testMatchesAFilePathWithEqualCanonicalPath() + { + $this->assertMatches( + aFileWithCanonicalPath(self::$CANONICAL_PATH), + self::$FILE_PATH, + 'should match a file path that has equal canonical path' + ); + } + + public function testDoesNotMatchAFileWithDifferentCanonicalPath() + { + $this->assertDoesNotMatch( + aFileWithCanonicalPath(self::$DIFFERENT_CANONICAL_PATH), + self::$FILE, + 'should not match a file that has a different canonical path' + ); + } + + public function testDoesNotMatchAFilePathWithDifferentCanonicalPath() + { + $this->assertDoesNotMatch( + aFileWithCanonicalPath(self::$DIFFERENT_CANONICAL_PATH), + self::$FILE_PATH, + 'should not match a file path that has a different canonical path' + ); + } + + public function testMatchesAFileWithCanonicalPathMatchedByAnotherMatcher() + { + $this->assertMatches( + aFileWithCanonicalPath(endsWith(self::$FILENAME)), + self::$FILE, + 'should match a file with canonical path that is matched by another matcher' + ); + } + + public function testMatchesAFilePathWithCanonicalPathMatchedByAnotherMatcher() + { + $this->assertMatches( + aFileWithCanonicalPath(endsWith(self::$FILENAME)), + self::$FILE_PATH, + 'should match a file path with canonical path that is matched by another matcher' + ); + } + + public function testDoesNotMatchAFileWithCanonicalPathNotMatchedByAnotherMatcher() + { + $this->assertDoesNotMatch( + aFileWithCanonicalPath(startsWith(self::$FILENAME)), + self::$FILE, + 'should not match a file with canonical path that is not matched by another matcher' + ); + } + + public function testDoesNotMatchNull() + { + $this->assertDoesNotMatch( + $this->createMatcher(), + null, + 'should not match null' + ); + } + + public function testHasAReadableDescription() + { + $this->assertDescription('a file with canonical path "/tmp/my-file.txt"', aFileWithCanonicalPath('/tmp/my-file.txt')); + } + + public function testHasAReadableDescriptionWithAnotherMatcher() + { + $this->assertDescription('a file with canonical path a string ending with "my-file"', aFileWithCanonicalPath(endsWith('my-file'))); + } + + public function testHasAReadableMissmatchDescription() + { + $this->assertMismatchDescription( + 'canonical path was "' . self::$CANONICAL_PATH . '"', + $this->createMatcher(), + self::$FILE + ); + } + + public function testHasAReadableTypeMissmatchDescription() + { + $this->assertMismatchDescription( + 'was ', + $this->createMatcher(), + new \stdClass() + ); + } +}