From fb546101dbb0ede8b31414aa53f0bf52a33166e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Fabr=C3=A9gat?= Date: Tue, 16 Oct 2018 10:50:02 +0200 Subject: [PATCH] first version --- .gitignore | 4 + LICENSE | 21 +++ README.md | 35 ++++- composer.json | 33 +++++ src/AbstractDirectoryClassesIterator.php | 119 +++++++++++++++ src/DirectoryClassesIterator.php | 41 ++++++ .../DirectoryClassesIteratorException.php | 33 +++++ src/Exceptions/NotADirectoryException.php | 64 ++++++++ src/RecursiveDirectoryClassesIterator.php | 46 ++++++ tests/Assets/ADotIncClass.inc | 33 +++++ tests/Assets/AFirstClass.php | 33 +++++ tests/Assets/ASecondClass.php | 33 +++++ tests/Assets/AThirdClass.php | 33 +++++ tests/Assets/AnotherClass.php | 33 +++++ tests/Assets/SubFolder/ASubDotIncClass.inc | 33 +++++ tests/Assets/SubFolder/ASubFolderClass.php | 33 +++++ .../ASubSubFolder/ASubSubFolderClass.php | 33 +++++ tests/Assets/SubFolder/AnotherSubClass.php | 33 +++++ tests/DirectoryClassesIteratorTest.php | 131 +++++++++++++++++ .../RecursiveDirectoryClassesIteratorTest.php | 138 ++++++++++++++++++ 20 files changed, 961 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 composer.json create mode 100644 src/AbstractDirectoryClassesIterator.php create mode 100644 src/DirectoryClassesIterator.php create mode 100644 src/Exceptions/DirectoryClassesIteratorException.php create mode 100644 src/Exceptions/NotADirectoryException.php create mode 100644 src/RecursiveDirectoryClassesIterator.php create mode 100644 tests/Assets/ADotIncClass.inc create mode 100644 tests/Assets/AFirstClass.php create mode 100644 tests/Assets/ASecondClass.php create mode 100644 tests/Assets/AThirdClass.php create mode 100644 tests/Assets/AnotherClass.php create mode 100644 tests/Assets/SubFolder/ASubDotIncClass.inc create mode 100644 tests/Assets/SubFolder/ASubFolderClass.php create mode 100644 tests/Assets/SubFolder/ASubSubFolder/ASubSubFolderClass.php create mode 100644 tests/Assets/SubFolder/AnotherSubClass.php create mode 100644 tests/DirectoryClassesIteratorTest.php create mode 100644 tests/RecursiveDirectoryClassesIteratorTest.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dccb98d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/.idea +/composer.lock +/vendor +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..16d89aa --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Joan Fabrégat / Code Inc. SAS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 836db4b..43f4ae9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,35 @@ # DirectoryClassesIterator -Iterator to list all the PHP classes within a directory + +This package provides two directory iterators to list PHP classes : +* [`DirectoryClassesIterator`](src/DirectoryClassesIterator.php) +* [`RecursiveDirectoryClassesIterator`](src/RecursiveDirectoryClassesIterator.php) + +The iterator loads the `.php` files using [`include_once()`](http://php.net/manual/function.include-once.php) and uses the [`ReflectionClass`](http://php.net/manual/class.reflectionclass.php) API to detect classes found within the loaded files. + +## Usage +```php +=7.1" + }, + "autoload": { + "psr-4": {"CodeInc\\DirectoryClassesIterator\\": "src"} + }, + "autoload-dev": { + "psr-4": {"CodeInc\\DirectoryClassesIterator\\Tests\\": "tests"} + }, + "authors": [ + { + "name": "Joan Fabrégat", + "email": "joan@codeinc.fr", + "homepage": "https://www.codeinc.fr", + "role": "developer" + } + ], + "config": { + "preferred-install": { + "*": "dist" + } + }, + "require-dev": { + "phpunit/phpunit": "^7" + } +} \ No newline at end of file diff --git a/src/AbstractDirectoryClassesIterator.php b/src/AbstractDirectoryClassesIterator.php new file mode 100644 index 0000000..0b25ff6 --- /dev/null +++ b/src/AbstractDirectoryClassesIterator.php @@ -0,0 +1,119 @@ + +// Date: 16/10/2018 +// Project: AritasIntranet +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator; +use CodeInc\DirectoryClassesIterator\Exceptions\NotADirectoryException; + + +/** + * Class AbstractDirectoryClassesIterator + * + * @package CodeInc\DirectoryClassesIterator + * @author Joan Fabrégat + */ +abstract class AbstractDirectoryClassesIterator implements \IteratorAggregate +{ + /** + * @var string + */ + private $path; + + /** + * @var string[] + */ + private $extensions; + + /** + * AbstractDirectoryClassesIterator constructor. + * + * @param string $path + * @param array $extensions + */ + public function __construct(string $path, array $extensions = ['php']) + { + if (!is_dir($path)) { + throw new NotADirectoryException($path); + } + $this->path = $path; + $this->extensions = $extensions; + } + + /** + * Returns the directory iterator. + * + * @return \Iterator|\SplFileInfo[] + */ + abstract protected function getDirectoryIterator():\Iterator; + + /** + * Returns the directory path. + * + * @return string + */ + public function getPath():string + { + return $this->path; + } + + /** + * Returns the allowed classes extensions. + * + * @return string[] + */ + public function getExtensions():array + { + return $this->extensions; + } + + /** + * Sets the allowed classes extensions. + * + * @param string[] $extensions + */ + public function setExtensions(array $extensions):void + { + $this->extensions = $extensions; + } + + /** + * @inheritdoc + * @return \ReflectionClass[]|\Generator + * @throws \ReflectionException + */ + public function getIterator():\Generator + { + $loadedFiles = []; + /** @var \SplFileInfo $entry */ + foreach ($this->getDirectoryIterator() as $entry) { + if (in_array($entry->getExtension(), $this->extensions)) { + $loadedFiles[] = $entry->getPathname(); + /** @noinspection PhpIncludeInspection */ + include_once $entry->getPathname(); + } + } + foreach (get_declared_classes() as $declaredClass) { + $reflectionClass = new \ReflectionClass($declaredClass); + if (in_array($reflectionClass->getFileName(), $loadedFiles)) { + yield $reflectionClass; + } + } + } +} \ No newline at end of file diff --git a/src/DirectoryClassesIterator.php b/src/DirectoryClassesIterator.php new file mode 100644 index 0000000..6c84093 --- /dev/null +++ b/src/DirectoryClassesIterator.php @@ -0,0 +1,41 @@ + +// Date: 16/10/2018 +// Project: AritasIntranet +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator; + + +/** + * Class DirectoryClassesIterator + * + * @package CodeInc\DirectoryClassesIterator + * @author Joan Fabrégat + */ +class DirectoryClassesIterator extends AbstractDirectoryClassesIterator +{ + /** + * @inheritdoc + * @return \Iterator|\SplFileInfo[] + */ + protected function getDirectoryIterator():\Iterator + { + return new \DirectoryIterator($this->getPath()); + } +} \ No newline at end of file diff --git a/src/Exceptions/DirectoryClassesIteratorException.php b/src/Exceptions/DirectoryClassesIteratorException.php new file mode 100644 index 0000000..58a1914 --- /dev/null +++ b/src/Exceptions/DirectoryClassesIteratorException.php @@ -0,0 +1,33 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Exceptions; + +/** + * Interface DirectoryClassesIteratorException + * + * @package CodeInc\DirectoryClassesIterator\Exceptions + * @author Joan Fabrégat + */ +interface DirectoryClassesIteratorException +{ + +} \ No newline at end of file diff --git a/src/Exceptions/NotADirectoryException.php b/src/Exceptions/NotADirectoryException.php new file mode 100644 index 0000000..f250a96 --- /dev/null +++ b/src/Exceptions/NotADirectoryException.php @@ -0,0 +1,64 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Exceptions; + +use Throwable; + + +/** + * Class NotADirectoryException + * + * @package CodeInc\DirectoryClassesIterator\Exceptions + * @author Joan Fabrégat + */ +class NotADirectoryException extends \RuntimeException implements DirectoryClassesIteratorException +{ + /** + * @var string + */ + private $path; + + /** + * NotADirectoryException constructor. + * + * @param string $path + * @param int $code + * @param Throwable|null $previous + */ + public function __construct(string $path, int $code = 0, Throwable $previous = null) + { + $this->path = $path; + parent::__construct( + sprintf("The path '%s' is not a directory.", $path), + $code, + $previous + ); + } + + /** + * @return string + */ + public function getPath():string + { + return $this->path; + } +} \ No newline at end of file diff --git a/src/RecursiveDirectoryClassesIterator.php b/src/RecursiveDirectoryClassesIterator.php new file mode 100644 index 0000000..63fef32 --- /dev/null +++ b/src/RecursiveDirectoryClassesIterator.php @@ -0,0 +1,46 @@ + +// Date: 16/10/2018 +// Project: AritasIntranet +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator; + + +/** + * Class RecursiveDirectoryClassesIterator + * + * @package CodeInc\DirectoryClassesIterator + * @author Joan Fabrégat + */ +class RecursiveDirectoryClassesIterator extends AbstractDirectoryClassesIterator +{ + /** + * @inheritdoc + * @return \Iterator|\SplFileInfo[] + */ + protected function getDirectoryIterator():\Iterator + { + return new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator( + $this->getPath(), + \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS + ) + ); + } +} \ No newline at end of file diff --git a/tests/Assets/ADotIncClass.inc b/tests/Assets/ADotIncClass.inc new file mode 100644 index 0000000..029f793 --- /dev/null +++ b/tests/Assets/ADotIncClass.inc @@ -0,0 +1,33 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Tests\Assets; + +/** + * Class ADotIncClass + * + * @package CodeInc\DirectoryClassesIterator\Tests\Assets + * @author Joan Fabrégat + */ +class ADotIncClass +{ + +} \ No newline at end of file diff --git a/tests/Assets/AFirstClass.php b/tests/Assets/AFirstClass.php new file mode 100644 index 0000000..d6fe961 --- /dev/null +++ b/tests/Assets/AFirstClass.php @@ -0,0 +1,33 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Tests\Assets; + +/** + * Class AFirstClass + * + * @package CodeInc\DirectoryClassesIterator\Tests\Assets + * @author Joan Fabrégat + */ +class AFirstClass +{ + +} \ No newline at end of file diff --git a/tests/Assets/ASecondClass.php b/tests/Assets/ASecondClass.php new file mode 100644 index 0000000..95f4272 --- /dev/null +++ b/tests/Assets/ASecondClass.php @@ -0,0 +1,33 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Tests\Assets; + +/** + * Class ASecondClass + * + * @package CodeInc\DirectoryClassesIterator\Tests\Assets + * @author Joan Fabrégat + */ +class ASecondClass +{ + +} \ No newline at end of file diff --git a/tests/Assets/AThirdClass.php b/tests/Assets/AThirdClass.php new file mode 100644 index 0000000..7d5b855 --- /dev/null +++ b/tests/Assets/AThirdClass.php @@ -0,0 +1,33 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Tests\Assets; + +/** + * Class AThirdClass + * + * @package CodeInc\DirectoryClassesIterator\Tests\Assets + * @author Joan Fabrégat + */ +class AThirdClass +{ + +} \ No newline at end of file diff --git a/tests/Assets/AnotherClass.php b/tests/Assets/AnotherClass.php new file mode 100644 index 0000000..c6065a1 --- /dev/null +++ b/tests/Assets/AnotherClass.php @@ -0,0 +1,33 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Tests\Assets; + +/** + * Class AnotherClass + * + * @package CodeInc\DirectoryClassesIterator\Tests\Assets + * @author Joan Fabrégat + */ +class AnotherClass +{ + +} \ No newline at end of file diff --git a/tests/Assets/SubFolder/ASubDotIncClass.inc b/tests/Assets/SubFolder/ASubDotIncClass.inc new file mode 100644 index 0000000..79242c4 --- /dev/null +++ b/tests/Assets/SubFolder/ASubDotIncClass.inc @@ -0,0 +1,33 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder; + +/** + * Class ASubDotIncClass + * + * @package CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder + * @author Joan Fabrégat + */ +class ASubDotIncClass +{ + +} \ No newline at end of file diff --git a/tests/Assets/SubFolder/ASubFolderClass.php b/tests/Assets/SubFolder/ASubFolderClass.php new file mode 100644 index 0000000..c193afa --- /dev/null +++ b/tests/Assets/SubFolder/ASubFolderClass.php @@ -0,0 +1,33 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder; + +/** + * Class ASubFolderClass + * + * @package CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder + * @author Joan Fabrégat + */ +class ASubFolderClass +{ + +} \ No newline at end of file diff --git a/tests/Assets/SubFolder/ASubSubFolder/ASubSubFolderClass.php b/tests/Assets/SubFolder/ASubSubFolder/ASubSubFolderClass.php new file mode 100644 index 0000000..9cb3f89 --- /dev/null +++ b/tests/Assets/SubFolder/ASubSubFolder/ASubSubFolderClass.php @@ -0,0 +1,33 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder\ASubSubFolder; + +/** + * Class ASubSubFolderClass + * + * @package CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder\ASubSubFolder + * @author Joan Fabrégat + */ +class ASubSubFolderClass +{ + +} \ No newline at end of file diff --git a/tests/Assets/SubFolder/AnotherSubClass.php b/tests/Assets/SubFolder/AnotherSubClass.php new file mode 100644 index 0000000..f0eeae7 --- /dev/null +++ b/tests/Assets/SubFolder/AnotherSubClass.php @@ -0,0 +1,33 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder; + +/** + * Class AnotherSubClass + * + * @package CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder + * @author Joan Fabrégat + */ +class AnotherSubClass +{ + +} \ No newline at end of file diff --git a/tests/DirectoryClassesIteratorTest.php b/tests/DirectoryClassesIteratorTest.php new file mode 100644 index 0000000..e9830fb --- /dev/null +++ b/tests/DirectoryClassesIteratorTest.php @@ -0,0 +1,131 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Tests; +use CodeInc\DirectoryClassesIterator\DirectoryClassesIterator; +use CodeInc\DirectoryClassesIterator\RecursiveDirectoryClassesIterator; +use CodeInc\DirectoryClassesIterator\Tests\Assets\ADotIncClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\AFirstClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\AnotherClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\ASecondClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\AThirdClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder\AnotherSubClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder\ASubDotIncClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder\ASubFolderClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder\ASubSubFolder\ASubSubFolderClass; +use PHPUnit\Framework\TestCase; + + +/** + * Class DirectoryClassesIteratorTest + * + * @package CodeInc\DirectoryClassesIterator\Tests + * @author Joan Fabrégat + */ +class DirectoryClassesIteratorTest extends TestCase +{ + public const ASSETS_PATH = RecursiveDirectoryClassesIteratorTest::ASSETS_PATH; + + public function testListing():void + { + $iterator = new DirectoryClassesIterator(self::ASSETS_PATH); + $this->assertInstanceOf(\Traversable::class, $iterator); + $classes = []; + foreach ($iterator as $class) { + $this->assertTrue( + substr($class->getFileName(), 0, strlen(self::ASSETS_PATH)) == self::ASSETS_PATH + ); + $this->assertFileExists($class->getFileName()); + $classes[$class->getName()] = $class->getFileName(); + } + + // .php + $this->assertArrayHasKey(AFirstClass::class, $classes); + $this->assertArrayHasKey(AnotherClass::class, $classes); + $this->assertArrayHasKey(ASecondClass::class, $classes); + $this->assertArrayHasKey(AThirdClass::class, $classes); + $this->assertContains(__DIR__.'/Assets/AFirstClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/AnotherClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/ASecondClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/AThirdClass.php', $classes); + + // .php recursive + $this->assertArrayNotHasKey(ASubFolderClass::class, $classes); + $this->assertArrayNotHasKey(AnotherSubClass::class, $classes); + $this->assertArrayNotHasKey(ASubSubFolderClass::class, $classes); + $this->assertNotContains(__DIR__.'/Assets/SubFolder/ASubFolderClass.php', $classes); + $this->assertNotContains(__DIR__.'/Assets/SubFolder/AnotherSubClass.php', $classes); + $this->assertNotContains(__DIR__.'/Assets/SubFolder/ASubSubFolder/ASubSubFolderClass.php', $classes); + + // .inc + recursive + $this->assertArrayNotHasKey(ADotIncClass::class, $classes); + $this->assertArrayNotHasKey(ASubDotIncClass::class, $classes); + $this->assertNotContains(__DIR__.'/Assets/ADotIncClass.inc', $classes); + $this->assertNotContains(__DIR__.'/Assets/SubFolder/ASubDotIncClass.inc', $classes); + } + + public function testDotInc():void + { + $iterator = new DirectoryClassesIterator(self::ASSETS_PATH, ['inc']); + $this->assertInstanceOf(\Traversable::class, $iterator); + $classes = []; + foreach ($iterator as $class) { + $this->assertTrue( + substr($class->getFileName(), 0, strlen(self::ASSETS_PATH)) == self::ASSETS_PATH + ); + $this->assertFileExists($class->getFileName()); + $classes[$class->getName()] = $class->getFileName(); + } + + // .php + $this->assertNotContains(__DIR__.'/Assets/AFirstClass.php', $classes); + + // .inc + $this->assertArrayHasKey(ADotIncClass::class, $classes); + $this->assertContains(__DIR__.'/Assets/ADotIncClass.inc', $classes); + } + + public function testMultiExtensions():void + { + $iterator = new DirectoryClassesIterator(self::ASSETS_PATH, ['inc', 'php']); + $this->assertInstanceOf(\Traversable::class, $iterator); + $classes = []; + foreach ($iterator as $class) { + $this->assertTrue( + substr($class->getFileName(), 0, strlen(self::ASSETS_PATH)) == self::ASSETS_PATH + ); + $this->assertFileExists($class->getFileName()); + $classes[$class->getName()] = $class->getFileName(); + } + $this->assertArrayHasKey(AFirstClass::class, $classes); + $this->assertArrayHasKey(ADotIncClass::class, $classes); + $this->assertArrayHasKey(AFirstClass::class, $classes); + $this->assertArrayNotHasKey(ASubFolderClass::class, $classes); + $this->assertArrayNotHasKey(ASubDotIncClass::class, $classes); + $this->assertArrayNotHasKey(ASubSubFolderClass::class, $classes); + $this->assertContains(__DIR__.'/Assets/AFirstClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/ADotIncClass.inc', $classes); + $this->assertContains(__DIR__.'/Assets/AFirstClass.php', $classes); + $this->assertNotContains(__DIR__.'/Assets/SubFolder/ASubFolderClass.php', $classes); + $this->assertNotContains(__DIR__.'/Assets/SubFolder/ASubDotIncClass.inc', $classes); + $this->assertNotContains(__DIR__.'/Assets/SubFolder/ASubSubFolder/ASubSubFolderClass.php', $classes); + } +} \ No newline at end of file diff --git a/tests/RecursiveDirectoryClassesIteratorTest.php b/tests/RecursiveDirectoryClassesIteratorTest.php new file mode 100644 index 0000000..fc94638 --- /dev/null +++ b/tests/RecursiveDirectoryClassesIteratorTest.php @@ -0,0 +1,138 @@ + +// Date: 16/10/2018 +// Project: DirectoryClassesIterator +// +declare(strict_types=1); +namespace CodeInc\DirectoryClassesIterator\Tests; +use CodeInc\DirectoryClassesIterator\RecursiveDirectoryClassesIterator; +use CodeInc\DirectoryClassesIterator\Tests\Assets\ADotIncClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\AFirstClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\AnotherClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\ASecondClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\AThirdClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder\AnotherSubClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder\ASubDotIncClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder\ASubFolderClass; +use CodeInc\DirectoryClassesIterator\Tests\Assets\SubFolder\ASubSubFolder\ASubSubFolderClass; +use PHPUnit\Framework\TestCase; + + +/** + * Class DirectoryClassesIteratorTest + * + * @package CodeInc\DirectoryClassesIterator\Tests + * @author Joan Fabrégat + */ +class RecursiveDirectoryClassesIteratorTest extends TestCase +{ + public const ASSETS_PATH = __DIR__.'/Assets'; + + public function testListing():void + { + $iterator = new RecursiveDirectoryClassesIterator(self::ASSETS_PATH); + $this->assertInstanceOf(\Traversable::class, $iterator); + + $classes = []; + foreach ($iterator as $class) { + $this->assertTrue( + substr($class->getFileName(), 0, strlen(self::ASSETS_PATH)) == self::ASSETS_PATH + ); + $this->assertFileExists($class->getFileName()); + $classes[$class->getName()] = $class->getFileName(); + } + + // .php + $this->assertArrayHasKey(AFirstClass::class, $classes); + $this->assertArrayHasKey(AnotherClass::class, $classes); + $this->assertArrayHasKey(ASecondClass::class, $classes); + $this->assertArrayHasKey(AThirdClass::class, $classes); + $this->assertContains(__DIR__.'/Assets/AFirstClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/AnotherClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/ASecondClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/AThirdClass.php', $classes); + + // .php recursive + $this->assertArrayHasKey(ASubFolderClass::class, $classes); + $this->assertArrayHasKey(AnotherSubClass::class, $classes); + $this->assertArrayHasKey(ASubSubFolderClass::class, $classes); + $this->assertContains(__DIR__.'/Assets/SubFolder/ASubFolderClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/SubFolder/AnotherSubClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/SubFolder/ASubSubFolder/ASubSubFolderClass.php', $classes); + + // .inc + recursive + $this->assertArrayNotHasKey(ADotIncClass::class, $classes); + $this->assertArrayNotHasKey(ASubDotIncClass::class, $classes); + $this->assertNotContains(__DIR__.'/Assets/ADotIncClass.inc', $classes); + $this->assertNotContains(__DIR__.'/Assets/SubFolder/ASubDotIncClass.inc', $classes); + } + + public function testDotInc():void + { + $iterator = new RecursiveDirectoryClassesIterator(self::ASSETS_PATH, ['inc']); + $this->assertInstanceOf(\Traversable::class, $iterator); + $classes = []; + foreach ($iterator as $class) { + $this->assertTrue( + substr($class->getFileName(), 0, strlen(self::ASSETS_PATH)) == self::ASSETS_PATH + ); + $this->assertFileExists($class->getFileName()); + $classes[$class->getName()] = $class->getFileName(); + } + + // .php + $this->assertArrayNotHasKey(AFirstClass::class, $classes); + $this->assertArrayNotHasKey(ASubFolderClass::class, $classes); + $this->assertArrayNotHasKey(ASubSubFolderClass::class, $classes); + $this->assertNotContains(__DIR__.'/Assets/AFirstClass.php', $classes); + $this->assertNotContains(__DIR__.'/Assets/SubFolder/ASubFolderClass.php', $classes); + $this->assertNotContains(__DIR__.'/Assets/SubFolder/ASubSubFolder/ASubSubFolderClass.php', $classes); + + // .inc + $this->assertArrayHasKey(ADotIncClass::class, $classes); + $this->assertArrayHasKey(ASubDotIncClass::class, $classes); + $this->assertContains(__DIR__.'/Assets/ADotIncClass.inc', $classes); + $this->assertContains(__DIR__.'/Assets/SubFolder/ASubDotIncClass.inc', $classes); + } + + public function testMultiExtensions():void + { + $iterator = new RecursiveDirectoryClassesIterator(self::ASSETS_PATH, ['inc', 'php']); + $this->assertInstanceOf(\Traversable::class, $iterator); + $classes = []; + foreach ($iterator as $class) { + $this->assertTrue( + substr($class->getFileName(), 0, strlen(self::ASSETS_PATH)) == self::ASSETS_PATH + ); + $this->assertFileExists($class->getFileName()); + $classes[$class->getName()] = $class->getFileName(); + } + $this->assertArrayHasKey(AFirstClass::class, $classes); + $this->assertArrayHasKey(ADotIncClass::class, $classes); + $this->assertArrayHasKey(AFirstClass::class, $classes); + $this->assertArrayHasKey(ASubFolderClass::class, $classes); + $this->assertArrayHasKey(ASubDotIncClass::class, $classes); + $this->assertArrayHasKey(ASubSubFolderClass::class, $classes); + $this->assertContains(__DIR__.'/Assets/AFirstClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/ADotIncClass.inc', $classes); + $this->assertContains(__DIR__.'/Assets/AFirstClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/SubFolder/ASubFolderClass.php', $classes); + $this->assertContains(__DIR__.'/Assets/SubFolder/ASubDotIncClass.inc', $classes); + $this->assertContains(__DIR__.'/Assets/SubFolder/ASubSubFolder/ASubSubFolderClass.php', $classes); + } +} \ No newline at end of file