From a9b036657d64fec61cf39cbf9ac817fbadd4e269 Mon Sep 17 00:00:00 2001 From: Herberto Graca Date: Thu, 27 Jul 2023 22:46:02 +0200 Subject: [PATCH] Create a MultipleDirClassSet This way we can specify just the directories we want it to scan, as opposed to include all dirs in the root and then excluding all dirs we don't want in the set. --- src/MultipleDirClassSet.php | 56 +++++++++++ tests/Unit/MultipleDirClassSetTest.php | 128 +++++++++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 src/MultipleDirClassSet.php create mode 100644 tests/Unit/MultipleDirClassSetTest.php diff --git a/src/MultipleDirClassSet.php b/src/MultipleDirClassSet.php new file mode 100644 index 00000000..0d9907d1 --- /dev/null +++ b/src/MultipleDirClassSet.php @@ -0,0 +1,56 @@ +directoryList = $directoryList; + $this->exclude = []; + } + + public static function fromDir(string ...$directoryList): self + { + return new self(...$directoryList); + } + + public function excludePath(string $pattern): ClassSetInterface + { + $this->exclude[] = Glob::toRegex($pattern); + + return $this; + } + + public function getDir(): string + { + return implode(', ', $this->directoryList); + } + + public function getIterator(): \Traversable + { + $finder = (new Finder()) + ->files() + ->in($this->directoryList) + ->name('*.php') + ->sortByName() + ->followLinks() + ->ignoreUnreadableDirs(true) + ->ignoreVCS(true); + + if ($this->exclude) { + $finder->notPath($this->exclude); + } + + return $finder; + } +} diff --git a/tests/Unit/MultipleDirClassSetTest.php b/tests/Unit/MultipleDirClassSetTest.php new file mode 100644 index 00000000..2e9e0391 --- /dev/null +++ b/tests/Unit/MultipleDirClassSetTest.php @@ -0,0 +1,128 @@ +createMvcProjectStructure(); + + $set = MultipleDirClassSet::fromDir($path . '/Controller', $path . '/Model') + ->excludePath("Repository"); + + $expected = [ + $path . '/Controller/CatalogController.php', + $path . '/Controller/Foo.php', + $path . '/Controller/ProductsController.php', + $path . '/Controller/UserController.php', + $path . '/Controller/YieldController.php', + $path . '/Model/Catalog.php', + $path . '/Model/Products.php', + $path . '/Model/User.php', + ]; + $actual = array_values(array_map(function ($item) { + /** @var SplFileInfo $item */ + return $item->getPathname(); + }, iterator_to_array($set))); + self::assertEquals($expected, $actual); + } + + public function test_can_exclude_files_or_directories(): void + { + $path = $this->createMvcProjectStructure(); + + $set = MultipleDirClassSet::fromDir($path) + ->excludePath('Model') + ->excludePath('ContainerAwareInterface'); + + $expected = [ + 'Controller/CatalogController.php', + 'Controller/Foo.php', + 'Controller/ProductsController.php', + 'Controller/UserController.php', + 'Controller/YieldController.php', + 'Services/UserService.php', + 'View/CatalogView.php', + 'View/ProductView.php', + 'View/UserView.php', + ]; + + $actual = array_values(array_map(function ($item) { + /** @var SplFileInfo $item */ + return $item->getRelativePathname(); + }, iterator_to_array($set))); + + self::assertEquals($expected, $actual); + } + + public function test_can_exclude_glob_patterns(): void + { + $path = $this->createMvcProjectStructure(); + + $set = MultipleDirClassSet::fromDir($path) + ->excludePath('*Catalog*'); + + $expected = [ + 'ContainerAwareInterface.php', + 'Controller/Foo.php', + 'Controller/ProductsController.php', + 'Controller/UserController.php', + 'Controller/YieldController.php', + 'Model/Products.php', + 'Model/Repository/ProductsRepository.php', + 'Model/Repository/UserRepository.php', + 'Model/User.php', + 'Services/UserService.php', + 'View/ProductView.php', + 'View/UserView.php', + ]; + + $actual = array_values(array_map(function ($item) { + return $item->getRelativePathname(); + }, iterator_to_array($set))); + + self::assertEquals($expected, $actual); + } + + protected function createMvcProjectStructure(): string + { + $structure = [ + 'Controller' => [ + 'CatalogController.php' => '', + 'Foo.php' => '', + 'ProductsController.php' => '', + 'UserController.php' => '', + 'YieldController.php' => '', + ], + 'Model' => [ + 'Repository' => [ + 'CatalogRepository.php' => '', + 'ProductsRepository.php' => '', + 'UserRepository.php' => '', + ], + 'Catalog.php' => '', + 'Products.php' => '', + 'User.php' => '', + ], + 'Services' => [ + 'UserService.php' => '', + ], + 'View' => [ + 'CatalogView.php' => '', + 'ProductView.php' => '', + 'UserView.php' => '', + ], + 'ContainerAwareInterface.php' => '', + ]; + + return vfsStream::setup('root', null, $structure)->url(); + } +}