diff --git a/src/TextUI/Configuration/SourceMapper.php b/src/TextUI/Configuration/SourceMapper.php index cbe8aa4c65..c8108a43bb 100644 --- a/src/TextUI/Configuration/SourceMapper.php +++ b/src/TextUI/Configuration/SourceMapper.php @@ -40,8 +40,10 @@ public function map(Source $source): array $files = []; - foreach ($source->includeDirectories() as $directory) { - foreach ((new FileIteratorFacade)->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) { + $directories = $this->aggregateDirectories($source->includeDirectories()); + + foreach ($directories as $path => [$prefixes, $suffixes]) { + foreach ((new FileIteratorFacade)->getFilesAsArray($path, $suffixes, $prefixes) as $file) { $file = realpath($file); if (!$file) { @@ -62,8 +64,10 @@ public function map(Source $source): array $files[$file] = true; } - foreach ($source->excludeDirectories() as $directory) { - foreach ((new FileIteratorFacade)->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) { + $directories = $this->aggregateDirectories($source->excludeDirectories()); + + foreach ($directories as $path => [$prefixes, $suffixes]) { + foreach ((new FileIteratorFacade)->getFilesAsArray($path, $suffixes, $prefixes) as $file) { $file = realpath($file); if (!$file) { @@ -96,4 +100,33 @@ public function map(Source $source): array return $files; } + + /** + * @return array,list}> + */ + private function aggregateDirectories(FilterDirectoryCollection $directories): array + { + $aggregated = []; + + foreach ($directories as $directory) { + if (!isset($aggregated[$directory->path()])) { + $aggregated[$directory->path()] = [ + 0 => [], + 1 => [], + ]; + } + $prefix = $directory->prefix(); + + if ($prefix !== '') { + $aggregated[$directory->path()][0][] = $prefix; + } + $suffix = $directory->suffix(); + + if ($suffix !== '') { + $aggregated[$directory->path()][1][] = $suffix; + } + } + + return $aggregated; + } } diff --git a/tests/unit/TextUI/SourceMapperTest.php b/tests/unit/TextUI/SourceMapperTest.php index a2d34e9000..d36d342e9c 100644 --- a/tests/unit/TextUI/SourceMapperTest.php +++ b/tests/unit/TextUI/SourceMapperTest.php @@ -270,6 +270,82 @@ public static function provider(): Generator ), ), ]; + + yield 'files included using same directory and different suffixes' => [ + [ + self::fixturePath('a/c/Prefix.php') => true, + self::fixturePath('a/c/d/Prefix.php') => true, + self::fixturePath('b/e/PrefixExampleSuffix.php') => true, + ], + self::createSource( + includeDirectories: FilterDirectoryCollection::fromArray( + [ + new FilterDirectory( + self::fixturePath(), + '', + 'ExampleSuffix.php', + ), + new FilterDirectory( + self::fixturePath(), + '', + 'Prefix.php', + ), + ], + ), + ), + ]; + + yield 'files included using same directory and different prefixes' => [ + [ + self::fixturePath('a/c/Suffix.php') => true, + self::fixturePath('a/c/d/Suffix.php') => true, + self::fixturePath('b/e/PrefixExampleSuffix.php') => true, + ], + self::createSource( + includeDirectories: FilterDirectoryCollection::fromArray( + [ + new FilterDirectory( + self::fixturePath(), + 'Suffix', + '.php', + ), + new FilterDirectory( + self::fixturePath(), + 'PrefixExample', + '.php', + ), + ], + ), + ), + ]; + + yield 'files excluded using same directory and different prefixes' => [ + [ + ], + self::createSource( + includeDirectories: FilterDirectoryCollection::fromArray([ + new FilterDirectory( + self::fixturePath(), + '', + '.php', + ), + ]), + excludeDirectories: FilterDirectoryCollection::fromArray( + [ + new FilterDirectory( + self::fixturePath(), + 'Prefix', + '.php', + ), + new FilterDirectory( + self::fixturePath(), + 'Suffix', + '.php', + ), + ], + ), + ), + ]; } public static function fixturePath(?string $subPath = null): string