This commit is contained in:
nuno maduro
2026-05-02 01:58:39 +01:00
parent 6e1bf63f6a
commit 6407c4f78f
2 changed files with 77 additions and 7 deletions

View File

@ -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)) {
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<int, string> $changedFiles
*/

View File

@ -68,6 +68,31 @@ final readonly class SourceScope
return new self($includes, $excludes);
}
/**
* @return list<string> 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);