From 6407c4f78f3a15bea6f7ccb7c5ac47bb9bc98bed Mon Sep 17 00:00:00 2001 From: nuno maduro Date: Sat, 2 May 2026 01:58:39 +0100 Subject: [PATCH] wip --- src/Plugins/Tia.php | 59 +++++++++++++++++++++++++++++---- src/Plugins/Tia/SourceScope.php | 25 ++++++++++++++ 2 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/Plugins/Tia.php b/src/Plugins/Tia.php index 964cd4ae..50c67593 100644 --- a/src/Plugins/Tia.php +++ b/src/Plugins/Tia.php @@ -1380,27 +1380,72 @@ final class Tia implements AddsOutput, HandlesArguments, Terminable */ private function hasExplicitPathArgument(array $arguments): bool { - $projectRoot = TestSuite::getInstance()->rootPath; + static $valueTakingFlags = [ + '-c', '--configuration', '--bootstrap', '--cache-directory', + '--filter', '--group', '--exclude-group', '--covers', '--uses', + '--test-suffix', '--testsuite', '--exclude-testsuite', + '--printer', '--columns', '--colors', '--order-by', '--random-order-seed', + '--include-path', '--whitelist', + '--log-junit', '--log-teamcity', '--testdox-html', '--testdox-text', + '--coverage-clover', '--coverage-cobertura', '--coverage-crap4j', + '--coverage-html', '--coverage-php', '--coverage-text', '--coverage-xml', + '--coverage-filter', '--path-coverage', + '--repeat', '--retry-times', '--memory-limit', '--seed', + '--compact', '--ci-build-id', '--min', + ]; - foreach ($arguments as $arg) { + $projectRoot = TestSuite::getInstance()->rootPath; + $testPaths = \Pest\Plugins\Tia\SourceScope::testPaths($projectRoot); + + if ($testPaths === []) { + return false; + } + + foreach ($arguments as $index => $arg) { if ($arg === '' || str_starts_with($arg, '-')) { continue; } - if (is_file($arg) || is_dir($arg)) { - return true; + if ($index > 0) { + $previous = $arguments[$index - 1] ?? ''; + if (in_array($previous, $valueTakingFlags, true)) { + continue; + } } - $absolute = rtrim($projectRoot, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.ltrim($arg, DIRECTORY_SEPARATOR); + $candidate = $this->resolveArgumentPath($arg, $projectRoot); - if (is_file($absolute) || is_dir($absolute)) { - return true; + if ($candidate === null) { + continue; + } + + foreach ($testPaths as $testPath) { + if ($candidate === $testPath || str_starts_with($candidate, $testPath.DIRECTORY_SEPARATOR)) { + return true; + } } } return false; } + private function resolveArgumentPath(string $arg, string $projectRoot): ?string + { + $candidates = [$arg, rtrim($projectRoot, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.ltrim($arg, DIRECTORY_SEPARATOR)]; + + foreach ($candidates as $candidate) { + if (! is_file($candidate) && ! is_dir($candidate)) { + continue; + } + + $real = @realpath($candidate); + + return rtrim($real === false ? $candidate : $real, '/\\'); + } + + return null; + } + /** * @param array $changedFiles */ diff --git a/src/Plugins/Tia/SourceScope.php b/src/Plugins/Tia/SourceScope.php index cf03064d..85374c5a 100644 --- a/src/Plugins/Tia/SourceScope.php +++ b/src/Plugins/Tia/SourceScope.php @@ -68,6 +68,31 @@ final readonly class SourceScope return new self($includes, $excludes); } + /** + * @return list Absolute, normalised paths to testsuite directories and files declared in phpunit.xml. + */ + public static function testPaths(string $projectRoot): array + { + $configPath = self::configPath($projectRoot); + + if ($configPath === null) { + return []; + } + + $xml = @simplexml_load_file($configPath); + + if ($xml === false) { + return []; + } + + $configDir = dirname($configPath); + + return array_values(array_unique([ + ...self::extractDirectories($xml, 'testsuites/testsuite/directory', $configDir), + ...self::extractDirectories($xml, 'testsuites/testsuite/file', $configDir), + ])); + } + public function contains(string $absoluteFile): bool { $real = @realpath($absoluteFile);