�ɲɾ�����ӯ�����һ��ˣ��������С���˴��ͣ�������P���ҹ��ñ˽��ά�Բ��������˸߸ԣ�������ơ��ҹ��ñ�����ά�Բ���ˡ���˳^�ӣ������ӡ� ���ͯj�ӣ��ƺ���ӣ� ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!PKYg3]K^ShellExitCodeCalculator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI; use PHPUnit\TestRunner\TestResult\TestResult; use PHPUnit\TextUI\Configuration\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ShellExitCodeCalculator { private const SUCCESS_EXIT = 0; private const FAILURE_EXIT = 1; private const EXCEPTION_EXIT = 2; public function calculate(Configuration $configuration, TestResult $result): int { $failOnDeprecation = false; $failOnPhpunitDeprecation = false; $failOnPhpunitWarning = false; $failOnEmptyTestSuite = false; $failOnIncomplete = false; $failOnNotice = false; $failOnRisky = false; $failOnSkipped = false; $failOnWarning = false; if ($configuration->failOnAllIssues()) { $failOnDeprecation = true; $failOnPhpunitDeprecation = true; $failOnPhpunitWarning = true; $failOnEmptyTestSuite = true; $failOnIncomplete = true; $failOnNotice = true; $failOnRisky = true; $failOnSkipped = true; $failOnWarning = true; } if ($configuration->failOnDeprecation()) { $failOnDeprecation = true; } if ($configuration->doNotFailOnDeprecation()) { $failOnDeprecation = false; } if ($configuration->failOnPhpunitDeprecation()) { $failOnPhpunitDeprecation = true; } if ($configuration->doNotFailOnPhpunitDeprecation()) { $failOnPhpunitDeprecation = false; } if ($configuration->failOnPhpunitWarning()) { $failOnPhpunitWarning = true; } if ($configuration->doNotFailOnPhpunitWarning()) { $failOnPhpunitWarning = false; } if ($configuration->failOnEmptyTestSuite()) { $failOnEmptyTestSuite = true; } if ($configuration->doNotFailOnEmptyTestSuite()) { $failOnEmptyTestSuite = false; } if ($configuration->failOnIncomplete()) { $failOnIncomplete = true; } if ($configuration->doNotFailOnIncomplete()) { $failOnIncomplete = false; } if ($configuration->failOnNotice()) { $failOnNotice = true; } if ($configuration->doNotFailOnNotice()) { $failOnNotice = false; } if ($configuration->failOnRisky()) { $failOnRisky = true; } if ($configuration->doNotFailOnRisky()) { $failOnRisky = false; } if ($configuration->failOnSkipped()) { $failOnSkipped = true; } if ($configuration->doNotFailOnSkipped()) { $failOnSkipped = false; } if ($configuration->failOnWarning()) { $failOnWarning = true; } if ($configuration->doNotFailOnWarning()) { $failOnWarning = false; } $returnCode = self::FAILURE_EXIT; if ($result->wasSuccessful()) { $returnCode = self::SUCCESS_EXIT; } if ($failOnEmptyTestSuite && !$result->hasTests()) { $returnCode = self::FAILURE_EXIT; } if ($failOnDeprecation && $result->hasPhpOrUserDeprecations()) { $returnCode = self::FAILURE_EXIT; } if ($failOnPhpunitDeprecation && $result->hasPhpunitDeprecations()) { $returnCode = self::FAILURE_EXIT; } if ($failOnPhpunitWarning && $result->hasPhpunitWarnings()) { $returnCode = self::FAILURE_EXIT; } if ($failOnIncomplete && $result->hasIncompleteTests()) { $returnCode = self::FAILURE_EXIT; } if ($failOnNotice && $result->hasNotices()) { $returnCode = self::FAILURE_EXIT; } if ($failOnRisky && $result->hasRiskyTests()) { $returnCode = self::FAILURE_EXIT; } if ($failOnSkipped && $result->hasSkippedTests()) { $returnCode = self::FAILURE_EXIT; } if ($failOnWarning && $result->hasWarnings()) { $returnCode = self::FAILURE_EXIT; } if ($result->hasErrors()) { $returnCode = self::EXCEPTION_EXIT; } return $returnCode; } } PKYg3][\  1Command/Commands/GenerateConfigurationCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; use const PHP_EOL; use const STDIN; use function fgets; use function file_put_contents; use function getcwd; use function sprintf; use function trim; use PHPUnit\Runner\Version; use PHPUnit\TextUI\XmlConfiguration\Generator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class GenerateConfigurationCommand implements Command { public function execute(): Result { print 'Generating phpunit.xml in ' . getcwd() . PHP_EOL . PHP_EOL; print 'Bootstrap script (relative to path shown above; default: vendor/autoload.php): '; $bootstrapScript = $this->read(); print 'Tests directory (relative to path shown above; default: tests): '; $testsDirectory = $this->read(); print 'Source directory (relative to path shown above; default: src): '; $src = $this->read(); print 'Cache directory (relative to path shown above; default: .phpunit.cache): '; $cacheDirectory = $this->read(); if ($bootstrapScript === '') { $bootstrapScript = 'vendor/autoload.php'; } if ($testsDirectory === '') { $testsDirectory = 'tests'; } if ($src === '') { $src = 'src'; } if ($cacheDirectory === '') { $cacheDirectory = '.phpunit.cache'; } $generator = new Generator; $result = @file_put_contents( 'phpunit.xml', $generator->generateDefaultConfiguration( Version::series(), $bootstrapScript, $testsDirectory, $src, $cacheDirectory, ), ); if ($result !== false) { return Result::from( sprintf( PHP_EOL . 'Generated phpunit.xml in %s.' . PHP_EOL . 'Make sure to exclude the %s directory from version control.' . PHP_EOL, getcwd(), $cacheDirectory, ), ); } // @codeCoverageIgnoreStart return Result::from( sprintf( PHP_EOL . 'Could not write phpunit.xml in %s.' . PHP_EOL, getcwd(), ), Result::EXCEPTION, ); // @codeCoverageIgnoreEnd } private function read(): string { return trim(fgets(STDIN)); } } PKYg3]yy*Command/Commands/ListTestSuitesCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; use const PHP_EOL; use function sprintf; use PHPUnit\TextUI\Configuration\Registry; use PHPUnit\TextUI\Configuration\TestSuiteCollection; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ListTestSuitesCommand implements Command { private readonly TestSuiteCollection $suites; public function __construct(TestSuiteCollection $suites) { $this->suites = $suites; } public function execute(): Result { $buffer = $this->warnAboutConflictingOptions(); $buffer .= 'Available test suite(s):' . PHP_EOL; foreach ($this->suites as $suite) { $buffer .= sprintf( ' - %s' . PHP_EOL, $suite->name(), ); } return Result::from($buffer); } private function warnAboutConflictingOptions(): string { $buffer = ''; $configuration = Registry::get(); if ($configuration->hasFilter()) { $buffer .= 'The --filter and --list-suites options cannot be combined, --filter is ignored' . PHP_EOL; } if ($configuration->hasGroups()) { $buffer .= 'The --group and --list-suites options cannot be combined, --group is ignored' . PHP_EOL; } if ($configuration->hasExcludeGroups()) { $buffer .= 'The --exclude-group and --list-suites options cannot be combined, --exclude-group is ignored' . PHP_EOL; } if ($configuration->includeTestSuite() !== '') { $buffer .= 'The --testsuite and --list-suites options cannot be combined, --testsuite is ignored' . PHP_EOL; } if (!empty($buffer)) { $buffer .= PHP_EOL; } return $buffer; } } PKYg3]y*Command/Commands/AtLeastVersionCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; use function version_compare; use PHPUnit\Runner\Version; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class AtLeastVersionCommand implements Command { private readonly string $version; public function __construct(string $version) { $this->version = $version; } public function execute(): Result { if (version_compare(Version::id(), $this->version, '>=')) { return Result::from(); } return Result::from('', Result::FAILURE); } } PKYg3]jᧀtt$Command/Commands/ShowHelpCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; use PHPUnit\TextUI\Help; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ShowHelpCommand implements Command { private readonly int $shellExitCode; public function __construct(int $shellExitCode) { $this->shellExitCode = $shellExitCode; } public function execute(): Result { return Result::from( (new Help)->generate(), $this->shellExitCode, ); } } PKYg3]0Command/Commands/MigrateConfigurationCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; use const PHP_EOL; use function copy; use function file_put_contents; use function sprintf; use PHPUnit\TextUI\XmlConfiguration\Migrator; use Throwable; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class MigrateConfigurationCommand implements Command { private readonly string $filename; public function __construct(string $filename) { $this->filename = $filename; } public function execute(): Result { try { $migrated = (new Migrator)->migrate($this->filename); copy($this->filename, $this->filename . '.bak'); file_put_contents($this->filename, $migrated); return Result::from( sprintf( 'Created backup: %s.bak%sMigrated configuration: %s%s', $this->filename, PHP_EOL, $this->filename, PHP_EOL, ), ); } catch (Throwable $t) { return Result::from( sprintf( 'Migration of %s failed:%s%s%s', $this->filename, PHP_EOL, $t->getMessage(), PHP_EOL, ), Result::FAILURE, ); } } } PKYg3]U"*Command/Commands/ListTestsAsXmlCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; use const PHP_EOL; use function file_put_contents; use function implode; use function sprintf; use function str_replace; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestSuite; use PHPUnit\Runner\PhptTestCase; use PHPUnit\TextUI\Configuration\Registry; use RecursiveIteratorIterator; use XMLWriter; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ListTestsAsXmlCommand implements Command { private readonly string $filename; private readonly TestSuite $suite; public function __construct(string $filename, TestSuite $suite) { $this->filename = $filename; $this->suite = $suite; } public function execute(): Result { $buffer = $this->warnAboutConflictingOptions(); $writer = new XMLWriter; $writer->openMemory(); $writer->setIndent(true); $writer->startDocument(); $writer->startElement('tests'); $currentTestCase = null; foreach (new RecursiveIteratorIterator($this->suite) as $test) { if ($test instanceof TestCase) { if ($test::class !== $currentTestCase) { if ($currentTestCase !== null) { $writer->endElement(); } $writer->startElement('testCaseClass'); $writer->writeAttribute('name', $test::class); $currentTestCase = $test::class; } $writer->startElement('testCaseMethod'); $writer->writeAttribute('id', $test->valueObjectForEvents()->id()); $writer->writeAttribute('name', $test->name()); $writer->writeAttribute('groups', implode(',', $test->groups())); /** * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5481 */ if (!empty($test->dataSetAsString())) { $writer->writeAttribute( 'dataSet', str_replace( ' with data set ', '', $test->dataSetAsString(), ), ); } $writer->endElement(); continue; } if ($test instanceof PhptTestCase) { if ($currentTestCase !== null) { $writer->endElement(); $currentTestCase = null; } $writer->startElement('phptFile'); $writer->writeAttribute('path', $test->getName()); $writer->endElement(); } } if ($currentTestCase !== null) { $writer->endElement(); } $writer->endElement(); file_put_contents($this->filename, $writer->outputMemory()); $buffer .= sprintf( 'Wrote list of tests that would have been run to %s' . PHP_EOL, $this->filename, ); return Result::from($buffer); } private function warnAboutConflictingOptions(): string { $buffer = ''; $configuration = Registry::get(); if ($configuration->hasFilter()) { $buffer .= 'The --filter and --list-tests-xml options cannot be combined, --filter is ignored' . PHP_EOL; } if ($configuration->hasGroups()) { $buffer .= 'The --group and --list-tests-xml options cannot be combined, --group is ignored' . PHP_EOL; } if ($configuration->hasExcludeGroups()) { $buffer .= 'The --exclude-group and --list-tests-xml options cannot be combined, --exclude-group is ignored' . PHP_EOL; } if (!empty($buffer)) { $buffer .= PHP_EOL; } return $buffer; } } PKYg3]j:z +Command/Commands/ListTestsAsTextCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; use const PHP_EOL; use function sprintf; use function str_replace; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestSuite; use PHPUnit\Runner\PhptTestCase; use PHPUnit\TextUI\Configuration\Registry; use RecursiveIteratorIterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ListTestsAsTextCommand implements Command { private readonly TestSuite $suite; public function __construct(TestSuite $suite) { $this->suite = $suite; } public function execute(): Result { $buffer = $this->warnAboutConflictingOptions(); $buffer .= 'Available test(s):' . PHP_EOL; foreach (new RecursiveIteratorIterator($this->suite) as $test) { if ($test instanceof TestCase) { $name = sprintf( '%s::%s', $test::class, str_replace(' with data set ', '', $test->nameWithDataSet()), ); } elseif ($test instanceof PhptTestCase) { $name = $test->getName(); } else { continue; } $buffer .= sprintf( ' - %s' . PHP_EOL, $name, ); } return Result::from($buffer); } private function warnAboutConflictingOptions(): string { $buffer = ''; $configuration = Registry::get(); if ($configuration->hasFilter()) { $buffer .= 'The --filter and --list-tests options cannot be combined, --filter is ignored' . PHP_EOL; } if ($configuration->hasGroups()) { $buffer .= 'The --group and --list-tests options cannot be combined, --group is ignored' . PHP_EOL; } if ($configuration->hasExcludeGroups()) { $buffer .= 'The --exclude-group and --list-tests options cannot be combined, --exclude-group is ignored' . PHP_EOL; } if (!empty($buffer)) { $buffer .= PHP_EOL; } return $buffer; } } PKYg3]rیc c (Command/Commands/VersionCheckCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; use const PHP_EOL; use function assert; use function sprintf; use function version_compare; use PHPUnit\Util\Http\Downloader; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class VersionCheckCommand implements Command { private readonly Downloader $downloader; private readonly int $majorVersionNumber; private readonly string $versionId; public function __construct(Downloader $downloader, int $majorVersionNumber, string $versionId) { $this->downloader = $downloader; $this->majorVersionNumber = $majorVersionNumber; $this->versionId = $versionId; } public function execute(): Result { $latestVersion = $this->downloader->download('https://phar.phpunit.de/latest-version-of/phpunit'); assert($latestVersion !== false); $latestCompatibleVersion = $this->downloader->download('https://phar.phpunit.de/latest-version-of/phpunit-' . $this->majorVersionNumber); assert($latestCompatibleVersion !== false); $notLatest = version_compare($latestVersion, $this->versionId, '>'); $notLatestCompatible = version_compare($latestCompatibleVersion, $this->versionId, '>'); if (!$notLatest && !$notLatestCompatible) { return Result::from( 'You are using the latest version of PHPUnit.' . PHP_EOL, ); } $buffer = 'You are not using the latest version of PHPUnit.' . PHP_EOL; if ($notLatestCompatible) { $buffer .= sprintf( 'The latest version compatible with PHPUnit %s is PHPUnit %s.' . PHP_EOL, $this->versionId, $latestCompatibleVersion, ); } if ($notLatest) { $buffer .= sprintf( 'The latest version is PHPUnit %s.' . PHP_EOL, $latestVersion, ); } return Result::from($buffer); } } PKYg3]Xtt'Command/Commands/ShowVersionCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ShowVersionCommand implements Command { public function execute(): Result { return Result::from(); } } PKYg3]ˎ. . 1Command/Commands/WarmCodeCoverageCacheCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; use const PHP_EOL; use function printf; use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry; use PHPUnit\TextUI\Configuration\Configuration; use PHPUnit\TextUI\Configuration\NoCoverageCacheDirectoryException; use SebastianBergmann\CodeCoverage\StaticAnalysis\CacheWarmer; use SebastianBergmann\Timer\NoActiveTimerException; use SebastianBergmann\Timer\Timer; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @codeCoverageIgnore */ final class WarmCodeCoverageCacheCommand implements Command { private readonly Configuration $configuration; private readonly CodeCoverageFilterRegistry $codeCoverageFilterRegistry; public function __construct(Configuration $configuration, CodeCoverageFilterRegistry $codeCoverageFilterRegistry) { $this->configuration = $configuration; $this->codeCoverageFilterRegistry = $codeCoverageFilterRegistry; } /** * @throws NoActiveTimerException * @throws NoCoverageCacheDirectoryException */ public function execute(): Result { if (!$this->configuration->hasCoverageCacheDirectory()) { return Result::from( 'Cache for static analysis has not been configured' . PHP_EOL, Result::FAILURE, ); } $this->codeCoverageFilterRegistry->init($this->configuration, true); if (!$this->codeCoverageFilterRegistry->configured()) { return Result::from( 'Filter for code coverage has not been configured' . PHP_EOL, Result::FAILURE, ); } $timer = new Timer; $timer->start(); print 'Warming cache for static analysis ... '; (new CacheWarmer)->warmCache( $this->configuration->coverageCacheDirectory(), !$this->configuration->disableCodeCoverageIgnore(), $this->configuration->ignoreDeprecatedCodeUnitsFromCodeCoverage(), $this->codeCoverageFilterRegistry->get(), ); printf( '[%s]%s', $timer->stop()->asString(), PHP_EOL, ); return Result::from(); } } PKYg3]hw  &Command/Commands/ListGroupsCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; use const PHP_EOL; use function sort; use function sprintf; use function str_starts_with; use PHPUnit\Framework\TestSuite; use PHPUnit\TextUI\Configuration\Registry; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ListGroupsCommand implements Command { private readonly TestSuite $suite; public function __construct(TestSuite $suite) { $this->suite = $suite; } public function execute(): Result { $buffer = $this->warnAboutConflictingOptions(); $buffer .= 'Available test group(s):' . PHP_EOL; $groups = $this->suite->groups(); sort($groups); foreach ($groups as $group) { if (str_starts_with($group, '__phpunit_')) { continue; } $buffer .= sprintf( ' - %s' . PHP_EOL, $group, ); } return Result::from($buffer); } private function warnAboutConflictingOptions(): string { $buffer = ''; $configuration = Registry::get(); if ($configuration->hasFilter()) { $buffer .= 'The --filter and --list-groups options cannot be combined, --filter is ignored' . PHP_EOL; } if ($configuration->hasGroups()) { $buffer .= 'The --group and --list-groups options cannot be combined, --group is ignored' . PHP_EOL; } if ($configuration->hasExcludeGroups()) { $buffer .= 'The --exclude-group and --list-groups options cannot be combined, --exclude-group is ignored' . PHP_EOL; } if ($configuration->includeTestSuite() !== '') { $buffer .= 'The --testsuite and --list-groups options cannot be combined, --exclude-group is ignored' . PHP_EOL; } if (!empty($buffer)) { $buffer .= PHP_EOL; } return $buffer; } } PKYg3]-bMM1Command/Commands/CheckPhpConfigurationCommand.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; use const E_ALL; use const PHP_EOL; use function extension_loaded; use function in_array; use function ini_get; use function max; use function sprintf; use function strlen; use PHPUnit\Runner\Version; use PHPUnit\Util\Color; use SebastianBergmann\Environment\Console; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CheckPhpConfigurationCommand implements Command { private readonly bool $colorize; public function __construct() { $this->colorize = (new Console)->hasColorSupport(); } public function execute(): Result { $lines = []; $shellExitCode = 0; foreach ($this->settings() as $name => $setting) { foreach ($setting['requiredExtensions'] as $extension) { if (!extension_loaded($extension)) { // @codeCoverageIgnoreStart continue 2; // @codeCoverageIgnoreEnd } } $actualValue = ini_get($name); if (in_array($actualValue, $setting['expectedValues'], true)) { $check = $this->ok(); } else { $check = $this->notOk($actualValue); $shellExitCode = 1; } $lines[] = [ sprintf( '%s = %s', $name, $setting['valueForConfiguration'], ), $check, ]; } $maxLength = 0; foreach ($lines as $line) { $maxLength = max($maxLength, strlen($line[0])); } $buffer = sprintf( 'Checking whether PHP is configured according to https://docs.phpunit.de/en/%s/installation.html#configuring-php-for-development' . PHP_EOL . PHP_EOL, Version::series(), ); foreach ($lines as $line) { $buffer .= sprintf( '%-' . $maxLength . 's ... %s' . PHP_EOL, $line[0], $line[1], ); } return Result::from($buffer, $shellExitCode); } /** * @return non-empty-string */ private function ok(): string { if (!$this->colorize) { return 'ok'; } // @codeCoverageIgnoreStart return Color::colorizeTextBox('fg-green, bold', 'ok'); // @codeCoverageIgnoreEnd } /** * @return non-empty-string */ private function notOk(string $actualValue): string { $message = sprintf('not ok (%s)', $actualValue); if (!$this->colorize) { return $message; } // @codeCoverageIgnoreStart return Color::colorizeTextBox('fg-red, bold', $message); // @codeCoverageIgnoreEnd } /** * @return non-empty-array, valueForConfiguration: non-empty-string, requiredExtensions: list}> */ private function settings(): array { return [ 'display_errors' => [ 'expectedValues' => ['1'], 'valueForConfiguration' => 'On', 'requiredExtensions' => [], ], 'display_startup_errors' => [ 'expectedValues' => ['1'], 'valueForConfiguration' => 'On', 'requiredExtensions' => [], ], 'error_reporting' => [ 'expectedValues' => ['-1', (string) E_ALL], 'valueForConfiguration' => '-1', 'requiredExtensions' => [], ], 'xdebug.show_exception_trace' => [ 'expectedValues' => ['0'], 'valueForConfiguration' => '0', 'requiredExtensions' => ['xdebug'], ], 'zend.assertions' => [ 'expectedValues' => ['1'], 'valueForConfiguration' => '1', 'requiredExtensions' => [], ], 'assert.exception' => [ 'expectedValues' => ['1'], 'valueForConfiguration' => '1', 'requiredExtensions' => [], ], 'memory_limit' => [ 'expectedValues' => ['-1'], 'valueForConfiguration' => '-1', 'requiredExtensions' => [], ], ]; } } PKYg3]=DCommand/Result.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Result { public const SUCCESS = 0; public const FAILURE = 1; public const EXCEPTION = 2; public const CRASH = 255; private readonly string $output; private readonly int $shellExitCode; public static function from(string $output = '', int $shellExitCode = self::SUCCESS): self { return new self($output, $shellExitCode); } private function __construct(string $output, int $shellExitCode) { $this->output = $output; $this->shellExitCode = $shellExitCode; } public function output(): string { return $this->output; } public function shellExitCode(): int { return $this->shellExitCode; } } PKYg3]맳 **Command/Command.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Command; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ interface Command { public function execute(): Result; } PKYg3][ TestSuiteFilterProcessor.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI; use function array_map; use PHPUnit\Event; use PHPUnit\Framework\TestSuite; use PHPUnit\Runner\Filter\Factory; use PHPUnit\TextUI\Configuration\Configuration; use PHPUnit\TextUI\Configuration\FilterNotConfiguredException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestSuiteFilterProcessor { /** * @throws Event\RuntimeException * @throws FilterNotConfiguredException */ public function process(Configuration $configuration, TestSuite $suite): void { $factory = new Factory; if (!$configuration->hasFilter() && !$configuration->hasGroups() && !$configuration->hasExcludeGroups() && !$configuration->hasTestsCovering() && !$configuration->hasTestsUsing()) { return; } if ($configuration->hasExcludeGroups()) { $factory->addExcludeGroupFilter( $configuration->excludeGroups(), ); } if ($configuration->hasGroups()) { $factory->addIncludeGroupFilter( $configuration->groups(), ); } if ($configuration->hasTestsCovering()) { $factory->addIncludeGroupFilter( array_map( static fn (string $name): string => '__phpunit_covers_' . $name, $configuration->testsCovering(), ), ); } if ($configuration->hasTestsUsing()) { $factory->addIncludeGroupFilter( array_map( static fn (string $name): string => '__phpunit_uses_' . $name, $configuration->testsUsing(), ), ); } if ($configuration->hasFilter()) { $factory->addNameFilter( $configuration->filter(), ); } $suite->injectFilter($factory); Event\Facade::emitter()->testSuiteFiltered( Event\TestSuite\TestSuiteBuilder::from($suite), ); } } PKYg3]P{]]'Exception/CannotOpenSocketException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI; use function sprintf; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CannotOpenSocketException extends RuntimeException implements Exception { public function __construct(string $hostname, int $port) { parent::__construct( sprintf( 'Cannot open socket %s:%d', $hostname, $port, ), ); } } PKYg3]W==,Exception/TestDirectoryNotFoundException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI; use function sprintf; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestDirectoryNotFoundException extends RuntimeException implements Exception { public function __construct(string $path) { parent::__construct( sprintf( 'Test directory "%s" not found', $path, ), ); } } PKYg3]e33'Exception/TestFileNotFoundException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI; use function sprintf; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestFileNotFoundException extends RuntimeException implements Exception { public function __construct(string $path) { parent::__construct( sprintf( 'Test file "%s" not found', $path, ), ); } } PKYg3]/d[OO$Exception/InvalidSocketException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI; use function sprintf; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class InvalidSocketException extends RuntimeException implements Exception { public function __construct(string $socket) { parent::__construct( sprintf( '"%s" does not match "socket://hostname:port" format', $socket, ), ); } } PKYg3]Z`##Exception/Exception.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI; use Throwable; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This interface is not covered by the backward compatibility promise for PHPUnit */ interface Exception extends Throwable { } PKYg3]4)55Exception/RuntimeException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RuntimeException extends \RuntimeException implements Exception { } PKYg3][[uGGHelp.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI; use const PHP_EOL; use function count; use function defined; use function explode; use function max; use function preg_replace_callback; use function str_pad; use function str_repeat; use function strlen; use function wordwrap; use PHPUnit\Util\Color; use SebastianBergmann\Environment\Console; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Help { private const LEFT_MARGIN = ' '; private int $lengthOfLongestOptionName = 0; private readonly int $columnsAvailableForDescription; private ?bool $hasColor; public function __construct(?int $width = null, ?bool $withColor = null) { if ($width === null) { $width = (new Console)->getNumberOfColumns(); } if ($withColor === null) { $this->hasColor = (new Console)->hasColorSupport(); } else { $this->hasColor = $withColor; } foreach ($this->elements() as $options) { foreach ($options as $option) { if (isset($option['arg'])) { $this->lengthOfLongestOptionName = max($this->lengthOfLongestOptionName, strlen($option['arg'])); } } } $this->columnsAvailableForDescription = $width - $this->lengthOfLongestOptionName - 4; } public function generate(): string { if ($this->hasColor) { return $this->writeWithColor(); } return $this->writeWithoutColor(); } private function writeWithoutColor(): string { $buffer = ''; foreach ($this->elements() as $section => $options) { $buffer .= "{$section}:" . PHP_EOL; if ($section !== 'Usage') { $buffer .= PHP_EOL; } foreach ($options as $option) { if (isset($option['spacer'])) { $buffer .= PHP_EOL; } if (isset($option['text'])) { $buffer .= self::LEFT_MARGIN . $option['text'] . PHP_EOL; } if (isset($option['arg'])) { $arg = str_pad($option['arg'], $this->lengthOfLongestOptionName); $buffer .= self::LEFT_MARGIN . $arg . ' ' . $option['desc'] . PHP_EOL; } } $buffer .= PHP_EOL; } return $buffer; } private function writeWithColor(): string { $buffer = ''; foreach ($this->elements() as $section => $options) { $buffer .= Color::colorize('fg-yellow', "{$section}:") . PHP_EOL; if ($section !== 'Usage') { $buffer .= PHP_EOL; } foreach ($options as $option) { if (isset($option['spacer'])) { $buffer .= PHP_EOL; } if (isset($option['text'])) { $buffer .= self::LEFT_MARGIN . $option['text'] . PHP_EOL; } if (isset($option['arg'])) { $arg = Color::colorize('fg-green', str_pad($option['arg'], $this->lengthOfLongestOptionName)); $arg = preg_replace_callback( '/(<[^>]+>)/', static fn ($matches) => Color::colorize('fg-cyan', $matches[0]), $arg, ); $desc = explode(PHP_EOL, wordwrap($option['desc'], $this->columnsAvailableForDescription, PHP_EOL)); $buffer .= self::LEFT_MARGIN . $arg . ' ' . $desc[0] . PHP_EOL; for ($i = 1; $i < count($desc); $i++) { $buffer .= str_repeat(' ', $this->lengthOfLongestOptionName + 3) . $desc[$i] . PHP_EOL; } } } $buffer .= PHP_EOL; } return $buffer; } /** * @psalm-return array> */ private function elements(): array { $elements = [ 'Usage' => [ ['text' => 'phpunit [options] ...'], ], 'Configuration' => [ ['arg' => '--bootstrap ', 'desc' => 'A PHP script that is included before the tests run'], ['arg' => '-c|--configuration ', 'desc' => 'Read configuration from XML file'], ['arg' => '--no-configuration', 'desc' => 'Ignore default configuration file (phpunit.xml)'], ['arg' => '--no-extensions', 'desc' => 'Do not load PHPUnit extensions'], ['arg' => '--include-path ', 'desc' => 'Prepend PHP\'s include_path with given path(s)'], ['arg' => '-d ', 'desc' => 'Sets a php.ini value'], ['arg' => '--cache-directory ', 'desc' => 'Specify cache directory'], ['arg' => '--generate-configuration', 'desc' => 'Generate configuration file with suggested settings'], ['arg' => '--migrate-configuration', 'desc' => 'Migrate configuration file to current format'], ['arg' => '--generate-baseline ', 'desc' => 'Generate baseline for issues'], ['arg' => '--use-baseline ', 'desc' => 'Use baseline to ignore issues'], ['arg' => '--ignore-baseline', 'desc' => 'Do not use baseline to ignore issues'], ], 'Selection' => [ ['arg' => '--list-suites', 'desc' => 'List available test suites'], ['arg' => '--testsuite ', 'desc' => 'Only run tests from the specified test suite(s)'], ['arg' => '--exclude-testsuite ', 'desc' => 'Exclude tests from the specified test suite(s)'], ['arg' => '--list-groups', 'desc' => 'List available test groups'], ['arg' => '--group ', 'desc' => 'Only run tests from the specified group(s)'], ['arg' => '--exclude-group ', 'desc' => 'Exclude tests from the specified group(s)'], ['arg' => '--covers ', 'desc' => 'Only run tests that intend to cover '], ['arg' => '--uses ', 'desc' => 'Only run tests that intend to use '], ['arg' => '--list-tests', 'desc' => 'List available tests'], ['arg' => '--list-tests-xml ', 'desc' => 'List available tests in XML format'], ['arg' => '--filter ', 'desc' => 'Filter which tests to run'], ['arg' => '--test-suffix ', 'desc' => 'Only search for test in files with specified suffix(es). Default: Test.php,.phpt'], ], 'Execution' => [ ['arg' => '--process-isolation', 'desc' => 'Run each test in a separate PHP process'], ['arg' => '--globals-backup', 'desc' => 'Backup and restore $GLOBALS for each test'], ['arg' => '--static-backup', 'desc' => 'Backup and restore static properties for each test'], ['spacer' => ''], ['arg' => '--strict-coverage', 'desc' => 'Be strict about code coverage metadata'], ['arg' => '--strict-global-state', 'desc' => 'Be strict about changes to global state'], ['arg' => '--disallow-test-output', 'desc' => 'Be strict about output during tests'], ['arg' => '--enforce-time-limit', 'desc' => 'Enforce time limit based on test size'], ['arg' => '--default-time-limit ', 'desc' => 'Timeout in seconds for tests that have no declared size'], ['arg' => '--do-not-report-useless-tests', 'desc' => 'Do not report tests that do not test anything'], ['spacer' => ''], ['arg' => '--stop-on-defect', 'desc' => 'Stop after first error, failure, warning, or risky test'], ['arg' => '--stop-on-error', 'desc' => 'Stop after first error'], ['arg' => '--stop-on-failure', 'desc' => 'Stop after first failure'], ['arg' => '--stop-on-warning', 'desc' => 'Stop after first warning'], ['arg' => '--stop-on-risky', 'desc' => 'Stop after first risky test'], ['arg' => '--stop-on-deprecation', 'desc' => 'Stop after first test that triggered a deprecation'], ['arg' => '--stop-on-notice', 'desc' => 'Stop after first test that triggered a notice'], ['arg' => '--stop-on-skipped', 'desc' => 'Stop after first skipped test'], ['arg' => '--stop-on-incomplete', 'desc' => 'Stop after first incomplete test'], ['spacer' => ''], ['arg' => '--fail-on-empty-test-suite', 'desc' => 'Signal failure using shell exit code when no tests were run'], ['arg' => '--fail-on-warning', 'desc' => 'Signal failure using shell exit code when a warning was triggered'], ['arg' => '--fail-on-risky', 'desc' => 'Signal failure using shell exit code when a test was considered risky'], ['arg' => '--fail-on-deprecation', 'desc' => 'Signal failure using shell exit code when a deprecation was triggered'], ['arg' => '--fail-on-phpunit-deprecation', 'desc' => 'Signal failure using shell exit code when a PHPUnit deprecation was triggered'], ['arg' => '--fail-on-phpunit-warning', 'desc' => 'Signal failure using shell exit code when a PHPUnit warning was triggered'], ['arg' => '--fail-on-notice', 'desc' => 'Signal failure using shell exit code when a notice was triggered'], ['arg' => '--fail-on-skipped', 'desc' => 'Signal failure using shell exit code when a test was skipped'], ['arg' => '--fail-on-incomplete', 'desc' => 'Signal failure using shell exit code when a test was marked incomplete'], ['arg' => '--fail-on-all-issues', 'desc' => 'Signal failure using shell exit code when an issue is triggered'], ['spacer' => ''], ['arg' => '--do-not-fail-on-empty-test-suite', 'desc' => 'Do not signal failure using shell exit code when no tests were run'], ['arg' => '--do-not-fail-on-warning', 'desc' => 'Do not signal failure using shell exit code when a warning was triggered'], ['arg' => '--do-not-fail-on-risky', 'desc' => 'Do not signal failure using shell exit code when a test was considered risky'], ['arg' => '--do-not-fail-on-deprecation', 'desc' => 'Do not signal failure using shell exit code when a deprecation was triggered'], ['arg' => '--do-not-fail-on-phpunit-deprecation', 'desc' => 'Do not signal failure using shell exit code when a PHPUnit deprecation was triggered'], ['arg' => '--do-not-fail-on-phpunit-warning', 'desc' => 'Do not signal failure using shell exit code when a PHPUnit warning was triggered'], ['arg' => '--do-not-fail-on-notice', 'desc' => 'Do not signal failure using shell exit code when a notice was triggered'], ['arg' => '--do-not-fail-on-skipped', 'desc' => 'Do not signal failure using shell exit code when a test was skipped'], ['arg' => '--do-not-fail-on-incomplete', 'desc' => 'Do not signal failure using shell exit code when a test was marked incomplete'], ['spacer' => ''], ['arg' => '--cache-result', 'desc' => 'Write test results to cache file'], ['arg' => '--do-not-cache-result', 'desc' => 'Do not write test results to cache file'], ['spacer' => ''], ['arg' => '--order-by ', 'desc' => 'Run tests in order: default|defects|depends|duration|no-depends|random|reverse|size'], ['arg' => '--random-order-seed ', 'desc' => 'Use the specified random seed when running tests in random order'], ], 'Reporting' => [ ['arg' => '--colors ', 'desc' => 'Use colors in output ("never", "auto" or "always")'], ['arg' => '--columns ', 'desc' => 'Number of columns to use for progress output'], ['arg' => '--columns max', 'desc' => 'Use maximum number of columns for progress output'], ['arg' => '--stderr', 'desc' => 'Write to STDERR instead of STDOUT'], ['spacer' => ''], ['arg' => '--no-progress', 'desc' => 'Disable output of test execution progress'], ['arg' => '--no-results', 'desc' => 'Disable output of test results'], ['arg' => '--no-output', 'desc' => 'Disable all output'], ['spacer' => ''], ['arg' => '--display-incomplete', 'desc' => 'Display details for incomplete tests'], ['arg' => '--display-skipped', 'desc' => 'Display details for skipped tests'], ['arg' => '--display-deprecations', 'desc' => 'Display details for deprecations triggered by tests'], ['arg' => '--display-phpunit-deprecations', 'desc' => 'Display details for PHPUnit deprecations'], ['arg' => '--display-errors', 'desc' => 'Display details for errors triggered by tests'], ['arg' => '--display-notices', 'desc' => 'Display details for notices triggered by tests'], ['arg' => '--display-warnings', 'desc' => 'Display details for warnings triggered by tests'], ['arg' => '--display-all-issues', 'desc' => 'Display details for all issues that are triggered'], ['arg' => '--reverse-list', 'desc' => 'Print defects in reverse order'], ['spacer' => ''], ['arg' => '--teamcity', 'desc' => 'Replace default progress and result output with TeamCity format'], ['arg' => '--testdox', 'desc' => 'Replace default result output with TestDox format'], ['spacer' => ''], ['arg' => '--debug', 'desc' => 'Replace default progress and result output with debugging information'], ], 'Logging' => [ ['arg' => '--log-junit ', 'desc' => 'Write test results in JUnit XML format to file'], ['arg' => '--log-teamcity ', 'desc' => 'Write test results in TeamCity format to file'], ['arg' => '--testdox-html ', 'desc' => 'Write test results in TestDox format (HTML) to file'], ['arg' => '--testdox-text ', 'desc' => 'Write test results in TestDox format (plain text) to file'], ['arg' => '--log-events-text ', 'desc' => 'Stream events as plain text to file'], ['arg' => '--log-events-verbose-text ', 'desc' => 'Stream events as plain text with extended information to file'], ['arg' => '--no-logging', 'desc' => 'Ignore logging configured in the XML configuration file'], ], 'Code Coverage' => [ ['arg' => '--coverage-clover ', 'desc' => 'Write code coverage report in Clover XML format to file'], ['arg' => '--coverage-cobertura ', 'desc' => 'Write code coverage report in Cobertura XML format to file'], ['arg' => '--coverage-crap4j ', 'desc' => 'Write code coverage report in Crap4J XML format to file'], ['arg' => '--coverage-html ', 'desc' => 'Write code coverage report in HTML format to directory'], ['arg' => '--coverage-php ', 'desc' => 'Write serialized code coverage data to file'], ['arg' => '--coverage-text=', 'desc' => 'Write code coverage report in text format to file [default: standard output]'], ['arg' => '--only-summary-for-coverage-text', 'desc' => 'Option for code coverage report in text format: only show summary'], ['arg' => '--show-uncovered-for-coverage-text', 'desc' => 'Option for code coverage report in text format: show uncovered files'], ['arg' => '--coverage-xml ', 'desc' => 'Write code coverage report in XML format to directory'], ['arg' => '--warm-coverage-cache', 'desc' => 'Warm static analysis cache'], ['arg' => '--coverage-filter ', 'desc' => 'Include in code coverage reporting'], ['arg' => '--path-coverage', 'desc' => 'Report path coverage in addition to line coverage'], ['arg' => '--disable-coverage-ignore', 'desc' => 'Disable metadata for ignoring code coverage'], ['arg' => '--no-coverage', 'desc' => 'Ignore code coverage reporting configured in the XML configuration file'], ], ]; if (defined('__PHPUNIT_PHAR__')) { $elements['PHAR'] = [ ['arg' => '--manifest', 'desc' => 'Print Software Bill of Materials (SBOM) in plain-text format'], ['arg' => '--sbom', 'desc' => 'Print Software Bill of Materials (SBOM) in CycloneDX XML format'], ['arg' => '--composer-lock', 'desc' => 'Print composer.lock file used to build the PHAR'], ]; } $elements['Miscellaneous'] = [ ['arg' => '-h|--help', 'desc' => 'Prints this usage information'], ['arg' => '--version', 'desc' => 'Prints the version and exits'], ['arg' => '--atleast-version ', 'desc' => 'Checks that version is greater than and exits'], ['arg' => '--check-version', 'desc' => 'Checks whether PHPUnit is the latest version and exits'], ['arg' => '--check-php-configuration', 'desc' => 'Checks whether PHP configuration follows best practices'], ]; return $elements; } } PKYg3]W%ttOutput/SummaryPrinter.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output; use const PHP_EOL; use function sprintf; use PHPUnit\TestRunner\TestResult\TestResult; use PHPUnit\Util\Color; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class SummaryPrinter { private readonly Printer $printer; private readonly bool $colors; private bool $countPrinted = false; public function __construct(Printer $printer, bool $colors) { $this->printer = $printer; $this->colors = $colors; } public function print(TestResult $result): void { if ($result->numberOfTestsRun() === 0) { $this->printWithColor( 'fg-black, bg-yellow', 'No tests executed!', ); return; } if ($result->wasSuccessful() && !$result->hasIssues() && !$result->hasTestSuiteSkippedEvents() && !$result->hasTestSkippedEvents()) { $this->printWithColor( 'fg-black, bg-green', sprintf( 'OK (%d test%s, %d assertion%s)', $result->numberOfTestsRun(), $result->numberOfTestsRun() === 1 ? '' : 's', $result->numberOfAssertions(), $result->numberOfAssertions() === 1 ? '' : 's', ), ); $this->printNumberOfIssuesIgnoredByBaseline($result); return; } $color = 'fg-black, bg-yellow'; if ($result->wasSuccessful()) { if ($result->hasIssues()) { $this->printWithColor( $color, 'OK, but there were issues!', ); } else { $this->printWithColor( $color, 'OK, but some tests were skipped!', ); } } else { if ($result->hasTestErroredEvents() || $result->hasTestTriggeredPhpunitErrorEvents()) { $color = 'fg-white, bg-red'; $this->printWithColor( $color, 'ERRORS!', ); } elseif ($result->hasTestFailedEvents()) { $color = 'fg-white, bg-red'; $this->printWithColor( $color, 'FAILURES!', ); } } $this->printCountString($result->numberOfTestsRun(), 'Tests', $color, true); $this->printCountString($result->numberOfAssertions(), 'Assertions', $color, true); $this->printCountString($result->numberOfErrors(), 'Errors', $color); $this->printCountString($result->numberOfTestFailedEvents(), 'Failures', $color); $this->printCountString($result->numberOfPhpunitWarnings(), 'PHPUnit Warnings', $color); $this->printCountString($result->numberOfWarnings(), 'Warnings', $color); $this->printCountString($result->numberOfPhpOrUserDeprecations(), 'Deprecations', $color); $this->printCountString($result->numberOfPhpunitDeprecations(), 'PHPUnit Deprecations', $color); $this->printCountString($result->numberOfNotices(), 'Notices', $color); $this->printCountString($result->numberOfTestSuiteSkippedEvents() + $result->numberOfTestSkippedEvents(), 'Skipped', $color); $this->printCountString($result->numberOfTestMarkedIncompleteEvents(), 'Incomplete', $color); $this->printCountString($result->numberOfTestsWithTestConsideredRiskyEvents(), 'Risky', $color); $this->printWithColor($color, '.'); $this->printNumberOfIssuesIgnoredByBaseline($result); } private function printCountString(int $count, string $name, string $color, bool $always = false): void { if ($always || $count > 0) { $this->printWithColor( $color, sprintf( '%s%s: %d', $this->countPrinted ? ', ' : '', $name, $count, ), false, ); $this->countPrinted = true; } } private function printWithColor(string $color, string $buffer, bool $lf = true): void { if ($this->colors) { $buffer = Color::colorizeTextBox($color, $buffer); } $this->printer->print($buffer); if ($lf) { $this->printer->print(PHP_EOL); } } private function printNumberOfIssuesIgnoredByBaseline(TestResult $result): void { if ($result->hasIssuesIgnoredByBaseline()) { $this->printer->print( sprintf( '%s%d issue%s %s ignored by baseline.%s', PHP_EOL, $result->numberOfIssuesIgnoredByBaseline(), $result->numberOfIssuesIgnoredByBaseline() > 1 ? 's' : '', $result->numberOfIssuesIgnoredByBaseline() > 1 ? 'were' : 'was', PHP_EOL, ), ); } } } PKYg3]\r&& Output/TestDox/ResultPrinter.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\TestDox; use const PHP_EOL; use function array_map; use function assert; use function explode; use function implode; use function preg_match; use function preg_split; use function rtrim; use function str_starts_with; use function trim; use PHPUnit\Event\Code\Throwable; use PHPUnit\Framework\TestStatus\TestStatus; use PHPUnit\Logging\TestDox\TestResult as TestDoxTestResult; use PHPUnit\Logging\TestDox\TestResultCollection; use PHPUnit\TextUI\Output\Printer; use PHPUnit\Util\Color; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ResultPrinter { private readonly Printer $printer; private readonly bool $colors; public function __construct(Printer $printer, bool $colors) { $this->printer = $printer; $this->colors = $colors; } /** * @psalm-param array $tests */ public function print(array $tests): void { foreach ($tests as $prettifiedClassName => $_tests) { $this->printPrettifiedClassName($prettifiedClassName); foreach ($_tests as $test) { $this->printTestResult($test); } $this->printer->print(PHP_EOL); } } /** * @psalm-param string $prettifiedClassName */ private function printPrettifiedClassName(string $prettifiedClassName): void { $buffer = $prettifiedClassName; if ($this->colors) { $buffer = Color::colorizeTextBox('underlined', $buffer); } $this->printer->print($buffer . PHP_EOL); } private function printTestResult(TestDoxTestResult $test): void { $this->printTestResultHeader($test); $this->printTestResultBody($test); } private function printTestResultHeader(TestDoxTestResult $test): void { $buffer = ' ' . $this->symbolFor($test->status()) . ' '; if ($this->colors) { $this->printer->print( Color::colorizeTextBox( $this->colorFor($test->status()), $buffer, ), ); } else { $this->printer->print($buffer); } $this->printer->print($test->test()->testDox()->prettifiedMethodName($this->colors) . PHP_EOL); } private function printTestResultBody(TestDoxTestResult $test): void { if ($test->status()->isSuccess()) { return; } if (!$test->hasThrowable()) { return; } $this->printTestResultBodyStart($test); $this->printThrowable($test); $this->printTestResultBodyEnd($test); } private function printTestResultBodyStart(TestDoxTestResult $test): void { $this->printer->print( $this->prefixLines( $this->prefixFor('start', $test->status()), '', ), ); $this->printer->print(PHP_EOL); } private function printTestResultBodyEnd(TestDoxTestResult $test): void { $this->printer->print(PHP_EOL); $this->printer->print( $this->prefixLines( $this->prefixFor('last', $test->status()), '', ), ); $this->printer->print(PHP_EOL); } private function printThrowable(TestDoxTestResult $test): void { $throwable = $test->throwable(); assert($throwable instanceof Throwable); $message = trim($throwable->description()); $stackTrace = $this->formatStackTrace($throwable->stackTrace()); $diff = ''; if (!empty($message) && $this->colors) { ['message' => $message, 'diff' => $diff] = $this->colorizeMessageAndDiff( $message, $this->messageColorFor($test->status()), ); } if (!empty($message)) { $this->printer->print( $this->prefixLines( $this->prefixFor('message', $test->status()), $message, ), ); $this->printer->print(PHP_EOL); } if (!empty($diff)) { $this->printer->print( $this->prefixLines( $this->prefixFor('diff', $test->status()), $diff, ), ); $this->printer->print(PHP_EOL); } if (!empty($stackTrace)) { if (!empty($message) || !empty($diff)) { $prefix = $this->prefixFor('default', $test->status()); } else { $prefix = $this->prefixFor('trace', $test->status()); } $this->printer->print( $this->prefixLines($prefix, PHP_EOL . $stackTrace), ); } } /** * @psalm-return array{message: string, diff: string} */ private function colorizeMessageAndDiff(string $buffer, string $style): array { $lines = $buffer ? array_map('\rtrim', explode(PHP_EOL, $buffer)) : []; $message = []; $diff = []; $insideDiff = false; foreach ($lines as $line) { if ($line === '--- Expected') { $insideDiff = true; } if (!$insideDiff) { $message[] = $line; } else { if (str_starts_with($line, '-')) { $line = Color::colorize('fg-red', Color::visualizeWhitespace($line, true)); } elseif (str_starts_with($line, '+')) { $line = Color::colorize('fg-green', Color::visualizeWhitespace($line, true)); } elseif ($line === '@@ @@') { $line = Color::colorize('fg-cyan', $line); } $diff[] = $line; } } $message = implode(PHP_EOL, $message); $diff = implode(PHP_EOL, $diff); if (!empty($message)) { $message = Color::colorizeTextBox($style, $message); } return [ 'message' => $message, 'diff' => $diff, ]; } private function formatStackTrace(string $stackTrace): string { if (!$this->colors) { return rtrim($stackTrace); } $lines = []; $previousPath = ''; foreach (explode(PHP_EOL, $stackTrace) as $line) { if (preg_match('/^(.*):(\d+)$/', $line, $matches)) { $lines[] = Color::colorizePath($matches[1], $previousPath) . Color::dim(':') . Color::colorize('fg-blue', $matches[2]) . "\n"; $previousPath = $matches[1]; continue; } $lines[] = $line; $previousPath = ''; } return rtrim(implode('', $lines)); } private function prefixLines(string $prefix, string $message): string { return implode( PHP_EOL, array_map( static fn (string $line) => ' ' . $prefix . ($line ? ' ' . $line : ''), preg_split('/\r\n|\r|\n/', $message), ), ); } /** * @psalm-param 'default'|'start'|'message'|'diff'|'trace'|'last' $type */ private function prefixFor(string $type, TestStatus $status): string { if (!$this->colors) { return '│'; } return Color::colorize( $this->colorFor($status), match ($type) { 'default' => '│', 'start' => '┐', 'message' => '├', 'diff' => '┊', 'trace' => '╵', 'last' => '┴', }, ); } private function colorFor(TestStatus $status): string { if ($status->isSuccess()) { return 'fg-green'; } if ($status->isError()) { return 'fg-yellow'; } if ($status->isFailure()) { return 'fg-red'; } if ($status->isSkipped()) { return 'fg-cyan'; } if ($status->isIncomplete() || $status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) { return 'fg-yellow'; } return 'fg-blue'; } private function messageColorFor(TestStatus $status): string { if ($status->isSuccess()) { return ''; } if ($status->isError()) { return 'bg-yellow,fg-black'; } if ($status->isFailure()) { return 'bg-red,fg-white'; } if ($status->isSkipped()) { return 'fg-cyan'; } if ($status->isIncomplete() || $status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) { return 'fg-yellow'; } return 'fg-white,bg-blue'; } private function symbolFor(TestStatus $status): string { if ($status->isSuccess()) { return '✔'; } if ($status->isError() || $status->isFailure()) { return '✘'; } if ($status->isSkipped()) { return '↩'; } if ($status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) { return '⚠'; } if ($status->isIncomplete()) { return '∅'; } return '?'; } } PKYg3]55*Output/Default/UnexpectedOutputPrinter.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default; use PHPUnit\Event\EventFacadeIsSealedException; use PHPUnit\Event\Facade; use PHPUnit\Event\Test\PrintedUnexpectedOutput; use PHPUnit\Event\Test\PrintedUnexpectedOutputSubscriber; use PHPUnit\Event\UnknownSubscriberTypeException; use PHPUnit\TextUI\Output\Printer; final class UnexpectedOutputPrinter implements PrintedUnexpectedOutputSubscriber { private readonly Printer $printer; /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ public function __construct(Printer $printer, Facade $facade) { $this->printer = $printer; $facade->registerSubscriber($this); } public function notify(PrintedUnexpectedOutput $event): void { $this->printer->print($event->output()); } } PKYg3]!r'R'R Output/Default/ResultPrinter.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default; use const PHP_EOL; use function array_keys; use function array_merge; use function array_reverse; use function array_unique; use function assert; use function count; use function explode; use function ksort; use function range; use function sprintf; use function str_starts_with; use function strlen; use function substr; use function trim; use PHPUnit\Event\Code\Test; use PHPUnit\Event\Code\TestMethod; use PHPUnit\Event\Test\AfterLastTestMethodErrored; use PHPUnit\Event\Test\BeforeFirstTestMethodErrored; use PHPUnit\Event\Test\ConsideredRisky; use PHPUnit\Event\Test\DeprecationTriggered; use PHPUnit\Event\Test\ErrorTriggered; use PHPUnit\Event\Test\NoticeTriggered; use PHPUnit\Event\Test\PhpDeprecationTriggered; use PHPUnit\Event\Test\PhpNoticeTriggered; use PHPUnit\Event\Test\PhpunitDeprecationTriggered; use PHPUnit\Event\Test\PhpunitErrorTriggered; use PHPUnit\Event\Test\PhpunitWarningTriggered; use PHPUnit\Event\Test\PhpWarningTriggered; use PHPUnit\Event\Test\WarningTriggered; use PHPUnit\TestRunner\TestResult\Issues\Issue; use PHPUnit\TestRunner\TestResult\TestResult; use PHPUnit\TextUI\Output\Printer; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ResultPrinter { private readonly Printer $printer; private readonly bool $displayPhpunitErrors; private readonly bool $displayPhpunitWarnings; private readonly bool $displayTestsWithErrors; private readonly bool $displayTestsWithFailedAssertions; private readonly bool $displayRiskyTests; private readonly bool $displayPhpunitDeprecations; private readonly bool $displayDetailsOnIncompleteTests; private readonly bool $displayDetailsOnSkippedTests; private readonly bool $displayDetailsOnTestsThatTriggerDeprecations; private readonly bool $displayDetailsOnTestsThatTriggerErrors; private readonly bool $displayDetailsOnTestsThatTriggerNotices; private readonly bool $displayDetailsOnTestsThatTriggerWarnings; private readonly bool $displayDefectsInReverseOrder; private bool $listPrinted = false; public function __construct(Printer $printer, bool $displayPhpunitErrors, bool $displayPhpunitWarnings, bool $displayPhpunitDeprecations, bool $displayTestsWithErrors, bool $displayTestsWithFailedAssertions, bool $displayRiskyTests, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $displayDefectsInReverseOrder) { $this->printer = $printer; $this->displayPhpunitErrors = $displayPhpunitErrors; $this->displayPhpunitWarnings = $displayPhpunitWarnings; $this->displayPhpunitDeprecations = $displayPhpunitDeprecations; $this->displayTestsWithErrors = $displayTestsWithErrors; $this->displayTestsWithFailedAssertions = $displayTestsWithFailedAssertions; $this->displayRiskyTests = $displayRiskyTests; $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests; $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests; $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations; $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors; $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices; $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings; $this->displayDefectsInReverseOrder = $displayDefectsInReverseOrder; } public function print(TestResult $result): void { if ($this->displayPhpunitErrors) { $this->printPhpunitErrors($result); } if ($this->displayPhpunitWarnings) { $this->printTestRunnerWarnings($result); } if ($this->displayPhpunitDeprecations) { $this->printTestRunnerDeprecations($result); } if ($this->displayTestsWithErrors) { $this->printTestsWithErrors($result); } if ($this->displayTestsWithFailedAssertions) { $this->printTestsWithFailedAssertions($result); } if ($this->displayPhpunitWarnings) { $this->printDetailsOnTestsThatTriggeredPhpunitWarnings($result); } if ($this->displayPhpunitDeprecations) { $this->printDetailsOnTestsThatTriggeredPhpunitDeprecations($result); } if ($this->displayRiskyTests) { $this->printRiskyTests($result); } if ($this->displayDetailsOnIncompleteTests) { $this->printIncompleteTests($result); } if ($this->displayDetailsOnSkippedTests) { $this->printSkippedTestSuites($result); $this->printSkippedTests($result); } if ($this->displayDetailsOnTestsThatTriggerErrors) { $this->printIssueList('error', $result->errors()); } if ($this->displayDetailsOnTestsThatTriggerWarnings) { $this->printIssueList('PHP warning', $result->phpWarnings()); $this->printIssueList('warning', $result->warnings()); } if ($this->displayDetailsOnTestsThatTriggerNotices) { $this->printIssueList('PHP notice', $result->phpNotices()); $this->printIssueList('notice', $result->notices()); } if ($this->displayDetailsOnTestsThatTriggerDeprecations) { $this->printIssueList('PHP deprecation', $result->phpDeprecations()); $this->printIssueList('deprecation', $result->deprecations()); } } private function printPhpunitErrors(TestResult $result): void { if (!$result->hasTestTriggeredPhpunitErrorEvents()) { return; } $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitErrorEvents()); $this->printListHeaderWithNumber($elements['numberOfTestsWithIssues'], 'PHPUnit error'); $this->printList($elements['elements']); } private function printDetailsOnTestsThatTriggeredPhpunitDeprecations(TestResult $result): void { if (!$result->hasTestTriggeredPhpunitDeprecationEvents()) { return; } $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitDeprecationEvents()); $this->printListHeaderWithNumberOfTestsAndNumberOfIssues( $elements['numberOfTestsWithIssues'], $elements['numberOfIssues'], 'PHPUnit deprecation', ); $this->printList($elements['elements']); } private function printTestRunnerWarnings(TestResult $result): void { if (!$result->hasTestRunnerTriggeredWarningEvents()) { return; } $elements = []; $messages = []; foreach ($result->testRunnerTriggeredWarningEvents() as $event) { if (isset($messages[$event->message()])) { continue; } $elements[] = [ 'title' => $event->message(), 'body' => '', ]; $messages[$event->message()] = true; } $this->printListHeaderWithNumber(count($elements), 'PHPUnit test runner warning'); $this->printList($elements); } private function printTestRunnerDeprecations(TestResult $result): void { if (!$result->hasTestRunnerTriggeredDeprecationEvents()) { return; } $elements = []; foreach ($result->testRunnerTriggeredDeprecationEvents() as $event) { $elements[] = [ 'title' => $event->message(), 'body' => '', ]; } $this->printListHeaderWithNumber(count($elements), 'PHPUnit test runner deprecation'); $this->printList($elements); } private function printDetailsOnTestsThatTriggeredPhpunitWarnings(TestResult $result): void { if (!$result->hasTestTriggeredPhpunitWarningEvents()) { return; } $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitWarningEvents()); $this->printListHeaderWithNumberOfTestsAndNumberOfIssues( $elements['numberOfTestsWithIssues'], $elements['numberOfIssues'], 'PHPUnit warning', ); $this->printList($elements['elements']); } private function printTestsWithErrors(TestResult $result): void { if (!$result->hasTestErroredEvents()) { return; } $elements = []; foreach ($result->testErroredEvents() as $event) { if ($event instanceof AfterLastTestMethodErrored || $event instanceof BeforeFirstTestMethodErrored) { $title = $event->testClassName(); } else { $title = $this->name($event->test()); } $elements[] = [ 'title' => $title, 'body' => $event->throwable()->asString(), ]; } $this->printListHeaderWithNumber(count($elements), 'error'); $this->printList($elements); } private function printTestsWithFailedAssertions(TestResult $result): void { if (!$result->hasTestFailedEvents()) { return; } $elements = []; foreach ($result->testFailedEvents() as $event) { $body = $event->throwable()->asString(); if (str_starts_with($body, 'AssertionError: ')) { $body = substr($body, strlen('AssertionError: ')); } $elements[] = [ 'title' => $this->name($event->test()), 'body' => $body, ]; } $this->printListHeaderWithNumber(count($elements), 'failure'); $this->printList($elements); } private function printRiskyTests(TestResult $result): void { if (!$result->hasTestConsideredRiskyEvents()) { return; } $elements = $this->mapTestsWithIssuesEventsToElements($result->testConsideredRiskyEvents()); $this->printListHeaderWithNumber($elements['numberOfTestsWithIssues'], 'risky test'); $this->printList($elements['elements']); } private function printIncompleteTests(TestResult $result): void { if (!$result->hasTestMarkedIncompleteEvents()) { return; } $elements = []; foreach ($result->testMarkedIncompleteEvents() as $event) { $elements[] = [ 'title' => $this->name($event->test()), 'body' => $event->throwable()->asString(), ]; } $this->printListHeaderWithNumber(count($elements), 'incomplete test'); $this->printList($elements); } private function printSkippedTestSuites(TestResult $result): void { if (!$result->hasTestSuiteSkippedEvents()) { return; } $elements = []; foreach ($result->testSuiteSkippedEvents() as $event) { $elements[] = [ 'title' => $event->testSuite()->name(), 'body' => $event->message(), ]; } $this->printListHeaderWithNumber(count($elements), 'skipped test suite'); $this->printList($elements); } private function printSkippedTests(TestResult $result): void { if (!$result->hasTestSkippedEvents()) { return; } $elements = []; foreach ($result->testSkippedEvents() as $event) { $elements[] = [ 'title' => $this->name($event->test()), 'body' => $event->message(), ]; } $this->printListHeaderWithNumber(count($elements), 'skipped test'); $this->printList($elements); } /** * @psalm-param non-empty-string $type * @psalm-param list $issues */ private function printIssueList(string $type, array $issues): void { if (empty($issues)) { return; } $numberOfUniqueIssues = count($issues); $triggeringTests = []; foreach ($issues as $issue) { $triggeringTests = array_merge($triggeringTests, array_keys($issue->triggeringTests())); } $numberOfTests = count(array_unique($triggeringTests)); unset($triggeringTests); $this->printListHeader( sprintf( '%d test%s triggered %d %s%s:' . PHP_EOL . PHP_EOL, $numberOfTests, $numberOfTests !== 1 ? 's' : '', $numberOfUniqueIssues, $type, $numberOfUniqueIssues !== 1 ? 's' : '', ), ); $i = 1; foreach ($issues as $issue) { $title = sprintf( '%s:%d', $issue->file(), $issue->line(), ); $body = trim($issue->description()) . PHP_EOL . PHP_EOL . 'Triggered by:'; $triggeringTests = $issue->triggeringTests(); ksort($triggeringTests); foreach ($triggeringTests as $triggeringTest) { $body .= PHP_EOL . PHP_EOL . '* ' . $triggeringTest['test']->id(); if ($triggeringTest['count'] > 1) { $body .= sprintf( ' (%d times)', $triggeringTest['count'], ); } if ($triggeringTest['test']->isTestMethod()) { $body .= PHP_EOL . ' ' . $triggeringTest['test']->file() . ':' . $triggeringTest['test']->line(); } } $this->printIssueListElement($i++, $title, $body); $this->printer->print(PHP_EOL); } } private function printListHeaderWithNumberOfTestsAndNumberOfIssues(int $numberOfTestsWithIssues, int $numberOfIssues, string $type): void { $this->printListHeader( sprintf( "%d test%s triggered %d %s%s:\n\n", $numberOfTestsWithIssues, $numberOfTestsWithIssues !== 1 ? 's' : '', $numberOfIssues, $type, $numberOfIssues !== 1 ? 's' : '', ), ); } private function printListHeaderWithNumber(int $number, string $type): void { $this->printListHeader( sprintf( "There %s %d %s%s:\n\n", ($number === 1) ? 'was' : 'were', $number, $type, ($number === 1) ? '' : 's', ), ); } private function printListHeader(string $header): void { if ($this->listPrinted) { $this->printer->print("--\n\n"); } $this->listPrinted = true; $this->printer->print($header); } /** * @psalm-param list $elements */ private function printList(array $elements): void { $i = 1; if ($this->displayDefectsInReverseOrder) { $elements = array_reverse($elements); } foreach ($elements as $element) { $this->printListElement($i++, $element['title'], $element['body']); } $this->printer->print("\n"); } private function printListElement(int $number, string $title, string $body): void { $body = trim($body); $this->printer->print( sprintf( "%s%d) %s\n%s%s", $number > 1 ? "\n" : '', $number, $title, $body, !empty($body) ? "\n" : '', ), ); } private function printIssueListElement(int $number, string $title, string $body): void { $body = trim($body); $this->printer->print( sprintf( "%d) %s\n%s%s", $number, $title, $body, !empty($body) ? "\n" : '', ), ); } private function name(Test $test): string { if ($test->isTestMethod()) { assert($test instanceof TestMethod); if (!$test->testData()->hasDataFromDataProvider()) { return $test->nameWithClass(); } return $test->className() . '::' . $test->methodName() . $test->testData()->dataFromDataProvider()->dataAsStringForResultOutput(); } return $test->name(); } /** * @psalm-param array> $events * * @psalm-return array{numberOfTestsWithIssues: int, numberOfIssues: int, elements: list} */ private function mapTestsWithIssuesEventsToElements(array $events): array { $elements = []; $issues = 0; foreach ($events as $reasons) { $test = $reasons[0]->test(); $testLocation = $this->testLocation($test); $title = $this->name($test); $body = ''; $first = true; $single = count($reasons) === 1; foreach ($reasons as $reason) { if ($first) { $first = false; } else { $body .= PHP_EOL; } $body .= $this->reasonMessage($reason, $single); $body .= $this->reasonLocation($reason, $single); $issues++; } if (!empty($testLocation)) { $body .= $testLocation; } $elements[] = [ 'title' => $title, 'body' => $body, ]; } return [ 'numberOfTestsWithIssues' => count($events), 'numberOfIssues' => $issues, 'elements' => $elements, ]; } private function testLocation(Test $test): string { if (!$test->isTestMethod()) { return ''; } assert($test instanceof TestMethod); return sprintf( '%s%s:%d%s', PHP_EOL, $test->file(), $test->line(), PHP_EOL, ); } private function reasonMessage(ConsideredRisky|DeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpunitDeprecationTriggered|PhpunitErrorTriggered|PhpunitWarningTriggered|PhpWarningTriggered|WarningTriggered $reason, bool $single): string { $message = trim($reason->message()); if ($single) { return $message . PHP_EOL; } $lines = explode(PHP_EOL, $message); $buffer = '* ' . $lines[0] . PHP_EOL; if (count($lines) > 1) { foreach (range(1, count($lines) - 1) as $line) { $buffer .= ' ' . $lines[$line] . PHP_EOL; } } return $buffer; } private function reasonLocation(ConsideredRisky|DeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpunitDeprecationTriggered|PhpunitErrorTriggered|PhpunitWarningTriggered|PhpWarningTriggered|WarningTriggered $reason, bool $single): string { if (!$reason instanceof DeprecationTriggered && !$reason instanceof PhpDeprecationTriggered && !$reason instanceof ErrorTriggered && !$reason instanceof NoticeTriggered && !$reason instanceof PhpNoticeTriggered && !$reason instanceof WarningTriggered && !$reason instanceof PhpWarningTriggered) { return ''; } return sprintf( '%s%s:%d%s', $single ? '' : ' ', $reason->file(), $reason->line(), PHP_EOL, ); } } PKYg3]wkkSOutput/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitWarningSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\PhpunitWarningTriggered; use PHPUnit\Event\Test\PhpunitWarningTriggeredSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestTriggeredPhpunitWarningSubscriber extends Subscriber implements PhpunitWarningTriggeredSubscriber { public function notify(PhpunitWarningTriggered $event): void { $this->printer()->testTriggeredPhpunitWarning(); } } PKYg3]xڃWOutput/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\PhpunitDeprecationTriggered; use PHPUnit\Event\Test\PhpunitDeprecationTriggeredSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestTriggeredPhpunitDeprecationSubscriber extends Subscriber implements PhpunitDeprecationTriggeredSubscriber { public function notify(PhpunitDeprecationTriggered $event): void { $this->printer()->testTriggeredPhpunitDeprecation(); } } PKYg3]2JqqSOutput/Default/ProgressPrinter/Subscriber/TestTriggeredPhpDeprecationSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\PhpDeprecationTriggered; use PHPUnit\Event\Test\PhpDeprecationTriggeredSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestTriggeredPhpDeprecationSubscriber extends Subscriber implements PhpDeprecationTriggeredSubscriber { public function notify(PhpDeprecationTriggered $event): void { $this->printer()->testTriggeredPhpDeprecation($event); } } PKYg3]FhAALOutput/Default/ProgressPrinter/Subscriber/TestMarkedIncompleteSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\MarkedIncomplete; use PHPUnit\Event\Test\MarkedIncompleteSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestMarkedIncompleteSubscriber extends Subscriber implements MarkedIncompleteSubscriber { public function notify(MarkedIncomplete $event): void { $this->printer()->testMarkedIncomplete(); } } PKYg3];SSNOutput/Default/ProgressPrinter/Subscriber/TestTriggeredPhpNoticeSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\PhpNoticeTriggered; use PHPUnit\Event\Test\PhpNoticeTriggeredSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestTriggeredPhpNoticeSubscriber extends Subscriber implements PhpNoticeTriggeredSubscriber { public function notify(PhpNoticeTriggered $event): void { $this->printer()->testTriggeredPhpNotice($event); } } PKYg3]ADOutput/Default/ProgressPrinter/Subscriber/TestFinishedSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\Finished; use PHPUnit\Event\Test\FinishedSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestFinishedSubscriber extends Subscriber implements FinishedSubscriber { public function notify(Finished $event): void { $this->printer()->testFinished(); } } PKYg3]% `__POutput/Default/ProgressPrinter/Subscriber/TestTriggeredDeprecationSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\DeprecationTriggered; use PHPUnit\Event\Test\DeprecationTriggeredSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestTriggeredDeprecationSubscriber extends Subscriber implements DeprecationTriggeredSubscriber { public function notify(DeprecationTriggered $event): void { $this->printer()->testTriggeredDeprecation($event); } } PKYg3]o]+8Output/Default/ProgressPrinter/Subscriber/Subscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ abstract class Subscriber { private readonly ProgressPrinter $printer; public function __construct(ProgressPrinter $printer) { $this->printer = $printer; } protected function printer(): ProgressPrinter { return $this->printer; } } PKYg3]as__ROutput/Default/ProgressPrinter/Subscriber/TestRunnerExecutionStartedSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\TestRunner\ExecutionStarted; use PHPUnit\Event\TestRunner\ExecutionStartedSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestRunnerExecutionStartedSubscriber extends Subscriber implements ExecutionStartedSubscriber { public function notify(ExecutionStarted $event): void { $this->printer()->testRunnerExecutionStarted($event); } } PKYg3]xTOutput/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\BeforeFirstTestMethodErrored; use PHPUnit\Event\Test\BeforeFirstTestMethodErroredSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class BeforeTestClassMethodErroredSubscriber extends Subscriber implements BeforeFirstTestMethodErroredSubscriber { public function notify(BeforeFirstTestMethodErrored $event): void { $this->printer()->beforeTestClassMethodErrored(); } } PKYg3]`);;JOutput/Default/ProgressPrinter/Subscriber/TestTriggeredErrorSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\ErrorTriggered; use PHPUnit\Event\Test\ErrorTriggeredSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestTriggeredErrorSubscriber extends Subscriber implements ErrorTriggeredSubscriber { public function notify(ErrorTriggered $event): void { $this->printer()->testTriggeredError($event); } } PKYg3]O  COutput/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\Skipped; use PHPUnit\Event\Test\SkippedSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestSkippedSubscriber extends Subscriber implements SkippedSubscriber { public function notify(Skipped $event): void { $this->printer()->testSkipped(); } } PKYg3]{DOutput/Default/ProgressPrinter/Subscriber/TestPreparedSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\Prepared; use PHPUnit\Event\Test\PreparedSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestPreparedSubscriber extends Subscriber implements PreparedSubscriber { public function notify(Prepared $event): void { $this->printer()->testPrepared(); } } PKYg3]HUBCOutput/Default/ProgressPrinter/Subscriber/TestErroredSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\Errored; use PHPUnit\Event\Test\ErroredSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestErroredSubscriber extends Subscriber implements ErroredSubscriber { public function notify(Errored $event): void { $this->printer()->testErrored($event); } } PKYg3]jJBOutput/Default/ProgressPrinter/Subscriber/TestFailedSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\Failed; use PHPUnit\Event\Test\FailedSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestFailedSubscriber extends Subscriber implements FailedSubscriber { public function notify(Failed $event): void { $this->printer()->testFailed(); } } PKYg3];YYOOutput/Default/ProgressPrinter/Subscriber/TestTriggeredPhpWarningSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\PhpWarningTriggered; use PHPUnit\Event\Test\PhpWarningTriggeredSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestTriggeredPhpWarningSubscriber extends Subscriber implements PhpWarningTriggeredSubscriber { public function notify(PhpWarningTriggered $event): void { $this->printer()->testTriggeredPhpWarning($event); } } PKYg3] GGLOutput/Default/ProgressPrinter/Subscriber/TestTriggeredWarningSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\WarningTriggered; use PHPUnit\Event\Test\WarningTriggeredSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestTriggeredWarningSubscriber extends Subscriber implements WarningTriggeredSubscriber { public function notify(WarningTriggered $event): void { $this->printer()->testTriggeredWarning($event); } } PKYg3]ɓ,l;;KOutput/Default/ProgressPrinter/Subscriber/TestConsideredRiskySubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\ConsideredRisky; use PHPUnit\Event\Test\ConsideredRiskySubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestConsideredRiskySubscriber extends Subscriber implements ConsideredRiskySubscriber { public function notify(ConsideredRisky $event): void { $this->printer()->testConsideredRisky(); } } PKYg3]SAAKOutput/Default/ProgressPrinter/Subscriber/TestTriggeredNoticeSubscriber.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use PHPUnit\Event\Test\NoticeTriggered; use PHPUnit\Event\Test\NoticeTriggeredSubscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestTriggeredNoticeSubscriber extends Subscriber implements NoticeTriggeredSubscriber { public function notify(NoticeTriggered $event): void { $this->printer()->testTriggeredNotice($event); } } PKYg3]d$//2Output/Default/ProgressPrinter/ProgressPrinter.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; use function floor; use function sprintf; use function str_contains; use function str_repeat; use function strlen; use PHPUnit\Event\EventFacadeIsSealedException; use PHPUnit\Event\Facade; use PHPUnit\Event\Test\DeprecationTriggered; use PHPUnit\Event\Test\Errored; use PHPUnit\Event\Test\ErrorTriggered; use PHPUnit\Event\Test\NoticeTriggered; use PHPUnit\Event\Test\PhpDeprecationTriggered; use PHPUnit\Event\Test\PhpNoticeTriggered; use PHPUnit\Event\Test\PhpWarningTriggered; use PHPUnit\Event\Test\WarningTriggered; use PHPUnit\Event\TestRunner\ExecutionStarted; use PHPUnit\Event\UnknownSubscriberTypeException; use PHPUnit\Framework\TestStatus\TestStatus; use PHPUnit\TextUI\Configuration\Source; use PHPUnit\TextUI\Configuration\SourceFilter; use PHPUnit\TextUI\Output\Printer; use PHPUnit\Util\Color; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ProgressPrinter { private readonly Printer $printer; private readonly bool $colors; private readonly int $numberOfColumns; private readonly Source $source; private int $column = 0; private int $numberOfTests = 0; private int $numberOfTestsWidth = 0; private int $maxColumn = 0; private int $numberOfTestsRun = 0; private ?TestStatus $status = null; private bool $prepared = false; /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ public function __construct(Printer $printer, Facade $facade, bool $colors, int $numberOfColumns, Source $source) { $this->printer = $printer; $this->colors = $colors; $this->numberOfColumns = $numberOfColumns; $this->source = $source; $this->registerSubscribers($facade); } public function testRunnerExecutionStarted(ExecutionStarted $event): void { $this->numberOfTestsRun = 0; $this->numberOfTests = $event->testSuite()->count(); $this->numberOfTestsWidth = strlen((string) $this->numberOfTests); $this->column = 0; $this->maxColumn = $this->numberOfColumns - strlen(' / (XXX%)') - (2 * $this->numberOfTestsWidth); } public function beforeTestClassMethodErrored(): void { $this->printProgressForError(); $this->updateTestStatus(TestStatus::error()); } public function testPrepared(): void { $this->prepared = true; } public function testSkipped(): void { if (!$this->prepared) { $this->printProgressForSkipped(); } else { $this->updateTestStatus(TestStatus::skipped()); } } public function testMarkedIncomplete(): void { $this->updateTestStatus(TestStatus::incomplete()); } public function testTriggeredNotice(NoticeTriggered $event): void { if ($event->ignoredByBaseline()) { return; } if ($this->source->restrictNotices() && !SourceFilter::instance()->includes($event->file())) { return; } if (!$this->source->ignoreSuppressionOfNotices() && $event->wasSuppressed()) { return; } $this->updateTestStatus(TestStatus::notice()); } public function testTriggeredPhpNotice(PhpNoticeTriggered $event): void { if ($event->ignoredByBaseline()) { return; } if ($this->source->restrictNotices() && !SourceFilter::instance()->includes($event->file())) { return; } if (!$this->source->ignoreSuppressionOfPhpNotices() && $event->wasSuppressed()) { return; } $this->updateTestStatus(TestStatus::notice()); } public function testTriggeredDeprecation(DeprecationTriggered $event): void { if ($event->ignoredByBaseline() || $event->ignoredByTest()) { return; } if ($this->source->restrictDeprecations() && !SourceFilter::instance()->includes($event->file())) { return; } if (!$this->source->ignoreSuppressionOfDeprecations() && $event->wasSuppressed()) { return; } $this->updateTestStatus(TestStatus::deprecation()); } public function testTriggeredPhpDeprecation(PhpDeprecationTriggered $event): void { if ($event->ignoredByBaseline() || $event->ignoredByTest()) { return; } if ($this->source->restrictDeprecations() && !SourceFilter::instance()->includes($event->file())) { return; } if (!$this->source->ignoreSuppressionOfPhpDeprecations() && $event->wasSuppressed()) { return; } $this->updateTestStatus(TestStatus::deprecation()); } public function testTriggeredPhpunitDeprecation(): void { $this->updateTestStatus(TestStatus::deprecation()); } public function testConsideredRisky(): void { $this->updateTestStatus(TestStatus::risky()); } public function testTriggeredWarning(WarningTriggered $event): void { if ($event->ignoredByBaseline()) { return; } if ($this->source->restrictWarnings() && !SourceFilter::instance()->includes($event->file())) { return; } if (!$this->source->ignoreSuppressionOfWarnings() && $event->wasSuppressed()) { return; } $this->updateTestStatus(TestStatus::warning()); } public function testTriggeredPhpWarning(PhpWarningTriggered $event): void { if ($event->ignoredByBaseline()) { return; } if ($this->source->restrictWarnings() && !SourceFilter::instance()->includes($event->file())) { return; } if (!$this->source->ignoreSuppressionOfPhpWarnings() && $event->wasSuppressed()) { return; } $this->updateTestStatus(TestStatus::warning()); } public function testTriggeredPhpunitWarning(): void { $this->updateTestStatus(TestStatus::warning()); } public function testTriggeredError(ErrorTriggered $event): void { if (!$this->source->ignoreSuppressionOfErrors() && $event->wasSuppressed()) { return; } $this->updateTestStatus(TestStatus::error()); } public function testFailed(): void { $this->updateTestStatus(TestStatus::failure()); } public function testErrored(Errored $event): void { /* * @todo Eliminate this special case */ if (str_contains($event->asString(), 'Test was run in child process and ended unexpectedly')) { $this->updateTestStatus(TestStatus::error()); return; } if (!$this->prepared) { $this->printProgressForError(); } else { $this->updateTestStatus(TestStatus::error()); } } public function testFinished(): void { if ($this->status === null) { $this->printProgressForSuccess(); } elseif ($this->status->isSkipped()) { $this->printProgressForSkipped(); } elseif ($this->status->isIncomplete()) { $this->printProgressForIncomplete(); } elseif ($this->status->isRisky()) { $this->printProgressForRisky(); } elseif ($this->status->isNotice()) { $this->printProgressForNotice(); } elseif ($this->status->isDeprecation()) { $this->printProgressForDeprecation(); } elseif ($this->status->isWarning()) { $this->printProgressForWarning(); } elseif ($this->status->isFailure()) { $this->printProgressForFailure(); } else { $this->printProgressForError(); } $this->status = null; $this->prepared = false; } /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ private function registerSubscribers(Facade $facade): void { $facade->registerSubscribers( new BeforeTestClassMethodErroredSubscriber($this), new TestConsideredRiskySubscriber($this), new TestErroredSubscriber($this), new TestFailedSubscriber($this), new TestFinishedSubscriber($this), new TestMarkedIncompleteSubscriber($this), new TestPreparedSubscriber($this), new TestRunnerExecutionStartedSubscriber($this), new TestSkippedSubscriber($this), new TestTriggeredDeprecationSubscriber($this), new TestTriggeredNoticeSubscriber($this), new TestTriggeredPhpDeprecationSubscriber($this), new TestTriggeredPhpNoticeSubscriber($this), new TestTriggeredPhpunitDeprecationSubscriber($this), new TestTriggeredPhpunitWarningSubscriber($this), new TestTriggeredPhpWarningSubscriber($this), new TestTriggeredWarningSubscriber($this), ); } private function updateTestStatus(TestStatus $status): void { if ($this->status !== null && $this->status->isMoreImportantThan($status)) { return; } $this->status = $status; } private function printProgressForSuccess(): void { $this->printProgress('.'); } private function printProgressForSkipped(): void { $this->printProgressWithColor('fg-cyan, bold', 'S'); } private function printProgressForIncomplete(): void { $this->printProgressWithColor('fg-yellow, bold', 'I'); } private function printProgressForNotice(): void { $this->printProgressWithColor('fg-yellow, bold', 'N'); } private function printProgressForDeprecation(): void { $this->printProgressWithColor('fg-yellow, bold', 'D'); } private function printProgressForRisky(): void { $this->printProgressWithColor('fg-yellow, bold', 'R'); } private function printProgressForWarning(): void { $this->printProgressWithColor('fg-yellow, bold', 'W'); } private function printProgressForFailure(): void { $this->printProgressWithColor('bg-red, fg-white', 'F'); } private function printProgressForError(): void { $this->printProgressWithColor('fg-red, bold', 'E'); } private function printProgressWithColor(string $color, string $progress): void { if ($this->colors) { $progress = Color::colorizeTextBox($color, $progress); } $this->printProgress($progress); } private function printProgress(string $progress): void { $this->printer->print($progress); $this->column++; $this->numberOfTestsRun++; if ($this->column === $this->maxColumn || $this->numberOfTestsRun === $this->numberOfTests) { if ($this->numberOfTestsRun === $this->numberOfTests) { $this->printer->print(str_repeat(' ', $this->maxColumn - $this->column)); } $this->printer->print( sprintf( ' %' . $this->numberOfTestsWidth . 'd / %' . $this->numberOfTestsWidth . 'd (%3s%%)', $this->numberOfTestsRun, $this->numberOfTests, floor(($this->numberOfTestsRun / $this->numberOfTests) * 100), ), ); if ($this->column === $this->maxColumn) { $this->column = 0; $this->printer->print("\n"); } } } } PKYg3]u~[[Output/Printer/Printer.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This interface is not covered by the backward compatibility promise for PHPUnit */ interface Printer { public function print(string $buffer): void; public function flush(): void; } PKYg3]ÆOutput/Printer/NullPrinter.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class NullPrinter implements Printer { public function print(string $buffer): void { } public function flush(): void { } } PKYg3]3C C !Output/Printer/DefaultPrinter.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output; use function assert; use function count; use function dirname; use function explode; use function fclose; use function fopen; use function fsockopen; use function fwrite; use function str_replace; use function str_starts_with; use PHPUnit\Runner\DirectoryDoesNotExistException; use PHPUnit\TextUI\CannotOpenSocketException; use PHPUnit\TextUI\InvalidSocketException; use PHPUnit\Util\Filesystem; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class DefaultPrinter implements Printer { /** * @psalm-var closed-resource|resource */ private $stream; private readonly bool $isPhpStream; private bool $isOpen; /** * @throws CannotOpenSocketException * @throws DirectoryDoesNotExistException * @throws InvalidSocketException */ public static function from(string $out): self { return new self($out); } /** * @throws CannotOpenSocketException * @throws DirectoryDoesNotExistException * @throws InvalidSocketException */ public static function standardOutput(): self { return new self('php://stdout'); } /** * @throws CannotOpenSocketException * @throws DirectoryDoesNotExistException * @throws InvalidSocketException */ public static function standardError(): self { return new self('php://stderr'); } /** * @throws CannotOpenSocketException * @throws DirectoryDoesNotExistException * @throws InvalidSocketException */ private function __construct(string $out) { $this->isPhpStream = str_starts_with($out, 'php://'); if (str_starts_with($out, 'socket://')) { $tmp = explode(':', str_replace('socket://', '', $out)); if (count($tmp) !== 2) { throw new InvalidSocketException($out); } $stream = @fsockopen($tmp[0], (int) $tmp[1]); if ($stream === false) { throw new CannotOpenSocketException($tmp[0], (int) $tmp[1]); } $this->stream = $stream; $this->isOpen = true; return; } if (!$this->isPhpStream && !Filesystem::createDirectory(dirname($out))) { throw new DirectoryDoesNotExistException(dirname($out)); } $this->stream = fopen($out, 'wb'); $this->isOpen = true; } public function print(string $buffer): void { assert($this->isOpen); fwrite($this->stream, $buffer); } public function flush(): void { if ($this->isOpen && $this->isPhpStream) { fclose($this->stream); $this->isOpen = false; } } } PKYg3]l۵$$Output/Facade.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Output; use const PHP_EOL; use function assert; use PHPUnit\Event\EventFacadeIsSealedException; use PHPUnit\Event\Facade as EventFacade; use PHPUnit\Event\UnknownSubscriberTypeException; use PHPUnit\Logging\TeamCity\TeamCityLogger; use PHPUnit\Logging\TestDox\TestResultCollection; use PHPUnit\Runner\DirectoryDoesNotExistException; use PHPUnit\TestRunner\TestResult\TestResult; use PHPUnit\TextUI\CannotOpenSocketException; use PHPUnit\TextUI\Configuration\Configuration; use PHPUnit\TextUI\InvalidSocketException; use PHPUnit\TextUI\Output\Default\ProgressPrinter\ProgressPrinter as DefaultProgressPrinter; use PHPUnit\TextUI\Output\Default\ResultPrinter as DefaultResultPrinter; use PHPUnit\TextUI\Output\Default\UnexpectedOutputPrinter; use PHPUnit\TextUI\Output\TestDox\ResultPrinter as TestDoxResultPrinter; use SebastianBergmann\Timer\Duration; use SebastianBergmann\Timer\ResourceUsageFormatter; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Facade { private static ?Printer $printer = null; private static ?DefaultResultPrinter $defaultResultPrinter = null; private static ?TestDoxResultPrinter $testDoxResultPrinter = null; private static ?SummaryPrinter $summaryPrinter = null; private static bool $defaultProgressPrinter = false; /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ public static function init(Configuration $configuration, bool $extensionReplacesProgressOutput, bool $extensionReplacesResultOutput): Printer { self::createPrinter($configuration); assert(self::$printer !== null); if ($configuration->debug()) { return self::$printer; } self::createUnexpectedOutputPrinter(); if (!$extensionReplacesProgressOutput) { self::createProgressPrinter($configuration); } if (!$extensionReplacesResultOutput) { self::createResultPrinter($configuration); self::createSummaryPrinter($configuration); } if ($configuration->outputIsTeamCity()) { new TeamCityLogger( DefaultPrinter::standardOutput(), EventFacade::instance(), ); } return self::$printer; } /** * @psalm-param ?array $testDoxResult */ public static function printResult(TestResult $result, ?array $testDoxResult, Duration $duration): void { assert(self::$printer !== null); if ($result->numberOfTestsRun() > 0) { if (self::$defaultProgressPrinter) { self::$printer->print(PHP_EOL . PHP_EOL); } self::$printer->print((new ResourceUsageFormatter)->resourceUsage($duration) . PHP_EOL . PHP_EOL); } if (self::$testDoxResultPrinter !== null && $testDoxResult !== null) { self::$testDoxResultPrinter->print($testDoxResult); } if (self::$defaultResultPrinter !== null) { self::$defaultResultPrinter->print($result); } if (self::$summaryPrinter !== null) { self::$summaryPrinter->print($result); } } /** * @throws CannotOpenSocketException * @throws DirectoryDoesNotExistException * @throws InvalidSocketException */ public static function printerFor(string $target): Printer { if ($target === 'php://stdout') { if (!self::$printer instanceof NullPrinter) { return self::$printer; } return DefaultPrinter::standardOutput(); } return DefaultPrinter::from($target); } private static function createPrinter(Configuration $configuration): void { $printerNeeded = false; if ($configuration->debug()) { $printerNeeded = true; } if ($configuration->outputIsTeamCity()) { $printerNeeded = true; } if ($configuration->outputIsTestDox()) { $printerNeeded = true; } if (!$configuration->noOutput() && !$configuration->noProgress()) { $printerNeeded = true; } if (!$configuration->noOutput() && !$configuration->noResults()) { $printerNeeded = true; } if ($printerNeeded) { if ($configuration->outputToStandardErrorStream()) { self::$printer = DefaultPrinter::standardError(); return; } self::$printer = DefaultPrinter::standardOutput(); return; } self::$printer = new NullPrinter; } private static function createProgressPrinter(Configuration $configuration): void { assert(self::$printer !== null); if (!self::useDefaultProgressPrinter($configuration)) { return; } new DefaultProgressPrinter( self::$printer, EventFacade::instance(), $configuration->colors(), $configuration->columns(), $configuration->source(), ); self::$defaultProgressPrinter = true; } private static function useDefaultProgressPrinter(Configuration $configuration): bool { if ($configuration->noOutput()) { return false; } if ($configuration->noProgress()) { return false; } if ($configuration->outputIsTeamCity()) { return false; } return true; } private static function createResultPrinter(Configuration $configuration): void { assert(self::$printer !== null); if ($configuration->outputIsTestDox()) { self::$defaultResultPrinter = new DefaultResultPrinter( self::$printer, true, true, $configuration->displayDetailsOnPhpunitDeprecations() || $configuration->displayDetailsOnAllIssues(), false, false, true, false, false, $configuration->displayDetailsOnTestsThatTriggerDeprecations() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerErrors() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerNotices() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerWarnings() || $configuration->displayDetailsOnAllIssues(), $configuration->reverseDefectList(), ); } if ($configuration->outputIsTestDox()) { self::$testDoxResultPrinter = new TestDoxResultPrinter( self::$printer, $configuration->colors(), ); } if ($configuration->noOutput() || $configuration->noResults()) { return; } if (self::$defaultResultPrinter !== null) { return; } self::$defaultResultPrinter = new DefaultResultPrinter( self::$printer, true, true, $configuration->displayDetailsOnPhpunitDeprecations() || $configuration->displayDetailsOnAllIssues(), true, true, true, $configuration->displayDetailsOnIncompleteTests() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnSkippedTests() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerDeprecations() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerErrors() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerNotices() || $configuration->displayDetailsOnAllIssues(), $configuration->displayDetailsOnTestsThatTriggerWarnings() || $configuration->displayDetailsOnAllIssues(), $configuration->reverseDefectList(), ); } private static function createSummaryPrinter(Configuration $configuration): void { assert(self::$printer !== null); if (($configuration->noOutput() || $configuration->noResults()) && !($configuration->outputIsTeamCity() || $configuration->outputIsTestDox())) { return; } self::$summaryPrinter = new SummaryPrinter( self::$printer, $configuration->colors(), ); } /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ private static function createUnexpectedOutputPrinter(): void { assert(self::$printer !== null); new UnexpectedOutputPrinter(self::$printer, EventFacade::instance()); } } PKYg3]_i TestRunner.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI; use function mt_srand; use PHPUnit\Event; use PHPUnit\Framework\TestSuite; use PHPUnit\Runner\ResultCache\ResultCache; use PHPUnit\Runner\TestSuiteSorter; use PHPUnit\TextUI\Configuration\Configuration; use Throwable; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestRunner { /** * @throws RuntimeException */ public function run(Configuration $configuration, ResultCache $resultCache, TestSuite $suite): void { try { Event\Facade::emitter()->testRunnerStarted(); if ($configuration->executionOrder() === TestSuiteSorter::ORDER_RANDOMIZED) { mt_srand($configuration->randomOrderSeed()); } if ($configuration->executionOrder() !== TestSuiteSorter::ORDER_DEFAULT || $configuration->executionOrderDefects() !== TestSuiteSorter::ORDER_DEFAULT || $configuration->resolveDependencies()) { $resultCache->load(); (new TestSuiteSorter($resultCache))->reorderTestsInSuite( $suite, $configuration->executionOrder(), $configuration->resolveDependencies(), $configuration->executionOrderDefects(), ); Event\Facade::emitter()->testSuiteSorted( $configuration->executionOrder(), $configuration->executionOrderDefects(), $configuration->resolveDependencies(), ); } (new TestSuiteFilterProcessor)->process($configuration, $suite); Event\Facade::emitter()->testRunnerExecutionStarted( Event\TestSuite\TestSuiteBuilder::from($suite), ); $suite->run(); Event\Facade::emitter()->testRunnerExecutionFinished(); Event\Facade::emitter()->testRunnerFinished(); } catch (Throwable $t) { throw new RuntimeException( $t->getMessage(), (int) $t->getCode(), $t, ); } } } PKYg3]^GfGfApplication.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI; use const PHP_EOL; use const PHP_VERSION; use function is_file; use function is_readable; use function printf; use function realpath; use function sprintf; use function trim; use function unlink; use PHPUnit\Event\EventFacadeIsSealedException; use PHPUnit\Event\Facade as EventFacade; use PHPUnit\Event\UnknownSubscriberTypeException; use PHPUnit\Framework\TestSuite; use PHPUnit\Logging\EventLogger; use PHPUnit\Logging\JUnit\JunitXmlLogger; use PHPUnit\Logging\TeamCity\TeamCityLogger; use PHPUnit\Logging\TestDox\HtmlRenderer as TestDoxHtmlRenderer; use PHPUnit\Logging\TestDox\PlainTextRenderer as TestDoxTextRenderer; use PHPUnit\Logging\TestDox\TestResultCollector as TestDoxResultCollector; use PHPUnit\Metadata\Api\CodeCoverage as CodeCoverageMetadataApi; use PHPUnit\Runner\Baseline\CannotLoadBaselineException; use PHPUnit\Runner\Baseline\Generator as BaselineGenerator; use PHPUnit\Runner\Baseline\Reader; use PHPUnit\Runner\Baseline\Writer; use PHPUnit\Runner\CodeCoverage; use PHPUnit\Runner\DirectoryDoesNotExistException; use PHPUnit\Runner\ErrorHandler; use PHPUnit\Runner\Extension\ExtensionBootstrapper; use PHPUnit\Runner\Extension\Facade as ExtensionFacade; use PHPUnit\Runner\Extension\PharLoader; use PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler; use PHPUnit\Runner\ResultCache\DefaultResultCache; use PHPUnit\Runner\ResultCache\NullResultCache; use PHPUnit\Runner\ResultCache\ResultCache; use PHPUnit\Runner\ResultCache\ResultCacheHandler; use PHPUnit\Runner\TestSuiteSorter; use PHPUnit\Runner\Version; use PHPUnit\TestRunner\TestResult\Facade as TestResultFacade; use PHPUnit\TextUI\CliArguments\Builder; use PHPUnit\TextUI\CliArguments\Configuration as CliConfiguration; use PHPUnit\TextUI\CliArguments\Exception as ArgumentsException; use PHPUnit\TextUI\CliArguments\XmlConfigurationFileFinder; use PHPUnit\TextUI\Command\AtLeastVersionCommand; use PHPUnit\TextUI\Command\CheckPhpConfigurationCommand; use PHPUnit\TextUI\Command\GenerateConfigurationCommand; use PHPUnit\TextUI\Command\ListGroupsCommand; use PHPUnit\TextUI\Command\ListTestsAsTextCommand; use PHPUnit\TextUI\Command\ListTestsAsXmlCommand; use PHPUnit\TextUI\Command\ListTestSuitesCommand; use PHPUnit\TextUI\Command\MigrateConfigurationCommand; use PHPUnit\TextUI\Command\Result; use PHPUnit\TextUI\Command\ShowHelpCommand; use PHPUnit\TextUI\Command\ShowVersionCommand; use PHPUnit\TextUI\Command\VersionCheckCommand; use PHPUnit\TextUI\Command\WarmCodeCoverageCacheCommand; use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry; use PHPUnit\TextUI\Configuration\Configuration; use PHPUnit\TextUI\Configuration\PhpHandler; use PHPUnit\TextUI\Configuration\Registry; use PHPUnit\TextUI\Configuration\TestSuiteBuilder; use PHPUnit\TextUI\Output\DefaultPrinter; use PHPUnit\TextUI\Output\Facade as OutputFacade; use PHPUnit\TextUI\Output\Printer; use PHPUnit\TextUI\XmlConfiguration\Configuration as XmlConfiguration; use PHPUnit\TextUI\XmlConfiguration\DefaultConfiguration; use PHPUnit\TextUI\XmlConfiguration\Loader; use PHPUnit\Util\Http\PhpDownloader; use SebastianBergmann\Timer\Timer; use Throwable; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Application { public function run(array $argv): int { try { EventFacade::emitter()->applicationStarted(); $cliConfiguration = $this->buildCliConfiguration($argv); $pathToXmlConfigurationFile = (new XmlConfigurationFileFinder)->find($cliConfiguration); $this->executeCommandsThatOnlyRequireCliConfiguration($cliConfiguration, $pathToXmlConfigurationFile); $xmlConfiguration = $this->loadXmlConfiguration($pathToXmlConfigurationFile); $configuration = Registry::init( $cliConfiguration, $xmlConfiguration, ); (new PhpHandler)->handle($configuration->php()); if ($configuration->hasBootstrap()) { $this->loadBootstrapScript($configuration->bootstrap()); } $this->executeCommandsThatRequireCompleteConfiguration($configuration, $cliConfiguration); $testSuite = $this->buildTestSuite($configuration); $this->executeCommandsThatRequireCliConfigurationAndTestSuite($cliConfiguration, $testSuite); $this->executeHelpCommandWhenThereIsNothingElseToDo($configuration, $testSuite); $pharExtensions = null; $extensionRequiresCodeCoverageCollection = false; $extensionReplacesOutput = false; $extensionReplacesProgressOutput = false; $extensionReplacesResultOutput = false; $extensionRequiresExportOfObjects = false; if (!$configuration->noExtensions()) { if ($configuration->hasPharExtensionDirectory()) { $pharExtensions = (new PharLoader)->loadPharExtensionsInDirectory( $configuration->pharExtensionDirectory(), ); } $bootstrappedExtensions = $this->bootstrapExtensions($configuration); $extensionRequiresCodeCoverageCollection = $bootstrappedExtensions['requiresCodeCoverageCollection']; $extensionReplacesOutput = $bootstrappedExtensions['replacesOutput']; $extensionReplacesProgressOutput = $bootstrappedExtensions['replacesProgressOutput']; $extensionReplacesResultOutput = $bootstrappedExtensions['replacesResultOutput']; $extensionRequiresExportOfObjects = $bootstrappedExtensions['requiresExportOfObjects']; } if ($extensionRequiresExportOfObjects) { EventFacade::emitter()->exportObjects(); } CodeCoverage::instance()->init( $configuration, CodeCoverageFilterRegistry::instance(), $extensionRequiresCodeCoverageCollection, ); if (CodeCoverage::instance()->isActive()) { CodeCoverage::instance()->ignoreLines( (new CodeCoverageMetadataApi)->linesToBeIgnored($testSuite), ); } $printer = OutputFacade::init( $configuration, $extensionReplacesProgressOutput, $extensionReplacesResultOutput, ); if (!$configuration->debug() && !$extensionReplacesOutput) { $this->writeRuntimeInformation($printer, $configuration); $this->writePharExtensionInformation($printer, $pharExtensions); $this->writeRandomSeedInformation($printer, $configuration); $printer->print(PHP_EOL); } if ($configuration->debug()) { EventFacade::instance()->registerTracer( new EventLogger( 'php://stdout', false, ), ); } $this->registerLogfileWriters($configuration); $testDoxResultCollector = $this->testDoxResultCollector($configuration); TestResultFacade::init(); $resultCache = $this->initializeTestResultCache($configuration); if ($configuration->controlGarbageCollector()) { new GarbageCollectionHandler( EventFacade::instance(), $configuration->numberOfTestsBeforeGarbageCollection(), ); } $baselineGenerator = $this->configureBaseline($configuration); EventFacade::instance()->seal(); $timer = new Timer; $timer->start(); $runner = new TestRunner; $runner->run( $configuration, $resultCache, $testSuite, ); $duration = $timer->stop(); $testDoxResult = null; if (isset($testDoxResultCollector)) { $testDoxResult = $testDoxResultCollector->testMethodsGroupedByClass(); } if ($testDoxResult !== null && $configuration->hasLogfileTestdoxHtml()) { try { OutputFacade::printerFor($configuration->logfileTestdoxHtml())->print( (new TestDoxHtmlRenderer)->render($testDoxResult), ); } catch (DirectoryDoesNotExistException|InvalidSocketException $e) { EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( sprintf( 'Cannot log test results in TestDox HTML format to "%s": %s', $configuration->logfileTestdoxHtml(), $e->getMessage(), ), ); } } if ($testDoxResult !== null && $configuration->hasLogfileTestdoxText()) { try { OutputFacade::printerFor($configuration->logfileTestdoxText())->print( (new TestDoxTextRenderer)->render($testDoxResult), ); } catch (DirectoryDoesNotExistException|InvalidSocketException $e) { EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( sprintf( 'Cannot log test results in TestDox plain text format to "%s": %s', $configuration->logfileTestdoxText(), $e->getMessage(), ), ); } } $result = TestResultFacade::result(); if (!$extensionReplacesResultOutput && !$configuration->debug()) { OutputFacade::printResult($result, $testDoxResult, $duration); } CodeCoverage::instance()->generateReports($printer, $configuration); if (isset($baselineGenerator)) { (new Writer)->write( $configuration->generateBaseline(), $baselineGenerator->baseline(), ); $printer->print( sprintf( PHP_EOL . 'Baseline written to %s.' . PHP_EOL, realpath($configuration->generateBaseline()), ), ); } $shellExitCode = (new ShellExitCodeCalculator)->calculate( $configuration, $result, ); EventFacade::emitter()->applicationFinished($shellExitCode); return $shellExitCode; // @codeCoverageIgnoreStart } catch (Throwable $t) { $this->exitWithCrashMessage($t); } // @codeCoverageIgnoreEnd } private function execute(Command\Command $command, bool $requiresResultCollectedFromEvents = false): never { if ($requiresResultCollectedFromEvents) { try { TestResultFacade::init(); EventFacade::instance()->seal(); $resultCollectedFromEvents = TestResultFacade::result(); } catch (EventFacadeIsSealedException|UnknownSubscriberTypeException) { } } print Version::getVersionString() . PHP_EOL . PHP_EOL; $result = $command->execute(); print $result->output(); $shellExitCode = $result->shellExitCode(); if (isset($resultCollectedFromEvents) && $resultCollectedFromEvents->hasTestTriggeredPhpunitErrorEvents()) { $shellExitCode = Result::EXCEPTION; print PHP_EOL . PHP_EOL . 'There were errors:' . PHP_EOL; foreach ($resultCollectedFromEvents->testTriggeredPhpunitErrorEvents() as $events) { foreach ($events as $event) { print PHP_EOL . trim($event->message()) . PHP_EOL; } } } exit($shellExitCode); } private function loadBootstrapScript(string $filename): void { if (!is_readable($filename)) { $this->exitWithErrorMessage( sprintf( 'Cannot open bootstrap script "%s"', $filename, ), ); } try { include_once $filename; } catch (Throwable $t) { $message = sprintf( 'Error in bootstrap script: %s:%s%s%s%s', $t::class, PHP_EOL, $t->getMessage(), PHP_EOL, $t->getTraceAsString(), ); while ($t = $t->getPrevious()) { $message .= sprintf( '%s%sPrevious error: %s:%s%s%s%s', PHP_EOL, PHP_EOL, $t::class, PHP_EOL, $t->getMessage(), PHP_EOL, $t->getTraceAsString(), ); } $this->exitWithErrorMessage($message); } EventFacade::emitter()->testRunnerBootstrapFinished($filename); } private function buildCliConfiguration(array $argv): CliConfiguration { try { $cliConfiguration = (new Builder)->fromParameters($argv); } catch (ArgumentsException $e) { $this->exitWithErrorMessage($e->getMessage()); } return $cliConfiguration; } private function loadXmlConfiguration(false|string $configurationFile): XmlConfiguration { if ($configurationFile === false) { return DefaultConfiguration::create(); } try { return (new Loader)->load($configurationFile); } catch (Throwable $e) { $this->exitWithErrorMessage($e->getMessage()); } } private function buildTestSuite(Configuration $configuration): TestSuite { try { return (new TestSuiteBuilder)->build($configuration); } catch (Exception $e) { $this->exitWithErrorMessage($e->getMessage()); } } /** * @psalm-return array{requiresCodeCoverageCollection: bool, replacesOutput: bool, replacesProgressOutput: bool, replacesResultOutput: bool, requiresExportOfObjects: bool} */ private function bootstrapExtensions(Configuration $configuration): array { $facade = new ExtensionFacade; $extensionBootstrapper = new ExtensionBootstrapper( $configuration, $facade, ); foreach ($configuration->extensionBootstrappers() as $bootstrapper) { $extensionBootstrapper->bootstrap( $bootstrapper['className'], $bootstrapper['parameters'], ); } return [ 'requiresCodeCoverageCollection' => $facade->requiresCodeCoverageCollection(), 'replacesOutput' => $facade->replacesOutput(), 'replacesProgressOutput' => $facade->replacesProgressOutput(), 'replacesResultOutput' => $facade->replacesResultOutput(), 'requiresExportOfObjects' => $facade->requiresExportOfObjects(), ]; } private function executeCommandsThatOnlyRequireCliConfiguration(CliConfiguration $cliConfiguration, false|string $configurationFile): void { if ($cliConfiguration->generateConfiguration()) { $this->execute(new GenerateConfigurationCommand); } if ($cliConfiguration->migrateConfiguration()) { if ($configurationFile === false) { $this->exitWithErrorMessage('No configuration file found to migrate'); } $this->execute(new MigrateConfigurationCommand(realpath($configurationFile))); } if ($cliConfiguration->hasAtLeastVersion()) { $this->execute(new AtLeastVersionCommand($cliConfiguration->atLeastVersion())); } if ($cliConfiguration->version()) { $this->execute(new ShowVersionCommand); } if ($cliConfiguration->checkPhpConfiguration()) { $this->execute(new CheckPhpConfigurationCommand); } if ($cliConfiguration->checkVersion()) { $this->execute(new VersionCheckCommand(new PhpDownloader, Version::majorVersionNumber(), Version::id())); } if ($cliConfiguration->help()) { $this->execute(new ShowHelpCommand(Result::SUCCESS)); } } private function executeCommandsThatRequireCliConfigurationAndTestSuite(CliConfiguration $cliConfiguration, TestSuite $testSuite): void { if ($cliConfiguration->listGroups()) { $this->execute(new ListGroupsCommand($testSuite), true); } if ($cliConfiguration->listTests()) { $this->execute(new ListTestsAsTextCommand($testSuite), true); } if ($cliConfiguration->hasListTestsXml()) { $this->execute( new ListTestsAsXmlCommand( $cliConfiguration->listTestsXml(), $testSuite, ), true, ); } } private function executeCommandsThatRequireCompleteConfiguration(Configuration $configuration, CliConfiguration $cliConfiguration): void { if ($cliConfiguration->listSuites()) { $this->execute(new ListTestSuitesCommand($configuration->testSuite())); } if ($cliConfiguration->warmCoverageCache()) { $this->execute(new WarmCodeCoverageCacheCommand($configuration, CodeCoverageFilterRegistry::instance())); } } private function executeHelpCommandWhenThereIsNothingElseToDo(Configuration $configuration, TestSuite $testSuite): void { if ($testSuite->isEmpty() && !$configuration->hasCliArguments() && $configuration->testSuite()->isEmpty()) { $this->execute(new ShowHelpCommand(Result::FAILURE)); } } private function writeRuntimeInformation(Printer $printer, Configuration $configuration): void { $printer->print(Version::getVersionString() . PHP_EOL . PHP_EOL); $runtime = 'PHP ' . PHP_VERSION; if (CodeCoverage::instance()->isActive()) { $runtime .= ' with ' . CodeCoverage::instance()->driver()->nameAndVersion(); } $this->writeMessage($printer, 'Runtime', $runtime); if ($configuration->hasConfigurationFile()) { $this->writeMessage( $printer, 'Configuration', $configuration->configurationFile(), ); } } /** * @psalm-param ?list $pharExtensions */ private function writePharExtensionInformation(Printer $printer, ?array $pharExtensions): void { if ($pharExtensions === null) { return; } foreach ($pharExtensions as $extension) { $this->writeMessage( $printer, 'Extension', $extension, ); } } private function writeMessage(Printer $printer, string $type, string $message): void { $printer->print( sprintf( "%-15s%s\n", $type . ':', $message, ), ); } private function writeRandomSeedInformation(Printer $printer, Configuration $configuration): void { if ($configuration->executionOrder() === TestSuiteSorter::ORDER_RANDOMIZED) { $this->writeMessage( $printer, 'Random Seed', (string) $configuration->randomOrderSeed(), ); } } /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ private function registerLogfileWriters(Configuration $configuration): void { if ($configuration->hasLogEventsText()) { if (is_file($configuration->logEventsText())) { unlink($configuration->logEventsText()); } EventFacade::instance()->registerTracer( new EventLogger( $configuration->logEventsText(), false, ), ); } if ($configuration->hasLogEventsVerboseText()) { if (is_file($configuration->logEventsVerboseText())) { unlink($configuration->logEventsVerboseText()); } EventFacade::instance()->registerTracer( new EventLogger( $configuration->logEventsVerboseText(), true, ), ); EventFacade::emitter()->exportObjects(); } if ($configuration->hasLogfileJunit()) { try { new JunitXmlLogger( OutputFacade::printerFor($configuration->logfileJunit()), EventFacade::instance(), ); } catch (DirectoryDoesNotExistException|InvalidSocketException $e) { EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( sprintf( 'Cannot log test results in JUnit XML format to "%s": %s', $configuration->logfileJunit(), $e->getMessage(), ), ); } } if ($configuration->hasLogfileTeamcity()) { try { new TeamCityLogger( DefaultPrinter::from( $configuration->logfileTeamcity(), ), EventFacade::instance(), ); } catch (DirectoryDoesNotExistException|InvalidSocketException $e) { EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( sprintf( 'Cannot log test results in TeamCity format to "%s": %s', $configuration->logfileTeamcity(), $e->getMessage(), ), ); } } } /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ private function testDoxResultCollector(Configuration $configuration): ?TestDoxResultCollector { if ($configuration->hasLogfileTestdoxHtml() || $configuration->hasLogfileTestdoxText() || $configuration->outputIsTestDox()) { return new TestDoxResultCollector( EventFacade::instance(), $configuration->source(), ); } return null; } /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ private function initializeTestResultCache(Configuration $configuration): ResultCache { if ($configuration->cacheResult()) { $cache = new DefaultResultCache($configuration->testResultCacheFile()); new ResultCacheHandler($cache, EventFacade::instance()); return $cache; } return new NullResultCache; } /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ private function configureBaseline(Configuration $configuration): ?BaselineGenerator { if ($configuration->hasGenerateBaseline()) { return new BaselineGenerator( EventFacade::instance(), $configuration->source(), ); } if ($configuration->source()->useBaseline()) { /** @psalm-suppress MissingThrowsDocblock */ $baselineFile = $configuration->source()->baseline(); $baseline = null; try { $baseline = (new Reader)->read($baselineFile); } catch (CannotLoadBaselineException $e) { EventFacade::emitter()->testRunnerTriggeredPhpunitWarning($e->getMessage()); } if ($baseline !== null) { ErrorHandler::instance()->use($baseline); } } return null; } /** * @codeCoverageIgnore */ private function exitWithCrashMessage(Throwable $t): never { $message = $t->getMessage(); if (empty(trim($message))) { $message = '(no message)'; } printf( '%s%sAn error occurred inside PHPUnit.%s%sMessage: %s', PHP_EOL, PHP_EOL, PHP_EOL, PHP_EOL, $message, ); $first = true; if ($t->getPrevious()) { $t = $t->getPrevious(); } do { printf( '%s%s: %s:%d%s%s%s%s', PHP_EOL, $first ? 'Location' : 'Caused by', $t->getFile(), $t->getLine(), PHP_EOL, PHP_EOL, $t->getTraceAsString(), PHP_EOL, ); $first = false; } while ($t = $t->getPrevious()); exit(Result::CRASH); } private function exitWithErrorMessage(string $message): never { print Version::getVersionString() . PHP_EOL . PHP_EOL . $message . PHP_EOL; exit(Result::EXCEPTION); } } PKYg3]?,Configuration/CodeCoverageFilterRegistry.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function array_keys; use function assert; use SebastianBergmann\CodeCoverage\Filter; /** * CLI options and XML configuration are static within a single PHPUnit process. * It is therefore okay to use a Singleton registry here. * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CodeCoverageFilterRegistry { private static ?self $instance = null; private ?Filter $filter = null; private bool $configured = false; public static function instance(): self { if (self::$instance === null) { self::$instance = new self; } return self::$instance; } /** * @codeCoverageIgnore */ public function get(): Filter { assert($this->filter !== null); return $this->filter; } /** * @codeCoverageIgnore */ public function init(Configuration $configuration, bool $force = false): void { if (!$configuration->hasCoverageReport() && !$force) { return; } if ($this->configured && !$force) { return; } $this->filter = new Filter; if ($configuration->source()->notEmpty()) { $this->filter->includeFiles(array_keys((new SourceMapper)->map($configuration->source()))); $this->configured = true; } } /** * @codeCoverageIgnore */ public function configured(): bool { return $this->configured; } } PKYg3], Configuration/SourceMapper.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function realpath; use SebastianBergmann\FileIterator\Facade as FileIteratorFacade; use SplObjectStorage; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class SourceMapper { /** * @psalm-var SplObjectStorage> */ private static ?SplObjectStorage $files = null; /** * @psalm-return array */ public function map(Source $source): array { if (self::$files === null) { self::$files = new SplObjectStorage; } if (isset(self::$files[$source])) { return self::$files[$source]; } $files = []; foreach ($source->includeDirectories() as $directory) { foreach ((new FileIteratorFacade)->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) { $file = realpath($file); if (!$file) { continue; } $files[$file] = true; } } foreach ($source->includeFiles() as $file) { $file = realpath($file->path()); if (!$file) { continue; } $files[$file] = true; } foreach ($source->excludeDirectories() as $directory) { foreach ((new FileIteratorFacade)->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) { $file = realpath($file); if (!$file) { continue; } if (!isset($files[$file])) { continue; } unset($files[$file]); } } foreach ($source->excludeFiles() as $file) { $file = realpath($file->path()); if (!$file) { continue; } if (!isset($files[$file])) { continue; } unset($files[$file]); } self::$files[$source] = $files; return $files; } } PKYg3]"smm0Configuration/Cli/XmlConfigurationFileFinder.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\CliArguments; use function getcwd; use function is_dir; use function is_file; use function realpath; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class XmlConfigurationFileFinder { public function find(Configuration $configuration): false|string { $useDefaultConfiguration = $configuration->useDefaultConfiguration(); if ($configuration->hasConfigurationFile()) { if (is_dir($configuration->configurationFile())) { $candidate = $this->configurationFileInDirectory($configuration->configurationFile()); if ($candidate !== false) { return $candidate; } return false; } return $configuration->configurationFile(); } if ($useDefaultConfiguration) { $candidate = $this->configurationFileInDirectory(getcwd()); if ($candidate !== false) { return $candidate; } } return false; } private function configurationFileInDirectory(string $directory): false|string { $candidates = [ $directory . '/phpunit.xml', $directory . '/phpunit.dist.xml', $directory . '/phpunit.xml.dist', ]; foreach ($candidates as $candidate) { if (is_file($candidate)) { return realpath($candidate); } } return false; } } PKYg3]kq>>#Configuration/Cli/Configuration.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\CliArguments; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Configuration { /** * @psalm-var list */ private readonly array $arguments; private readonly ?string $atLeastVersion; private readonly ?bool $backupGlobals; private readonly ?bool $backupStaticProperties; private readonly ?bool $beStrictAboutChangesToGlobalState; private readonly ?string $bootstrap; private readonly ?string $cacheDirectory; private readonly ?bool $cacheResult; private readonly ?string $cacheResultFile; private readonly bool $checkPhpConfiguration; private readonly bool $checkVersion; private readonly ?string $colors; private readonly null|int|string $columns; private readonly ?string $configurationFile; private readonly ?array $coverageFilter; private readonly ?string $coverageClover; private readonly ?string $coverageCobertura; private readonly ?string $coverageCrap4J; private readonly ?string $coverageHtml; private readonly ?string $coveragePhp; private readonly ?string $coverageText; private readonly ?bool $coverageTextShowUncoveredFiles; private readonly ?bool $coverageTextShowOnlySummary; private readonly ?string $coverageXml; private readonly ?bool $pathCoverage; private readonly ?string $coverageCacheDirectory; private readonly bool $warmCoverageCache; private readonly ?int $defaultTimeLimit; private readonly ?bool $disableCodeCoverageIgnore; private readonly ?bool $disallowTestOutput; private readonly ?bool $enforceTimeLimit; private readonly ?array $excludeGroups; private readonly ?int $executionOrder; private readonly ?int $executionOrderDefects; private readonly ?bool $failOnAllIssues; private readonly ?bool $failOnDeprecation; private readonly ?bool $failOnPhpunitDeprecation; private readonly ?bool $failOnPhpunitWarning; private readonly ?bool $failOnEmptyTestSuite; private readonly ?bool $failOnIncomplete; private readonly ?bool $failOnNotice; private readonly ?bool $failOnRisky; private readonly ?bool $failOnSkipped; private readonly ?bool $failOnWarning; private readonly ?bool $doNotFailOnDeprecation; private readonly ?bool $doNotFailOnPhpunitDeprecation; private readonly ?bool $doNotFailOnPhpunitWarning; private readonly ?bool $doNotFailOnEmptyTestSuite; private readonly ?bool $doNotFailOnIncomplete; private readonly ?bool $doNotFailOnNotice; private readonly ?bool $doNotFailOnRisky; private readonly ?bool $doNotFailOnSkipped; private readonly ?bool $doNotFailOnWarning; private readonly ?bool $stopOnDefect; private readonly ?bool $stopOnDeprecation; private readonly ?bool $stopOnError; private readonly ?bool $stopOnFailure; private readonly ?bool $stopOnIncomplete; private readonly ?bool $stopOnNotice; private readonly ?bool $stopOnRisky; private readonly ?bool $stopOnSkipped; private readonly ?bool $stopOnWarning; private readonly ?string $filter; private readonly ?string $generateBaseline; private readonly ?string $useBaseline; private readonly bool $ignoreBaseline; private readonly bool $generateConfiguration; private readonly bool $migrateConfiguration; private readonly ?array $groups; private readonly ?array $testsCovering; private readonly ?array $testsUsing; private readonly bool $help; private readonly ?string $includePath; private readonly ?array $iniSettings; private readonly ?string $junitLogfile; private readonly bool $listGroups; private readonly bool $listSuites; private readonly bool $listTests; private readonly ?string $listTestsXml; private readonly ?bool $noCoverage; private readonly ?bool $noExtensions; private readonly ?bool $noOutput; private readonly ?bool $noProgress; private readonly ?bool $noResults; private readonly ?bool $noLogging; private readonly ?bool $processIsolation; private readonly ?int $randomOrderSeed; private readonly ?bool $reportUselessTests; private readonly ?bool $resolveDependencies; private readonly ?bool $reverseList; private readonly ?bool $stderr; private readonly ?bool $strictCoverage; private readonly ?string $teamcityLogfile; private readonly ?bool $teamCityPrinter; private readonly ?string $testdoxHtmlFile; private readonly ?string $testdoxTextFile; private readonly ?bool $testdoxPrinter; /** * @psalm-var ?non-empty-list */ private readonly ?array $testSuffixes; private readonly ?string $testSuite; private readonly ?string $excludeTestSuite; private readonly bool $useDefaultConfiguration; private readonly ?bool $displayDetailsOnAllIssues; private readonly ?bool $displayDetailsOnIncompleteTests; private readonly ?bool $displayDetailsOnSkippedTests; private readonly ?bool $displayDetailsOnTestsThatTriggerDeprecations; private readonly ?bool $displayDetailsOnPhpunitDeprecations; private readonly ?bool $displayDetailsOnTestsThatTriggerErrors; private readonly ?bool $displayDetailsOnTestsThatTriggerNotices; private readonly ?bool $displayDetailsOnTestsThatTriggerWarnings; private readonly bool $version; private readonly ?string $logEventsText; private readonly ?string $logEventsVerboseText; private readonly bool $debug; /** * @psalm-param list $arguments * @psalm-param ?non-empty-list $testSuffixes */ public function __construct(array $arguments, ?string $atLeastVersion, ?bool $backupGlobals, ?bool $backupStaticProperties, ?bool $beStrictAboutChangesToGlobalState, ?string $bootstrap, ?string $cacheDirectory, ?bool $cacheResult, ?string $cacheResultFile, bool $checkPhpConfiguration, bool $checkVersion, ?string $colors, null|int|string $columns, ?string $configurationFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4J, ?string $coverageHtml, ?string $coveragePhp, ?string $coverageText, ?bool $coverageTextShowUncoveredFiles, ?bool $coverageTextShowOnlySummary, ?string $coverageXml, ?bool $pathCoverage, ?string $coverageCacheDirectory, bool $warmCoverageCache, ?int $defaultTimeLimit, ?bool $disableCodeCoverageIgnore, ?bool $disallowTestOutput, ?bool $enforceTimeLimit, ?array $excludeGroups, ?int $executionOrder, ?int $executionOrderDefects, ?bool $failOnAllIssues, ?bool $failOnDeprecation, ?bool $failOnPhpunitDeprecation, ?bool $failOnPhpunitWarning, ?bool $failOnEmptyTestSuite, ?bool $failOnIncomplete, ?bool $failOnNotice, ?bool $failOnRisky, ?bool $failOnSkipped, ?bool $failOnWarning, ?bool $doNotFailOnDeprecation, ?bool $doNotFailOnPhpunitDeprecation, ?bool $doNotFailOnPhpunitWarning, ?bool $doNotFailOnEmptyTestSuite, ?bool $doNotFailOnIncomplete, ?bool $doNotFailOnNotice, ?bool $doNotFailOnRisky, ?bool $doNotFailOnSkipped, ?bool $doNotFailOnWarning, ?bool $stopOnDefect, ?bool $stopOnDeprecation, ?bool $stopOnError, ?bool $stopOnFailure, ?bool $stopOnIncomplete, ?bool $stopOnNotice, ?bool $stopOnRisky, ?bool $stopOnSkipped, ?bool $stopOnWarning, ?string $filter, ?string $generateBaseline, ?string $useBaseline, bool $ignoreBaseline, bool $generateConfiguration, bool $migrateConfiguration, ?array $groups, ?array $testsCovering, ?array $testsUsing, bool $help, ?string $includePath, ?array $iniSettings, ?string $junitLogfile, bool $listGroups, bool $listSuites, bool $listTests, ?string $listTestsXml, ?bool $noCoverage, ?bool $noExtensions, ?bool $noOutput, ?bool $noProgress, ?bool $noResults, ?bool $noLogging, ?bool $processIsolation, ?int $randomOrderSeed, ?bool $reportUselessTests, ?bool $resolveDependencies, ?bool $reverseList, ?bool $stderr, ?bool $strictCoverage, ?string $teamcityLogfile, ?string $testdoxHtmlFile, ?string $testdoxTextFile, ?array $testSuffixes, ?string $testSuite, ?string $excludeTestSuite, bool $useDefaultConfiguration, ?bool $displayDetailsOnAllIssues, ?bool $displayDetailsOnIncompleteTests, ?bool $displayDetailsOnSkippedTests, ?bool $displayDetailsOnTestsThatTriggerDeprecations, ?bool $displayDetailsOnPhpunitDeprecations, ?bool $displayDetailsOnTestsThatTriggerErrors, ?bool $displayDetailsOnTestsThatTriggerNotices, ?bool $displayDetailsOnTestsThatTriggerWarnings, bool $version, ?array $coverageFilter, ?string $logEventsText, ?string $logEventsVerboseText, ?bool $printerTeamCity, ?bool $printerTestDox, bool $debug) { $this->arguments = $arguments; $this->atLeastVersion = $atLeastVersion; $this->backupGlobals = $backupGlobals; $this->backupStaticProperties = $backupStaticProperties; $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState; $this->bootstrap = $bootstrap; $this->cacheDirectory = $cacheDirectory; $this->cacheResult = $cacheResult; $this->cacheResultFile = $cacheResultFile; $this->checkPhpConfiguration = $checkPhpConfiguration; $this->checkVersion = $checkVersion; $this->colors = $colors; $this->columns = $columns; $this->configurationFile = $configurationFile; $this->coverageFilter = $coverageFilter; $this->coverageClover = $coverageClover; $this->coverageCobertura = $coverageCobertura; $this->coverageCrap4J = $coverageCrap4J; $this->coverageHtml = $coverageHtml; $this->coveragePhp = $coveragePhp; $this->coverageText = $coverageText; $this->coverageTextShowUncoveredFiles = $coverageTextShowUncoveredFiles; $this->coverageTextShowOnlySummary = $coverageTextShowOnlySummary; $this->coverageXml = $coverageXml; $this->pathCoverage = $pathCoverage; $this->coverageCacheDirectory = $coverageCacheDirectory; $this->warmCoverageCache = $warmCoverageCache; $this->defaultTimeLimit = $defaultTimeLimit; $this->disableCodeCoverageIgnore = $disableCodeCoverageIgnore; $this->disallowTestOutput = $disallowTestOutput; $this->enforceTimeLimit = $enforceTimeLimit; $this->excludeGroups = $excludeGroups; $this->executionOrder = $executionOrder; $this->executionOrderDefects = $executionOrderDefects; $this->failOnAllIssues = $failOnAllIssues; $this->failOnDeprecation = $failOnDeprecation; $this->failOnPhpunitDeprecation = $failOnPhpunitDeprecation; $this->failOnPhpunitWarning = $failOnPhpunitWarning; $this->failOnEmptyTestSuite = $failOnEmptyTestSuite; $this->failOnIncomplete = $failOnIncomplete; $this->failOnNotice = $failOnNotice; $this->failOnRisky = $failOnRisky; $this->failOnSkipped = $failOnSkipped; $this->failOnWarning = $failOnWarning; $this->doNotFailOnDeprecation = $doNotFailOnDeprecation; $this->doNotFailOnPhpunitDeprecation = $doNotFailOnPhpunitDeprecation; $this->doNotFailOnPhpunitWarning = $doNotFailOnPhpunitWarning; $this->doNotFailOnEmptyTestSuite = $doNotFailOnEmptyTestSuite; $this->doNotFailOnIncomplete = $doNotFailOnIncomplete; $this->doNotFailOnNotice = $doNotFailOnNotice; $this->doNotFailOnRisky = $doNotFailOnRisky; $this->doNotFailOnSkipped = $doNotFailOnSkipped; $this->doNotFailOnWarning = $doNotFailOnWarning; $this->stopOnDefect = $stopOnDefect; $this->stopOnDeprecation = $stopOnDeprecation; $this->stopOnError = $stopOnError; $this->stopOnFailure = $stopOnFailure; $this->stopOnIncomplete = $stopOnIncomplete; $this->stopOnNotice = $stopOnNotice; $this->stopOnRisky = $stopOnRisky; $this->stopOnSkipped = $stopOnSkipped; $this->stopOnWarning = $stopOnWarning; $this->filter = $filter; $this->generateBaseline = $generateBaseline; $this->useBaseline = $useBaseline; $this->ignoreBaseline = $ignoreBaseline; $this->generateConfiguration = $generateConfiguration; $this->migrateConfiguration = $migrateConfiguration; $this->groups = $groups; $this->testsCovering = $testsCovering; $this->testsUsing = $testsUsing; $this->help = $help; $this->includePath = $includePath; $this->iniSettings = $iniSettings; $this->junitLogfile = $junitLogfile; $this->listGroups = $listGroups; $this->listSuites = $listSuites; $this->listTests = $listTests; $this->listTestsXml = $listTestsXml; $this->noCoverage = $noCoverage; $this->noExtensions = $noExtensions; $this->noOutput = $noOutput; $this->noProgress = $noProgress; $this->noResults = $noResults; $this->noLogging = $noLogging; $this->processIsolation = $processIsolation; $this->randomOrderSeed = $randomOrderSeed; $this->reportUselessTests = $reportUselessTests; $this->resolveDependencies = $resolveDependencies; $this->reverseList = $reverseList; $this->stderr = $stderr; $this->strictCoverage = $strictCoverage; $this->teamcityLogfile = $teamcityLogfile; $this->testdoxHtmlFile = $testdoxHtmlFile; $this->testdoxTextFile = $testdoxTextFile; $this->testSuffixes = $testSuffixes; $this->testSuite = $testSuite; $this->excludeTestSuite = $excludeTestSuite; $this->useDefaultConfiguration = $useDefaultConfiguration; $this->displayDetailsOnAllIssues = $displayDetailsOnAllIssues; $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests; $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests; $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations; $this->displayDetailsOnPhpunitDeprecations = $displayDetailsOnPhpunitDeprecations; $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors; $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices; $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings; $this->version = $version; $this->logEventsText = $logEventsText; $this->logEventsVerboseText = $logEventsVerboseText; $this->teamCityPrinter = $printerTeamCity; $this->testdoxPrinter = $printerTestDox; $this->debug = $debug; } /** * @psalm-return list */ public function arguments(): array { return $this->arguments; } /** * @psalm-assert-if-true !null $this->atLeastVersion */ public function hasAtLeastVersion(): bool { return $this->atLeastVersion !== null; } /** * @throws Exception */ public function atLeastVersion(): string { if (!$this->hasAtLeastVersion()) { throw new Exception; } return $this->atLeastVersion; } /** * @psalm-assert-if-true !null $this->backupGlobals */ public function hasBackupGlobals(): bool { return $this->backupGlobals !== null; } /** * @throws Exception */ public function backupGlobals(): bool { if (!$this->hasBackupGlobals()) { throw new Exception; } return $this->backupGlobals; } /** * @psalm-assert-if-true !null $this->backupStaticProperties */ public function hasBackupStaticProperties(): bool { return $this->backupStaticProperties !== null; } /** * @throws Exception */ public function backupStaticProperties(): bool { if (!$this->hasBackupStaticProperties()) { throw new Exception; } return $this->backupStaticProperties; } /** * @psalm-assert-if-true !null $this->beStrictAboutChangesToGlobalState */ public function hasBeStrictAboutChangesToGlobalState(): bool { return $this->beStrictAboutChangesToGlobalState !== null; } /** * @throws Exception */ public function beStrictAboutChangesToGlobalState(): bool { if (!$this->hasBeStrictAboutChangesToGlobalState()) { throw new Exception; } return $this->beStrictAboutChangesToGlobalState; } /** * @psalm-assert-if-true !null $this->bootstrap */ public function hasBootstrap(): bool { return $this->bootstrap !== null; } /** * @throws Exception */ public function bootstrap(): string { if (!$this->hasBootstrap()) { throw new Exception; } return $this->bootstrap; } /** * @psalm-assert-if-true !null $this->cacheDirectory */ public function hasCacheDirectory(): bool { return $this->cacheDirectory !== null; } /** * @throws Exception */ public function cacheDirectory(): string { if (!$this->hasCacheDirectory()) { throw new Exception; } return $this->cacheDirectory; } /** * @psalm-assert-if-true !null $this->cacheResult */ public function hasCacheResult(): bool { return $this->cacheResult !== null; } /** * @throws Exception */ public function cacheResult(): bool { if (!$this->hasCacheResult()) { throw new Exception; } return $this->cacheResult; } /** * @psalm-assert-if-true !null $this->cacheResultFile * * @deprecated */ public function hasCacheResultFile(): bool { return $this->cacheResultFile !== null; } /** * @throws Exception * * @deprecated */ public function cacheResultFile(): string { if (!$this->hasCacheResultFile()) { throw new Exception; } return $this->cacheResultFile; } public function checkPhpConfiguration(): bool { return $this->checkPhpConfiguration; } public function checkVersion(): bool { return $this->checkVersion; } /** * @psalm-assert-if-true !null $this->colors */ public function hasColors(): bool { return $this->colors !== null; } /** * @throws Exception */ public function colors(): string { if (!$this->hasColors()) { throw new Exception; } return $this->colors; } /** * @psalm-assert-if-true !null $this->columns */ public function hasColumns(): bool { return $this->columns !== null; } /** * @throws Exception */ public function columns(): int|string { if (!$this->hasColumns()) { throw new Exception; } return $this->columns; } /** * @psalm-assert-if-true !null $this->configurationFile */ public function hasConfigurationFile(): bool { return $this->configurationFile !== null; } /** * @throws Exception */ public function configurationFile(): string { if (!$this->hasConfigurationFile()) { throw new Exception; } return $this->configurationFile; } /** * @psalm-assert-if-true !null $this->coverageFilter */ public function hasCoverageFilter(): bool { return $this->coverageFilter !== null; } /** * @throws Exception */ public function coverageFilter(): array { if (!$this->hasCoverageFilter()) { throw new Exception; } return $this->coverageFilter; } /** * @psalm-assert-if-true !null $this->coverageClover */ public function hasCoverageClover(): bool { return $this->coverageClover !== null; } /** * @throws Exception */ public function coverageClover(): string { if (!$this->hasCoverageClover()) { throw new Exception; } return $this->coverageClover; } /** * @psalm-assert-if-true !null $this->coverageCobertura */ public function hasCoverageCobertura(): bool { return $this->coverageCobertura !== null; } /** * @throws Exception */ public function coverageCobertura(): string { if (!$this->hasCoverageCobertura()) { throw new Exception; } return $this->coverageCobertura; } /** * @psalm-assert-if-true !null $this->coverageCrap4J */ public function hasCoverageCrap4J(): bool { return $this->coverageCrap4J !== null; } /** * @throws Exception */ public function coverageCrap4J(): string { if (!$this->hasCoverageCrap4J()) { throw new Exception; } return $this->coverageCrap4J; } /** * @psalm-assert-if-true !null $this->coverageHtml */ public function hasCoverageHtml(): bool { return $this->coverageHtml !== null; } /** * @throws Exception */ public function coverageHtml(): string { if (!$this->hasCoverageHtml()) { throw new Exception; } return $this->coverageHtml; } /** * @psalm-assert-if-true !null $this->coveragePhp */ public function hasCoveragePhp(): bool { return $this->coveragePhp !== null; } /** * @throws Exception */ public function coveragePhp(): string { if (!$this->hasCoveragePhp()) { throw new Exception; } return $this->coveragePhp; } /** * @psalm-assert-if-true !null $this->coverageText */ public function hasCoverageText(): bool { return $this->coverageText !== null; } /** * @throws Exception */ public function coverageText(): string { if (!$this->hasCoverageText()) { throw new Exception; } return $this->coverageText; } /** * @psalm-assert-if-true !null $this->coverageTextShowUncoveredFiles */ public function hasCoverageTextShowUncoveredFiles(): bool { return $this->coverageTextShowUncoveredFiles !== null; } /** * @throws Exception */ public function coverageTextShowUncoveredFiles(): bool { if (!$this->hasCoverageTextShowUncoveredFiles()) { throw new Exception; } return $this->coverageTextShowUncoveredFiles; } /** * @psalm-assert-if-true !null $this->coverageTextShowOnlySummary */ public function hasCoverageTextShowOnlySummary(): bool { return $this->coverageTextShowOnlySummary !== null; } /** * @throws Exception */ public function coverageTextShowOnlySummary(): bool { if (!$this->hasCoverageTextShowOnlySummary()) { throw new Exception; } return $this->coverageTextShowOnlySummary; } /** * @psalm-assert-if-true !null $this->coverageXml */ public function hasCoverageXml(): bool { return $this->coverageXml !== null; } /** * @throws Exception */ public function coverageXml(): string { if (!$this->hasCoverageXml()) { throw new Exception; } return $this->coverageXml; } /** * @psalm-assert-if-true !null $this->pathCoverage */ public function hasPathCoverage(): bool { return $this->pathCoverage !== null; } /** * @throws Exception */ public function pathCoverage(): bool { if (!$this->hasPathCoverage()) { throw new Exception; } return $this->pathCoverage; } /** * @psalm-assert-if-true !null $this->coverageCacheDirectory * * @deprecated */ public function hasCoverageCacheDirectory(): bool { return $this->coverageCacheDirectory !== null; } /** * @throws Exception * * @deprecated */ public function coverageCacheDirectory(): string { if (!$this->hasCoverageCacheDirectory()) { throw new Exception; } return $this->coverageCacheDirectory; } public function warmCoverageCache(): bool { return $this->warmCoverageCache; } /** * @psalm-assert-if-true !null $this->defaultTimeLimit */ public function hasDefaultTimeLimit(): bool { return $this->defaultTimeLimit !== null; } /** * @throws Exception */ public function defaultTimeLimit(): int { if (!$this->hasDefaultTimeLimit()) { throw new Exception; } return $this->defaultTimeLimit; } /** * @psalm-assert-if-true !null $this->disableCodeCoverageIgnore */ public function hasDisableCodeCoverageIgnore(): bool { return $this->disableCodeCoverageIgnore !== null; } /** * @throws Exception */ public function disableCodeCoverageIgnore(): bool { if (!$this->hasDisableCodeCoverageIgnore()) { throw new Exception; } return $this->disableCodeCoverageIgnore; } /** * @psalm-assert-if-true !null $this->disallowTestOutput */ public function hasDisallowTestOutput(): bool { return $this->disallowTestOutput !== null; } /** * @throws Exception */ public function disallowTestOutput(): bool { if (!$this->hasDisallowTestOutput()) { throw new Exception; } return $this->disallowTestOutput; } /** * @psalm-assert-if-true !null $this->enforceTimeLimit */ public function hasEnforceTimeLimit(): bool { return $this->enforceTimeLimit !== null; } /** * @throws Exception */ public function enforceTimeLimit(): bool { if (!$this->hasEnforceTimeLimit()) { throw new Exception; } return $this->enforceTimeLimit; } /** * @psalm-assert-if-true !null $this->excludeGroups */ public function hasExcludeGroups(): bool { return $this->excludeGroups !== null; } /** * @throws Exception */ public function excludeGroups(): array { if (!$this->hasExcludeGroups()) { throw new Exception; } return $this->excludeGroups; } /** * @psalm-assert-if-true !null $this->executionOrder */ public function hasExecutionOrder(): bool { return $this->executionOrder !== null; } /** * @throws Exception */ public function executionOrder(): int { if (!$this->hasExecutionOrder()) { throw new Exception; } return $this->executionOrder; } /** * @psalm-assert-if-true !null $this->executionOrderDefects */ public function hasExecutionOrderDefects(): bool { return $this->executionOrderDefects !== null; } /** * @throws Exception */ public function executionOrderDefects(): int { if (!$this->hasExecutionOrderDefects()) { throw new Exception; } return $this->executionOrderDefects; } /** * @psalm-assert-if-true !null $this->failOnAllIssues */ public function hasFailOnAllIssues(): bool { return $this->failOnAllIssues !== null; } /** * @throws Exception */ public function failOnAllIssues(): bool { if (!$this->hasFailOnAllIssues()) { throw new Exception; } return $this->failOnAllIssues; } /** * @psalm-assert-if-true !null $this->failOnDeprecation */ public function hasFailOnDeprecation(): bool { return $this->failOnDeprecation !== null; } /** * @throws Exception */ public function failOnDeprecation(): bool { if (!$this->hasFailOnDeprecation()) { throw new Exception; } return $this->failOnDeprecation; } /** * @psalm-assert-if-true !null $this->failOnPhpunitDeprecation */ public function hasFailOnPhpunitDeprecation(): bool { return $this->failOnPhpunitDeprecation !== null; } /** * @throws Exception */ public function failOnPhpunitDeprecation(): bool { if (!$this->hasFailOnPhpunitDeprecation()) { throw new Exception; } return $this->failOnPhpunitDeprecation; } /** * @psalm-assert-if-true !null $this->failOnPhpunitWarning */ public function hasFailOnPhpunitWarning(): bool { return $this->failOnPhpunitWarning !== null; } /** * @throws Exception */ public function failOnPhpunitWarning(): bool { if (!$this->hasFailOnPhpunitWarning()) { throw new Exception; } return $this->failOnPhpunitWarning; } /** * @psalm-assert-if-true !null $this->failOnEmptyTestSuite */ public function hasFailOnEmptyTestSuite(): bool { return $this->failOnEmptyTestSuite !== null; } /** * @throws Exception */ public function failOnEmptyTestSuite(): bool { if (!$this->hasFailOnEmptyTestSuite()) { throw new Exception; } return $this->failOnEmptyTestSuite; } /** * @psalm-assert-if-true !null $this->failOnIncomplete */ public function hasFailOnIncomplete(): bool { return $this->failOnIncomplete !== null; } /** * @throws Exception */ public function failOnIncomplete(): bool { if (!$this->hasFailOnIncomplete()) { throw new Exception; } return $this->failOnIncomplete; } /** * @psalm-assert-if-true !null $this->failOnNotice */ public function hasFailOnNotice(): bool { return $this->failOnNotice !== null; } /** * @throws Exception */ public function failOnNotice(): bool { if (!$this->hasFailOnNotice()) { throw new Exception; } return $this->failOnNotice; } /** * @psalm-assert-if-true !null $this->failOnRisky */ public function hasFailOnRisky(): bool { return $this->failOnRisky !== null; } /** * @throws Exception */ public function failOnRisky(): bool { if (!$this->hasFailOnRisky()) { throw new Exception; } return $this->failOnRisky; } /** * @psalm-assert-if-true !null $this->failOnSkipped */ public function hasFailOnSkipped(): bool { return $this->failOnSkipped !== null; } /** * @throws Exception */ public function failOnSkipped(): bool { if (!$this->hasFailOnSkipped()) { throw new Exception; } return $this->failOnSkipped; } /** * @psalm-assert-if-true !null $this->failOnWarning */ public function hasFailOnWarning(): bool { return $this->failOnWarning !== null; } /** * @throws Exception */ public function failOnWarning(): bool { if (!$this->hasFailOnWarning()) { throw new Exception; } return $this->failOnWarning; } /** * @psalm-assert-if-true !null $this->doNotFailOnDeprecation */ public function hasDoNotFailOnDeprecation(): bool { return $this->doNotFailOnDeprecation !== null; } /** * @throws Exception */ public function doNotFailOnDeprecation(): bool { if (!$this->hasDoNotFailOnDeprecation()) { throw new Exception; } return $this->doNotFailOnDeprecation; } /** * @psalm-assert-if-true !null $this->doNotFailOnPhpunitDeprecation */ public function hasDoNotFailOnPhpunitDeprecation(): bool { return $this->doNotFailOnPhpunitDeprecation !== null; } /** * @throws Exception */ public function doNotFailOnPhpunitDeprecation(): bool { if (!$this->hasDoNotFailOnPhpunitDeprecation()) { throw new Exception; } return $this->doNotFailOnPhpunitDeprecation; } /** * @psalm-assert-if-true !null $this->doNotFailOnPhpunitWarning */ public function hasDoNotFailOnPhpunitWarning(): bool { return $this->doNotFailOnPhpunitWarning !== null; } /** * @throws Exception */ public function doNotFailOnPhpunitWarning(): bool { if (!$this->hasDoNotFailOnPhpunitWarning()) { throw new Exception; } return $this->doNotFailOnPhpunitWarning; } /** * @psalm-assert-if-true !null $this->doNotFailOnEmptyTestSuite */ public function hasDoNotFailOnEmptyTestSuite(): bool { return $this->doNotFailOnEmptyTestSuite !== null; } /** * @throws Exception */ public function doNotFailOnEmptyTestSuite(): bool { if (!$this->hasDoNotFailOnEmptyTestSuite()) { throw new Exception; } return $this->doNotFailOnEmptyTestSuite; } /** * @psalm-assert-if-true !null $this->doNotFailOnIncomplete */ public function hasDoNotFailOnIncomplete(): bool { return $this->doNotFailOnIncomplete !== null; } /** * @throws Exception */ public function doNotFailOnIncomplete(): bool { if (!$this->hasDoNotFailOnIncomplete()) { throw new Exception; } return $this->doNotFailOnIncomplete; } /** * @psalm-assert-if-true !null $this->doNotFailOnNotice */ public function hasDoNotFailOnNotice(): bool { return $this->doNotFailOnNotice !== null; } /** * @throws Exception */ public function doNotFailOnNotice(): bool { if (!$this->hasDoNotFailOnNotice()) { throw new Exception; } return $this->doNotFailOnNotice; } /** * @psalm-assert-if-true !null $this->doNotFailOnRisky */ public function hasDoNotFailOnRisky(): bool { return $this->doNotFailOnRisky !== null; } /** * @throws Exception */ public function doNotFailOnRisky(): bool { if (!$this->hasDoNotFailOnRisky()) { throw new Exception; } return $this->doNotFailOnRisky; } /** * @psalm-assert-if-true !null $this->doNotFailOnSkipped */ public function hasDoNotFailOnSkipped(): bool { return $this->doNotFailOnSkipped !== null; } /** * @throws Exception */ public function doNotFailOnSkipped(): bool { if (!$this->hasDoNotFailOnSkipped()) { throw new Exception; } return $this->doNotFailOnSkipped; } /** * @psalm-assert-if-true !null $this->doNotFailOnWarning */ public function hasDoNotFailOnWarning(): bool { return $this->doNotFailOnWarning !== null; } /** * @throws Exception */ public function doNotFailOnWarning(): bool { if (!$this->hasDoNotFailOnWarning()) { throw new Exception; } return $this->doNotFailOnWarning; } /** * @psalm-assert-if-true !null $this->stopOnDefect */ public function hasStopOnDefect(): bool { return $this->stopOnDefect !== null; } /** * @throws Exception */ public function stopOnDefect(): bool { if (!$this->hasStopOnDefect()) { throw new Exception; } return $this->stopOnDefect; } /** * @psalm-assert-if-true !null $this->stopOnDeprecation */ public function hasStopOnDeprecation(): bool { return $this->stopOnDeprecation !== null; } /** * @throws Exception */ public function stopOnDeprecation(): bool { if (!$this->hasStopOnDeprecation()) { throw new Exception; } return $this->stopOnDeprecation; } /** * @psalm-assert-if-true !null $this->stopOnError */ public function hasStopOnError(): bool { return $this->stopOnError !== null; } /** * @throws Exception */ public function stopOnError(): bool { if (!$this->hasStopOnError()) { throw new Exception; } return $this->stopOnError; } /** * @psalm-assert-if-true !null $this->stopOnFailure */ public function hasStopOnFailure(): bool { return $this->stopOnFailure !== null; } /** * @throws Exception */ public function stopOnFailure(): bool { if (!$this->hasStopOnFailure()) { throw new Exception; } return $this->stopOnFailure; } /** * @psalm-assert-if-true !null $this->stopOnIncomplete */ public function hasStopOnIncomplete(): bool { return $this->stopOnIncomplete !== null; } /** * @throws Exception */ public function stopOnIncomplete(): bool { if (!$this->hasStopOnIncomplete()) { throw new Exception; } return $this->stopOnIncomplete; } /** * @psalm-assert-if-true !null $this->stopOnNotice */ public function hasStopOnNotice(): bool { return $this->stopOnNotice !== null; } /** * @throws Exception */ public function stopOnNotice(): bool { if (!$this->hasStopOnNotice()) { throw new Exception; } return $this->stopOnNotice; } /** * @psalm-assert-if-true !null $this->stopOnRisky */ public function hasStopOnRisky(): bool { return $this->stopOnRisky !== null; } /** * @throws Exception */ public function stopOnRisky(): bool { if (!$this->hasStopOnRisky()) { throw new Exception; } return $this->stopOnRisky; } /** * @psalm-assert-if-true !null $this->stopOnSkipped */ public function hasStopOnSkipped(): bool { return $this->stopOnSkipped !== null; } /** * @throws Exception */ public function stopOnSkipped(): bool { if (!$this->hasStopOnSkipped()) { throw new Exception; } return $this->stopOnSkipped; } /** * @psalm-assert-if-true !null $this->stopOnWarning */ public function hasStopOnWarning(): bool { return $this->stopOnWarning !== null; } /** * @throws Exception */ public function stopOnWarning(): bool { if (!$this->hasStopOnWarning()) { throw new Exception; } return $this->stopOnWarning; } /** * @psalm-assert-if-true !null $this->filter */ public function hasFilter(): bool { return $this->filter !== null; } /** * @throws Exception */ public function filter(): string { if (!$this->hasFilter()) { throw new Exception; } return $this->filter; } /** * @psalm-assert-if-true !null $this->generateBaseline */ public function hasGenerateBaseline(): bool { return $this->generateBaseline !== null; } /** * @throws Exception */ public function generateBaseline(): string { if (!$this->hasGenerateBaseline()) { throw new Exception; } return $this->generateBaseline; } /** * @psalm-assert-if-true !null $this->useBaseline */ public function hasUseBaseline(): bool { return $this->useBaseline !== null; } /** * @throws Exception */ public function useBaseline(): string { if (!$this->hasUseBaseline()) { throw new Exception; } return $this->useBaseline; } public function ignoreBaseline(): bool { return $this->ignoreBaseline; } public function generateConfiguration(): bool { return $this->generateConfiguration; } public function migrateConfiguration(): bool { return $this->migrateConfiguration; } /** * @psalm-assert-if-true !null $this->groups */ public function hasGroups(): bool { return $this->groups !== null; } /** * @throws Exception */ public function groups(): array { if (!$this->hasGroups()) { throw new Exception; } return $this->groups; } /** * @psalm-assert-if-true !null $this->testsCovering */ public function hasTestsCovering(): bool { return $this->testsCovering !== null; } /** * @throws Exception */ public function testsCovering(): array { if (!$this->hasTestsCovering()) { throw new Exception; } return $this->testsCovering; } /** * @psalm-assert-if-true !null $this->testsUsing */ public function hasTestsUsing(): bool { return $this->testsUsing !== null; } /** * @throws Exception */ public function testsUsing(): array { if (!$this->hasTestsUsing()) { throw new Exception; } return $this->testsUsing; } public function help(): bool { return $this->help; } /** * @psalm-assert-if-true !null $this->includePath */ public function hasIncludePath(): bool { return $this->includePath !== null; } /** * @throws Exception */ public function includePath(): string { if (!$this->hasIncludePath()) { throw new Exception; } return $this->includePath; } /** * @psalm-assert-if-true !null $this->iniSettings */ public function hasIniSettings(): bool { return $this->iniSettings !== null; } /** * @throws Exception */ public function iniSettings(): array { if (!$this->hasIniSettings()) { throw new Exception; } return $this->iniSettings; } /** * @psalm-assert-if-true !null $this->junitLogfile */ public function hasJunitLogfile(): bool { return $this->junitLogfile !== null; } /** * @throws Exception */ public function junitLogfile(): string { if (!$this->hasJunitLogfile()) { throw new Exception; } return $this->junitLogfile; } public function listGroups(): bool { return $this->listGroups; } public function listSuites(): bool { return $this->listSuites; } public function listTests(): bool { return $this->listTests; } /** * @psalm-assert-if-true !null $this->listTestsXml */ public function hasListTestsXml(): bool { return $this->listTestsXml !== null; } /** * @throws Exception */ public function listTestsXml(): string { if (!$this->hasListTestsXml()) { throw new Exception; } return $this->listTestsXml; } /** * @psalm-assert-if-true !null $this->noCoverage */ public function hasNoCoverage(): bool { return $this->noCoverage !== null; } /** * @throws Exception */ public function noCoverage(): bool { if (!$this->hasNoCoverage()) { throw new Exception; } return $this->noCoverage; } /** * @psalm-assert-if-true !null $this->noExtensions */ public function hasNoExtensions(): bool { return $this->noExtensions !== null; } /** * @throws Exception */ public function noExtensions(): bool { if (!$this->hasNoExtensions()) { throw new Exception; } return $this->noExtensions; } /** * @psalm-assert-if-true !null $this->noOutput */ public function hasNoOutput(): bool { return $this->noOutput !== null; } /** * @throws Exception */ public function noOutput(): bool { if ($this->noOutput === null) { throw new Exception; } return $this->noOutput; } /** * @psalm-assert-if-true !null $this->noProgress */ public function hasNoProgress(): bool { return $this->noProgress !== null; } /** * @throws Exception */ public function noProgress(): bool { if ($this->noProgress === null) { throw new Exception; } return $this->noProgress; } /** * @psalm-assert-if-true !null $this->noResults */ public function hasNoResults(): bool { return $this->noResults !== null; } /** * @throws Exception */ public function noResults(): bool { if ($this->noResults === null) { throw new Exception; } return $this->noResults; } /** * @psalm-assert-if-true !null $this->noLogging */ public function hasNoLogging(): bool { return $this->noLogging !== null; } /** * @throws Exception */ public function noLogging(): bool { if (!$this->hasNoLogging()) { throw new Exception; } return $this->noLogging; } /** * @psalm-assert-if-true !null $this->processIsolation */ public function hasProcessIsolation(): bool { return $this->processIsolation !== null; } /** * @throws Exception */ public function processIsolation(): bool { if (!$this->hasProcessIsolation()) { throw new Exception; } return $this->processIsolation; } /** * @psalm-assert-if-true !null $this->randomOrderSeed */ public function hasRandomOrderSeed(): bool { return $this->randomOrderSeed !== null; } /** * @throws Exception */ public function randomOrderSeed(): int { if (!$this->hasRandomOrderSeed()) { throw new Exception; } return $this->randomOrderSeed; } /** * @psalm-assert-if-true !null $this->reportUselessTests */ public function hasReportUselessTests(): bool { return $this->reportUselessTests !== null; } /** * @throws Exception */ public function reportUselessTests(): bool { if (!$this->hasReportUselessTests()) { throw new Exception; } return $this->reportUselessTests; } /** * @psalm-assert-if-true !null $this->resolveDependencies */ public function hasResolveDependencies(): bool { return $this->resolveDependencies !== null; } /** * @throws Exception */ public function resolveDependencies(): bool { if (!$this->hasResolveDependencies()) { throw new Exception; } return $this->resolveDependencies; } /** * @psalm-assert-if-true !null $this->reverseList */ public function hasReverseList(): bool { return $this->reverseList !== null; } /** * @throws Exception */ public function reverseList(): bool { if (!$this->hasReverseList()) { throw new Exception; } return $this->reverseList; } /** * @psalm-assert-if-true !null $this->stderr */ public function hasStderr(): bool { return $this->stderr !== null; } /** * @throws Exception */ public function stderr(): bool { if (!$this->hasStderr()) { throw new Exception; } return $this->stderr; } /** * @psalm-assert-if-true !null $this->strictCoverage */ public function hasStrictCoverage(): bool { return $this->strictCoverage !== null; } /** * @throws Exception */ public function strictCoverage(): bool { if (!$this->hasStrictCoverage()) { throw new Exception; } return $this->strictCoverage; } /** * @psalm-assert-if-true !null $this->teamcityLogfile */ public function hasTeamcityLogfile(): bool { return $this->teamcityLogfile !== null; } /** * @throws Exception */ public function teamcityLogfile(): string { if (!$this->hasTeamcityLogfile()) { throw new Exception; } return $this->teamcityLogfile; } /** * @psalm-assert-if-true !null $this->teamcityPrinter */ public function hasTeamCityPrinter(): bool { return $this->teamCityPrinter !== null; } /** * @throws Exception */ public function teamCityPrinter(): bool { if (!$this->hasTeamCityPrinter()) { throw new Exception; } return $this->teamCityPrinter; } /** * @psalm-assert-if-true !null $this->testdoxHtmlFile */ public function hasTestdoxHtmlFile(): bool { return $this->testdoxHtmlFile !== null; } /** * @throws Exception */ public function testdoxHtmlFile(): string { if (!$this->hasTestdoxHtmlFile()) { throw new Exception; } return $this->testdoxHtmlFile; } /** * @psalm-assert-if-true !null $this->testdoxTextFile */ public function hasTestdoxTextFile(): bool { return $this->testdoxTextFile !== null; } /** * @throws Exception */ public function testdoxTextFile(): string { if (!$this->hasTestdoxTextFile()) { throw new Exception; } return $this->testdoxTextFile; } /** * @psalm-assert-if-true !null $this->testdoxPrinter */ public function hasTestDoxPrinter(): bool { return $this->testdoxPrinter !== null; } /** * @throws Exception */ public function testdoxPrinter(): bool { if (!$this->hasTestdoxPrinter()) { throw new Exception; } return $this->testdoxPrinter; } /** * @psalm-assert-if-true !null $this->testSuffixes */ public function hasTestSuffixes(): bool { return $this->testSuffixes !== null; } /** * @throws Exception * * @psalm-return non-empty-list */ public function testSuffixes(): array { if (!$this->hasTestSuffixes()) { throw new Exception; } return $this->testSuffixes; } /** * @psalm-assert-if-true !null $this->testSuite */ public function hasTestSuite(): bool { return $this->testSuite !== null; } /** * @throws Exception */ public function testSuite(): string { if (!$this->hasTestSuite()) { throw new Exception; } return $this->testSuite; } /** * @psalm-assert-if-true !null $this->excludedTestSuite */ public function hasExcludedTestSuite(): bool { return $this->excludeTestSuite !== null; } /** * @throws Exception */ public function excludedTestSuite(): string { if (!$this->hasExcludedTestSuite()) { throw new Exception; } return $this->excludeTestSuite; } public function useDefaultConfiguration(): bool { return $this->useDefaultConfiguration; } /** * @psalm-assert-if-true !null $this->displayDetailsOnAllIssues */ public function hasDisplayDetailsOnAllIssues(): bool { return $this->displayDetailsOnAllIssues !== null; } /** * @throws Exception */ public function displayDetailsOnAllIssues(): bool { if (!$this->hasDisplayDetailsOnAllIssues()) { throw new Exception; } return $this->displayDetailsOnAllIssues; } /** * @psalm-assert-if-true !null $this->displayDetailsOnIncompleteTests */ public function hasDisplayDetailsOnIncompleteTests(): bool { return $this->displayDetailsOnIncompleteTests !== null; } /** * @throws Exception */ public function displayDetailsOnIncompleteTests(): bool { if (!$this->hasDisplayDetailsOnIncompleteTests()) { throw new Exception; } return $this->displayDetailsOnIncompleteTests; } /** * @psalm-assert-if-true !null $this->displayDetailsOnSkippedTests */ public function hasDisplayDetailsOnSkippedTests(): bool { return $this->displayDetailsOnSkippedTests !== null; } /** * @throws Exception */ public function displayDetailsOnSkippedTests(): bool { if (!$this->hasDisplayDetailsOnSkippedTests()) { throw new Exception; } return $this->displayDetailsOnSkippedTests; } /** * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerDeprecations */ public function hasDisplayDetailsOnTestsThatTriggerDeprecations(): bool { return $this->displayDetailsOnTestsThatTriggerDeprecations !== null; } /** * @throws Exception */ public function displayDetailsOnTestsThatTriggerDeprecations(): bool { if (!$this->hasDisplayDetailsOnTestsThatTriggerDeprecations()) { throw new Exception; } return $this->displayDetailsOnTestsThatTriggerDeprecations; } /** * @psalm-assert-if-true !null $this->displayDetailsOnPhpunitDeprecations */ public function hasDisplayDetailsOnPhpunitDeprecations(): bool { return $this->displayDetailsOnPhpunitDeprecations !== null; } /** * @throws Exception */ public function displayDetailsOnPhpunitDeprecations(): bool { if (!$this->hasDisplayDetailsOnPhpunitDeprecations()) { throw new Exception; } return $this->displayDetailsOnPhpunitDeprecations; } /** * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerErrors */ public function hasDisplayDetailsOnTestsThatTriggerErrors(): bool { return $this->displayDetailsOnTestsThatTriggerErrors !== null; } /** * @throws Exception */ public function displayDetailsOnTestsThatTriggerErrors(): bool { if (!$this->hasDisplayDetailsOnTestsThatTriggerErrors()) { throw new Exception; } return $this->displayDetailsOnTestsThatTriggerErrors; } /** * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerNotices */ public function hasDisplayDetailsOnTestsThatTriggerNotices(): bool { return $this->displayDetailsOnTestsThatTriggerNotices !== null; } /** * @throws Exception */ public function displayDetailsOnTestsThatTriggerNotices(): bool { if (!$this->hasDisplayDetailsOnTestsThatTriggerNotices()) { throw new Exception; } return $this->displayDetailsOnTestsThatTriggerNotices; } /** * @psalm-assert-if-true !null $this->displayDetailsOnTestsThatTriggerWarnings */ public function hasDisplayDetailsOnTestsThatTriggerWarnings(): bool { return $this->displayDetailsOnTestsThatTriggerWarnings !== null; } /** * @throws Exception */ public function displayDetailsOnTestsThatTriggerWarnings(): bool { if (!$this->hasDisplayDetailsOnTestsThatTriggerWarnings()) { throw new Exception; } return $this->displayDetailsOnTestsThatTriggerWarnings; } public function version(): bool { return $this->version; } /** * @psalm-assert-if-true !null $this->logEventsText */ public function hasLogEventsText(): bool { return $this->logEventsText !== null; } /** * @throws Exception */ public function logEventsText(): string { if (!$this->hasLogEventsText()) { throw new Exception; } return $this->logEventsText; } /** * @psalm-assert-if-true !null $this->logEventsVerboseText */ public function hasLogEventsVerboseText(): bool { return $this->logEventsVerboseText !== null; } /** * @throws Exception */ public function logEventsVerboseText(): string { if (!$this->hasLogEventsVerboseText()) { throw new Exception; } return $this->logEventsVerboseText; } public function debug(): bool { return $this->debug; } } PKYg3]tConfiguration/Cli/Builder.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\CliArguments; use const DIRECTORY_SEPARATOR; use function array_map; use function basename; use function explode; use function getcwd; use function is_file; use function is_numeric; use function sprintf; use PHPUnit\Event\Facade as EventFacade; use PHPUnit\Runner\TestSuiteSorter; use PHPUnit\Util\Filesystem; use SebastianBergmann\CliParser\Exception as CliParserException; use SebastianBergmann\CliParser\Parser as CliParser; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Builder { private const LONG_OPTIONS = [ 'atleast-version=', 'bootstrap=', 'cache-result', 'do-not-cache-result', 'cache-directory=', 'cache-result-file=', 'check-version', 'check-php-configuration', 'colors==', 'columns=', 'configuration=', 'coverage-cache=', 'warm-coverage-cache', 'coverage-filter=', 'coverage-clover=', 'coverage-cobertura=', 'coverage-crap4j=', 'coverage-html=', 'coverage-php=', 'coverage-text==', 'only-summary-for-coverage-text', 'show-uncovered-for-coverage-text', 'coverage-xml=', 'path-coverage', 'disallow-test-output', 'display-all-issues', 'display-incomplete', 'display-skipped', 'display-deprecations', 'display-phpunit-deprecations', 'display-errors', 'display-notices', 'display-warnings', 'default-time-limit=', 'enforce-time-limit', 'exclude-group=', 'filter=', 'generate-baseline=', 'use-baseline=', 'ignore-baseline', 'generate-configuration', 'globals-backup', 'group=', 'covers=', 'uses=', 'help', 'resolve-dependencies', 'ignore-dependencies', 'include-path=', 'list-groups', 'list-suites', 'list-tests', 'list-tests-xml=', 'log-junit=', 'log-teamcity=', 'migrate-configuration', 'no-configuration', 'no-coverage', 'no-logging', 'no-extensions', 'no-output', 'no-progress', 'no-results', 'order-by=', 'process-isolation', 'do-not-report-useless-tests', 'dont-report-useless-tests', 'random-order', 'random-order-seed=', 'reverse-order', 'reverse-list', 'static-backup', 'stderr', 'fail-on-all-issues', 'fail-on-deprecation', 'fail-on-phpunit-deprecation', 'fail-on-phpunit-warning', 'fail-on-empty-test-suite', 'fail-on-incomplete', 'fail-on-notice', 'fail-on-risky', 'fail-on-skipped', 'fail-on-warning', 'do-not-fail-on-deprecation', 'do-not-fail-on-phpunit-deprecation', 'do-not-fail-on-phpunit-warning', 'do-not-fail-on-empty-test-suite', 'do-not-fail-on-incomplete', 'do-not-fail-on-notice', 'do-not-fail-on-risky', 'do-not-fail-on-skipped', 'do-not-fail-on-warning', 'stop-on-defect', 'stop-on-deprecation', 'stop-on-error', 'stop-on-failure', 'stop-on-incomplete', 'stop-on-notice', 'stop-on-risky', 'stop-on-skipped', 'stop-on-warning', 'strict-coverage', 'disable-coverage-ignore', 'strict-global-state', 'teamcity', 'testdox', 'testdox-html=', 'testdox-text=', 'test-suffix=', 'testsuite=', 'exclude-testsuite=', 'log-events-text=', 'log-events-verbose-text=', 'version', 'debug', ]; private const SHORT_OPTIONS = 'd:c:h'; /** * @psalm-var array */ private array $processed = []; /** * @throws Exception */ public function fromParameters(array $parameters): Configuration { try { $options = (new CliParser)->parse( $parameters, self::SHORT_OPTIONS, self::LONG_OPTIONS, ); } catch (CliParserException $e) { throw new Exception( $e->getMessage(), $e->getCode(), $e, ); } $atLeastVersion = null; $backupGlobals = null; $backupStaticProperties = null; $beStrictAboutChangesToGlobalState = null; $bootstrap = null; $cacheDirectory = null; $cacheResult = null; $cacheResultFile = null; $checkPhpConfiguration = false; $checkVersion = false; $colors = null; $columns = null; $configuration = null; $coverageCacheDirectory = null; $warmCoverageCache = false; $coverageFilter = null; $coverageClover = null; $coverageCobertura = null; $coverageCrap4J = null; $coverageHtml = null; $coveragePhp = null; $coverageText = null; $coverageTextShowUncoveredFiles = null; $coverageTextShowOnlySummary = null; $coverageXml = null; $pathCoverage = null; $defaultTimeLimit = null; $disableCodeCoverageIgnore = null; $disallowTestOutput = null; $displayAllIssues = null; $displayIncomplete = null; $displaySkipped = null; $displayDeprecations = null; $displayPhpunitDeprecations = null; $displayErrors = null; $displayNotices = null; $displayWarnings = null; $enforceTimeLimit = null; $excludeGroups = null; $executionOrder = null; $executionOrderDefects = null; $failOnAllIssues = null; $failOnDeprecation = null; $failOnPhpunitDeprecation = null; $failOnPhpunitWarning = null; $failOnEmptyTestSuite = null; $failOnIncomplete = null; $failOnNotice = null; $failOnRisky = null; $failOnSkipped = null; $failOnWarning = null; $doNotFailOnDeprecation = null; $doNotFailOnPhpunitDeprecation = null; $doNotFailOnPhpunitWarning = null; $doNotFailOnEmptyTestSuite = null; $doNotFailOnIncomplete = null; $doNotFailOnNotice = null; $doNotFailOnRisky = null; $doNotFailOnSkipped = null; $doNotFailOnWarning = null; $stopOnDefect = null; $stopOnDeprecation = null; $stopOnError = null; $stopOnFailure = null; $stopOnIncomplete = null; $stopOnNotice = null; $stopOnRisky = null; $stopOnSkipped = null; $stopOnWarning = null; $filter = null; $generateBaseline = null; $useBaseline = null; $ignoreBaseline = false; $generateConfiguration = false; $migrateConfiguration = false; $groups = null; $testsCovering = null; $testsUsing = null; $help = false; $includePath = null; $iniSettings = []; $junitLogfile = null; $listGroups = false; $listSuites = false; $listTests = false; $listTestsXml = null; $noCoverage = null; $noExtensions = null; $noOutput = null; $noProgress = null; $noResults = null; $noLogging = null; $processIsolation = null; $randomOrderSeed = null; $reportUselessTests = null; $resolveDependencies = null; $reverseList = null; $stderr = null; $strictCoverage = null; $teamcityLogfile = null; $testdoxHtmlFile = null; $testdoxTextFile = null; $testSuffixes = null; $testSuite = null; $excludeTestSuite = null; $useDefaultConfiguration = true; $version = false; $logEventsText = null; $logEventsVerboseText = null; $printerTeamCity = null; $printerTestDox = null; $debug = false; foreach ($options[0] as $option) { $optionAllowedMultipleTimes = false; switch ($option[0]) { case '--colors': $colors = $option[1] ?: \PHPUnit\TextUI\Configuration\Configuration::COLOR_AUTO; break; case '--bootstrap': $bootstrap = $option[1]; break; case '--cache-directory': $cacheDirectory = $option[1]; break; case '--cache-result': $cacheResult = true; break; case '--do-not-cache-result': $cacheResult = false; break; case '--cache-result-file': $cacheResultFile = $option[1]; break; case '--columns': if (is_numeric($option[1])) { $columns = (int) $option[1]; } elseif ($option[1] === 'max') { $columns = 'max'; } break; case 'c': case '--configuration': $configuration = $option[1]; break; case '--coverage-cache': $coverageCacheDirectory = $option[1]; break; case '--warm-coverage-cache': $warmCoverageCache = true; break; case '--coverage-clover': $coverageClover = $option[1]; break; case '--coverage-cobertura': $coverageCobertura = $option[1]; break; case '--coverage-crap4j': $coverageCrap4J = $option[1]; break; case '--coverage-html': $coverageHtml = $option[1]; break; case '--coverage-php': $coveragePhp = $option[1]; break; case '--coverage-text': if ($option[1] === null) { $option[1] = 'php://stdout'; } $coverageText = $option[1]; break; case '--only-summary-for-coverage-text': $coverageTextShowOnlySummary = true; break; case '--show-uncovered-for-coverage-text': $coverageTextShowUncoveredFiles = true; break; case '--coverage-xml': $coverageXml = $option[1]; break; case '--path-coverage': $pathCoverage = true; break; case 'd': $tmp = explode('=', $option[1]); if (isset($tmp[0])) { if (isset($tmp[1])) { $iniSettings[$tmp[0]] = $tmp[1]; } else { $iniSettings[$tmp[0]] = '1'; } } $optionAllowedMultipleTimes = true; break; case 'h': case '--help': $help = true; break; case '--filter': $filter = $option[1]; break; case '--testsuite': $testSuite = $option[1]; break; case '--exclude-testsuite': $excludeTestSuite = $option[1]; break; case '--generate-baseline': $generateBaseline = $option[1]; if (basename($generateBaseline) === $generateBaseline) { $generateBaseline = getcwd() . DIRECTORY_SEPARATOR . $generateBaseline; } break; case '--use-baseline': $useBaseline = $option[1]; if (basename($useBaseline) === $useBaseline && !is_file($useBaseline)) { $useBaseline = getcwd() . DIRECTORY_SEPARATOR . $useBaseline; } break; case '--ignore-baseline': $ignoreBaseline = true; break; case '--generate-configuration': $generateConfiguration = true; break; case '--migrate-configuration': $migrateConfiguration = true; break; case '--group': $groups = explode(',', $option[1]); break; case '--exclude-group': $excludeGroups = explode(',', $option[1]); break; case '--covers': $testsCovering = array_map('strtolower', explode(',', $option[1])); break; case '--uses': $testsUsing = array_map('strtolower', explode(',', $option[1])); break; case '--test-suffix': $testSuffixes = explode(',', $option[1]); break; case '--include-path': $includePath = $option[1]; break; case '--list-groups': $listGroups = true; break; case '--list-suites': $listSuites = true; break; case '--list-tests': $listTests = true; break; case '--list-tests-xml': $listTestsXml = $option[1]; break; case '--log-junit': $junitLogfile = $option[1]; break; case '--log-teamcity': $teamcityLogfile = $option[1]; break; case '--order-by': foreach (explode(',', $option[1]) as $order) { switch ($order) { case 'default': $executionOrder = TestSuiteSorter::ORDER_DEFAULT; $executionOrderDefects = TestSuiteSorter::ORDER_DEFAULT; $resolveDependencies = true; break; case 'defects': $executionOrderDefects = TestSuiteSorter::ORDER_DEFECTS_FIRST; break; case 'depends': $resolveDependencies = true; break; case 'duration': $executionOrder = TestSuiteSorter::ORDER_DURATION; break; case 'no-depends': $resolveDependencies = false; break; case 'random': $executionOrder = TestSuiteSorter::ORDER_RANDOMIZED; break; case 'reverse': $executionOrder = TestSuiteSorter::ORDER_REVERSED; break; case 'size': $executionOrder = TestSuiteSorter::ORDER_SIZE; break; default: throw new Exception( sprintf( 'unrecognized --order-by option: %s', $order, ), ); } } break; case '--process-isolation': $processIsolation = true; break; case '--stderr': $stderr = true; break; case '--fail-on-all-issues': $failOnAllIssues = true; break; case '--fail-on-deprecation': $this->warnWhenOptionsConflict( $doNotFailOnDeprecation, '--fail-on-deprecation', '--do-not-fail-on-deprecation', ); $failOnDeprecation = true; break; case '--fail-on-phpunit-deprecation': $this->warnWhenOptionsConflict( $doNotFailOnPhpunitDeprecation, '--fail-on-phpunit-deprecation', '--do-not-fail-on-phpunit-deprecation', ); $failOnPhpunitDeprecation = true; break; case '--fail-on-phpunit-warning': $this->warnWhenOptionsConflict( $doNotFailOnPhpunitWarning, '--fail-on-phpunit-warning', '--do-not-fail-on-phpunit-warning', ); $failOnPhpunitWarning = true; break; case '--fail-on-empty-test-suite': $this->warnWhenOptionsConflict( $doNotFailOnEmptyTestSuite, '--fail-on-empty-test-suite', '--do-not-fail-on-empty-test-suite', ); $failOnEmptyTestSuite = true; break; case '--fail-on-incomplete': $this->warnWhenOptionsConflict( $doNotFailOnIncomplete, '--fail-on-incomplete', '--do-not-fail-on-incomplete', ); $failOnIncomplete = true; break; case '--fail-on-notice': $this->warnWhenOptionsConflict( $doNotFailOnNotice, '--fail-on-notice', '--do-not-fail-on-notice', ); $failOnNotice = true; break; case '--fail-on-risky': $this->warnWhenOptionsConflict( $doNotFailOnRisky, '--fail-on-risky', '--do-not-fail-on-risky', ); $failOnRisky = true; break; case '--fail-on-skipped': $this->warnWhenOptionsConflict( $doNotFailOnSkipped, '--fail-on-skipped', '--do-not-fail-on-skipped', ); $failOnSkipped = true; break; case '--fail-on-warning': $this->warnWhenOptionsConflict( $doNotFailOnWarning, '--fail-on-warning', '--do-not-fail-on-warning', ); $failOnWarning = true; break; case '--do-not-fail-on-deprecation': $this->warnWhenOptionsConflict( $failOnDeprecation, '--do-not-fail-on-deprecation', '--fail-on-deprecation', ); $doNotFailOnDeprecation = true; break; case '--do-not-fail-on-phpunit-deprecation': $this->warnWhenOptionsConflict( $failOnPhpunitDeprecation, '--do-not-fail-on-phpunit-deprecation', '--fail-on-phpunit-deprecation', ); $doNotFailOnPhpunitDeprecation = true; break; case '--do-not-fail-on-phpunit-warning': $this->warnWhenOptionsConflict( $failOnPhpunitWarning, '--do-not-fail-on-phpunit-warning', '--fail-on-phpunit-warning', ); $doNotFailOnPhpunitWarning = true; break; case '--do-not-fail-on-empty-test-suite': $this->warnWhenOptionsConflict( $failOnEmptyTestSuite, '--do-not-fail-on-empty-test-suite', '--fail-on-empty-test-suite', ); $doNotFailOnEmptyTestSuite = true; break; case '--do-not-fail-on-incomplete': $this->warnWhenOptionsConflict( $failOnIncomplete, '--do-not-fail-on-incomplete', '--fail-on-incomplete', ); $doNotFailOnIncomplete = true; break; case '--do-not-fail-on-notice': $this->warnWhenOptionsConflict( $failOnNotice, '--do-not-fail-on-notice', '--fail-on-notice', ); $doNotFailOnNotice = true; break; case '--do-not-fail-on-risky': $this->warnWhenOptionsConflict( $failOnRisky, '--do-not-fail-on-risky', '--fail-on-risky', ); $doNotFailOnRisky = true; break; case '--do-not-fail-on-skipped': $this->warnWhenOptionsConflict( $failOnSkipped, '--do-not-fail-on-skipped', '--fail-on-skipped', ); $doNotFailOnSkipped = true; break; case '--do-not-fail-on-warning': $this->warnWhenOptionsConflict( $failOnWarning, '--do-not-fail-on-warning', '--fail-on-warning', ); $doNotFailOnWarning = true; break; case '--stop-on-defect': $stopOnDefect = true; break; case '--stop-on-deprecation': $stopOnDeprecation = true; break; case '--stop-on-error': $stopOnError = true; break; case '--stop-on-failure': $stopOnFailure = true; break; case '--stop-on-incomplete': $stopOnIncomplete = true; break; case '--stop-on-notice': $stopOnNotice = true; break; case '--stop-on-risky': $stopOnRisky = true; break; case '--stop-on-skipped': $stopOnSkipped = true; break; case '--stop-on-warning': $stopOnWarning = true; break; case '--teamcity': $printerTeamCity = true; break; case '--testdox': $printerTestDox = true; break; case '--testdox-html': $testdoxHtmlFile = $option[1]; break; case '--testdox-text': $testdoxTextFile = $option[1]; break; case '--no-configuration': $useDefaultConfiguration = false; break; case '--no-extensions': $noExtensions = true; break; case '--no-coverage': $noCoverage = true; break; case '--no-logging': $noLogging = true; break; case '--no-output': $noOutput = true; break; case '--no-progress': $noProgress = true; break; case '--no-results': $noResults = true; break; case '--globals-backup': $backupGlobals = true; break; case '--static-backup': $backupStaticProperties = true; break; case '--atleast-version': $atLeastVersion = $option[1]; break; case '--version': $version = true; break; case '--do-not-report-useless-tests': case '--dont-report-useless-tests': $reportUselessTests = false; break; case '--strict-coverage': $strictCoverage = true; break; case '--disable-coverage-ignore': $disableCodeCoverageIgnore = true; break; case '--strict-global-state': $beStrictAboutChangesToGlobalState = true; break; case '--disallow-test-output': $disallowTestOutput = true; break; case '--display-all-issues': $displayAllIssues = true; break; case '--display-incomplete': $displayIncomplete = true; break; case '--display-skipped': $displaySkipped = true; break; case '--display-deprecations': $displayDeprecations = true; break; case '--display-phpunit-deprecations': $displayPhpunitDeprecations = true; break; case '--display-errors': $displayErrors = true; break; case '--display-notices': $displayNotices = true; break; case '--display-warnings': $displayWarnings = true; break; case '--default-time-limit': $defaultTimeLimit = (int) $option[1]; break; case '--enforce-time-limit': $enforceTimeLimit = true; break; case '--reverse-list': $reverseList = true; break; case '--check-php-configuration': $checkPhpConfiguration = true; break; case '--check-version': $checkVersion = true; break; case '--coverage-filter': if ($coverageFilter === null) { $coverageFilter = []; } $coverageFilter[] = $option[1]; $optionAllowedMultipleTimes = true; break; case '--random-order': $executionOrder = TestSuiteSorter::ORDER_RANDOMIZED; break; case '--random-order-seed': $randomOrderSeed = (int) $option[1]; break; case '--resolve-dependencies': $resolveDependencies = true; break; case '--ignore-dependencies': $resolveDependencies = false; break; case '--reverse-order': $executionOrder = TestSuiteSorter::ORDER_REVERSED; break; case '--log-events-text': $logEventsText = Filesystem::resolveStreamOrFile($option[1]); if ($logEventsText === false) { throw new Exception( sprintf( 'The path "%s" specified for the --log-events-text option could not be resolved', $option[1], ), ); } break; case '--log-events-verbose-text': $logEventsVerboseText = Filesystem::resolveStreamOrFile($option[1]); if ($logEventsVerboseText === false) { throw new Exception( sprintf( 'The path "%s" specified for the --log-events-verbose-text option could not be resolved', $option[1], ), ); } break; case '--debug': $debug = true; break; } if (!$optionAllowedMultipleTimes) { $this->markProcessed($option[0]); } } if (empty($iniSettings)) { $iniSettings = null; } if (empty($coverageFilter)) { $coverageFilter = null; } return new Configuration( $options[1], $atLeastVersion, $backupGlobals, $backupStaticProperties, $beStrictAboutChangesToGlobalState, $bootstrap, $cacheDirectory, $cacheResult, $cacheResultFile, $checkPhpConfiguration, $checkVersion, $colors, $columns, $configuration, $coverageClover, $coverageCobertura, $coverageCrap4J, $coverageHtml, $coveragePhp, $coverageText, $coverageTextShowUncoveredFiles, $coverageTextShowOnlySummary, $coverageXml, $pathCoverage, $coverageCacheDirectory, $warmCoverageCache, $defaultTimeLimit, $disableCodeCoverageIgnore, $disallowTestOutput, $enforceTimeLimit, $excludeGroups, $executionOrder, $executionOrderDefects, $failOnAllIssues, $failOnDeprecation, $failOnPhpunitDeprecation, $failOnPhpunitWarning, $failOnEmptyTestSuite, $failOnIncomplete, $failOnNotice, $failOnRisky, $failOnSkipped, $failOnWarning, $doNotFailOnDeprecation, $doNotFailOnPhpunitDeprecation, $doNotFailOnPhpunitWarning, $doNotFailOnEmptyTestSuite, $doNotFailOnIncomplete, $doNotFailOnNotice, $doNotFailOnRisky, $doNotFailOnSkipped, $doNotFailOnWarning, $stopOnDefect, $stopOnDeprecation, $stopOnError, $stopOnFailure, $stopOnIncomplete, $stopOnNotice, $stopOnRisky, $stopOnSkipped, $stopOnWarning, $filter, $generateBaseline, $useBaseline, $ignoreBaseline, $generateConfiguration, $migrateConfiguration, $groups, $testsCovering, $testsUsing, $help, $includePath, $iniSettings, $junitLogfile, $listGroups, $listSuites, $listTests, $listTestsXml, $noCoverage, $noExtensions, $noOutput, $noProgress, $noResults, $noLogging, $processIsolation, $randomOrderSeed, $reportUselessTests, $resolveDependencies, $reverseList, $stderr, $strictCoverage, $teamcityLogfile, $testdoxHtmlFile, $testdoxTextFile, $testSuffixes, $testSuite, $excludeTestSuite, $useDefaultConfiguration, $displayAllIssues, $displayIncomplete, $displaySkipped, $displayDeprecations, $displayPhpunitDeprecations, $displayErrors, $displayNotices, $displayWarnings, $version, $coverageFilter, $logEventsText, $logEventsVerboseText, $printerTeamCity, $printerTestDox, $debug, ); } /** * @psalm-param non-empty-string $option */ private function markProcessed(string $option): void { if (!isset($this->processed[$option])) { $this->processed[$option] = 1; return; } $this->processed[$option]++; if ($this->processed[$option] === 2) { EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( sprintf( 'Option %s cannot be used more than once', $option, ), ); } } /** * @psalm-param non-empty-string $option */ private function warnWhenOptionsConflict(?bool $current, string $option, string $opposite): void { if ($current === null) { return; } EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( sprintf( 'Options %s and %s cannot be used together', $option, $opposite, ), ); } } PKYg3]CZZConfiguration/Cli/Exception.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\CliArguments; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Exception extends RuntimeException implements \PHPUnit\Exception { } PKYg3] ܋Q Q Configuration/Registry.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function assert; use function file_get_contents; use function file_put_contents; use function serialize; use function unserialize; use PHPUnit\Event\Facade as EventFacade; use PHPUnit\TextUI\CliArguments\Configuration as CliConfiguration; use PHPUnit\TextUI\CliArguments\Exception; use PHPUnit\TextUI\XmlConfiguration\Configuration as XmlConfiguration; use PHPUnit\Util\VersionComparisonOperator; /** * CLI options and XML configuration are static within a single PHPUnit process. * It is therefore okay to use a Singleton registry here. * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Registry { private static ?Configuration $instance = null; public static function saveTo(string $path): bool { $result = file_put_contents( $path, serialize(self::get()), ); if ($result) { return true; } // @codeCoverageIgnoreStart return false; // @codeCoverageIgnoreEnd } /** * This method is used by the "run test(s) in separate process" templates. * * @noinspection PhpUnused * * @codeCoverageIgnore */ public static function loadFrom(string $path): void { self::$instance = unserialize( file_get_contents($path), [ 'allowed_classes' => [ Configuration::class, Php::class, ConstantCollection::class, Constant::class, IniSettingCollection::class, IniSetting::class, VariableCollection::class, Variable::class, DirectoryCollection::class, Directory::class, FileCollection::class, File::class, FilterDirectoryCollection::class, FilterDirectory::class, TestDirectoryCollection::class, TestDirectory::class, TestFileCollection::class, TestFile::class, TestSuiteCollection::class, TestSuite::class, VersionComparisonOperator::class, Source::class, ], ], ); } public static function get(): Configuration { assert(self::$instance instanceof Configuration); return self::$instance; } /** * @throws \PHPUnit\TextUI\XmlConfiguration\Exception * @throws Exception * @throws NoCustomCssFileException */ public static function init(CliConfiguration $cliConfiguration, XmlConfiguration $xmlConfiguration): Configuration { self::$instance = (new Merger)->merge($cliConfiguration, $xmlConfiguration); EventFacade::emitter()->testRunnerConfigured(self::$instance); return self::$instance; } } PKYg3]&&Configuration/Configuration.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class Configuration { public const COLOR_NEVER = 'never'; public const COLOR_AUTO = 'auto'; public const COLOR_ALWAYS = 'always'; public const COLOR_DEFAULT = self::COLOR_NEVER; /** * @psalm-var list */ private readonly array $cliArguments; private readonly ?string $configurationFile; private readonly ?string $bootstrap; private readonly bool $cacheResult; private readonly ?string $cacheDirectory; private readonly ?string $coverageCacheDirectory; private readonly Source $source; private readonly bool $pathCoverage; private readonly ?string $coverageClover; private readonly ?string $coverageCobertura; private readonly ?string $coverageCrap4j; private readonly int $coverageCrap4jThreshold; private readonly ?string $coverageHtml; private readonly int $coverageHtmlLowUpperBound; private readonly int $coverageHtmlHighLowerBound; private readonly string $coverageHtmlColorSuccessLow; private readonly string $coverageHtmlColorSuccessMedium; private readonly string $coverageHtmlColorSuccessHigh; private readonly string $coverageHtmlColorWarning; private readonly string $coverageHtmlColorDanger; private readonly ?string $coverageHtmlCustomCssFile; private readonly ?string $coveragePhp; private readonly ?string $coverageText; private readonly bool $coverageTextShowUncoveredFiles; private readonly bool $coverageTextShowOnlySummary; private readonly ?string $coverageXml; private readonly string $testResultCacheFile; private readonly bool $ignoreDeprecatedCodeUnitsFromCodeCoverage; private readonly bool $disableCodeCoverageIgnore; private readonly bool $failOnAllIssues; private readonly bool $failOnDeprecation; private readonly bool $failOnPhpunitDeprecation; private readonly bool $failOnPhpunitWarning; private readonly bool $failOnEmptyTestSuite; private readonly bool $failOnIncomplete; private readonly bool $failOnNotice; private readonly bool $failOnRisky; private readonly bool $failOnSkipped; private readonly bool $failOnWarning; private readonly bool $doNotFailOnDeprecation; private readonly bool $doNotFailOnPhpunitDeprecation; private readonly bool $doNotFailOnPhpunitWarning; private readonly bool $doNotFailOnEmptyTestSuite; private readonly bool $doNotFailOnIncomplete; private readonly bool $doNotFailOnNotice; private readonly bool $doNotFailOnRisky; private readonly bool $doNotFailOnSkipped; private readonly bool $doNotFailOnWarning; private readonly bool $stopOnDefect; private readonly bool $stopOnDeprecation; private readonly bool $stopOnError; private readonly bool $stopOnFailure; private readonly bool $stopOnIncomplete; private readonly bool $stopOnNotice; private readonly bool $stopOnRisky; private readonly bool $stopOnSkipped; private readonly bool $stopOnWarning; private readonly bool $outputToStandardErrorStream; private readonly int $columns; private readonly bool $noExtensions; /** * @psalm-var ?non-empty-string */ private readonly ?string $pharExtensionDirectory; /** * @psalm-var list}> */ private readonly array $extensionBootstrappers; private readonly bool $backupGlobals; private readonly bool $backupStaticProperties; private readonly bool $beStrictAboutChangesToGlobalState; private readonly bool $colors; private readonly bool $processIsolation; private readonly bool $enforceTimeLimit; private readonly int $defaultTimeLimit; private readonly int $timeoutForSmallTests; private readonly int $timeoutForMediumTests; private readonly int $timeoutForLargeTests; private readonly bool $reportUselessTests; private readonly bool $strictCoverage; private readonly bool $disallowTestOutput; private readonly bool $displayDetailsOnAllIssues; private readonly bool $displayDetailsOnIncompleteTests; private readonly bool $displayDetailsOnSkippedTests; private readonly bool $displayDetailsOnTestsThatTriggerDeprecations; private readonly bool $displayDetailsOnPhpunitDeprecations; private readonly bool $displayDetailsOnTestsThatTriggerErrors; private readonly bool $displayDetailsOnTestsThatTriggerNotices; private readonly bool $displayDetailsOnTestsThatTriggerWarnings; private readonly bool $reverseDefectList; private readonly bool $requireCoverageMetadata; private readonly bool $registerMockObjectsFromTestArgumentsRecursively; private readonly bool $noProgress; private readonly bool $noResults; private readonly bool $noOutput; private readonly int $executionOrder; private readonly int $executionOrderDefects; private readonly bool $resolveDependencies; private readonly ?string $logfileTeamcity; private readonly ?string $logfileJunit; private readonly ?string $logfileTestdoxHtml; private readonly ?string $logfileTestdoxText; private readonly ?string $logEventsText; private readonly ?string $logEventsVerboseText; private readonly ?array $testsCovering; private readonly ?array $testsUsing; private readonly bool $teamCityOutput; private readonly bool $testDoxOutput; private readonly ?string $filter; private readonly ?array $groups; private readonly ?array $excludeGroups; private readonly int $randomOrderSeed; private readonly bool $includeUncoveredFiles; private readonly TestSuiteCollection $testSuite; private readonly string $includeTestSuite; private readonly string $excludeTestSuite; private readonly ?string $defaultTestSuite; /** * @psalm-var non-empty-list */ private readonly array $testSuffixes; private readonly Php $php; private readonly bool $controlGarbageCollector; private readonly int $numberOfTestsBeforeGarbageCollection; private readonly ?string $generateBaseline; private readonly bool $debug; /** * @psalm-param list $cliArguments * @psalm-param ?non-empty-string $pharExtensionDirectory * @psalm-param non-empty-list $testSuffixes * @psalm-param list}> $extensionBootstrappers */ public function __construct(array $cliArguments, ?string $configurationFile, ?string $bootstrap, bool $cacheResult, ?string $cacheDirectory, ?string $coverageCacheDirectory, Source $source, string $testResultCacheFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4j, int $coverageCrap4jThreshold, ?string $coverageHtml, int $coverageHtmlLowUpperBound, int $coverageHtmlHighLowerBound, string $coverageHtmlColorSuccessLow, string $coverageHtmlColorSuccessMedium, string $coverageHtmlColorSuccessHigh, string $coverageHtmlColorWarning, string $coverageHtmlColorDanger, ?string $coverageHtmlCustomCssFile, ?string $coveragePhp, ?string $coverageText, bool $coverageTextShowUncoveredFiles, bool $coverageTextShowOnlySummary, ?string $coverageXml, bool $pathCoverage, bool $ignoreDeprecatedCodeUnitsFromCodeCoverage, bool $disableCodeCoverageIgnore, bool $failOnAllIssues, bool $failOnDeprecation, bool $failOnPhpunitDeprecation, bool $failOnPhpunitWarning, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $doNotFailOnDeprecation, bool $doNotFailOnPhpunitDeprecation, bool $doNotFailOnPhpunitWarning, bool $doNotFailOnEmptyTestSuite, bool $doNotFailOnIncomplete, bool $doNotFailOnNotice, bool $doNotFailOnRisky, bool $doNotFailOnSkipped, bool $doNotFailOnWarning, bool $stopOnDefect, bool $stopOnDeprecation, bool $stopOnError, bool $stopOnFailure, bool $stopOnIncomplete, bool $stopOnNotice, bool $stopOnRisky, bool $stopOnSkipped, bool $stopOnWarning, bool $outputToStandardErrorStream, int|string $columns, bool $noExtensions, ?string $pharExtensionDirectory, array $extensionBootstrappers, bool $backupGlobals, bool $backupStaticProperties, bool $beStrictAboutChangesToGlobalState, bool $colors, bool $processIsolation, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, bool $reportUselessTests, bool $strictCoverage, bool $disallowTestOutput, bool $displayDetailsOnAllIssues, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnPhpunitDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, bool $registerMockObjectsFromTestArgumentsRecursively, bool $noProgress, bool $noResults, bool $noOutput, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies, ?string $logfileTeamcity, ?string $logfileJunit, ?string $logfileTestdoxHtml, ?string $logfileTestdoxText, ?string $logEventsText, ?string $logEventsVerboseText, bool $teamCityOutput, bool $testDoxOutput, ?array $testsCovering, ?array $testsUsing, ?string $filter, ?array $groups, ?array $excludeGroups, int $randomOrderSeed, bool $includeUncoveredFiles, TestSuiteCollection $testSuite, string $includeTestSuite, string $excludeTestSuite, ?string $defaultTestSuite, array $testSuffixes, Php $php, bool $controlGarbageCollector, int $numberOfTestsBeforeGarbageCollection, ?string $generateBaseline, bool $debug) { $this->cliArguments = $cliArguments; $this->configurationFile = $configurationFile; $this->bootstrap = $bootstrap; $this->cacheResult = $cacheResult; $this->cacheDirectory = $cacheDirectory; $this->coverageCacheDirectory = $coverageCacheDirectory; $this->source = $source; $this->testResultCacheFile = $testResultCacheFile; $this->coverageClover = $coverageClover; $this->coverageCobertura = $coverageCobertura; $this->coverageCrap4j = $coverageCrap4j; $this->coverageCrap4jThreshold = $coverageCrap4jThreshold; $this->coverageHtml = $coverageHtml; $this->coverageHtmlLowUpperBound = $coverageHtmlLowUpperBound; $this->coverageHtmlHighLowerBound = $coverageHtmlHighLowerBound; $this->coverageHtmlColorSuccessLow = $coverageHtmlColorSuccessLow; $this->coverageHtmlColorSuccessMedium = $coverageHtmlColorSuccessMedium; $this->coverageHtmlColorSuccessHigh = $coverageHtmlColorSuccessHigh; $this->coverageHtmlColorWarning = $coverageHtmlColorWarning; $this->coverageHtmlColorDanger = $coverageHtmlColorDanger; $this->coverageHtmlCustomCssFile = $coverageHtmlCustomCssFile; $this->coveragePhp = $coveragePhp; $this->coverageText = $coverageText; $this->coverageTextShowUncoveredFiles = $coverageTextShowUncoveredFiles; $this->coverageTextShowOnlySummary = $coverageTextShowOnlySummary; $this->coverageXml = $coverageXml; $this->pathCoverage = $pathCoverage; $this->ignoreDeprecatedCodeUnitsFromCodeCoverage = $ignoreDeprecatedCodeUnitsFromCodeCoverage; $this->disableCodeCoverageIgnore = $disableCodeCoverageIgnore; $this->failOnAllIssues = $failOnAllIssues; $this->failOnDeprecation = $failOnDeprecation; $this->failOnPhpunitDeprecation = $failOnPhpunitDeprecation; $this->failOnPhpunitWarning = $failOnPhpunitWarning; $this->failOnEmptyTestSuite = $failOnEmptyTestSuite; $this->failOnIncomplete = $failOnIncomplete; $this->failOnNotice = $failOnNotice; $this->failOnRisky = $failOnRisky; $this->failOnSkipped = $failOnSkipped; $this->failOnWarning = $failOnWarning; $this->doNotFailOnDeprecation = $doNotFailOnDeprecation; $this->doNotFailOnPhpunitDeprecation = $doNotFailOnPhpunitDeprecation; $this->doNotFailOnPhpunitWarning = $doNotFailOnPhpunitWarning; $this->doNotFailOnEmptyTestSuite = $doNotFailOnEmptyTestSuite; $this->doNotFailOnIncomplete = $doNotFailOnIncomplete; $this->doNotFailOnNotice = $doNotFailOnNotice; $this->doNotFailOnRisky = $doNotFailOnRisky; $this->doNotFailOnSkipped = $doNotFailOnSkipped; $this->doNotFailOnWarning = $doNotFailOnWarning; $this->stopOnDefect = $stopOnDefect; $this->stopOnDeprecation = $stopOnDeprecation; $this->stopOnError = $stopOnError; $this->stopOnFailure = $stopOnFailure; $this->stopOnIncomplete = $stopOnIncomplete; $this->stopOnNotice = $stopOnNotice; $this->stopOnRisky = $stopOnRisky; $this->stopOnSkipped = $stopOnSkipped; $this->stopOnWarning = $stopOnWarning; $this->outputToStandardErrorStream = $outputToStandardErrorStream; $this->columns = $columns; $this->noExtensions = $noExtensions; $this->pharExtensionDirectory = $pharExtensionDirectory; $this->extensionBootstrappers = $extensionBootstrappers; $this->backupGlobals = $backupGlobals; $this->backupStaticProperties = $backupStaticProperties; $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState; $this->colors = $colors; $this->processIsolation = $processIsolation; $this->enforceTimeLimit = $enforceTimeLimit; $this->defaultTimeLimit = $defaultTimeLimit; $this->timeoutForSmallTests = $timeoutForSmallTests; $this->timeoutForMediumTests = $timeoutForMediumTests; $this->timeoutForLargeTests = $timeoutForLargeTests; $this->reportUselessTests = $reportUselessTests; $this->strictCoverage = $strictCoverage; $this->disallowTestOutput = $disallowTestOutput; $this->displayDetailsOnAllIssues = $displayDetailsOnAllIssues; $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests; $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests; $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations; $this->displayDetailsOnPhpunitDeprecations = $displayDetailsOnPhpunitDeprecations; $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors; $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices; $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings; $this->reverseDefectList = $reverseDefectList; $this->requireCoverageMetadata = $requireCoverageMetadata; $this->registerMockObjectsFromTestArgumentsRecursively = $registerMockObjectsFromTestArgumentsRecursively; $this->noProgress = $noProgress; $this->noResults = $noResults; $this->noOutput = $noOutput; $this->executionOrder = $executionOrder; $this->executionOrderDefects = $executionOrderDefects; $this->resolveDependencies = $resolveDependencies; $this->logfileTeamcity = $logfileTeamcity; $this->logfileJunit = $logfileJunit; $this->logfileTestdoxHtml = $logfileTestdoxHtml; $this->logfileTestdoxText = $logfileTestdoxText; $this->logEventsText = $logEventsText; $this->logEventsVerboseText = $logEventsVerboseText; $this->teamCityOutput = $teamCityOutput; $this->testDoxOutput = $testDoxOutput; $this->testsCovering = $testsCovering; $this->testsUsing = $testsUsing; $this->filter = $filter; $this->groups = $groups; $this->excludeGroups = $excludeGroups; $this->randomOrderSeed = $randomOrderSeed; $this->includeUncoveredFiles = $includeUncoveredFiles; $this->testSuite = $testSuite; $this->includeTestSuite = $includeTestSuite; $this->excludeTestSuite = $excludeTestSuite; $this->defaultTestSuite = $defaultTestSuite; $this->testSuffixes = $testSuffixes; $this->php = $php; $this->controlGarbageCollector = $controlGarbageCollector; $this->numberOfTestsBeforeGarbageCollection = $numberOfTestsBeforeGarbageCollection; $this->generateBaseline = $generateBaseline; $this->debug = $debug; } /** * @psalm-assert-if-true !empty $this->cliArguments */ public function hasCliArguments(): bool { return !empty($this->cliArguments); } /** * @psalm-return list */ public function cliArguments(): array { return $this->cliArguments; } /** * @psalm-assert-if-true !empty $this->cliArguments * * @deprecated Use hasCliArguments() instead */ public function hasCliArgument(): bool { return !empty($this->cliArguments); } /** * @throws NoCliArgumentException * * @return non-empty-string * * @deprecated Use cliArguments()[0] instead */ public function cliArgument(): string { if (!$this->hasCliArguments()) { throw new NoCliArgumentException; } return $this->cliArguments[0]; } /** * @psalm-assert-if-true !null $this->configurationFile */ public function hasConfigurationFile(): bool { return $this->configurationFile !== null; } /** * @throws NoConfigurationFileException */ public function configurationFile(): string { if (!$this->hasConfigurationFile()) { throw new NoConfigurationFileException; } return $this->configurationFile; } /** * @psalm-assert-if-true !null $this->bootstrap */ public function hasBootstrap(): bool { return $this->bootstrap !== null; } /** * @throws NoBootstrapException */ public function bootstrap(): string { if (!$this->hasBootstrap()) { throw new NoBootstrapException; } return $this->bootstrap; } public function cacheResult(): bool { return $this->cacheResult; } /** * @psalm-assert-if-true !null $this->cacheDirectory */ public function hasCacheDirectory(): bool { return $this->cacheDirectory !== null; } /** * @throws NoCacheDirectoryException */ public function cacheDirectory(): string { if (!$this->hasCacheDirectory()) { throw new NoCacheDirectoryException; } return $this->cacheDirectory; } /** * @psalm-assert-if-true !null $this->coverageCacheDirectory */ public function hasCoverageCacheDirectory(): bool { return $this->coverageCacheDirectory !== null; } /** * @throws NoCoverageCacheDirectoryException */ public function coverageCacheDirectory(): string { if (!$this->hasCoverageCacheDirectory()) { throw new NoCoverageCacheDirectoryException; } return $this->coverageCacheDirectory; } public function source(): Source { return $this->source; } /** * @deprecated Use source()->restrictDeprecations() instead */ public function restrictDeprecations(): bool { return $this->source()->restrictDeprecations(); } /** * @deprecated Use source()->restrictNotices() instead */ public function restrictNotices(): bool { return $this->source()->restrictNotices(); } /** * @deprecated Use source()->restrictWarnings() instead */ public function restrictWarnings(): bool { return $this->source()->restrictWarnings(); } /** * @deprecated Use source()->notEmpty() instead */ public function hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport(): bool { return $this->source->notEmpty(); } /** * @deprecated Use source()->includeDirectories() instead */ public function coverageIncludeDirectories(): FilterDirectoryCollection { return $this->source()->includeDirectories(); } /** * @deprecated Use source()->includeFiles() instead */ public function coverageIncludeFiles(): FileCollection { return $this->source()->includeFiles(); } /** * @deprecated Use source()->excludeDirectories() instead */ public function coverageExcludeDirectories(): FilterDirectoryCollection { return $this->source()->excludeDirectories(); } /** * @deprecated Use source()->excludeFiles() instead */ public function coverageExcludeFiles(): FileCollection { return $this->source()->excludeFiles(); } public function testResultCacheFile(): string { return $this->testResultCacheFile; } public function ignoreDeprecatedCodeUnitsFromCodeCoverage(): bool { return $this->ignoreDeprecatedCodeUnitsFromCodeCoverage; } public function disableCodeCoverageIgnore(): bool { return $this->disableCodeCoverageIgnore; } public function pathCoverage(): bool { return $this->pathCoverage; } public function hasCoverageReport(): bool { return $this->hasCoverageClover() || $this->hasCoverageCobertura() || $this->hasCoverageCrap4j() || $this->hasCoverageHtml() || $this->hasCoveragePhp() || $this->hasCoverageText() || $this->hasCoverageXml(); } /** * @psalm-assert-if-true !null $this->coverageClover */ public function hasCoverageClover(): bool { return $this->coverageClover !== null; } /** * @throws CodeCoverageReportNotConfiguredException */ public function coverageClover(): string { if (!$this->hasCoverageClover()) { throw new CodeCoverageReportNotConfiguredException; } return $this->coverageClover; } /** * @psalm-assert-if-true !null $this->coverageCobertura */ public function hasCoverageCobertura(): bool { return $this->coverageCobertura !== null; } /** * @throws CodeCoverageReportNotConfiguredException */ public function coverageCobertura(): string { if (!$this->hasCoverageCobertura()) { throw new CodeCoverageReportNotConfiguredException; } return $this->coverageCobertura; } /** * @psalm-assert-if-true !null $this->coverageCrap4j */ public function hasCoverageCrap4j(): bool { return $this->coverageCrap4j !== null; } /** * @throws CodeCoverageReportNotConfiguredException */ public function coverageCrap4j(): string { if (!$this->hasCoverageCrap4j()) { throw new CodeCoverageReportNotConfiguredException; } return $this->coverageCrap4j; } public function coverageCrap4jThreshold(): int { return $this->coverageCrap4jThreshold; } /** * @psalm-assert-if-true !null $this->coverageHtml */ public function hasCoverageHtml(): bool { return $this->coverageHtml !== null; } /** * @throws CodeCoverageReportNotConfiguredException */ public function coverageHtml(): string { if (!$this->hasCoverageHtml()) { throw new CodeCoverageReportNotConfiguredException; } return $this->coverageHtml; } public function coverageHtmlLowUpperBound(): int { return $this->coverageHtmlLowUpperBound; } public function coverageHtmlHighLowerBound(): int { return $this->coverageHtmlHighLowerBound; } public function coverageHtmlColorSuccessLow(): string { return $this->coverageHtmlColorSuccessLow; } public function coverageHtmlColorSuccessMedium(): string { return $this->coverageHtmlColorSuccessMedium; } public function coverageHtmlColorSuccessHigh(): string { return $this->coverageHtmlColorSuccessHigh; } public function coverageHtmlColorWarning(): string { return $this->coverageHtmlColorWarning; } public function coverageHtmlColorDanger(): string { return $this->coverageHtmlColorDanger; } /** * @psalm-assert-if-true !null $this->coverageHtmlCustomCssFile */ public function hasCoverageHtmlCustomCssFile(): bool { return $this->coverageHtmlCustomCssFile !== null; } /** * @throws NoCustomCssFileException */ public function coverageHtmlCustomCssFile(): string { if (!$this->hasCoverageHtmlCustomCssFile()) { throw new NoCustomCssFileException; } return $this->coverageHtmlCustomCssFile; } /** * @psalm-assert-if-true !null $this->coveragePhp */ public function hasCoveragePhp(): bool { return $this->coveragePhp !== null; } /** * @throws CodeCoverageReportNotConfiguredException */ public function coveragePhp(): string { if (!$this->hasCoveragePhp()) { throw new CodeCoverageReportNotConfiguredException; } return $this->coveragePhp; } /** * @psalm-assert-if-true !null $this->coverageText */ public function hasCoverageText(): bool { return $this->coverageText !== null; } /** * @throws CodeCoverageReportNotConfiguredException */ public function coverageText(): string { if (!$this->hasCoverageText()) { throw new CodeCoverageReportNotConfiguredException; } return $this->coverageText; } public function coverageTextShowUncoveredFiles(): bool { return $this->coverageTextShowUncoveredFiles; } public function coverageTextShowOnlySummary(): bool { return $this->coverageTextShowOnlySummary; } /** * @psalm-assert-if-true !null $this->coverageXml */ public function hasCoverageXml(): bool { return $this->coverageXml !== null; } /** * @throws CodeCoverageReportNotConfiguredException */ public function coverageXml(): string { if (!$this->hasCoverageXml()) { throw new CodeCoverageReportNotConfiguredException; } return $this->coverageXml; } public function failOnAllIssues(): bool { return $this->failOnAllIssues; } public function failOnDeprecation(): bool { return $this->failOnDeprecation; } public function failOnPhpunitDeprecation(): bool { return $this->failOnPhpunitDeprecation; } public function failOnPhpunitWarning(): bool { return $this->failOnPhpunitWarning; } public function failOnEmptyTestSuite(): bool { return $this->failOnEmptyTestSuite; } public function failOnIncomplete(): bool { return $this->failOnIncomplete; } public function failOnNotice(): bool { return $this->failOnNotice; } public function failOnRisky(): bool { return $this->failOnRisky; } public function failOnSkipped(): bool { return $this->failOnSkipped; } public function failOnWarning(): bool { return $this->failOnWarning; } public function doNotFailOnDeprecation(): bool { return $this->doNotFailOnDeprecation; } public function doNotFailOnPhpunitDeprecation(): bool { return $this->doNotFailOnPhpunitDeprecation; } public function doNotFailOnPhpunitWarning(): bool { return $this->doNotFailOnPhpunitWarning; } public function doNotFailOnEmptyTestSuite(): bool { return $this->doNotFailOnEmptyTestSuite; } public function doNotFailOnIncomplete(): bool { return $this->doNotFailOnIncomplete; } public function doNotFailOnNotice(): bool { return $this->doNotFailOnNotice; } public function doNotFailOnRisky(): bool { return $this->doNotFailOnRisky; } public function doNotFailOnSkipped(): bool { return $this->doNotFailOnSkipped; } public function doNotFailOnWarning(): bool { return $this->doNotFailOnWarning; } public function stopOnDefect(): bool { return $this->stopOnDefect; } public function stopOnDeprecation(): bool { return $this->stopOnDeprecation; } public function stopOnError(): bool { return $this->stopOnError; } public function stopOnFailure(): bool { return $this->stopOnFailure; } public function stopOnIncomplete(): bool { return $this->stopOnIncomplete; } public function stopOnNotice(): bool { return $this->stopOnNotice; } public function stopOnRisky(): bool { return $this->stopOnRisky; } public function stopOnSkipped(): bool { return $this->stopOnSkipped; } public function stopOnWarning(): bool { return $this->stopOnWarning; } public function outputToStandardErrorStream(): bool { return $this->outputToStandardErrorStream; } public function columns(): int { return $this->columns; } /** * @deprecated Use noExtensions() instead */ public function loadPharExtensions(): bool { return $this->noExtensions; } public function noExtensions(): bool { return $this->noExtensions; } /** * @psalm-assert-if-true !null $this->pharExtensionDirectory */ public function hasPharExtensionDirectory(): bool { return $this->pharExtensionDirectory !== null; } /** * @throws NoPharExtensionDirectoryException * * @psalm-return non-empty-string */ public function pharExtensionDirectory(): string { if (!$this->hasPharExtensionDirectory()) { throw new NoPharExtensionDirectoryException; } return $this->pharExtensionDirectory; } /** * @psalm-return list}> */ public function extensionBootstrappers(): array { return $this->extensionBootstrappers; } public function backupGlobals(): bool { return $this->backupGlobals; } public function backupStaticProperties(): bool { return $this->backupStaticProperties; } public function beStrictAboutChangesToGlobalState(): bool { return $this->beStrictAboutChangesToGlobalState; } public function colors(): bool { return $this->colors; } public function processIsolation(): bool { return $this->processIsolation; } public function enforceTimeLimit(): bool { return $this->enforceTimeLimit; } public function defaultTimeLimit(): int { return $this->defaultTimeLimit; } public function timeoutForSmallTests(): int { return $this->timeoutForSmallTests; } public function timeoutForMediumTests(): int { return $this->timeoutForMediumTests; } public function timeoutForLargeTests(): int { return $this->timeoutForLargeTests; } public function reportUselessTests(): bool { return $this->reportUselessTests; } public function strictCoverage(): bool { return $this->strictCoverage; } public function disallowTestOutput(): bool { return $this->disallowTestOutput; } public function displayDetailsOnAllIssues(): bool { return $this->displayDetailsOnAllIssues; } public function displayDetailsOnIncompleteTests(): bool { return $this->displayDetailsOnIncompleteTests; } public function displayDetailsOnSkippedTests(): bool { return $this->displayDetailsOnSkippedTests; } public function displayDetailsOnTestsThatTriggerDeprecations(): bool { return $this->displayDetailsOnTestsThatTriggerDeprecations; } public function displayDetailsOnPhpunitDeprecations(): bool { return $this->displayDetailsOnPhpunitDeprecations; } public function displayDetailsOnTestsThatTriggerErrors(): bool { return $this->displayDetailsOnTestsThatTriggerErrors; } public function displayDetailsOnTestsThatTriggerNotices(): bool { return $this->displayDetailsOnTestsThatTriggerNotices; } public function displayDetailsOnTestsThatTriggerWarnings(): bool { return $this->displayDetailsOnTestsThatTriggerWarnings; } public function reverseDefectList(): bool { return $this->reverseDefectList; } public function requireCoverageMetadata(): bool { return $this->requireCoverageMetadata; } /** * @deprecated */ public function registerMockObjectsFromTestArgumentsRecursively(): bool { return $this->registerMockObjectsFromTestArgumentsRecursively; } public function noProgress(): bool { return $this->noProgress; } public function noResults(): bool { return $this->noResults; } public function noOutput(): bool { return $this->noOutput; } public function executionOrder(): int { return $this->executionOrder; } public function executionOrderDefects(): int { return $this->executionOrderDefects; } public function resolveDependencies(): bool { return $this->resolveDependencies; } /** * @psalm-assert-if-true !null $this->logfileTeamcity */ public function hasLogfileTeamcity(): bool { return $this->logfileTeamcity !== null; } /** * @throws LoggingNotConfiguredException */ public function logfileTeamcity(): string { if (!$this->hasLogfileTeamcity()) { throw new LoggingNotConfiguredException; } return $this->logfileTeamcity; } /** * @psalm-assert-if-true !null $this->logfileJunit */ public function hasLogfileJunit(): bool { return $this->logfileJunit !== null; } /** * @throws LoggingNotConfiguredException */ public function logfileJunit(): string { if (!$this->hasLogfileJunit()) { throw new LoggingNotConfiguredException; } return $this->logfileJunit; } /** * @psalm-assert-if-true !null $this->logfileTestdoxHtml */ public function hasLogfileTestdoxHtml(): bool { return $this->logfileTestdoxHtml !== null; } /** * @throws LoggingNotConfiguredException */ public function logfileTestdoxHtml(): string { if (!$this->hasLogfileTestdoxHtml()) { throw new LoggingNotConfiguredException; } return $this->logfileTestdoxHtml; } /** * @psalm-assert-if-true !null $this->logfileTestdoxText */ public function hasLogfileTestdoxText(): bool { return $this->logfileTestdoxText !== null; } /** * @throws LoggingNotConfiguredException */ public function logfileTestdoxText(): string { if (!$this->hasLogfileTestdoxText()) { throw new LoggingNotConfiguredException; } return $this->logfileTestdoxText; } /** * @psalm-assert-if-true !null $this->logEventsText */ public function hasLogEventsText(): bool { return $this->logEventsText !== null; } /** * @throws LoggingNotConfiguredException */ public function logEventsText(): string { if (!$this->hasLogEventsText()) { throw new LoggingNotConfiguredException; } return $this->logEventsText; } /** * @psalm-assert-if-true !null $this->logEventsVerboseText */ public function hasLogEventsVerboseText(): bool { return $this->logEventsVerboseText !== null; } /** * @throws LoggingNotConfiguredException */ public function logEventsVerboseText(): string { if (!$this->hasLogEventsVerboseText()) { throw new LoggingNotConfiguredException; } return $this->logEventsVerboseText; } public function outputIsTeamCity(): bool { return $this->teamCityOutput; } public function outputIsTestDox(): bool { return $this->testDoxOutput; } /** * @psalm-assert-if-true !empty $this->testsCovering */ public function hasTestsCovering(): bool { return !empty($this->testsCovering); } /** * @throws FilterNotConfiguredException * * @psalm-return list */ public function testsCovering(): array { if (!$this->hasTestsCovering()) { throw new FilterNotConfiguredException; } return $this->testsCovering; } /** * @psalm-assert-if-true !empty $this->testsUsing */ public function hasTestsUsing(): bool { return !empty($this->testsUsing); } /** * @throws FilterNotConfiguredException * * @psalm-return list */ public function testsUsing(): array { if (!$this->hasTestsUsing()) { throw new FilterNotConfiguredException; } return $this->testsUsing; } /** * @psalm-assert-if-true !null $this->filter */ public function hasFilter(): bool { return $this->filter !== null; } /** * @throws FilterNotConfiguredException */ public function filter(): string { if (!$this->hasFilter()) { throw new FilterNotConfiguredException; } return $this->filter; } /** * @psalm-assert-if-true !empty $this->groups */ public function hasGroups(): bool { return !empty($this->groups); } /** * @throws FilterNotConfiguredException */ public function groups(): array { if (!$this->hasGroups()) { throw new FilterNotConfiguredException; } return $this->groups; } /** * @psalm-assert-if-true !empty $this->excludeGroups */ public function hasExcludeGroups(): bool { return !empty($this->excludeGroups); } /** * @throws FilterNotConfiguredException */ public function excludeGroups(): array { if (!$this->hasExcludeGroups()) { throw new FilterNotConfiguredException; } return $this->excludeGroups; } public function randomOrderSeed(): int { return $this->randomOrderSeed; } public function includeUncoveredFiles(): bool { return $this->includeUncoveredFiles; } public function testSuite(): TestSuiteCollection { return $this->testSuite; } public function includeTestSuite(): string { return $this->includeTestSuite; } public function excludeTestSuite(): string { return $this->excludeTestSuite; } /** * @psalm-assert-if-true !null $this->defaultTestSuite */ public function hasDefaultTestSuite(): bool { return $this->defaultTestSuite !== null; } /** * @throws NoDefaultTestSuiteException */ public function defaultTestSuite(): string { if (!$this->hasDefaultTestSuite()) { throw new NoDefaultTestSuiteException; } return $this->defaultTestSuite; } /** * @psalm-return non-empty-list */ public function testSuffixes(): array { return $this->testSuffixes; } public function php(): Php { return $this->php; } public function controlGarbageCollector(): bool { return $this->controlGarbageCollector; } public function numberOfTestsBeforeGarbageCollection(): int { return $this->numberOfTestsBeforeGarbageCollection; } /** * @psalm-assert-if-true !null $this->generateBaseline */ public function hasGenerateBaseline(): bool { return $this->generateBaseline !== null; } /** * @throws NoBaselineException */ public function generateBaseline(): string { if (!$this->hasGenerateBaseline()) { throw new NoBaselineException; } return $this->generateBaseline; } public function debug(): bool { return $this->debug; } } PKYg3]xConfiguration/Builder.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use PHPUnit\TextUI\CliArguments\Builder as CliConfigurationBuilder; use PHPUnit\TextUI\CliArguments\Exception as CliConfigurationException; use PHPUnit\TextUI\CliArguments\XmlConfigurationFileFinder; use PHPUnit\TextUI\XmlConfiguration\DefaultConfiguration; use PHPUnit\TextUI\XmlConfiguration\Exception as XmlConfigurationException; use PHPUnit\TextUI\XmlConfiguration\Loader; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @codeCoverageIgnore */ final class Builder { /** * @throws ConfigurationCannotBeBuiltException */ public function build(array $argv): Configuration { try { $cliConfiguration = (new CliConfigurationBuilder)->fromParameters($argv); $configurationFile = (new XmlConfigurationFileFinder)->find($cliConfiguration); $xmlConfiguration = DefaultConfiguration::create(); if ($configurationFile !== false) { $xmlConfiguration = (new Loader)->load($configurationFile); } return Registry::init( $cliConfiguration, $xmlConfiguration, ); } catch (CliConfigurationException|XmlConfigurationException $e) { throw new ConfigurationCannotBeBuiltException( $e->getMessage(), $e->getCode(), $e, ); } } } PKYg3]5>rrConfiguration/Xml/Loader.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use const DIRECTORY_SEPARATOR; use const PHP_VERSION; use function assert; use function defined; use function dirname; use function explode; use function is_numeric; use function preg_match; use function realpath; use function str_contains; use function str_starts_with; use function strlen; use function strtolower; use function substr; use function trim; use DOMDocument; use DOMElement; use DOMNode; use DOMXPath; use PHPUnit\Runner\TestSuiteSorter; use PHPUnit\Runner\Version; use PHPUnit\TextUI\Configuration\Configuration; use PHPUnit\TextUI\Configuration\Constant; use PHPUnit\TextUI\Configuration\ConstantCollection; use PHPUnit\TextUI\Configuration\Directory; use PHPUnit\TextUI\Configuration\DirectoryCollection; use PHPUnit\TextUI\Configuration\ExtensionBootstrap; use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection; use PHPUnit\TextUI\Configuration\File; use PHPUnit\TextUI\Configuration\FileCollection; use PHPUnit\TextUI\Configuration\FilterDirectory; use PHPUnit\TextUI\Configuration\FilterDirectoryCollection; use PHPUnit\TextUI\Configuration\Group; use PHPUnit\TextUI\Configuration\GroupCollection; use PHPUnit\TextUI\Configuration\IniSetting; use PHPUnit\TextUI\Configuration\IniSettingCollection; use PHPUnit\TextUI\Configuration\Php; use PHPUnit\TextUI\Configuration\Source; use PHPUnit\TextUI\Configuration\TestDirectory; use PHPUnit\TextUI\Configuration\TestDirectoryCollection; use PHPUnit\TextUI\Configuration\TestFile; use PHPUnit\TextUI\Configuration\TestFileCollection; use PHPUnit\TextUI\Configuration\TestSuite as TestSuiteConfiguration; use PHPUnit\TextUI\Configuration\TestSuiteCollection; use PHPUnit\TextUI\Configuration\Variable; use PHPUnit\TextUI\Configuration\VariableCollection; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Clover; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Cobertura; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Crap4j; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Html as CodeCoverageHtml; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Php as CodeCoveragePhp; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Text as CodeCoverageText; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Xml as CodeCoverageXml; use PHPUnit\TextUI\XmlConfiguration\Logging\Junit; use PHPUnit\TextUI\XmlConfiguration\Logging\Logging; use PHPUnit\TextUI\XmlConfiguration\Logging\TeamCity; use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Html as TestDoxHtml; use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Text as TestDoxText; use PHPUnit\Util\VersionComparisonOperator; use PHPUnit\Util\Xml\Loader as XmlLoader; use PHPUnit\Util\Xml\XmlException; use SebastianBergmann\CodeCoverage\Report\Html\Colors; use SebastianBergmann\CodeCoverage\Report\Thresholds; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Loader { /** * @throws Exception */ public function load(string $filename): LoadedFromFileConfiguration { try { $document = (new XmlLoader)->loadFile($filename); } catch (XmlException $e) { throw new Exception( $e->getMessage(), $e->getCode(), $e, ); } $xpath = new DOMXPath($document); try { $xsdFilename = (new SchemaFinder)->find(Version::series()); } catch (CannotFindSchemaException $e) { throw new Exception( $e->getMessage(), $e->getCode(), $e, ); } $configurationFileRealpath = realpath($filename); return new LoadedFromFileConfiguration( $configurationFileRealpath, (new Validator)->validate($document, $xsdFilename), $this->extensions($xpath), $this->source($configurationFileRealpath, $xpath), $this->codeCoverage($configurationFileRealpath, $xpath), $this->groups($xpath), $this->logging($configurationFileRealpath, $xpath), $this->php($configurationFileRealpath, $xpath), $this->phpunit($configurationFileRealpath, $document), $this->testSuite($configurationFileRealpath, $xpath), ); } private function logging(string $filename, DOMXPath $xpath): Logging { $junit = null; $element = $this->element($xpath, 'logging/junit'); if ($element) { $junit = new Junit( new File( $this->toAbsolutePath( $filename, (string) $this->getStringAttribute($element, 'outputFile'), ), ), ); } $teamCity = null; $element = $this->element($xpath, 'logging/teamcity'); if ($element) { $teamCity = new TeamCity( new File( $this->toAbsolutePath( $filename, (string) $this->getStringAttribute($element, 'outputFile'), ), ), ); } $testDoxHtml = null; $element = $this->element($xpath, 'logging/testdoxHtml'); if ($element) { $testDoxHtml = new TestDoxHtml( new File( $this->toAbsolutePath( $filename, (string) $this->getStringAttribute($element, 'outputFile'), ), ), ); } $testDoxText = null; $element = $this->element($xpath, 'logging/testdoxText'); if ($element) { $testDoxText = new TestDoxText( new File( $this->toAbsolutePath( $filename, (string) $this->getStringAttribute($element, 'outputFile'), ), ), ); } return new Logging( $junit, $teamCity, $testDoxHtml, $testDoxText, ); } private function extensions(DOMXPath $xpath): ExtensionBootstrapCollection { $extensionBootstrappers = []; foreach ($xpath->query('extensions/bootstrap') as $bootstrap) { assert($bootstrap instanceof DOMElement); $parameters = []; foreach ($xpath->query('parameter', $bootstrap) as $parameter) { assert($parameter instanceof DOMElement); $parameters[$parameter->getAttribute('name')] = $parameter->getAttribute('value'); } $extensionBootstrappers[] = new ExtensionBootstrap( $bootstrap->getAttribute('class'), $parameters, ); } return ExtensionBootstrapCollection::fromArray($extensionBootstrappers); } /** * @psalm-return non-empty-string */ private function toAbsolutePath(string $filename, string $path): string { $path = trim($path); if (str_starts_with($path, '/')) { return $path; } // Matches the following on Windows: // - \\NetworkComputer\Path // - \\.\D: // - \\.\c: // - C:\Windows // - C:\windows // - C:/windows // - c:/windows if (defined('PHP_WINDOWS_VERSION_BUILD') && !empty($path) && ($path[0] === '\\' || (strlen($path) >= 3 && preg_match('#^[A-Z]:[/\\\]#i', substr($path, 0, 3))))) { return $path; } if (str_contains($path, '://')) { return $path; } return dirname($filename) . DIRECTORY_SEPARATOR . $path; } private function source(string $filename, DOMXPath $xpath): Source { $baseline = null; $restrictDeprecations = false; $restrictNotices = false; $restrictWarnings = false; $ignoreSuppressionOfDeprecations = false; $ignoreSuppressionOfPhpDeprecations = false; $ignoreSuppressionOfErrors = false; $ignoreSuppressionOfNotices = false; $ignoreSuppressionOfPhpNotices = false; $ignoreSuppressionOfWarnings = false; $ignoreSuppressionOfPhpWarnings = false; $element = $this->element($xpath, 'source'); if ($element) { $baseline = $this->getStringAttribute($element, 'baseline'); if ($baseline !== null) { $baseline = $this->toAbsolutePath($filename, $baseline); } $restrictDeprecations = $this->getBooleanAttribute($element, 'restrictDeprecations', false); $restrictNotices = $this->getBooleanAttribute($element, 'restrictNotices', false); $restrictWarnings = $this->getBooleanAttribute($element, 'restrictWarnings', false); $ignoreSuppressionOfDeprecations = $this->getBooleanAttribute($element, 'ignoreSuppressionOfDeprecations', false); $ignoreSuppressionOfPhpDeprecations = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpDeprecations', false); $ignoreSuppressionOfErrors = $this->getBooleanAttribute($element, 'ignoreSuppressionOfErrors', false); $ignoreSuppressionOfNotices = $this->getBooleanAttribute($element, 'ignoreSuppressionOfNotices', false); $ignoreSuppressionOfPhpNotices = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpNotices', false); $ignoreSuppressionOfWarnings = $this->getBooleanAttribute($element, 'ignoreSuppressionOfWarnings', false); $ignoreSuppressionOfPhpWarnings = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpWarnings', false); } return new Source( $baseline, false, $this->readFilterDirectories($filename, $xpath, 'source/include/directory'), $this->readFilterFiles($filename, $xpath, 'source/include/file'), $this->readFilterDirectories($filename, $xpath, 'source/exclude/directory'), $this->readFilterFiles($filename, $xpath, 'source/exclude/file'), $restrictDeprecations, $restrictNotices, $restrictWarnings, $ignoreSuppressionOfDeprecations, $ignoreSuppressionOfPhpDeprecations, $ignoreSuppressionOfErrors, $ignoreSuppressionOfNotices, $ignoreSuppressionOfPhpNotices, $ignoreSuppressionOfWarnings, $ignoreSuppressionOfPhpWarnings, ); } private function codeCoverage(string $filename, DOMXPath $xpath): CodeCoverage { $cacheDirectory = null; $pathCoverage = false; $includeUncoveredFiles = true; $ignoreDeprecatedCodeUnits = false; $disableCodeCoverageIgnore = false; $element = $this->element($xpath, 'coverage'); if ($element) { $cacheDirectory = $this->getStringAttribute($element, 'cacheDirectory'); if ($cacheDirectory !== null) { $cacheDirectory = new Directory( $this->toAbsolutePath($filename, $cacheDirectory), ); } $pathCoverage = $this->getBooleanAttribute( $element, 'pathCoverage', false, ); $includeUncoveredFiles = $this->getBooleanAttribute( $element, 'includeUncoveredFiles', true, ); $ignoreDeprecatedCodeUnits = $this->getBooleanAttribute( $element, 'ignoreDeprecatedCodeUnits', false, ); $disableCodeCoverageIgnore = $this->getBooleanAttribute( $element, 'disableCodeCoverageIgnore', false, ); } $clover = null; $element = $this->element($xpath, 'coverage/report/clover'); if ($element) { $clover = new Clover( new File( $this->toAbsolutePath( $filename, (string) $this->getStringAttribute($element, 'outputFile'), ), ), ); } $cobertura = null; $element = $this->element($xpath, 'coverage/report/cobertura'); if ($element) { $cobertura = new Cobertura( new File( $this->toAbsolutePath( $filename, (string) $this->getStringAttribute($element, 'outputFile'), ), ), ); } $crap4j = null; $element = $this->element($xpath, 'coverage/report/crap4j'); if ($element) { $crap4j = new Crap4j( new File( $this->toAbsolutePath( $filename, (string) $this->getStringAttribute($element, 'outputFile'), ), ), $this->getIntegerAttribute($element, 'threshold', 30), ); } $html = null; $element = $this->element($xpath, 'coverage/report/html'); if ($element) { $defaultColors = Colors::default(); $defaultThresholds = Thresholds::default(); $html = new CodeCoverageHtml( new Directory( $this->toAbsolutePath( $filename, (string) $this->getStringAttribute($element, 'outputDirectory'), ), ), $this->getIntegerAttribute($element, 'lowUpperBound', $defaultThresholds->lowUpperBound()), $this->getIntegerAttribute($element, 'highLowerBound', $defaultThresholds->highLowerBound()), $this->getStringAttributeWithDefault($element, 'colorSuccessLow', $defaultColors->successLow()), $this->getStringAttributeWithDefault($element, 'colorSuccessMedium', $defaultColors->successMedium()), $this->getStringAttributeWithDefault($element, 'colorSuccessHigh', $defaultColors->successHigh()), $this->getStringAttributeWithDefault($element, 'colorWarning', $defaultColors->warning()), $this->getStringAttributeWithDefault($element, 'colorDanger', $defaultColors->danger()), $this->getStringAttribute($element, 'customCssFile'), ); } $php = null; $element = $this->element($xpath, 'coverage/report/php'); if ($element) { $php = new CodeCoveragePhp( new File( $this->toAbsolutePath( $filename, (string) $this->getStringAttribute($element, 'outputFile'), ), ), ); } $text = null; $element = $this->element($xpath, 'coverage/report/text'); if ($element) { $text = new CodeCoverageText( new File( $this->toAbsolutePath( $filename, (string) $this->getStringAttribute($element, 'outputFile'), ), ), $this->getBooleanAttribute($element, 'showUncoveredFiles', false), $this->getBooleanAttribute($element, 'showOnlySummary', false), ); } $xml = null; $element = $this->element($xpath, 'coverage/report/xml'); if ($element) { $xml = new CodeCoverageXml( new Directory( $this->toAbsolutePath( $filename, (string) $this->getStringAttribute($element, 'outputDirectory'), ), ), ); } return new CodeCoverage( $cacheDirectory, $this->readFilterDirectories($filename, $xpath, 'coverage/include/directory'), $this->readFilterFiles($filename, $xpath, 'coverage/include/file'), $this->readFilterDirectories($filename, $xpath, 'coverage/exclude/directory'), $this->readFilterFiles($filename, $xpath, 'coverage/exclude/file'), $pathCoverage, $includeUncoveredFiles, $ignoreDeprecatedCodeUnits, $disableCodeCoverageIgnore, $clover, $cobertura, $crap4j, $html, $php, $text, $xml, ); } private function getBoolean(string $value, bool $default): bool { if (strtolower($value) === 'false') { return false; } if (strtolower($value) === 'true') { return true; } return $default; } private function getValue(string $value): bool|string { if (strtolower($value) === 'false') { return false; } if (strtolower($value) === 'true') { return true; } return $value; } private function readFilterDirectories(string $filename, DOMXPath $xpath, string $query): FilterDirectoryCollection { $directories = []; foreach ($xpath->query($query) as $directoryNode) { assert($directoryNode instanceof DOMElement); $directoryPath = $directoryNode->textContent; if (!$directoryPath) { continue; } $directories[] = new FilterDirectory( $this->toAbsolutePath($filename, $directoryPath), $directoryNode->hasAttribute('prefix') ? $directoryNode->getAttribute('prefix') : '', $directoryNode->hasAttribute('suffix') ? $directoryNode->getAttribute('suffix') : '.php', ); } return FilterDirectoryCollection::fromArray($directories); } private function readFilterFiles(string $filename, DOMXPath $xpath, string $query): FileCollection { $files = []; foreach ($xpath->query($query) as $file) { assert($file instanceof DOMNode); $filePath = $file->textContent; if ($filePath) { $files[] = new File($this->toAbsolutePath($filename, $filePath)); } } return FileCollection::fromArray($files); } private function groups(DOMXPath $xpath): Groups { $include = []; $exclude = []; foreach ($xpath->query('groups/include/group') as $group) { assert($group instanceof DOMNode); $include[] = new Group($group->textContent); } foreach ($xpath->query('groups/exclude/group') as $group) { assert($group instanceof DOMNode); $exclude[] = new Group($group->textContent); } return new Groups( GroupCollection::fromArray($include), GroupCollection::fromArray($exclude), ); } private function getBooleanAttribute(DOMElement $element, string $attribute, bool $default): bool { if (!$element->hasAttribute($attribute)) { return $default; } return $this->getBoolean( $element->getAttribute($attribute), false, ); } private function getIntegerAttribute(DOMElement $element, string $attribute, int $default): int { if (!$element->hasAttribute($attribute)) { return $default; } return $this->getInteger( $element->getAttribute($attribute), $default, ); } private function getStringAttribute(DOMElement $element, string $attribute): ?string { if (!$element->hasAttribute($attribute)) { return null; } return $element->getAttribute($attribute); } private function getStringAttributeWithDefault(DOMElement $element, string $attribute, string $default): string { if (!$element->hasAttribute($attribute)) { return $default; } return $element->getAttribute($attribute); } private function getInteger(string $value, int $default): int { if (is_numeric($value)) { return (int) $value; } return $default; } private function php(string $filename, DOMXPath $xpath): Php { $includePaths = []; foreach ($xpath->query('php/includePath') as $includePath) { assert($includePath instanceof DOMNode); $path = $includePath->textContent; if ($path) { $includePaths[] = new Directory($this->toAbsolutePath($filename, $path)); } } $iniSettings = []; foreach ($xpath->query('php/ini') as $ini) { assert($ini instanceof DOMElement); $iniSettings[] = new IniSetting( $ini->getAttribute('name'), $ini->getAttribute('value'), ); } $constants = []; foreach ($xpath->query('php/const') as $const) { assert($const instanceof DOMElement); $value = $const->getAttribute('value'); $constants[] = new Constant( $const->getAttribute('name'), $this->getValue($value), ); } $variables = [ 'var' => [], 'env' => [], 'post' => [], 'get' => [], 'cookie' => [], 'server' => [], 'files' => [], 'request' => [], ]; foreach (['var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request'] as $array) { foreach ($xpath->query('php/' . $array) as $var) { assert($var instanceof DOMElement); $name = $var->getAttribute('name'); $value = $var->getAttribute('value'); $force = false; $verbatim = false; if ($var->hasAttribute('force')) { $force = $this->getBoolean($var->getAttribute('force'), false); } if ($var->hasAttribute('verbatim')) { $verbatim = $this->getBoolean($var->getAttribute('verbatim'), false); } if (!$verbatim) { $value = $this->getValue($value); } $variables[$array][] = new Variable($name, $value, $force); } } return new Php( DirectoryCollection::fromArray($includePaths), IniSettingCollection::fromArray($iniSettings), ConstantCollection::fromArray($constants), VariableCollection::fromArray($variables['var']), VariableCollection::fromArray($variables['env']), VariableCollection::fromArray($variables['post']), VariableCollection::fromArray($variables['get']), VariableCollection::fromArray($variables['cookie']), VariableCollection::fromArray($variables['server']), VariableCollection::fromArray($variables['files']), VariableCollection::fromArray($variables['request']), ); } private function phpunit(string $filename, DOMDocument $document): PHPUnit { $executionOrder = TestSuiteSorter::ORDER_DEFAULT; $defectsFirst = false; $resolveDependencies = $this->getBooleanAttribute($document->documentElement, 'resolveDependencies', true); if ($document->documentElement->hasAttribute('executionOrder')) { foreach (explode(',', $document->documentElement->getAttribute('executionOrder')) as $order) { switch ($order) { case 'default': $executionOrder = TestSuiteSorter::ORDER_DEFAULT; $defectsFirst = false; $resolveDependencies = true; break; case 'depends': $resolveDependencies = true; break; case 'no-depends': $resolveDependencies = false; break; case 'defects': $defectsFirst = true; break; case 'duration': $executionOrder = TestSuiteSorter::ORDER_DURATION; break; case 'random': $executionOrder = TestSuiteSorter::ORDER_RANDOMIZED; break; case 'reverse': $executionOrder = TestSuiteSorter::ORDER_REVERSED; break; case 'size': $executionOrder = TestSuiteSorter::ORDER_SIZE; break; } } } $cacheDirectory = $this->getStringAttribute($document->documentElement, 'cacheDirectory'); if ($cacheDirectory !== null) { $cacheDirectory = $this->toAbsolutePath($filename, $cacheDirectory); } $cacheResultFile = $this->getStringAttribute($document->documentElement, 'cacheResultFile'); if ($cacheResultFile !== null) { $cacheResultFile = $this->toAbsolutePath($filename, $cacheResultFile); } $bootstrap = $this->getStringAttribute($document->documentElement, 'bootstrap'); if ($bootstrap !== null) { $bootstrap = $this->toAbsolutePath($filename, $bootstrap); } $extensionsDirectory = $this->getStringAttribute($document->documentElement, 'extensionsDirectory'); if ($extensionsDirectory !== null) { $extensionsDirectory = $this->toAbsolutePath($filename, $extensionsDirectory); } $backupStaticProperties = false; if ($document->documentElement->hasAttribute('backupStaticProperties')) { $backupStaticProperties = $this->getBooleanAttribute($document->documentElement, 'backupStaticProperties', false); } elseif ($document->documentElement->hasAttribute('backupStaticAttributes')) { $backupStaticProperties = $this->getBooleanAttribute($document->documentElement, 'backupStaticAttributes', false); } $requireCoverageMetadata = false; if ($document->documentElement->hasAttribute('requireCoverageMetadata')) { $requireCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'requireCoverageMetadata', false); } elseif ($document->documentElement->hasAttribute('forceCoversAnnotation')) { $requireCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'forceCoversAnnotation', false); } $beStrictAboutCoverageMetadata = false; if ($document->documentElement->hasAttribute('beStrictAboutCoverageMetadata')) { $beStrictAboutCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'beStrictAboutCoverageMetadata', false); } elseif ($document->documentElement->hasAttribute('forceCoversAnnotation')) { $beStrictAboutCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'beStrictAboutCoversAnnotation', false); } return new PHPUnit( $cacheDirectory, $this->getBooleanAttribute($document->documentElement, 'cacheResult', true), $cacheResultFile, $this->getColumns($document), $this->getColors($document), $this->getBooleanAttribute($document->documentElement, 'stderr', false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnAllIssues', false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnIncompleteTests', false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnSkippedTests', false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerDeprecations', false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnPhpunitDeprecations', false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerErrors', false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerNotices', false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerWarnings', false), $this->getBooleanAttribute($document->documentElement, 'reverseDefectList', false), $requireCoverageMetadata, $bootstrap, $this->getBooleanAttribute($document->documentElement, 'processIsolation', false), $this->getBooleanAttribute($document->documentElement, 'failOnAllIssues', false), $this->getBooleanAttribute($document->documentElement, 'failOnDeprecation', false), $this->getBooleanAttribute($document->documentElement, 'failOnPhpunitDeprecation', false), $this->getBooleanAttribute($document->documentElement, 'failOnPhpunitWarning', true), $this->getBooleanAttribute($document->documentElement, 'failOnEmptyTestSuite', false), $this->getBooleanAttribute($document->documentElement, 'failOnIncomplete', false), $this->getBooleanAttribute($document->documentElement, 'failOnNotice', false), $this->getBooleanAttribute($document->documentElement, 'failOnRisky', false), $this->getBooleanAttribute($document->documentElement, 'failOnSkipped', false), $this->getBooleanAttribute($document->documentElement, 'failOnWarning', false), $this->getBooleanAttribute($document->documentElement, 'stopOnDefect', false), $this->getBooleanAttribute($document->documentElement, 'stopOnDeprecation', false), $this->getBooleanAttribute($document->documentElement, 'stopOnError', false), $this->getBooleanAttribute($document->documentElement, 'stopOnFailure', false), $this->getBooleanAttribute($document->documentElement, 'stopOnIncomplete', false), $this->getBooleanAttribute($document->documentElement, 'stopOnNotice', false), $this->getBooleanAttribute($document->documentElement, 'stopOnRisky', false), $this->getBooleanAttribute($document->documentElement, 'stopOnSkipped', false), $this->getBooleanAttribute($document->documentElement, 'stopOnWarning', false), $extensionsDirectory, $this->getBooleanAttribute($document->documentElement, 'beStrictAboutChangesToGlobalState', false), $this->getBooleanAttribute($document->documentElement, 'beStrictAboutOutputDuringTests', false), $this->getBooleanAttribute($document->documentElement, 'beStrictAboutTestsThatDoNotTestAnything', true), $beStrictAboutCoverageMetadata, $this->getBooleanAttribute($document->documentElement, 'enforceTimeLimit', false), $this->getIntegerAttribute($document->documentElement, 'defaultTimeLimit', 1), $this->getIntegerAttribute($document->documentElement, 'timeoutForSmallTests', 1), $this->getIntegerAttribute($document->documentElement, 'timeoutForMediumTests', 10), $this->getIntegerAttribute($document->documentElement, 'timeoutForLargeTests', 60), $this->getStringAttribute($document->documentElement, 'defaultTestSuite'), $executionOrder, $resolveDependencies, $defectsFirst, $this->getBooleanAttribute($document->documentElement, 'backupGlobals', false), $backupStaticProperties, $this->getBooleanAttribute($document->documentElement, 'registerMockObjectsFromTestArgumentsRecursively', false), $this->getBooleanAttribute($document->documentElement, 'testdox', false), $this->getBooleanAttribute($document->documentElement, 'controlGarbageCollector', false), $this->getIntegerAttribute($document->documentElement, 'numberOfTestsBeforeGarbageCollection', 100), ); } private function getColors(DOMDocument $document): string { $colors = Configuration::COLOR_DEFAULT; if ($document->documentElement->hasAttribute('colors')) { /* only allow boolean for compatibility with previous versions 'always' only allowed from command line */ if ($this->getBoolean($document->documentElement->getAttribute('colors'), false)) { $colors = Configuration::COLOR_AUTO; } else { $colors = Configuration::COLOR_NEVER; } } return $colors; } private function getColumns(DOMDocument $document): int|string { $columns = 80; if ($document->documentElement->hasAttribute('columns')) { $columns = $document->documentElement->getAttribute('columns'); if ($columns !== 'max') { $columns = $this->getInteger($columns, 80); } } return $columns; } private function testSuite(string $filename, DOMXPath $xpath): TestSuiteCollection { $testSuites = []; foreach ($this->getTestSuiteElements($xpath) as $element) { $exclude = []; foreach ($element->getElementsByTagName('exclude') as $excludeNode) { $excludeFile = $excludeNode->textContent; if ($excludeFile) { $exclude[] = new File($this->toAbsolutePath($filename, $excludeFile)); } } $directories = []; foreach ($element->getElementsByTagName('directory') as $directoryNode) { assert($directoryNode instanceof DOMElement); $directory = $directoryNode->textContent; if (empty($directory)) { continue; } $prefix = ''; if ($directoryNode->hasAttribute('prefix')) { $prefix = $directoryNode->getAttribute('prefix'); } $suffix = 'Test.php'; if ($directoryNode->hasAttribute('suffix')) { $suffix = $directoryNode->getAttribute('suffix'); } $phpVersion = PHP_VERSION; if ($directoryNode->hasAttribute('phpVersion')) { $phpVersion = $directoryNode->getAttribute('phpVersion'); } $phpVersionOperator = new VersionComparisonOperator('>='); if ($directoryNode->hasAttribute('phpVersionOperator')) { $phpVersionOperator = new VersionComparisonOperator($directoryNode->getAttribute('phpVersionOperator')); } $directories[] = new TestDirectory( $this->toAbsolutePath($filename, $directory), $prefix, $suffix, $phpVersion, $phpVersionOperator, ); } $files = []; foreach ($element->getElementsByTagName('file') as $fileNode) { assert($fileNode instanceof DOMElement); $file = $fileNode->textContent; if (empty($file)) { continue; } $phpVersion = PHP_VERSION; if ($fileNode->hasAttribute('phpVersion')) { $phpVersion = $fileNode->getAttribute('phpVersion'); } $phpVersionOperator = new VersionComparisonOperator('>='); if ($fileNode->hasAttribute('phpVersionOperator')) { $phpVersionOperator = new VersionComparisonOperator($fileNode->getAttribute('phpVersionOperator')); } $files[] = new TestFile( $this->toAbsolutePath($filename, $file), $phpVersion, $phpVersionOperator, ); } $name = $element->getAttribute('name'); assert(!empty($name)); $testSuites[] = new TestSuiteConfiguration( $name, TestDirectoryCollection::fromArray($directories), TestFileCollection::fromArray($files), FileCollection::fromArray($exclude), ); } return TestSuiteCollection::fromArray($testSuites); } /** * @psalm-return list */ private function getTestSuiteElements(DOMXPath $xpath): array { $elements = []; $testSuiteNodes = $xpath->query('testsuites/testsuite'); if ($testSuiteNodes->length === 0) { $testSuiteNodes = $xpath->query('testsuite'); } if ($testSuiteNodes->length === 1) { $element = $testSuiteNodes->item(0); assert($element instanceof DOMElement); $elements[] = $element; } else { foreach ($testSuiteNodes as $testSuiteNode) { assert($testSuiteNode instanceof DOMElement); $elements[] = $testSuiteNode; } } return $elements; } private function element(DOMXPath $xpath, string $element): ?DOMElement { $nodes = $xpath->query($element); if ($nodes->length === 1) { $node = $nodes->item(0); assert($node instanceof DOMElement); return $node; } return null; } } PKYg3]4&|"Configuration/Xml/SchemaFinder.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use function defined; use function is_file; use function rsort; use function sprintf; use DirectoryIterator; use PHPUnit\Runner\Version; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class SchemaFinder { /** * @psalm-return non-empty-list */ public function available(): array { $result = [Version::series()]; foreach ((new DirectoryIterator($this->path() . 'schema')) as $file) { if ($file->isDot()) { continue; } $version = $file->getBasename('.xsd'); assert(!empty($version)); $result[] = $version; } rsort($result); return $result; } /** * @throws CannotFindSchemaException */ public function find(string $version): string { if ($version === Version::series()) { $filename = $this->path() . 'phpunit.xsd'; } else { $filename = $this->path() . 'schema/' . $version . '.xsd'; } if (!is_file($filename)) { throw new CannotFindSchemaException( sprintf( 'Schema for PHPUnit %s is not available', $version, ), ); } return $filename; } private function path(): string { if (defined('__PHPUNIT_PHAR_ROOT__')) { return __PHPUNIT_PHAR_ROOT__ . '/'; } return __DIR__ . '/../../../../'; } } PKYg3]k.~1Configuration/Xml/LoadedFromFileConfiguration.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection; use PHPUnit\TextUI\Configuration\Php; use PHPUnit\TextUI\Configuration\Source; use PHPUnit\TextUI\Configuration\TestSuiteCollection; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage; use PHPUnit\TextUI\XmlConfiguration\Logging\Logging; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class LoadedFromFileConfiguration extends Configuration { private readonly string $filename; private readonly ValidationResult $validationResult; public function __construct(string $filename, ValidationResult $validationResult, ExtensionBootstrapCollection $extensions, Source $source, CodeCoverage $codeCoverage, Groups $groups, Logging $logging, Php $php, PHPUnit $phpunit, TestSuiteCollection $testSuite) { $this->filename = $filename; $this->validationResult = $validationResult; parent::__construct( $extensions, $source, $codeCoverage, $groups, $logging, $php, $phpunit, $testSuite, ); } public function filename(): string { return $this->filename; } public function hasValidationErrors(): bool { return $this->validationResult->hasValidationErrors(); } public function validationErrors(): string { return $this->validationResult->asString(); } public function wasLoadedFromFile(): bool { return true; } } PKYg3]%~mm*Configuration/Xml/DefaultConfiguration.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use PHPUnit\Runner\TestSuiteSorter; use PHPUnit\TextUI\Configuration\ConstantCollection; use PHPUnit\TextUI\Configuration\DirectoryCollection; use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection; use PHPUnit\TextUI\Configuration\FileCollection; use PHPUnit\TextUI\Configuration\FilterDirectoryCollection as CodeCoverageFilterDirectoryCollection; use PHPUnit\TextUI\Configuration\GroupCollection; use PHPUnit\TextUI\Configuration\IniSettingCollection; use PHPUnit\TextUI\Configuration\Php; use PHPUnit\TextUI\Configuration\Source; use PHPUnit\TextUI\Configuration\TestSuiteCollection; use PHPUnit\TextUI\Configuration\VariableCollection; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage; use PHPUnit\TextUI\XmlConfiguration\Logging\Logging; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class DefaultConfiguration extends Configuration { public static function create(): self { return new self( ExtensionBootstrapCollection::fromArray([]), new Source( null, false, CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), false, false, false, false, false, false, false, false, false, false, ), new CodeCoverage( null, CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), false, true, false, false, null, null, null, null, null, null, null, ), new Groups( GroupCollection::fromArray([]), GroupCollection::fromArray([]), ), new Logging( null, null, null, null, ), new Php( DirectoryCollection::fromArray([]), IniSettingCollection::fromArray([]), ConstantCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), ), new PHPUnit( null, true, null, 80, \PHPUnit\TextUI\Configuration\Configuration::COLOR_DEFAULT, false, false, false, false, false, false, false, false, false, false, false, null, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, null, false, false, true, false, false, 1, 1, 10, 60, null, TestSuiteSorter::ORDER_DEFAULT, true, false, false, false, false, false, false, 100, ), TestSuiteCollection::fromArray([]), ); } public function isDefault(): bool { return true; } } PKYg3]Q #Configuration/Xml/Configuration.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection; use PHPUnit\TextUI\Configuration\Php; use PHPUnit\TextUI\Configuration\Source; use PHPUnit\TextUI\Configuration\TestSuiteCollection; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage; use PHPUnit\TextUI\XmlConfiguration\Logging\Logging; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ abstract class Configuration { private readonly ExtensionBootstrapCollection $extensions; private readonly Source $source; private readonly CodeCoverage $codeCoverage; private readonly Groups $groups; private readonly Logging $logging; private readonly Php $php; private readonly PHPUnit $phpunit; private readonly TestSuiteCollection $testSuite; public function __construct(ExtensionBootstrapCollection $extensions, Source $source, CodeCoverage $codeCoverage, Groups $groups, Logging $logging, Php $php, PHPUnit $phpunit, TestSuiteCollection $testSuite) { $this->extensions = $extensions; $this->source = $source; $this->codeCoverage = $codeCoverage; $this->groups = $groups; $this->logging = $logging; $this->php = $php; $this->phpunit = $phpunit; $this->testSuite = $testSuite; } public function extensions(): ExtensionBootstrapCollection { return $this->extensions; } public function source(): Source { return $this->source; } public function codeCoverage(): CodeCoverage { return $this->codeCoverage; } public function groups(): Groups { return $this->groups; } public function logging(): Logging { return $this->logging; } public function php(): Php { return $this->php; } public function phpunit(): PHPUnit { return $this->phpunit; } public function testSuite(): TestSuiteCollection { return $this->testSuite; } /** * @psalm-assert-if-true DefaultConfiguration $this */ public function isDefault(): bool { return false; } /** * @psalm-assert-if-true LoadedFromFileConfiguration $this */ public function wasLoadedFromFile(): bool { return false; } } PKYg3]L:@@0Configuration/Xml/Validator/ValidationResult.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use const PHP_EOL; use function sprintf; use function trim; use LibXMLError; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class ValidationResult { /** * @psalm-var array> */ private readonly array $validationErrors; /** * @psalm-param array $errors */ public static function fromArray(array $errors): self { $validationErrors = []; foreach ($errors as $error) { if (!isset($validationErrors[$error->line])) { $validationErrors[$error->line] = []; } $validationErrors[$error->line][] = trim($error->message); } return new self($validationErrors); } private function __construct(array $validationErrors) { $this->validationErrors = $validationErrors; } public function hasValidationErrors(): bool { return !empty($this->validationErrors); } public function asString(): string { $buffer = ''; foreach ($this->validationErrors as $line => $validationErrorsOnLine) { $buffer .= sprintf(PHP_EOL . ' Line %d:' . PHP_EOL, $line); foreach ($validationErrorsOnLine as $validationError) { $buffer .= sprintf(' - %s' . PHP_EOL, $validationError); } } return $buffer; } } PKYg3][[)Configuration/Xml/Validator/Validator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function file_get_contents; use function libxml_clear_errors; use function libxml_get_errors; use function libxml_use_internal_errors; use DOMDocument; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Validator { public function validate(DOMDocument $document, string $xsdFilename): ValidationResult { $originalErrorHandling = libxml_use_internal_errors(true); $document->schemaValidateSource(file_get_contents($xsdFilename)); $errors = libxml_get_errors(); libxml_clear_errors(); libxml_use_internal_errors($originalErrorHandling); return ValidationResult::fromArray($errors); } } PKYg3];Configuration/Xml/Generator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function str_replace; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Generator { /** * @var string */ private const TEMPLATE = <<<'EOT' {tests_directory} {src_directory} EOT; public function generateDefaultConfiguration(string $phpunitVersion, string $bootstrapScript, string $testsDirectory, string $srcDirectory, string $cacheDirectory): string { return str_replace( [ '{phpunit_version}', '{bootstrap_script}', '{tests_directory}', '{src_directory}', '{cache_directory}', ], [ $phpunitVersion, $bootstrapScript, $testsDirectory, $srcDirectory, $cacheDirectory, ], self::TEMPLATE, ); } } PKYg3]Et t 0Configuration/Xml/Migration/MigrationBuilder.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function version_compare; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class MigrationBuilder { private const AVAILABLE_MIGRATIONS = [ '8.5' => [ RemoveLogTypes::class, ], '9.2' => [ RemoveCacheTokensAttribute::class, IntroduceCoverageElement::class, MoveAttributesFromRootToCoverage::class, MoveAttributesFromFilterWhitelistToCoverage::class, MoveWhitelistIncludesToCoverage::class, MoveWhitelistExcludesToCoverage::class, RemoveEmptyFilter::class, CoverageCloverToReport::class, CoverageCrap4jToReport::class, CoverageHtmlToReport::class, CoveragePhpToReport::class, CoverageTextToReport::class, CoverageXmlToReport::class, ConvertLogTypes::class, ], '9.5' => [ RemoveListeners::class, RemoveTestSuiteLoaderAttributes::class, RemoveCacheResultFileAttribute::class, RemoveCoverageElementCacheDirectoryAttribute::class, RemoveCoverageElementProcessUncoveredFilesAttribute::class, IntroduceCacheDirectoryAttribute::class, RenameBackupStaticAttributesAttribute::class, RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute::class, RemoveBeStrictAboutTodoAnnotatedTestsAttribute::class, RemovePrinterAttributes::class, RemoveVerboseAttribute::class, RenameForceCoversAnnotationAttribute::class, RenameBeStrictAboutCoversAnnotationAttribute::class, RemoveConversionToExceptionsAttributes::class, RemoveNoInteractionAttribute::class, RemoveLoggingElements::class, RemoveTestDoxGroupsElement::class, ], '10.0' => [ MoveCoverageDirectoriesToSource::class, ], '10.4' => [ RemoveBeStrictAboutTodoAnnotatedTestsAttribute::class, ], ]; public function build(string $fromVersion): array { $stack = [new UpdateSchemaLocation]; foreach (self::AVAILABLE_MIGRATIONS as $version => $migrations) { if (version_compare($version, $fromVersion, '<')) { continue; } foreach ($migrations as $migration) { $stack[] = new $migration; } } return $stack; } } PKYg3]f(Configuration/Xml/Migration/Migrator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use PHPUnit\Runner\Version; use PHPUnit\Util\Xml\Loader as XmlLoader; use PHPUnit\Util\Xml\XmlException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Migrator { /** * @throws Exception * @throws MigrationException * @throws XmlException */ public function migrate(string $filename): string { $origin = (new SchemaDetector)->detect($filename); if (!$origin->detected()) { throw new Exception('The file does not validate against any known schema'); } if ($origin->version() === Version::series()) { throw new Exception('The file does not need to be migrated'); } $configurationDocument = (new XmlLoader)->loadFile($filename); foreach ((new MigrationBuilder)->build($origin->version()) as $migration) { $migration->migrate($configurationDocument); } $configurationDocument->formatOutput = true; $configurationDocument->preserveWhiteSpace = false; return $configurationDocument->saveXML(); } } PKYg3]KConfiguration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class IntroduceCacheDirectoryAttribute implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('cacheDirectory')) { return; } $root->setAttribute('cacheDirectory', '.phpunit.cache'); } } PKYg3]קk[?Configuration/Xml/Migration/Migrations/UpdateSchemaLocation.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; use PHPUnit\Runner\Version; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class UpdateSchemaLocation implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); $root->setAttributeNS( 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:noNamespaceSchemaLocation', 'https://schema.phpunit.de/' . Version::series() . '/phpunit.xsd', ); } } PKYg3]a}DGConfiguration/Xml/Migration/Migrations/RemoveNoInteractionAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveNoInteractionAttribute implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('noInteraction')) { $root->removeAttribute('noInteraction'); } } } PKYg3]'AConfiguration/Xml/Migration/Migrations/CoverageCrap4jToReport.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CoverageCrap4jToReport extends LogToReportMigration { protected function forType(): string { return 'coverage-crap4j'; } protected function toReportFormat(DOMElement $logNode): DOMElement { $crap4j = $logNode->ownerDocument->createElement('crap4j'); $crap4j->setAttribute('outputFile', $logNode->getAttribute('target')); $this->migrateAttributes($logNode, $crap4j, ['threshold']); return $crap4j; } } PKYg3]#]?Configuration/Xml/Migration/Migrations/CoverageHtmlToReport.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CoverageHtmlToReport extends LogToReportMigration { protected function forType(): string { return 'coverage-html'; } protected function toReportFormat(DOMElement $logNode): DOMElement { $html = $logNode->ownerDocument->createElement('html'); $html->setAttribute('outputDirectory', $logNode->getAttribute('target')); $this->migrateAttributes($logNode, $html, ['lowUpperBound', 'highLowerBound']); return $html; } } PKYg3]d^Configuration/Xml/Migration/Migrations/RemoveCoverageElementProcessUncoveredFilesAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveCoverageElementProcessUncoveredFilesAttribute implements Migration { public function migrate(DOMDocument $document): void { $node = $document->getElementsByTagName('coverage')->item(0); if (!$node instanceof DOMElement || $node->parentNode === null) { return; } if ($node->hasAttribute('processUncoveredFiles')) { $node->removeAttribute('processUncoveredFiles'); } } } PKYg3],BRvv@Configuration/Xml/Migration/Migrations/RemoveLoggingElements.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMDocument; use DOMElement; use DOMXPath; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveLoggingElements implements Migration { public function migrate(DOMDocument $document): void { $this->removeTestDoxElement($document); $this->removeTextElement($document); } private function removeTestDoxElement(DOMDocument $document): void { $node = (new DOMXPath($document))->query('logging/testdoxXml')->item(0); if (!$node instanceof DOMElement || $node->parentNode === null) { return; } $node->parentNode->removeChild($node); } private function removeTextElement(DOMDocument $document): void { $node = (new DOMXPath($document))->query('logging/text')->item(0); if (!$node instanceof DOMElement || $node->parentNode === null) { return; } $node->parentNode->removeChild($node); } } PKYg3]Q1>Configuration/Xml/Migration/Migrations/CoverageXmlToReport.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CoverageXmlToReport extends LogToReportMigration { protected function forType(): string { return 'coverage-xml'; } protected function toReportFormat(DOMElement $logNode): DOMElement { $xml = $logNode->ownerDocument->createElement('xml'); $xml->setAttribute('outputDirectory', $logNode->getAttribute('target')); return $xml; } } PKYg3]:NNCConfiguration/Xml/Migration/Migrations/IntroduceCoverageElement.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMDocument; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class IntroduceCoverageElement implements Migration { public function migrate(DOMDocument $document): void { $coverage = $document->createElement('coverage'); $document->documentElement->insertBefore( $coverage, $document->documentElement->firstChild, ); } } PKYg3]D??Configuration/Xml/Migration/Migrations/CoverageTextToReport.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CoverageTextToReport extends LogToReportMigration { protected function forType(): string { return 'coverage-text'; } protected function toReportFormat(DOMElement $logNode): DOMElement { $text = $logNode->ownerDocument->createElement('text'); $text->setAttribute('outputFile', $logNode->getAttribute('target')); $this->migrateAttributes($logNode, $text, ['showUncoveredFiles', 'showOnlySummary']); return $text; } } PKYg3]mKConfiguration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class MoveAttributesFromRootToCoverage implements Migration { /** * @throws MigrationException */ public function migrate(DOMDocument $document): void { $map = [ 'disableCodeCoverageIgnore' => 'disableCodeCoverageIgnore', 'ignoreDeprecatedCodeUnitsFromCodeCoverage' => 'ignoreDeprecatedCodeUnits', ]; $root = $document->documentElement; assert($root instanceof DOMElement); $coverage = $document->getElementsByTagName('coverage')->item(0); if (!$coverage instanceof DOMElement) { throw new MigrationException('Unexpected state - No coverage element'); } foreach ($map as $old => $new) { if (!$root->hasAttribute($old)) { continue; } $coverage->setAttribute($new, $root->getAttribute($old)); $root->removeAttribute($old); } } } PKYg3]R@BConfiguration/Xml/Migration/Migrations/RemovePrinterAttributes.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemovePrinterAttributes implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('printerClass')) { $root->removeAttribute('printerClass'); } if ($root->hasAttribute('printerFile')) { $root->removeAttribute('printerFile'); } } } PKYg3]?VConfiguration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class MoveAttributesFromFilterWhitelistToCoverage implements Migration { /** * @throws MigrationException */ public function migrate(DOMDocument $document): void { $whitelist = $document->getElementsByTagName('whitelist')->item(0); if (!$whitelist) { return; } $coverage = $document->getElementsByTagName('coverage')->item(0); if (!$coverage instanceof DOMElement) { throw new MigrationException('Unexpected state - No coverage element'); } $map = [ 'addUncoveredFilesFromWhitelist' => 'includeUncoveredFiles', 'processUncoveredFilesFromWhitelist' => 'processUncoveredFiles', ]; foreach ($map as $old => $new) { if (!$whitelist->hasAttribute($old)) { continue; } $coverage->setAttribute($new, $whitelist->getAttribute($old)); $whitelist->removeAttribute($old); } } } PKYg3] m+WConfiguration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RenameBeStrictAboutCoversAnnotationAttribute implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('beStrictAboutCoverageMetadata')) { return; } if (!$root->hasAttribute('beStrictAboutCoversAnnotation')) { return; } $root->setAttribute('beStrictAboutCoverageMetadata', $root->getAttribute('beStrictAboutCoversAnnotation')); $root->removeAttribute('beStrictAboutCoversAnnotation'); } } PKYg3] E[rr:Configuration/Xml/Migration/Migrations/RemoveListeners.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveListeners implements Migration { public function migrate(DOMDocument $document): void { $node = $document->getElementsByTagName('listeners')->item(0); if (!$node instanceof DOMElement || $node->parentNode === null) { return; } $node->parentNode->removeChild($node); } } PKYg3]tYConfiguration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveBeStrictAboutTodoAnnotatedTestsAttribute implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) { $root->removeAttribute('beStrictAboutTodoAnnotatedTests'); } } } PKYg3]w``:Configuration/Xml/Migration/Migrations/ConvertLogTypes.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ConvertLogTypes implements Migration { public function migrate(DOMDocument $document): void { $logging = $document->getElementsByTagName('logging')->item(0); if (!$logging instanceof DOMElement) { return; } $types = [ 'junit' => 'junit', 'teamcity' => 'teamcity', 'testdox-html' => 'testdoxHtml', 'testdox-text' => 'testdoxText', 'testdox-xml' => 'testdoxXml', 'plain' => 'text', ]; $logNodes = []; foreach ($logging->getElementsByTagName('log') as $logNode) { if (!isset($types[$logNode->getAttribute('type')])) { continue; } $logNodes[] = $logNode; } foreach ($logNodes as $oldNode) { $newLogNode = $document->createElement($types[$oldNode->getAttribute('type')]); $newLogNode->setAttribute('outputFile', $oldNode->getAttribute('target')); $logging->replaceChild($newLogNode, $oldNode); } } } PKYg3]t*hWConfiguration/Xml/Migration/Migrations/RemoveCoverageElementCacheDirectoryAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveCoverageElementCacheDirectoryAttribute implements Migration { public function migrate(DOMDocument $document): void { $node = $document->getElementsByTagName('coverage')->item(0); if (!$node instanceof DOMElement || $node->parentNode === null) { return; } if ($node->hasAttribute('cacheDirectory')) { $node->removeAttribute('cacheDirectory'); } } } PKYg3]7T9Configuration/Xml/Migration/Migrations/RemoveLogTypes.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveLogTypes implements Migration { public function migrate(DOMDocument $document): void { $logging = $document->getElementsByTagName('logging')->item(0); if (!$logging instanceof DOMElement) { return; } foreach (SnapshotNodeList::fromNodeList($logging->getElementsByTagName('log')) as $logNode) { assert($logNode instanceof DOMElement); switch ($logNode->getAttribute('type')) { case 'json': case 'tap': $logging->removeChild($logNode); } } } } PKYg3]QdJConfiguration/Xml/Migration/Migrations/MoveCoverageDirectoriesToSource.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; use DOMXPath; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class MoveCoverageDirectoriesToSource implements Migration { /** * @throws MigrationException */ public function migrate(DOMDocument $document): void { $source = $document->getElementsByTagName('source')->item(0); if ($source !== null) { return; } $coverage = $document->getElementsByTagName('coverage')->item(0); if ($coverage === null) { return; } $root = $document->documentElement; assert($root instanceof DOMElement); $source = $document->createElement('source'); $root->appendChild($source); $xpath = new DOMXPath($document); foreach (['include', 'exclude'] as $element) { foreach (SnapshotNodeList::fromNodeList($xpath->query('//coverage/' . $element)) as $node) { $source->appendChild($node); } } if ($coverage->childElementCount !== 0) { return; } assert($coverage->parentNode !== null); $coverage->parentNode->removeChild($coverage); } } PKYg3]qNJConfiguration/Xml/Migration/Migrations/RemoveTestSuiteLoaderAttributes.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveTestSuiteLoaderAttributes implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('testSuiteLoaderClass')) { $root->removeAttribute('testSuiteLoaderClass'); } if ($root->hasAttribute('testSuiteLoaderFile')) { $root->removeAttribute('testSuiteLoaderFile'); } } } PKYg3]&9qqPConfiguration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RenameBackupStaticAttributesAttribute implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('backupStaticProperties')) { return; } if (!$root->hasAttribute('backupStaticAttributes')) { return; } $root->setAttribute('backupStaticProperties', $root->getAttribute('backupStaticAttributes')); $root->removeAttribute('backupStaticAttributes'); } } PKYg3]̨ZZ4Configuration/Xml/Migration/Migrations/Migration.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMDocument; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ interface Migration { public function migrate(DOMDocument $document): void; } PKYg3]Q!EConfiguration/Xml/Migration/Migrations/RemoveTestDoxGroupsElement.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveTestDoxGroupsElement implements Migration { public function migrate(DOMDocument $document): void { $node = $document->getElementsByTagName('testdoxGroups')->item(0); if (!$node instanceof DOMElement || $node->parentNode === null) { return; } $node->parentNode->removeChild($node); } } PKYg3]/"_dConfiguration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('beStrictAboutResourceUsageDuringSmallTests')) { $root->removeAttribute('beStrictAboutResourceUsageDuringSmallTests'); } } } PKYg3]'ӪRAConfiguration/Xml/Migration/Migrations/CoverageCloverToReport.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CoverageCloverToReport extends LogToReportMigration { protected function forType(): string { return 'coverage-clover'; } protected function toReportFormat(DOMElement $logNode): DOMElement { $clover = $logNode->ownerDocument->createElement('clover'); $clover->setAttribute('outputFile', $logNode->getAttribute('target')); return $clover; } } PKYg3]8 >Configuration/Xml/Migration/Migrations/CoveragePhpToReport.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CoveragePhpToReport extends LogToReportMigration { protected function forType(): string { return 'coverage-php'; } protected function toReportFormat(DOMElement $logNode): DOMElement { $php = $logNode->ownerDocument->createElement('php'); $php->setAttribute('outputFile', $logNode->getAttribute('target')); return $php; } } PKYg3] ]JConfiguration/Xml/Migration/Migrations/MoveWhitelistIncludesToCoverage.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class MoveWhitelistIncludesToCoverage implements Migration { /** * @throws MigrationException */ public function migrate(DOMDocument $document): void { $whitelist = $document->getElementsByTagName('whitelist')->item(0); if ($whitelist === null) { return; } $coverage = $document->getElementsByTagName('coverage')->item(0); if (!$coverage instanceof DOMElement) { throw new MigrationException('Unexpected state - No coverage element'); } $include = $document->createElement('include'); $coverage->appendChild($include); foreach (SnapshotNodeList::fromNodeList($whitelist->childNodes) as $child) { if (!$child instanceof DOMElement) { continue; } if (!($child->nodeName === 'directory' || $child->nodeName === 'file')) { continue; } $include->appendChild($child); } } } PKYg3]J||EConfiguration/Xml/Migration/Migrations/RemoveCacheTokensAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveCacheTokensAttribute implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('cacheTokens')) { $root->removeAttribute('cacheTokens'); } } } PKYg3]5ǖe?Configuration/Xml/Migration/Migrations/LogToReportMigration.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function sprintf; use DOMDocument; use DOMElement; use DOMXPath; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ abstract class LogToReportMigration implements Migration { /** * @throws MigrationException */ public function migrate(DOMDocument $document): void { $coverage = $document->getElementsByTagName('coverage')->item(0); if (!$coverage instanceof DOMElement) { throw new MigrationException('Unexpected state - No coverage element'); } $logNode = $this->findLogNode($document); if ($logNode === null) { return; } $reportChild = $this->toReportFormat($logNode); $report = $coverage->getElementsByTagName('report')->item(0); if ($report === null) { $report = $coverage->appendChild($document->createElement('report')); } $report->appendChild($reportChild); $logNode->parentNode->removeChild($logNode); } protected function migrateAttributes(DOMElement $src, DOMElement $dest, array $attributes): void { foreach ($attributes as $attr) { if (!$src->hasAttribute($attr)) { continue; } $dest->setAttribute($attr, $src->getAttribute($attr)); $src->removeAttribute($attr); } } abstract protected function forType(): string; abstract protected function toReportFormat(DOMElement $logNode): DOMElement; private function findLogNode(DOMDocument $document): ?DOMElement { $logNode = (new DOMXPath($document))->query( sprintf('//logging/log[@type="%s"]', $this->forType()), )->item(0); if (!$logNode instanceof DOMElement) { return null; } return $logNode; } } PKYg3] ֺ7ZZQConfiguration/Xml/Migration/Migrations/RemoveConversionToExceptionsAttributes.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveConversionToExceptionsAttributes implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('convertDeprecationsToExceptions')) { $root->removeAttribute('convertDeprecationsToExceptions'); } if ($root->hasAttribute('convertErrorsToExceptions')) { $root->removeAttribute('convertErrorsToExceptions'); } if ($root->hasAttribute('convertNoticesToExceptions')) { $root->removeAttribute('convertNoticesToExceptions'); } if ($root->hasAttribute('convertWarningsToExceptions')) { $root->removeAttribute('convertWarningsToExceptions'); } } } PKYg3]t<Configuration/Xml/Migration/Migrations/RemoveEmptyFilter.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function sprintf; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveEmptyFilter implements Migration { /** * @throws MigrationException */ public function migrate(DOMDocument $document): void { $whitelist = $document->getElementsByTagName('whitelist')->item(0); if ($whitelist instanceof DOMElement) { $this->ensureEmpty($whitelist); $whitelist->parentNode->removeChild($whitelist); } $filter = $document->getElementsByTagName('filter')->item(0); if ($filter instanceof DOMElement) { $this->ensureEmpty($filter); $filter->parentNode->removeChild($filter); } } /** * @throws MigrationException */ private function ensureEmpty(DOMElement $element): void { if ($element->attributes->length > 0) { throw new MigrationException(sprintf('%s element has unexpected attributes', $element->nodeName)); } if ($element->getElementsByTagName('*')->length > 0) { throw new MigrationException(sprintf('%s element has unexpected children', $element->nodeName)); } } } PKYg3]ppAConfiguration/Xml/Migration/Migrations/RemoveVerboseAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveVerboseAttribute implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('verbose')) { $root->removeAttribute('verbose'); } } } PKYg3]-ooOConfiguration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RenameForceCoversAnnotationAttribute implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('requireCoverageMetadata')) { return; } if (!$root->hasAttribute('forceCoversAnnotation')) { return; } $root->setAttribute('requireCoverageMetadata', $root->getAttribute('forceCoversAnnotation')); $root->removeAttribute('forceCoversAnnotation'); } } PKYg3]NH;$JConfiguration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use function in_array; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class MoveWhitelistExcludesToCoverage implements Migration { /** * @throws MigrationException */ public function migrate(DOMDocument $document): void { $whitelist = $document->getElementsByTagName('whitelist')->item(0); if ($whitelist === null) { return; } $excludeNodes = SnapshotNodeList::fromNodeList($whitelist->getElementsByTagName('exclude')); if ($excludeNodes->count() === 0) { return; } $coverage = $document->getElementsByTagName('coverage')->item(0); if (!$coverage instanceof DOMElement) { throw new MigrationException('Unexpected state - No coverage element'); } $targetExclude = $coverage->getElementsByTagName('exclude')->item(0); if ($targetExclude === null) { $targetExclude = $coverage->appendChild( $document->createElement('exclude'), ); } foreach ($excludeNodes as $excludeNode) { assert($excludeNode instanceof DOMElement); foreach (SnapshotNodeList::fromNodeList($excludeNode->childNodes) as $child) { if (!$child instanceof DOMElement || !in_array($child->nodeName, ['directory', 'file'], true)) { continue; } $targetExclude->appendChild($child); } if ($excludeNode->getElementsByTagName('*')->count() !== 0) { throw new MigrationException('Dangling child elements in exclude found.'); } $whitelist->removeChild($excludeNode); } } } PKYg3]ЈIConfiguration/Xml/Migration/Migrations/RemoveCacheResultFileAttribute.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function assert; use DOMDocument; use DOMElement; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class RemoveCacheResultFileAttribute implements Migration { public function migrate(DOMDocument $document): void { $root = $document->documentElement; assert($root instanceof DOMElement); if ($root->hasAttribute('cacheResultFile')) { $root->removeAttribute('cacheResultFile'); } } } PKYg3]O$0Configuration/Xml/Migration/SnapshotNodeList.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use function count; use ArrayIterator; use Countable; use DOMNode; use DOMNodeList; use IteratorAggregate; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @template-implements IteratorAggregate */ final class SnapshotNodeList implements Countable, IteratorAggregate { /** * @psalm-var list */ private array $nodes = []; public static function fromNodeList(DOMNodeList $list): self { $snapshot = new self; foreach ($list as $node) { $snapshot->nodes[] = $node; } return $snapshot; } public function count(): int { return count($this->nodes); } public function getIterator(): ArrayIterator { return new ArrayIterator($this->nodes); } } PKYg3]z*uu2Configuration/Xml/Migration/MigrationException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use PHPUnit\Exception; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class MigrationException extends RuntimeException implements Exception { } PKYg3]}"m=''*Configuration/Xml/Logging/TestDox/Html.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\Logging\TestDox; use PHPUnit\TextUI\Configuration\File; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Html { private readonly File $target; public function __construct(File $target) { $this->target = $target; } public function target(): File { return $this->target; } } PKYg3]v''*Configuration/Xml/Logging/TestDox/Text.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\Logging\TestDox; use PHPUnit\TextUI\Configuration\File; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Text { private readonly File $target; public function __construct(File $target) { $this->target = $target; } public function target(): File { return $this->target; } } PKYg3][}D##&Configuration/Xml/Logging/TeamCity.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\Logging; use PHPUnit\TextUI\Configuration\File; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class TeamCity { private readonly File $target; public function __construct(File $target) { $this->target = $target; } public function target(): File { return $this->target; } } PKYg3]8  #Configuration/Xml/Logging/Junit.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\Logging; use PHPUnit\TextUI\Configuration\File; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Junit { private readonly File $target; public function __construct(File $target) { $this->target = $target; } public function target(): File { return $this->target; } } PKYg3]n=C C %Configuration/Xml/Logging/Logging.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\Logging; use PHPUnit\TextUI\XmlConfiguration\Exception; use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Html as TestDoxHtml; use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Text as TestDoxText; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Logging { private readonly ?Junit $junit; private readonly ?TeamCity $teamCity; private readonly ?TestDoxHtml $testDoxHtml; private readonly ?TestDoxText $testDoxText; public function __construct(?Junit $junit, ?TeamCity $teamCity, ?TestDoxHtml $testDoxHtml, ?TestDoxText $testDoxText) { $this->junit = $junit; $this->teamCity = $teamCity; $this->testDoxHtml = $testDoxHtml; $this->testDoxText = $testDoxText; } public function hasJunit(): bool { return $this->junit !== null; } /** * @throws Exception */ public function junit(): Junit { if ($this->junit === null) { throw new Exception('Logger "JUnit XML" is not configured'); } return $this->junit; } public function hasTeamCity(): bool { return $this->teamCity !== null; } /** * @throws Exception */ public function teamCity(): TeamCity { if ($this->teamCity === null) { throw new Exception('Logger "Team City" is not configured'); } return $this->teamCity; } public function hasTestDoxHtml(): bool { return $this->testDoxHtml !== null; } /** * @throws Exception */ public function testDoxHtml(): TestDoxHtml { if ($this->testDoxHtml === null) { throw new Exception('Logger "TestDox HTML" is not configured'); } return $this->testDoxHtml; } public function hasTestDoxText(): bool { return $this->testDoxText !== null; } /** * @throws Exception */ public function testDoxText(): TestDoxText { if ($this->testDoxText === null) { throw new Exception('Logger "TestDox Text" is not configured'); } return $this->testDoxText; } } PKYg3]<"JJ%Configuration/Xml/TestSuiteMapper.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use const PHP_VERSION; use function array_merge; use function array_unique; use function explode; use function in_array; use function is_dir; use function is_file; use function str_contains; use function version_compare; use PHPUnit\Framework\Exception as FrameworkException; use PHPUnit\Framework\TestSuite as TestSuiteObject; use PHPUnit\TextUI\Configuration\TestSuiteCollection; use PHPUnit\TextUI\RuntimeException; use PHPUnit\TextUI\TestDirectoryNotFoundException; use PHPUnit\TextUI\TestFileNotFoundException; use SebastianBergmann\FileIterator\Facade; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestSuiteMapper { /** * @psalm-param non-empty-string $xmlConfigurationFile, * * @throws RuntimeException * @throws TestDirectoryNotFoundException * @throws TestFileNotFoundException */ public function map(string $xmlConfigurationFile, TestSuiteCollection $configuration, string $filter, string $excludedTestSuites): TestSuiteObject { try { $filterAsArray = $filter ? explode(',', $filter) : []; $excludedFilterAsArray = $excludedTestSuites ? explode(',', $excludedTestSuites) : []; $result = TestSuiteObject::empty($xmlConfigurationFile); foreach ($configuration as $testSuiteConfiguration) { if (!empty($filterAsArray) && !in_array($testSuiteConfiguration->name(), $filterAsArray, true)) { continue; } if (!empty($excludedFilterAsArray) && in_array($testSuiteConfiguration->name(), $excludedFilterAsArray, true)) { continue; } $exclude = []; foreach ($testSuiteConfiguration->exclude()->asArray() as $file) { $exclude[] = $file->path(); } $files = []; foreach ($testSuiteConfiguration->directories() as $directory) { if (!str_contains($directory->path(), '*') && !is_dir($directory->path())) { throw new TestDirectoryNotFoundException($directory->path()); } if (!version_compare(PHP_VERSION, $directory->phpVersion(), $directory->phpVersionOperator()->asString())) { continue; } $files = array_merge( $files, (new Facade)->getFilesAsArray( $directory->path(), $directory->suffix(), $directory->prefix(), $exclude, ), ); } foreach ($testSuiteConfiguration->files() as $file) { if (!is_file($file->path())) { throw new TestFileNotFoundException($file->path()); } if (!version_compare(PHP_VERSION, $file->phpVersion(), $file->phpVersionOperator()->asString())) { continue; } $files[] = $file->path(); } if (!empty($files)) { $testSuite = TestSuiteObject::empty($testSuiteConfiguration->name()); $testSuite->addTestFiles(array_unique($files)); $result->addTest($testSuite); } } return $result; } catch (FrameworkException $e) { throw new RuntimeException( $e->getMessage(), $e->getCode(), $e, ); } } } PKYg3]:4uuDConfiguration/Xml/SchemaDetector/SuccessfulSchemaDetectionResult.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class SuccessfulSchemaDetectionResult extends SchemaDetectionResult { /** * @psalm-var non-empty-string */ private readonly string $version; /** * @psalm-param non-empty-string $version */ public function __construct(string $version) { $this->version = $version; } /** * @psalm-assert-if-true SuccessfulSchemaDetectionResult $this */ public function detected(): bool { return true; } /** * @psalm-return non-empty-string */ public function version(): string { return $this->version; } } PKYg3]DZI[WW@Configuration/Xml/SchemaDetector/FailedSchemaDetectionResult.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class FailedSchemaDetectionResult extends SchemaDetectionResult { } PKYg3]N3Configuration/Xml/SchemaDetector/SchemaDetector.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use PHPUnit\Util\Xml\Loader; use PHPUnit\Util\Xml\XmlException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class SchemaDetector { /** * @throws XmlException */ public function detect(string $filename): SchemaDetectionResult { $document = (new Loader)->loadFile($filename); $schemaFinder = new SchemaFinder; foreach ($schemaFinder->available() as $candidate) { $schema = (new SchemaFinder)->find($candidate); if (!(new Validator)->validate($document, $schema)->hasValidationErrors()) { return new SuccessfulSchemaDetectionResult($candidate); } } return new FailedSchemaDetectionResult; } } PKYg3] :Configuration/Xml/SchemaDetector/SchemaDetectionResult.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use PHPUnit\Util\Xml\XmlException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ abstract class SchemaDetectionResult { /** * @psalm-assert-if-true SuccessfulSchemaDetectionResult $this */ public function detected(): bool { return false; } /** * @throws XmlException */ public function version(): string { throw new XmlException('No supported schema was detected'); } } PKYg3]/P^^Configuration/Xml/Exception.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Exception extends RuntimeException implements \PHPUnit\Exception { } PKYg3]VConfiguration/Xml/Groups.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use PHPUnit\TextUI\Configuration\GroupCollection; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Groups { private readonly GroupCollection $include; private readonly GroupCollection $exclude; public function __construct(GroupCollection $include, GroupCollection $exclude) { $this->include = $include; $this->exclude = $exclude; } public function hasInclude(): bool { return !$this->include->isEmpty(); } public function include(): GroupCollection { return $this->include; } public function hasExclude(): bool { return !$this->exclude->isEmpty(); } public function exclude(): GroupCollection { return $this->exclude; } } PKYg3]/Configuration/Xml/CodeCoverage/CodeCoverage.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage; use function count; use PHPUnit\TextUI\Configuration\Directory; use PHPUnit\TextUI\Configuration\FileCollection; use PHPUnit\TextUI\Configuration\FilterDirectoryCollection; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Clover; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Cobertura; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Crap4j; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Html; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Php; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Text; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report\Xml; use PHPUnit\TextUI\XmlConfiguration\Exception; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class CodeCoverage { private readonly ?Directory $cacheDirectory; private readonly FilterDirectoryCollection $directories; private readonly FileCollection $files; private readonly FilterDirectoryCollection $excludeDirectories; private readonly FileCollection $excludeFiles; private readonly bool $pathCoverage; private readonly bool $includeUncoveredFiles; private readonly bool $ignoreDeprecatedCodeUnits; private readonly bool $disableCodeCoverageIgnore; private readonly ?Clover $clover; private readonly ?Cobertura $cobertura; private readonly ?Crap4j $crap4j; private readonly ?Html $html; private readonly ?Php $php; private readonly ?Text $text; private readonly ?Xml $xml; public function __construct(?Directory $cacheDirectory, FilterDirectoryCollection $directories, FileCollection $files, FilterDirectoryCollection $excludeDirectories, FileCollection $excludeFiles, bool $pathCoverage, bool $includeUncoveredFiles, bool $ignoreDeprecatedCodeUnits, bool $disableCodeCoverageIgnore, ?Clover $clover, ?Cobertura $cobertura, ?Crap4j $crap4j, ?Html $html, ?Php $php, ?Text $text, ?Xml $xml) { $this->cacheDirectory = $cacheDirectory; $this->directories = $directories; $this->files = $files; $this->excludeDirectories = $excludeDirectories; $this->excludeFiles = $excludeFiles; $this->pathCoverage = $pathCoverage; $this->includeUncoveredFiles = $includeUncoveredFiles; $this->ignoreDeprecatedCodeUnits = $ignoreDeprecatedCodeUnits; $this->disableCodeCoverageIgnore = $disableCodeCoverageIgnore; $this->clover = $clover; $this->cobertura = $cobertura; $this->crap4j = $crap4j; $this->html = $html; $this->php = $php; $this->text = $text; $this->xml = $xml; } /** * @psalm-assert-if-true !null $this->cacheDirectory * * @deprecated */ public function hasCacheDirectory(): bool { return $this->cacheDirectory !== null; } /** * @throws Exception * * @deprecated */ public function cacheDirectory(): Directory { if (!$this->hasCacheDirectory()) { throw new Exception( 'No cache directory has been configured', ); } return $this->cacheDirectory; } public function hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport(): bool { return count($this->directories) > 0 || count($this->files) > 0; } public function directories(): FilterDirectoryCollection { return $this->directories; } public function files(): FileCollection { return $this->files; } public function excludeDirectories(): FilterDirectoryCollection { return $this->excludeDirectories; } public function excludeFiles(): FileCollection { return $this->excludeFiles; } public function pathCoverage(): bool { return $this->pathCoverage; } public function includeUncoveredFiles(): bool { return $this->includeUncoveredFiles; } public function ignoreDeprecatedCodeUnits(): bool { return $this->ignoreDeprecatedCodeUnits; } public function disableCodeCoverageIgnore(): bool { return $this->disableCodeCoverageIgnore; } /** * @psalm-assert-if-true !null $this->clover */ public function hasClover(): bool { return $this->clover !== null; } /** * @throws Exception */ public function clover(): Clover { if (!$this->hasClover()) { throw new Exception( 'Code Coverage report "Clover XML" has not been configured', ); } return $this->clover; } /** * @psalm-assert-if-true !null $this->cobertura */ public function hasCobertura(): bool { return $this->cobertura !== null; } /** * @throws Exception */ public function cobertura(): Cobertura { if (!$this->hasCobertura()) { throw new Exception( 'Code Coverage report "Cobertura XML" has not been configured', ); } return $this->cobertura; } /** * @psalm-assert-if-true !null $this->crap4j */ public function hasCrap4j(): bool { return $this->crap4j !== null; } /** * @throws Exception */ public function crap4j(): Crap4j { if (!$this->hasCrap4j()) { throw new Exception( 'Code Coverage report "Crap4J" has not been configured', ); } return $this->crap4j; } /** * @psalm-assert-if-true !null $this->html */ public function hasHtml(): bool { return $this->html !== null; } /** * @throws Exception */ public function html(): Html { if (!$this->hasHtml()) { throw new Exception( 'Code Coverage report "HTML" has not been configured', ); } return $this->html; } /** * @psalm-assert-if-true !null $this->php */ public function hasPhp(): bool { return $this->php !== null; } /** * @throws Exception */ public function php(): Php { if (!$this->hasPhp()) { throw new Exception( 'Code Coverage report "PHP" has not been configured', ); } return $this->php; } /** * @psalm-assert-if-true !null $this->text */ public function hasText(): bool { return $this->text !== null; } /** * @throws Exception */ public function text(): Text { if (!$this->hasText()) { throw new Exception( 'Code Coverage report "Text" has not been configured', ); } return $this->text; } /** * @psalm-assert-if-true !null $this->xml */ public function hasXml(): bool { return $this->xml !== null; } /** * @throws Exception */ public function xml(): Xml { if (!$this->hasXml()) { throw new Exception( 'Code Coverage report "XML" has not been configured', ); } return $this->xml; } } PKYg3]\B003Configuration/Xml/CodeCoverage/Report/Cobertura.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report; use PHPUnit\TextUI\Configuration\File; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Cobertura { private readonly File $target; public function __construct(File $target) { $this->target = $target; } public function target(): File { return $this->target; } } PKYg3]\Ó .Configuration/Xml/CodeCoverage/Report/Html.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report; use PHPUnit\TextUI\Configuration\Directory; use PHPUnit\TextUI\Configuration\NoCustomCssFileException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Html { private readonly Directory $target; private readonly int $lowUpperBound; private readonly int $highLowerBound; private readonly string $colorSuccessLow; private readonly string $colorSuccessMedium; private readonly string $colorSuccessHigh; private readonly string $colorWarning; private readonly string $colorDanger; private readonly ?string $customCssFile; public function __construct(Directory $target, int $lowUpperBound, int $highLowerBound, string $colorSuccessLow, string $colorSuccessMedium, string $colorSuccessHigh, string $colorWarning, string $colorDanger, ?string $customCssFile) { $this->target = $target; $this->lowUpperBound = $lowUpperBound; $this->highLowerBound = $highLowerBound; $this->colorSuccessLow = $colorSuccessLow; $this->colorSuccessMedium = $colorSuccessMedium; $this->colorSuccessHigh = $colorSuccessHigh; $this->colorWarning = $colorWarning; $this->colorDanger = $colorDanger; $this->customCssFile = $customCssFile; } public function target(): Directory { return $this->target; } public function lowUpperBound(): int { return $this->lowUpperBound; } public function highLowerBound(): int { return $this->highLowerBound; } public function colorSuccessLow(): string { return $this->colorSuccessLow; } public function colorSuccessMedium(): string { return $this->colorSuccessMedium; } public function colorSuccessHigh(): string { return $this->colorSuccessHigh; } public function colorWarning(): string { return $this->colorWarning; } public function colorDanger(): string { return $this->colorDanger; } /** * @psalm-assert-if-true !null $this->customCssFile */ public function hasCustomCssFile(): bool { return $this->customCssFile !== null; } /** * @throws NoCustomCssFileException */ public function customCssFile(): string { if (!$this->hasCustomCssFile()) { throw new NoCustomCssFileException; } return $this->customCssFile; } } PKYg3]q#30Configuration/Xml/CodeCoverage/Report/Crap4j.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report; use PHPUnit\TextUI\Configuration\File; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Crap4j { private readonly File $target; private readonly int $threshold; public function __construct(File $target, int $threshold) { $this->target = $target; $this->threshold = $threshold; } public function target(): File { return $this->target; } public function threshold(): int { return $this->threshold; } } PKYg3]ު--0Configuration/Xml/CodeCoverage/Report/Clover.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report; use PHPUnit\TextUI\Configuration\File; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Clover { private readonly File $target; public function __construct(File $target) { $this->target = $target; } public function target(): File { return $this->target; } } PKYg3]6=>>-Configuration/Xml/CodeCoverage/Report/Xml.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report; use PHPUnit\TextUI\Configuration\Directory; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Xml { private readonly Directory $target; public function __construct(Directory $target) { $this->target = $target; } public function target(): Directory { return $this->target; } } PKYg3]jz.Configuration/Xml/CodeCoverage/Report/Text.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report; use PHPUnit\TextUI\Configuration\File; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Text { private readonly File $target; private readonly bool $showUncoveredFiles; private readonly bool $showOnlySummary; public function __construct(File $target, bool $showUncoveredFiles, bool $showOnlySummary) { $this->target = $target; $this->showUncoveredFiles = $showUncoveredFiles; $this->showOnlySummary = $showOnlySummary; } public function target(): File { return $this->target; } public function showUncoveredFiles(): bool { return $this->showUncoveredFiles; } public function showOnlySummary(): bool { return $this->showOnlySummary; } } PKYg3]&*q**-Configuration/Xml/CodeCoverage/Report/Php.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration\CodeCoverage\Report; use PHPUnit\TextUI\Configuration\File; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Php { private readonly File $target; public function __construct(File $target) { $this->target = $target; } public function target(): File { return $this->target; } } PKYg3]G0=FFConfiguration/Xml/PHPUnit.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class PHPUnit { private readonly ?string $cacheDirectory; private readonly bool $cacheResult; private readonly ?string $cacheResultFile; private readonly int|string $columns; private readonly string $colors; private readonly bool $stderr; private readonly bool $displayDetailsOnAllIssues; private readonly bool $displayDetailsOnIncompleteTests; private readonly bool $displayDetailsOnSkippedTests; private readonly bool $displayDetailsOnTestsThatTriggerDeprecations; private readonly bool $displayDetailsOnPhpunitDeprecations; private readonly bool $displayDetailsOnTestsThatTriggerErrors; private readonly bool $displayDetailsOnTestsThatTriggerNotices; private readonly bool $displayDetailsOnTestsThatTriggerWarnings; private readonly bool $reverseDefectList; private readonly bool $requireCoverageMetadata; private readonly ?string $bootstrap; private readonly bool $processIsolation; private readonly bool $failOnAllIssues; private readonly bool $failOnDeprecation; private readonly bool $failOnPhpunitDeprecation; private readonly bool $failOnPhpunitWarning; private readonly bool $failOnEmptyTestSuite; private readonly bool $failOnIncomplete; private readonly bool $failOnNotice; private readonly bool $failOnRisky; private readonly bool $failOnSkipped; private readonly bool $failOnWarning; private readonly bool $stopOnDefect; private readonly bool $stopOnDeprecation; private readonly bool $stopOnError; private readonly bool $stopOnFailure; private readonly bool $stopOnIncomplete; private readonly bool $stopOnNotice; private readonly bool $stopOnRisky; private readonly bool $stopOnSkipped; private readonly bool $stopOnWarning; /** * @psalm-var ?non-empty-string */ private readonly ?string $extensionsDirectory; private readonly bool $beStrictAboutChangesToGlobalState; private readonly bool $beStrictAboutOutputDuringTests; private readonly bool $beStrictAboutTestsThatDoNotTestAnything; private readonly bool $beStrictAboutCoverageMetadata; private readonly bool $enforceTimeLimit; private readonly int $defaultTimeLimit; private readonly int $timeoutForSmallTests; private readonly int $timeoutForMediumTests; private readonly int $timeoutForLargeTests; private readonly ?string $defaultTestSuite; private readonly int $executionOrder; private readonly bool $resolveDependencies; private readonly bool $defectsFirst; private readonly bool $backupGlobals; private readonly bool $backupStaticProperties; private readonly bool $registerMockObjectsFromTestArgumentsRecursively; private readonly bool $testdoxPrinter; private readonly bool $controlGarbageCollector; private readonly int $numberOfTestsBeforeGarbageCollection; /** * @psalm-param ?non-empty-string $extensionsDirectory */ public function __construct(?string $cacheDirectory, bool $cacheResult, ?string $cacheResultFile, int|string $columns, string $colors, bool $stderr, bool $displayDetailsOnAllIssues, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnPhpunitDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, ?string $bootstrap, bool $processIsolation, bool $failOnAllIssues, bool $failOnDeprecation, bool $failOnPhpunitDeprecation, bool $failOnPhpunitWarning, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $stopOnDefect, bool $stopOnDeprecation, bool $stopOnError, bool $stopOnFailure, bool $stopOnIncomplete, bool $stopOnNotice, bool $stopOnRisky, bool $stopOnSkipped, bool $stopOnWarning, ?string $extensionsDirectory, bool $beStrictAboutChangesToGlobalState, bool $beStrictAboutOutputDuringTests, bool $beStrictAboutTestsThatDoNotTestAnything, bool $beStrictAboutCoverageMetadata, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, ?string $defaultTestSuite, int $executionOrder, bool $resolveDependencies, bool $defectsFirst, bool $backupGlobals, bool $backupStaticProperties, bool $registerMockObjectsFromTestArgumentsRecursively, bool $testdoxPrinter, bool $controlGarbageCollector, int $numberOfTestsBeforeGarbageCollection) { $this->cacheDirectory = $cacheDirectory; $this->cacheResult = $cacheResult; $this->cacheResultFile = $cacheResultFile; $this->columns = $columns; $this->colors = $colors; $this->stderr = $stderr; $this->displayDetailsOnAllIssues = $displayDetailsOnAllIssues; $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests; $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests; $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations; $this->displayDetailsOnPhpunitDeprecations = $displayDetailsOnPhpunitDeprecations; $this->displayDetailsOnTestsThatTriggerErrors = $displayDetailsOnTestsThatTriggerErrors; $this->displayDetailsOnTestsThatTriggerNotices = $displayDetailsOnTestsThatTriggerNotices; $this->displayDetailsOnTestsThatTriggerWarnings = $displayDetailsOnTestsThatTriggerWarnings; $this->reverseDefectList = $reverseDefectList; $this->requireCoverageMetadata = $requireCoverageMetadata; $this->bootstrap = $bootstrap; $this->processIsolation = $processIsolation; $this->failOnAllIssues = $failOnAllIssues; $this->failOnDeprecation = $failOnDeprecation; $this->failOnPhpunitDeprecation = $failOnPhpunitDeprecation; $this->failOnPhpunitWarning = $failOnPhpunitWarning; $this->failOnEmptyTestSuite = $failOnEmptyTestSuite; $this->failOnIncomplete = $failOnIncomplete; $this->failOnNotice = $failOnNotice; $this->failOnRisky = $failOnRisky; $this->failOnSkipped = $failOnSkipped; $this->failOnWarning = $failOnWarning; $this->stopOnDefect = $stopOnDefect; $this->stopOnDeprecation = $stopOnDeprecation; $this->stopOnError = $stopOnError; $this->stopOnFailure = $stopOnFailure; $this->stopOnIncomplete = $stopOnIncomplete; $this->stopOnNotice = $stopOnNotice; $this->stopOnRisky = $stopOnRisky; $this->stopOnSkipped = $stopOnSkipped; $this->stopOnWarning = $stopOnWarning; $this->extensionsDirectory = $extensionsDirectory; $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState; $this->beStrictAboutOutputDuringTests = $beStrictAboutOutputDuringTests; $this->beStrictAboutTestsThatDoNotTestAnything = $beStrictAboutTestsThatDoNotTestAnything; $this->beStrictAboutCoverageMetadata = $beStrictAboutCoverageMetadata; $this->enforceTimeLimit = $enforceTimeLimit; $this->defaultTimeLimit = $defaultTimeLimit; $this->timeoutForSmallTests = $timeoutForSmallTests; $this->timeoutForMediumTests = $timeoutForMediumTests; $this->timeoutForLargeTests = $timeoutForLargeTests; $this->defaultTestSuite = $defaultTestSuite; $this->executionOrder = $executionOrder; $this->resolveDependencies = $resolveDependencies; $this->defectsFirst = $defectsFirst; $this->backupGlobals = $backupGlobals; $this->backupStaticProperties = $backupStaticProperties; $this->registerMockObjectsFromTestArgumentsRecursively = $registerMockObjectsFromTestArgumentsRecursively; $this->testdoxPrinter = $testdoxPrinter; $this->controlGarbageCollector = $controlGarbageCollector; $this->numberOfTestsBeforeGarbageCollection = $numberOfTestsBeforeGarbageCollection; } /** * @psalm-assert-if-true !null $this->cacheDirectory */ public function hasCacheDirectory(): bool { return $this->cacheDirectory !== null; } /** * @throws Exception */ public function cacheDirectory(): string { if (!$this->hasCacheDirectory()) { throw new Exception('Cache directory is not configured'); } return $this->cacheDirectory; } public function cacheResult(): bool { return $this->cacheResult; } /** * @psalm-assert-if-true !null $this->cacheResultFile * * @deprecated */ public function hasCacheResultFile(): bool { return $this->cacheResultFile !== null; } /** * @throws Exception * * @deprecated */ public function cacheResultFile(): string { if (!$this->hasCacheResultFile()) { throw new Exception('Cache result file is not configured'); } return $this->cacheResultFile; } public function columns(): int|string { return $this->columns; } public function colors(): string { return $this->colors; } public function stderr(): bool { return $this->stderr; } public function displayDetailsOnAllIssues(): bool { return $this->displayDetailsOnAllIssues; } public function displayDetailsOnIncompleteTests(): bool { return $this->displayDetailsOnIncompleteTests; } public function displayDetailsOnSkippedTests(): bool { return $this->displayDetailsOnSkippedTests; } public function displayDetailsOnTestsThatTriggerDeprecations(): bool { return $this->displayDetailsOnTestsThatTriggerDeprecations; } public function displayDetailsOnPhpunitDeprecations(): bool { return $this->displayDetailsOnPhpunitDeprecations; } public function displayDetailsOnTestsThatTriggerErrors(): bool { return $this->displayDetailsOnTestsThatTriggerErrors; } public function displayDetailsOnTestsThatTriggerNotices(): bool { return $this->displayDetailsOnTestsThatTriggerNotices; } public function displayDetailsOnTestsThatTriggerWarnings(): bool { return $this->displayDetailsOnTestsThatTriggerWarnings; } public function reverseDefectList(): bool { return $this->reverseDefectList; } public function requireCoverageMetadata(): bool { return $this->requireCoverageMetadata; } /** * @psalm-assert-if-true !null $this->bootstrap */ public function hasBootstrap(): bool { return $this->bootstrap !== null; } /** * @throws Exception */ public function bootstrap(): string { if (!$this->hasBootstrap()) { throw new Exception('Bootstrap script is not configured'); } return $this->bootstrap; } public function processIsolation(): bool { return $this->processIsolation; } public function failOnAllIssues(): bool { return $this->failOnAllIssues; } public function failOnDeprecation(): bool { return $this->failOnDeprecation; } public function failOnPhpunitDeprecation(): bool { return $this->failOnPhpunitDeprecation; } public function failOnPhpunitWarning(): bool { return $this->failOnPhpunitWarning; } public function failOnEmptyTestSuite(): bool { return $this->failOnEmptyTestSuite; } public function failOnIncomplete(): bool { return $this->failOnIncomplete; } public function failOnNotice(): bool { return $this->failOnNotice; } public function failOnRisky(): bool { return $this->failOnRisky; } public function failOnSkipped(): bool { return $this->failOnSkipped; } public function failOnWarning(): bool { return $this->failOnWarning; } public function stopOnDefect(): bool { return $this->stopOnDefect; } public function stopOnDeprecation(): bool { return $this->stopOnDeprecation; } public function stopOnError(): bool { return $this->stopOnError; } public function stopOnFailure(): bool { return $this->stopOnFailure; } public function stopOnIncomplete(): bool { return $this->stopOnIncomplete; } public function stopOnNotice(): bool { return $this->stopOnNotice; } public function stopOnRisky(): bool { return $this->stopOnRisky; } public function stopOnSkipped(): bool { return $this->stopOnSkipped; } public function stopOnWarning(): bool { return $this->stopOnWarning; } /** * @psalm-assert-if-true !null $this->extensionsDirectory */ public function hasExtensionsDirectory(): bool { return $this->extensionsDirectory !== null; } /** * @throws Exception * * @psalm-return non-empty-string */ public function extensionsDirectory(): string { if (!$this->hasExtensionsDirectory()) { throw new Exception('Extensions directory is not configured'); } return $this->extensionsDirectory; } public function beStrictAboutChangesToGlobalState(): bool { return $this->beStrictAboutChangesToGlobalState; } public function beStrictAboutOutputDuringTests(): bool { return $this->beStrictAboutOutputDuringTests; } public function beStrictAboutTestsThatDoNotTestAnything(): bool { return $this->beStrictAboutTestsThatDoNotTestAnything; } public function beStrictAboutCoverageMetadata(): bool { return $this->beStrictAboutCoverageMetadata; } public function enforceTimeLimit(): bool { return $this->enforceTimeLimit; } public function defaultTimeLimit(): int { return $this->defaultTimeLimit; } public function timeoutForSmallTests(): int { return $this->timeoutForSmallTests; } public function timeoutForMediumTests(): int { return $this->timeoutForMediumTests; } public function timeoutForLargeTests(): int { return $this->timeoutForLargeTests; } /** * @psalm-assert-if-true !null $this->defaultTestSuite */ public function hasDefaultTestSuite(): bool { return $this->defaultTestSuite !== null; } /** * @throws Exception */ public function defaultTestSuite(): string { if (!$this->hasDefaultTestSuite()) { throw new Exception('Default test suite is not configured'); } return $this->defaultTestSuite; } public function executionOrder(): int { return $this->executionOrder; } public function resolveDependencies(): bool { return $this->resolveDependencies; } public function defectsFirst(): bool { return $this->defectsFirst; } public function backupGlobals(): bool { return $this->backupGlobals; } public function backupStaticProperties(): bool { return $this->backupStaticProperties; } /** * @deprecated */ public function registerMockObjectsFromTestArgumentsRecursively(): bool { return $this->registerMockObjectsFromTestArgumentsRecursively; } public function testdoxPrinter(): bool { return $this->testdoxPrinter; } public function controlGarbageCollector(): bool { return $this->controlGarbageCollector; } public function numberOfTestsBeforeGarbageCollection(): int { return $this->numberOfTestsBeforeGarbageCollection; } } PKYg3]Ujj=Configuration/Exception/NoPharExtensionDirectoryException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class NoPharExtensionDirectoryException extends RuntimeException implements Exception { } PKYg3]al__2Configuration/Exception/NoCliArgumentException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class NoCliArgumentException extends RuntimeException implements Exception { } PKYg3],~Hdd7Configuration/Exception/NoDefaultTestSuiteException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class NoDefaultTestSuiteException extends RuntimeException implements Exception { } PKYg3] Tll?Configuration/Exception/ConfigurationCannotBeBuiltException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ConfigurationCannotBeBuiltException extends RuntimeException implements Exception { } PKYg3]c1Yee8Configuration/Exception/NoConfigurationFileException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class NoConfigurationFileException extends RuntimeException implements Exception { } PKYg3]gZ3bb5Configuration/Exception/NoCacheDirectoryException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class NoCacheDirectoryException extends RuntimeException implements Exception { } PKYg3](U^5Configuration/Exception/CannotFindSchemaException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\XmlConfiguration; use PHPUnit\TextUI\Configuration\Exception; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CannotFindSchemaException extends RuntimeException implements Exception { } PKYg3]mee8Configuration/Exception/FilterNotConfiguredException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class FilterNotConfiguredException extends RuntimeException implements Exception { } PKYg3]|"ff9Configuration/Exception/LoggingNotConfiguredException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class LoggingNotConfiguredException extends RuntimeException implements Exception { } PKYg3]aa4Configuration/Exception/NoCustomCssFileException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class NoCustomCssFileException extends RuntimeException implements Exception { } PKYg3]Z@jj=Configuration/Exception/NoCoverageCacheDirectoryException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class NoCoverageCacheDirectoryException extends RuntimeException implements Exception { } PKYg3]^kqqDConfiguration/Exception/CodeCoverageReportNotConfiguredException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CodeCoverageReportNotConfiguredException extends RuntimeException implements Exception { } PKYg3]da\\/Configuration/Exception/NoBaselineException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class NoBaselineException extends RuntimeException implements Exception { } PKYg3]5P11%Configuration/Exception/Exception.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This interface is not covered by the backward compatibility promise for PHPUnit */ interface Exception extends \PHPUnit\TextUI\Exception { } PKYg3]N&]]0Configuration/Exception/NoBootstrapException.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use RuntimeException; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class NoBootstrapException extends RuntimeException implements Exception { } PKYg3] "Configuration/TestSuiteBuilder.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use const PHP_EOL; use function assert; use function count; use function is_dir; use function is_file; use function realpath; use function str_ends_with; use PHPUnit\Event\Facade as EventFacade; use PHPUnit\Exception; use PHPUnit\Framework\TestSuite; use PHPUnit\Runner\TestSuiteLoader; use PHPUnit\TextUI\RuntimeException; use PHPUnit\TextUI\TestDirectoryNotFoundException; use PHPUnit\TextUI\TestFileNotFoundException; use PHPUnit\TextUI\XmlConfiguration\TestSuiteMapper; use SebastianBergmann\FileIterator\Facade as FileIteratorFacade; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class TestSuiteBuilder { /** * @throws \PHPUnit\Framework\Exception * @throws RuntimeException * @throws TestDirectoryNotFoundException * @throws TestFileNotFoundException */ public function build(Configuration $configuration): TestSuite { if ($configuration->hasCliArguments()) { $arguments = []; foreach ($configuration->cliArguments() as $cliArgument) { $argument = realpath($cliArgument); if (!$argument) { throw new TestFileNotFoundException($cliArgument); } $arguments[] = $argument; } if (count($arguments) === 1) { $testSuite = $this->testSuiteFromPath( $arguments[0], $configuration->testSuffixes(), ); } else { $testSuite = $this->testSuiteFromPathList( $arguments, $configuration->testSuffixes(), ); } } if (!isset($testSuite)) { $xmlConfigurationFile = $configuration->hasConfigurationFile() ? $configuration->configurationFile() : 'Root Test Suite'; assert(!empty($xmlConfigurationFile)); $testSuite = (new TestSuiteMapper)->map( $xmlConfigurationFile, $configuration->testSuite(), $configuration->includeTestSuite(), $configuration->excludeTestSuite(), ); } EventFacade::emitter()->testSuiteLoaded(\PHPUnit\Event\TestSuite\TestSuiteBuilder::from($testSuite)); return $testSuite; } /** * @psalm-param non-empty-string $path * @psalm-param list $suffixes * @psalm-param ?TestSuite $suite * * @throws \PHPUnit\Framework\Exception */ private function testSuiteFromPath(string $path, array $suffixes, ?TestSuite $suite = null): TestSuite { if (str_ends_with($path, '.phpt') && is_file($path)) { $suite = $suite ?: TestSuite::empty($path); $suite->addTestFile($path); return $suite; } if (is_dir($path)) { $files = (new FileIteratorFacade)->getFilesAsArray($path, $suffixes); $suite = $suite ?: TestSuite::empty('CLI Arguments'); $suite->addTestFiles($files); return $suite; } try { $testClass = (new TestSuiteLoader)->load($path); } catch (Exception $e) { print $e->getMessage() . PHP_EOL; exit(1); } if (!$suite) { return TestSuite::fromClassReflector($testClass); } $suite->addTestSuite($testClass); return $suite; } /** * @psalm-param list $paths * @psalm-param list $suffixes * * @throws \PHPUnit\Framework\Exception */ private function testSuiteFromPathList(array $paths, array $suffixes): TestSuite { $suite = TestSuite::empty('CLI Arguments'); foreach ($paths as $path) { $this->testSuiteFromPath($path, $suffixes, $suite); } return $suite; } } PKYg3]Configuration/SourceFilter.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class SourceFilter { private static ?self $instance = null; /** * @psalm-var array */ private readonly array $map; public static function instance(): self { if (self::$instance === null) { self::$instance = new self( (new SourceMapper)->map( Registry::get()->source(), ), ); } return self::$instance; } /** * @psalm-param array $map */ public function __construct(array $map) { $this->map = $map; } public function includes(string $path): bool { return isset($this->map[$path]); } } PKYg3]#Configuration/Merger.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use const DIRECTORY_SEPARATOR; use const PATH_SEPARATOR; use function array_diff; use function assert; use function dirname; use function explode; use function is_int; use function realpath; use function time; use PHPUnit\Event\Facade as EventFacade; use PHPUnit\Runner\TestSuiteSorter; use PHPUnit\TextUI\CliArguments\Configuration as CliConfiguration; use PHPUnit\TextUI\CliArguments\Exception; use PHPUnit\TextUI\XmlConfiguration\Configuration as XmlConfiguration; use PHPUnit\TextUI\XmlConfiguration\LoadedFromFileConfiguration; use PHPUnit\TextUI\XmlConfiguration\SchemaDetector; use PHPUnit\Util\Filesystem; use SebastianBergmann\CodeCoverage\Report\Html\Colors; use SebastianBergmann\CodeCoverage\Report\Thresholds; use SebastianBergmann\Environment\Console; use SebastianBergmann\Invoker\Invoker; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Merger { /** * @throws \PHPUnit\TextUI\XmlConfiguration\Exception * @throws Exception * @throws NoCustomCssFileException */ public function merge(CliConfiguration $cliConfiguration, XmlConfiguration $xmlConfiguration): Configuration { $configurationFile = null; if ($xmlConfiguration->wasLoadedFromFile()) { assert($xmlConfiguration instanceof LoadedFromFileConfiguration); $configurationFile = $xmlConfiguration->filename(); } $bootstrap = null; if ($cliConfiguration->hasBootstrap()) { $bootstrap = $cliConfiguration->bootstrap(); } elseif ($xmlConfiguration->phpunit()->hasBootstrap()) { $bootstrap = $xmlConfiguration->phpunit()->bootstrap(); } if ($cliConfiguration->hasCacheResult()) { $cacheResult = $cliConfiguration->cacheResult(); } else { $cacheResult = $xmlConfiguration->phpunit()->cacheResult(); } $cacheDirectory = null; $coverageCacheDirectory = null; if ($cliConfiguration->hasCacheDirectory() && Filesystem::createDirectory($cliConfiguration->cacheDirectory())) { $cacheDirectory = realpath($cliConfiguration->cacheDirectory()); } elseif ($xmlConfiguration->phpunit()->hasCacheDirectory() && Filesystem::createDirectory($xmlConfiguration->phpunit()->cacheDirectory())) { $cacheDirectory = realpath($xmlConfiguration->phpunit()->cacheDirectory()); } if ($cacheDirectory !== null) { $coverageCacheDirectory = $cacheDirectory . DIRECTORY_SEPARATOR . 'code-coverage'; $testResultCacheFile = $cacheDirectory . DIRECTORY_SEPARATOR . 'test-results'; } if ($coverageCacheDirectory === null) { if ($cliConfiguration->hasCoverageCacheDirectory() && Filesystem::createDirectory($cliConfiguration->coverageCacheDirectory())) { $coverageCacheDirectory = realpath($cliConfiguration->coverageCacheDirectory()); } elseif ($xmlConfiguration->codeCoverage()->hasCacheDirectory()) { $coverageCacheDirectory = $xmlConfiguration->codeCoverage()->cacheDirectory()->path(); } } if (!isset($testResultCacheFile)) { if ($cliConfiguration->hasCacheResultFile()) { $testResultCacheFile = $cliConfiguration->cacheResultFile(); } elseif ($xmlConfiguration->phpunit()->hasCacheResultFile()) { $testResultCacheFile = $xmlConfiguration->phpunit()->cacheResultFile(); } elseif ($xmlConfiguration->wasLoadedFromFile()) { $testResultCacheFile = dirname(realpath($xmlConfiguration->filename())) . DIRECTORY_SEPARATOR . '.phpunit.result.cache'; } else { $candidate = realpath($_SERVER['PHP_SELF']); if ($candidate) { $testResultCacheFile = dirname($candidate) . DIRECTORY_SEPARATOR . '.phpunit.result.cache'; } else { $testResultCacheFile = '.phpunit.result.cache'; } } } if ($cliConfiguration->hasDisableCodeCoverageIgnore()) { $disableCodeCoverageIgnore = $cliConfiguration->disableCodeCoverageIgnore(); } else { $disableCodeCoverageIgnore = $xmlConfiguration->codeCoverage()->disableCodeCoverageIgnore(); } if ($cliConfiguration->hasFailOnAllIssues()) { $failOnAllIssues = $cliConfiguration->failOnAllIssues(); } else { $failOnAllIssues = $xmlConfiguration->phpunit()->failOnAllIssues(); } if ($cliConfiguration->hasFailOnDeprecation()) { $failOnDeprecation = $cliConfiguration->failOnDeprecation(); } else { $failOnDeprecation = $xmlConfiguration->phpunit()->failOnDeprecation(); } if ($cliConfiguration->hasFailOnPhpunitDeprecation()) { $failOnPhpunitDeprecation = $cliConfiguration->failOnPhpunitDeprecation(); } else { $failOnPhpunitDeprecation = $xmlConfiguration->phpunit()->failOnPhpunitDeprecation(); } if ($cliConfiguration->hasFailOnPhpunitWarning()) { $failOnPhpunitWarning = $cliConfiguration->failOnPhpunitWarning(); } else { $failOnPhpunitWarning = $xmlConfiguration->phpunit()->failOnPhpunitWarning(); } if ($cliConfiguration->hasFailOnEmptyTestSuite()) { $failOnEmptyTestSuite = $cliConfiguration->failOnEmptyTestSuite(); } else { $failOnEmptyTestSuite = $xmlConfiguration->phpunit()->failOnEmptyTestSuite(); } if ($cliConfiguration->hasFailOnIncomplete()) { $failOnIncomplete = $cliConfiguration->failOnIncomplete(); } else { $failOnIncomplete = $xmlConfiguration->phpunit()->failOnIncomplete(); } if ($cliConfiguration->hasFailOnNotice()) { $failOnNotice = $cliConfiguration->failOnNotice(); } else { $failOnNotice = $xmlConfiguration->phpunit()->failOnNotice(); } if ($cliConfiguration->hasFailOnRisky()) { $failOnRisky = $cliConfiguration->failOnRisky(); } else { $failOnRisky = $xmlConfiguration->phpunit()->failOnRisky(); } if ($cliConfiguration->hasFailOnSkipped()) { $failOnSkipped = $cliConfiguration->failOnSkipped(); } else { $failOnSkipped = $xmlConfiguration->phpunit()->failOnSkipped(); } if ($cliConfiguration->hasFailOnWarning()) { $failOnWarning = $cliConfiguration->failOnWarning(); } else { $failOnWarning = $xmlConfiguration->phpunit()->failOnWarning(); } $doNotFailOnDeprecation = false; if ($cliConfiguration->hasDoNotFailOnDeprecation()) { $doNotFailOnDeprecation = $cliConfiguration->doNotFailOnDeprecation(); } $doNotFailOnPhpunitDeprecation = false; if ($cliConfiguration->hasDoNotFailOnPhpunitDeprecation()) { $doNotFailOnPhpunitDeprecation = $cliConfiguration->doNotFailOnPhpunitDeprecation(); } $doNotFailOnPhpunitWarning = false; if ($cliConfiguration->hasDoNotFailOnPhpunitWarning()) { $doNotFailOnPhpunitWarning = $cliConfiguration->doNotFailOnPhpunitWarning(); } $doNotFailOnEmptyTestSuite = false; if ($cliConfiguration->hasDoNotFailOnEmptyTestSuite()) { $doNotFailOnEmptyTestSuite = $cliConfiguration->doNotFailOnEmptyTestSuite(); } $doNotFailOnIncomplete = false; if ($cliConfiguration->hasDoNotFailOnIncomplete()) { $doNotFailOnIncomplete = $cliConfiguration->doNotFailOnIncomplete(); } $doNotFailOnNotice = false; if ($cliConfiguration->hasDoNotFailOnNotice()) { $doNotFailOnNotice = $cliConfiguration->doNotFailOnNotice(); } $doNotFailOnRisky = false; if ($cliConfiguration->hasDoNotFailOnRisky()) { $doNotFailOnRisky = $cliConfiguration->doNotFailOnRisky(); } $doNotFailOnSkipped = false; if ($cliConfiguration->hasDoNotFailOnSkipped()) { $doNotFailOnSkipped = $cliConfiguration->doNotFailOnSkipped(); } $doNotFailOnWarning = false; if ($cliConfiguration->hasDoNotFailOnWarning()) { $doNotFailOnWarning = $cliConfiguration->doNotFailOnWarning(); } if ($cliConfiguration->hasStopOnDefect()) { $stopOnDefect = $cliConfiguration->stopOnDefect(); } else { $stopOnDefect = $xmlConfiguration->phpunit()->stopOnDefect(); } if ($cliConfiguration->hasStopOnDeprecation()) { $stopOnDeprecation = $cliConfiguration->stopOnDeprecation(); } else { $stopOnDeprecation = $xmlConfiguration->phpunit()->stopOnDeprecation(); } if ($cliConfiguration->hasStopOnError()) { $stopOnError = $cliConfiguration->stopOnError(); } else { $stopOnError = $xmlConfiguration->phpunit()->stopOnError(); } if ($cliConfiguration->hasStopOnFailure()) { $stopOnFailure = $cliConfiguration->stopOnFailure(); } else { $stopOnFailure = $xmlConfiguration->phpunit()->stopOnFailure(); } if ($cliConfiguration->hasStopOnIncomplete()) { $stopOnIncomplete = $cliConfiguration->stopOnIncomplete(); } else { $stopOnIncomplete = $xmlConfiguration->phpunit()->stopOnIncomplete(); } if ($cliConfiguration->hasStopOnNotice()) { $stopOnNotice = $cliConfiguration->stopOnNotice(); } else { $stopOnNotice = $xmlConfiguration->phpunit()->stopOnNotice(); } if ($cliConfiguration->hasStopOnRisky()) { $stopOnRisky = $cliConfiguration->stopOnRisky(); } else { $stopOnRisky = $xmlConfiguration->phpunit()->stopOnRisky(); } if ($cliConfiguration->hasStopOnSkipped()) { $stopOnSkipped = $cliConfiguration->stopOnSkipped(); } else { $stopOnSkipped = $xmlConfiguration->phpunit()->stopOnSkipped(); } if ($cliConfiguration->hasStopOnWarning()) { $stopOnWarning = $cliConfiguration->stopOnWarning(); } else { $stopOnWarning = $xmlConfiguration->phpunit()->stopOnWarning(); } if ($cliConfiguration->hasStderr() && $cliConfiguration->stderr()) { $outputToStandardErrorStream = true; } else { $outputToStandardErrorStream = $xmlConfiguration->phpunit()->stderr(); } if ($cliConfiguration->hasColumns()) { $columns = $cliConfiguration->columns(); } else { $columns = $xmlConfiguration->phpunit()->columns(); } if ($columns === 'max') { $columns = (new Console)->getNumberOfColumns(); } if ($columns < 16) { $columns = 16; EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( 'Less than 16 columns requested, number of columns set to 16', ); } assert(is_int($columns)); $noExtensions = false; if ($cliConfiguration->hasNoExtensions() && $cliConfiguration->noExtensions()) { $noExtensions = true; } $pharExtensionDirectory = null; if ($xmlConfiguration->phpunit()->hasExtensionsDirectory()) { $pharExtensionDirectory = $xmlConfiguration->phpunit()->extensionsDirectory(); } $extensionBootstrappers = []; foreach ($xmlConfiguration->extensions() as $extension) { $extensionBootstrappers[] = [ 'className' => $extension->className(), 'parameters' => $extension->parameters(), ]; } if ($cliConfiguration->hasPathCoverage() && $cliConfiguration->pathCoverage()) { $pathCoverage = $cliConfiguration->pathCoverage(); } else { $pathCoverage = $xmlConfiguration->codeCoverage()->pathCoverage(); } $defaultColors = Colors::default(); $defaultThresholds = Thresholds::default(); $coverageClover = null; $coverageCobertura = null; $coverageCrap4j = null; $coverageCrap4jThreshold = 30; $coverageHtml = null; $coverageHtmlLowUpperBound = $defaultThresholds->lowUpperBound(); $coverageHtmlHighLowerBound = $defaultThresholds->highLowerBound(); $coverageHtmlColorSuccessLow = $defaultColors->successLow(); $coverageHtmlColorSuccessMedium = $defaultColors->successMedium(); $coverageHtmlColorSuccessHigh = $defaultColors->successHigh(); $coverageHtmlColorWarning = $defaultColors->warning(); $coverageHtmlColorDanger = $defaultColors->danger(); $coverageHtmlCustomCssFile = null; $coveragePhp = null; $coverageText = null; $coverageTextShowUncoveredFiles = false; $coverageTextShowOnlySummary = false; $coverageXml = null; $coverageFromXmlConfiguration = true; if ($cliConfiguration->hasNoCoverage() && $cliConfiguration->noCoverage()) { $coverageFromXmlConfiguration = false; } if ($cliConfiguration->hasCoverageClover()) { $coverageClover = $cliConfiguration->coverageClover(); } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasClover()) { $coverageClover = $xmlConfiguration->codeCoverage()->clover()->target()->path(); } if ($cliConfiguration->hasCoverageCobertura()) { $coverageCobertura = $cliConfiguration->coverageCobertura(); } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasCobertura()) { $coverageCobertura = $xmlConfiguration->codeCoverage()->cobertura()->target()->path(); } if ($xmlConfiguration->codeCoverage()->hasCrap4j()) { $coverageCrap4jThreshold = $xmlConfiguration->codeCoverage()->crap4j()->threshold(); } if ($cliConfiguration->hasCoverageCrap4J()) { $coverageCrap4j = $cliConfiguration->coverageCrap4J(); } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasCrap4j()) { $coverageCrap4j = $xmlConfiguration->codeCoverage()->crap4j()->target()->path(); } if ($xmlConfiguration->codeCoverage()->hasHtml()) { $coverageHtmlHighLowerBound = $xmlConfiguration->codeCoverage()->html()->highLowerBound(); $coverageHtmlLowUpperBound = $xmlConfiguration->codeCoverage()->html()->lowUpperBound(); if ($coverageHtmlLowUpperBound > $coverageHtmlHighLowerBound) { $coverageHtmlLowUpperBound = $defaultThresholds->lowUpperBound(); $coverageHtmlHighLowerBound = $defaultThresholds->highLowerBound(); } $coverageHtmlColorSuccessLow = $xmlConfiguration->codeCoverage()->html()->colorSuccessLow(); $coverageHtmlColorSuccessMedium = $xmlConfiguration->codeCoverage()->html()->colorSuccessMedium(); $coverageHtmlColorSuccessHigh = $xmlConfiguration->codeCoverage()->html()->colorSuccessHigh(); $coverageHtmlColorWarning = $xmlConfiguration->codeCoverage()->html()->colorWarning(); $coverageHtmlColorDanger = $xmlConfiguration->codeCoverage()->html()->colorDanger(); if ($xmlConfiguration->codeCoverage()->html()->hasCustomCssFile()) { $coverageHtmlCustomCssFile = $xmlConfiguration->codeCoverage()->html()->customCssFile(); } } if ($cliConfiguration->hasCoverageHtml()) { $coverageHtml = $cliConfiguration->coverageHtml(); } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasHtml()) { $coverageHtml = $xmlConfiguration->codeCoverage()->html()->target()->path(); } if ($cliConfiguration->hasCoveragePhp()) { $coveragePhp = $cliConfiguration->coveragePhp(); } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasPhp()) { $coveragePhp = $xmlConfiguration->codeCoverage()->php()->target()->path(); } if ($xmlConfiguration->codeCoverage()->hasText()) { $coverageTextShowUncoveredFiles = $xmlConfiguration->codeCoverage()->text()->showUncoveredFiles(); $coverageTextShowOnlySummary = $xmlConfiguration->codeCoverage()->text()->showOnlySummary(); } if ($cliConfiguration->hasCoverageTextShowUncoveredFiles()) { $coverageTextShowUncoveredFiles = $cliConfiguration->coverageTextShowUncoveredFiles(); } if ($cliConfiguration->hasCoverageTextShowOnlySummary()) { $coverageTextShowOnlySummary = $cliConfiguration->coverageTextShowOnlySummary(); } if ($cliConfiguration->hasCoverageText()) { $coverageText = $cliConfiguration->coverageText(); } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasText()) { $coverageText = $xmlConfiguration->codeCoverage()->text()->target()->path(); } if ($cliConfiguration->hasCoverageXml()) { $coverageXml = $cliConfiguration->coverageXml(); } elseif ($coverageFromXmlConfiguration && $xmlConfiguration->codeCoverage()->hasXml()) { $coverageXml = $xmlConfiguration->codeCoverage()->xml()->target()->path(); } if ($cliConfiguration->hasBackupGlobals()) { $backupGlobals = $cliConfiguration->backupGlobals(); } else { $backupGlobals = $xmlConfiguration->phpunit()->backupGlobals(); } if ($cliConfiguration->hasBackupStaticProperties()) { $backupStaticProperties = $cliConfiguration->backupStaticProperties(); } else { $backupStaticProperties = $xmlConfiguration->phpunit()->backupStaticProperties(); } if ($cliConfiguration->hasBeStrictAboutChangesToGlobalState()) { $beStrictAboutChangesToGlobalState = $cliConfiguration->beStrictAboutChangesToGlobalState(); } else { $beStrictAboutChangesToGlobalState = $xmlConfiguration->phpunit()->beStrictAboutChangesToGlobalState(); } if ($cliConfiguration->hasProcessIsolation()) { $processIsolation = $cliConfiguration->processIsolation(); } else { $processIsolation = $xmlConfiguration->phpunit()->processIsolation(); } if ($cliConfiguration->hasEnforceTimeLimit()) { $enforceTimeLimit = $cliConfiguration->enforceTimeLimit(); } else { $enforceTimeLimit = $xmlConfiguration->phpunit()->enforceTimeLimit(); } if ($enforceTimeLimit && !(new Invoker)->canInvokeWithTimeout()) { EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( 'The pcntl extension is required for enforcing time limits', ); } if ($cliConfiguration->hasDefaultTimeLimit()) { $defaultTimeLimit = $cliConfiguration->defaultTimeLimit(); } else { $defaultTimeLimit = $xmlConfiguration->phpunit()->defaultTimeLimit(); } $timeoutForSmallTests = $xmlConfiguration->phpunit()->timeoutForSmallTests(); $timeoutForMediumTests = $xmlConfiguration->phpunit()->timeoutForMediumTests(); $timeoutForLargeTests = $xmlConfiguration->phpunit()->timeoutForLargeTests(); if ($cliConfiguration->hasReportUselessTests()) { $reportUselessTests = $cliConfiguration->reportUselessTests(); } else { $reportUselessTests = $xmlConfiguration->phpunit()->beStrictAboutTestsThatDoNotTestAnything(); } if ($cliConfiguration->hasStrictCoverage()) { $strictCoverage = $cliConfiguration->strictCoverage(); } else { $strictCoverage = $xmlConfiguration->phpunit()->beStrictAboutCoverageMetadata(); } if ($cliConfiguration->hasDisallowTestOutput()) { $disallowTestOutput = $cliConfiguration->disallowTestOutput(); } else { $disallowTestOutput = $xmlConfiguration->phpunit()->beStrictAboutOutputDuringTests(); } if ($cliConfiguration->hasDisplayDetailsOnAllIssues()) { $displayDetailsOnAllIssues = $cliConfiguration->displayDetailsOnAllIssues(); } else { $displayDetailsOnAllIssues = $xmlConfiguration->phpunit()->displayDetailsOnAllIssues(); } if ($cliConfiguration->hasDisplayDetailsOnIncompleteTests()) { $displayDetailsOnIncompleteTests = $cliConfiguration->displayDetailsOnIncompleteTests(); } else { $displayDetailsOnIncompleteTests = $xmlConfiguration->phpunit()->displayDetailsOnIncompleteTests(); } if ($cliConfiguration->hasDisplayDetailsOnSkippedTests()) { $displayDetailsOnSkippedTests = $cliConfiguration->displayDetailsOnSkippedTests(); } else { $displayDetailsOnSkippedTests = $xmlConfiguration->phpunit()->displayDetailsOnSkippedTests(); } if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerDeprecations()) { $displayDetailsOnTestsThatTriggerDeprecations = $cliConfiguration->displayDetailsOnTestsThatTriggerDeprecations(); } else { $displayDetailsOnTestsThatTriggerDeprecations = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerDeprecations(); } if ($cliConfiguration->hasDisplayDetailsOnPhpunitDeprecations()) { $displayDetailsOnPhpunitDeprecations = $cliConfiguration->displayDetailsOnPhpunitDeprecations(); } else { $displayDetailsOnPhpunitDeprecations = $xmlConfiguration->phpunit()->displayDetailsOnPhpunitDeprecations(); } if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerErrors()) { $displayDetailsOnTestsThatTriggerErrors = $cliConfiguration->displayDetailsOnTestsThatTriggerErrors(); } else { $displayDetailsOnTestsThatTriggerErrors = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerErrors(); } if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerNotices()) { $displayDetailsOnTestsThatTriggerNotices = $cliConfiguration->displayDetailsOnTestsThatTriggerNotices(); } else { $displayDetailsOnTestsThatTriggerNotices = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerNotices(); } if ($cliConfiguration->hasDisplayDetailsOnTestsThatTriggerWarnings()) { $displayDetailsOnTestsThatTriggerWarnings = $cliConfiguration->displayDetailsOnTestsThatTriggerWarnings(); } else { $displayDetailsOnTestsThatTriggerWarnings = $xmlConfiguration->phpunit()->displayDetailsOnTestsThatTriggerWarnings(); } if ($cliConfiguration->hasReverseList()) { $reverseDefectList = $cliConfiguration->reverseList(); } else { $reverseDefectList = $xmlConfiguration->phpunit()->reverseDefectList(); } $requireCoverageMetadata = $xmlConfiguration->phpunit()->requireCoverageMetadata(); $registerMockObjectsFromTestArgumentsRecursively = $xmlConfiguration->phpunit()->registerMockObjectsFromTestArgumentsRecursively(); if ($cliConfiguration->hasExecutionOrder()) { $executionOrder = $cliConfiguration->executionOrder(); } else { $executionOrder = $xmlConfiguration->phpunit()->executionOrder(); } $executionOrderDefects = TestSuiteSorter::ORDER_DEFAULT; if ($cliConfiguration->hasExecutionOrderDefects()) { $executionOrderDefects = $cliConfiguration->executionOrderDefects(); } elseif ($xmlConfiguration->phpunit()->defectsFirst()) { $executionOrderDefects = TestSuiteSorter::ORDER_DEFECTS_FIRST; } if ($cliConfiguration->hasResolveDependencies()) { $resolveDependencies = $cliConfiguration->resolveDependencies(); } else { $resolveDependencies = $xmlConfiguration->phpunit()->resolveDependencies(); } $colors = false; $colorsSupported = (new Console)->hasColorSupport(); if ($cliConfiguration->hasColors()) { if ($cliConfiguration->colors() === Configuration::COLOR_ALWAYS) { $colors = true; } elseif ($colorsSupported && $cliConfiguration->colors() === Configuration::COLOR_AUTO) { $colors = true; } } elseif ($xmlConfiguration->phpunit()->colors() === Configuration::COLOR_ALWAYS) { $colors = true; } elseif ($colorsSupported && $xmlConfiguration->phpunit()->colors() === Configuration::COLOR_AUTO) { $colors = true; } $logfileTeamcity = null; $logfileJunit = null; $logfileTestdoxHtml = null; $logfileTestdoxText = null; $loggingFromXmlConfiguration = true; if ($cliConfiguration->hasNoLogging() && $cliConfiguration->noLogging()) { $loggingFromXmlConfiguration = false; } if ($cliConfiguration->hasTeamcityLogfile()) { $logfileTeamcity = $cliConfiguration->teamcityLogfile(); } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasTeamCity()) { $logfileTeamcity = $xmlConfiguration->logging()->teamCity()->target()->path(); } if ($cliConfiguration->hasJunitLogfile()) { $logfileJunit = $cliConfiguration->junitLogfile(); } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasJunit()) { $logfileJunit = $xmlConfiguration->logging()->junit()->target()->path(); } if ($cliConfiguration->hasTestdoxHtmlFile()) { $logfileTestdoxHtml = $cliConfiguration->testdoxHtmlFile(); } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasTestDoxHtml()) { $logfileTestdoxHtml = $xmlConfiguration->logging()->testDoxHtml()->target()->path(); } if ($cliConfiguration->hasTestdoxTextFile()) { $logfileTestdoxText = $cliConfiguration->testdoxTextFile(); } elseif ($loggingFromXmlConfiguration && $xmlConfiguration->logging()->hasTestDoxText()) { $logfileTestdoxText = $xmlConfiguration->logging()->testDoxText()->target()->path(); } $logEventsText = null; if ($cliConfiguration->hasLogEventsText()) { $logEventsText = $cliConfiguration->logEventsText(); } $logEventsVerboseText = null; if ($cliConfiguration->hasLogEventsVerboseText()) { $logEventsVerboseText = $cliConfiguration->logEventsVerboseText(); } $teamCityOutput = false; if ($cliConfiguration->hasTeamCityPrinter() && $cliConfiguration->teamCityPrinter()) { $teamCityOutput = true; } if ($cliConfiguration->hasTestDoxPrinter() && $cliConfiguration->testdoxPrinter()) { $testDoxOutput = true; } else { $testDoxOutput = $xmlConfiguration->phpunit()->testdoxPrinter(); } $noProgress = false; if ($cliConfiguration->hasNoProgress() && $cliConfiguration->noProgress()) { $noProgress = true; } $noResults = false; if ($cliConfiguration->hasNoResults() && $cliConfiguration->noResults()) { $noResults = true; } $noOutput = false; if ($cliConfiguration->hasNoOutput() && $cliConfiguration->noOutput()) { $noOutput = true; } $testsCovering = null; if ($cliConfiguration->hasTestsCovering()) { $testsCovering = $cliConfiguration->testsCovering(); } $testsUsing = null; if ($cliConfiguration->hasTestsUsing()) { $testsUsing = $cliConfiguration->testsUsing(); } $filter = null; if ($cliConfiguration->hasFilter()) { $filter = $cliConfiguration->filter(); } if ($cliConfiguration->hasGroups()) { $groups = $cliConfiguration->groups(); } else { $groups = $xmlConfiguration->groups()->include()->asArrayOfStrings(); } if ($cliConfiguration->hasExcludeGroups()) { $excludeGroups = $cliConfiguration->excludeGroups(); } else { $excludeGroups = $xmlConfiguration->groups()->exclude()->asArrayOfStrings(); } $excludeGroups = array_diff($excludeGroups, $groups); if ($cliConfiguration->hasRandomOrderSeed()) { $randomOrderSeed = $cliConfiguration->randomOrderSeed(); } else { $randomOrderSeed = time(); } if ($xmlConfiguration->wasLoadedFromFile() && $xmlConfiguration->hasValidationErrors()) { if ((new SchemaDetector)->detect($xmlConfiguration->filename())->detected()) { EventFacade::emitter()->testRunnerTriggeredPhpunitDeprecation( 'Your XML configuration validates against a deprecated schema. Migrate your XML configuration using "--migrate-configuration"!', ); } else { EventFacade::emitter()->testRunnerTriggeredPhpunitWarning( "Test results may not be as expected because the XML configuration file did not pass validation:\n" . $xmlConfiguration->validationErrors(), ); } } $includeUncoveredFiles = $xmlConfiguration->codeCoverage()->includeUncoveredFiles(); $includePaths = []; if ($cliConfiguration->hasIncludePath()) { foreach (explode(PATH_SEPARATOR, $cliConfiguration->includePath()) as $includePath) { $includePaths[] = new Directory($includePath); } } foreach ($xmlConfiguration->php()->includePaths() as $includePath) { $includePaths[] = $includePath; } $iniSettings = []; if ($cliConfiguration->hasIniSettings()) { foreach ($cliConfiguration->iniSettings() as $name => $value) { $iniSettings[] = new IniSetting($name, $value); } } foreach ($xmlConfiguration->php()->iniSettings() as $iniSetting) { $iniSettings[] = $iniSetting; } $includeTestSuite = ''; if ($cliConfiguration->hasTestSuite()) { $includeTestSuite = $cliConfiguration->testSuite(); } elseif ($xmlConfiguration->phpunit()->hasDefaultTestSuite()) { $includeTestSuite = $xmlConfiguration->phpunit()->defaultTestSuite(); } $excludeTestSuite = ''; if ($cliConfiguration->hasExcludedTestSuite()) { $excludeTestSuite = $cliConfiguration->excludedTestSuite(); } $testSuffixes = ['Test.php', '.phpt']; if ($cliConfiguration->hasTestSuffixes()) { $testSuffixes = $cliConfiguration->testSuffixes(); } $sourceIncludeDirectories = []; if ($cliConfiguration->hasCoverageFilter()) { foreach ($cliConfiguration->coverageFilter() as $directory) { $sourceIncludeDirectories[] = new FilterDirectory($directory, '', '.php'); } } if ($xmlConfiguration->codeCoverage()->hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport()) { foreach ($xmlConfiguration->codeCoverage()->directories() as $directory) { $sourceIncludeDirectories[] = $directory; } $sourceIncludeFiles = $xmlConfiguration->codeCoverage()->files(); $sourceExcludeDirectories = $xmlConfiguration->codeCoverage()->excludeDirectories(); $sourceExcludeFiles = $xmlConfiguration->codeCoverage()->excludeFiles(); } else { foreach ($xmlConfiguration->source()->includeDirectories() as $directory) { $sourceIncludeDirectories[] = $directory; } $sourceIncludeFiles = $xmlConfiguration->source()->includeFiles(); $sourceExcludeDirectories = $xmlConfiguration->source()->excludeDirectories(); $sourceExcludeFiles = $xmlConfiguration->source()->excludeFiles(); } $useBaseline = null; $generateBaseline = null; if (!$cliConfiguration->hasGenerateBaseline()) { if ($cliConfiguration->hasUseBaseline()) { $useBaseline = $cliConfiguration->useBaseline(); } elseif ($xmlConfiguration->source()->hasBaseline()) { $useBaseline = $xmlConfiguration->source()->baseline(); } } else { $generateBaseline = $cliConfiguration->generateBaseline(); } assert($useBaseline !== ''); assert($generateBaseline !== ''); return new Configuration( $cliConfiguration->arguments(), $configurationFile, $bootstrap, $cacheResult, $cacheDirectory, $coverageCacheDirectory, new Source( $useBaseline, $cliConfiguration->ignoreBaseline(), FilterDirectoryCollection::fromArray($sourceIncludeDirectories), $sourceIncludeFiles, $sourceExcludeDirectories, $sourceExcludeFiles, $xmlConfiguration->source()->restrictDeprecations(), $xmlConfiguration->source()->restrictNotices(), $xmlConfiguration->source()->restrictWarnings(), $xmlConfiguration->source()->ignoreSuppressionOfDeprecations(), $xmlConfiguration->source()->ignoreSuppressionOfPhpDeprecations(), $xmlConfiguration->source()->ignoreSuppressionOfErrors(), $xmlConfiguration->source()->ignoreSuppressionOfNotices(), $xmlConfiguration->source()->ignoreSuppressionOfPhpNotices(), $xmlConfiguration->source()->ignoreSuppressionOfWarnings(), $xmlConfiguration->source()->ignoreSuppressionOfPhpWarnings(), ), $testResultCacheFile, $coverageClover, $coverageCobertura, $coverageCrap4j, $coverageCrap4jThreshold, $coverageHtml, $coverageHtmlLowUpperBound, $coverageHtmlHighLowerBound, $coverageHtmlColorSuccessLow, $coverageHtmlColorSuccessMedium, $coverageHtmlColorSuccessHigh, $coverageHtmlColorWarning, $coverageHtmlColorDanger, $coverageHtmlCustomCssFile, $coveragePhp, $coverageText, $coverageTextShowUncoveredFiles, $coverageTextShowOnlySummary, $coverageXml, $pathCoverage, $xmlConfiguration->codeCoverage()->ignoreDeprecatedCodeUnits(), $disableCodeCoverageIgnore, $failOnAllIssues, $failOnDeprecation, $failOnPhpunitDeprecation, $failOnPhpunitWarning, $failOnEmptyTestSuite, $failOnIncomplete, $failOnNotice, $failOnRisky, $failOnSkipped, $failOnWarning, $doNotFailOnDeprecation, $doNotFailOnPhpunitDeprecation, $doNotFailOnPhpunitWarning, $doNotFailOnEmptyTestSuite, $doNotFailOnIncomplete, $doNotFailOnNotice, $doNotFailOnRisky, $doNotFailOnSkipped, $doNotFailOnWarning, $stopOnDefect, $stopOnDeprecation, $stopOnError, $stopOnFailure, $stopOnIncomplete, $stopOnNotice, $stopOnRisky, $stopOnSkipped, $stopOnWarning, $outputToStandardErrorStream, $columns, $noExtensions, $pharExtensionDirectory, $extensionBootstrappers, $backupGlobals, $backupStaticProperties, $beStrictAboutChangesToGlobalState, $colors, $processIsolation, $enforceTimeLimit, $defaultTimeLimit, $timeoutForSmallTests, $timeoutForMediumTests, $timeoutForLargeTests, $reportUselessTests, $strictCoverage, $disallowTestOutput, $displayDetailsOnAllIssues, $displayDetailsOnIncompleteTests, $displayDetailsOnSkippedTests, $displayDetailsOnTestsThatTriggerDeprecations, $displayDetailsOnPhpunitDeprecations, $displayDetailsOnTestsThatTriggerErrors, $displayDetailsOnTestsThatTriggerNotices, $displayDetailsOnTestsThatTriggerWarnings, $reverseDefectList, $requireCoverageMetadata, $registerMockObjectsFromTestArgumentsRecursively, $noProgress, $noResults, $noOutput, $executionOrder, $executionOrderDefects, $resolveDependencies, $logfileTeamcity, $logfileJunit, $logfileTestdoxHtml, $logfileTestdoxText, $logEventsText, $logEventsVerboseText, $teamCityOutput, $testDoxOutput, $testsCovering, $testsUsing, $filter, $groups, $excludeGroups, $randomOrderSeed, $includeUncoveredFiles, $xmlConfiguration->testSuite(), $includeTestSuite, $excludeTestSuite, $xmlConfiguration->phpunit()->hasDefaultTestSuite() ? $xmlConfiguration->phpunit()->defaultTestSuite() : null, $testSuffixes, new Php( DirectoryCollection::fromArray($includePaths), IniSettingCollection::fromArray($iniSettings), $xmlConfiguration->php()->constants(), $xmlConfiguration->php()->globalVariables(), $xmlConfiguration->php()->envVariables(), $xmlConfiguration->php()->postVariables(), $xmlConfiguration->php()->getVariables(), $xmlConfiguration->php()->cookieVariables(), $xmlConfiguration->php()->serverVariables(), $xmlConfiguration->php()->filesVariables(), $xmlConfiguration->php()->requestVariables(), ), $xmlConfiguration->phpunit()->controlGarbageCollector(), $xmlConfiguration->phpunit()->numberOfTestsBeforeGarbageCollection(), $generateBaseline, $cliConfiguration->debug(), ); } } PKYg3]ʃ7Configuration/Value/TestDirectoryCollectionIterator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use function iterator_count; use Countable; use Iterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @template-implements Iterator */ final class TestDirectoryCollectionIterator implements Countable, Iterator { /** * @psalm-var list */ private readonly array $directories; private int $position = 0; public function __construct(TestDirectoryCollection $directories) { $this->directories = $directories->asArray(); } public function count(): int { return iterator_count($this); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->directories); } public function key(): int { return $this->position; } public function current(): TestDirectory { return $this->directories[$this->position]; } public function next(): void { $this->position++; } } PKYg3]W̋8Configuration/Value/Group.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Group { private readonly string $name; public function __construct(string $name) { $this->name = $name; } public function name(): string { return $this->name; } } PKYg3]luu*Configuration/Value/TestFileCollection.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use Countable; use IteratorAggregate; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable * * @template-implements IteratorAggregate */ final class TestFileCollection implements Countable, IteratorAggregate { /** * @psalm-var list */ private readonly array $files; /** * @psalm-param list $files */ public static function fromArray(array $files): self { return new self(...$files); } private function __construct(TestFile ...$files) { $this->files = $files; } /** * @psalm-return list */ public function asArray(): array { return $this->files; } public function count(): int { return count($this->files); } public function getIterator(): TestFileCollectionIterator { return new TestFileCollectionIterator($this); } public function isEmpty(): bool { return $this->count() === 0; } } PKYg3]=|FF2Configuration/Value/TestFileCollectionIterator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use function iterator_count; use Countable; use Iterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @template-implements Iterator */ final class TestFileCollectionIterator implements Countable, Iterator { /** * @psalm-var list */ private readonly array $files; private int $position = 0; public function __construct(TestFileCollection $files) { $this->files = $files->asArray(); } public function count(): int { return iterator_count($this); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->files); } public function key(): int { return $this->position; } public function current(): TestFile { return $this->files[$this->position]; } public function next(): void { $this->position++; } } PKYg3]5O^^2Configuration/Value/VariableCollectionIterator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use function iterator_count; use Countable; use Iterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @template-implements Iterator */ final class VariableCollectionIterator implements Countable, Iterator { /** * @psalm-var list */ private readonly array $variables; private int $position = 0; public function __construct(VariableCollection $variables) { $this->variables = $variables->asArray(); } public function count(): int { return iterator_count($this); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->variables); } public function key(): int { return $this->position; } public function current(): Variable { return $this->variables[$this->position]; } public function next(): void { $this->position++; } } PKYg3]mii3Configuration/Value/TestSuiteCollectionIterator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use function iterator_count; use Countable; use Iterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @template-implements Iterator */ final class TestSuiteCollectionIterator implements Countable, Iterator { /** * @psalm-var list */ private readonly array $testSuites; private int $position = 0; public function __construct(TestSuiteCollection $testSuites) { $this->testSuites = $testSuites->asArray(); } public function count(): int { return iterator_count($this); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->testSuites); } public function key(): int { return $this->position; } public function current(): TestSuite { return $this->testSuites[$this->position]; } public function next(): void { $this->position++; } } PKYg3]r/Configuration/Value/TestDirectoryCollection.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use Countable; use IteratorAggregate; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable * * @template-implements IteratorAggregate */ final class TestDirectoryCollection implements Countable, IteratorAggregate { /** * @psalm-var list */ private readonly array $directories; /** * @psalm-param list $directories */ public static function fromArray(array $directories): self { return new self(...$directories); } private function __construct(TestDirectory ...$directories) { $this->directories = $directories; } /** * @psalm-return list */ public function asArray(): array { return $this->directories; } public function count(): int { return count($this->directories); } public function getIterator(): TestDirectoryCollectionIterator { return new TestDirectoryCollectionIterator($this); } public function isEmpty(): bool { return $this->count() === 0; } } PKYg3]'Configuration/Value/FilterDirectory.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class FilterDirectory { /** * @psalm-var non-empty-string */ private readonly string $path; private readonly string $prefix; private readonly string $suffix; /** * @psalm-param non-empty-string $path */ public function __construct(string $path, string $prefix, string $suffix) { $this->path = $path; $this->prefix = $prefix; $this->suffix = $suffix; } /** * @psalm-return non-empty-string */ public function path(): string { return $this->path; } public function prefix(): string { return $this->prefix; } public function suffix(): string { return $this->suffix; } } PKYg3]ʅP^^2Configuration/Value/ConstantCollectionIterator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use function iterator_count; use Countable; use Iterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @template-implements Iterator */ final class ConstantCollectionIterator implements Countable, Iterator { /** * @psalm-var list */ private readonly array $constants; private int $position = 0; public function __construct(ConstantCollection $constants) { $this->constants = $constants->asArray(); } public function count(): int { return iterator_count($this); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->constants); } public function key(): int { return $this->position; } public function current(): Constant { return $this->constants[$this->position]; } public function next(): void { $this->position++; } } PKYg3]Yȸ*Configuration/Value/ExtensionBootstrap.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class ExtensionBootstrap { /** * @psalm-var class-string */ private readonly string $className; /** * @psalm-var array */ private readonly array $parameters; /** * @psalm-param class-string $className * @psalm-param array $parameters */ public function __construct(string $className, array $parameters) { $this->className = $className; $this->parameters = $parameters; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } /** * @psalm-return array */ public function parameters(): array { return $this->parameters; } } PKYg3]v!G>> Configuration/Value/Constant.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Constant { private readonly string $name; private readonly bool|string $value; public function __construct(string $name, bool|string $value) { $this->name = $name; $this->value = $value; } public function name(): string { return $this->name; } public function value(): bool|string { return $this->value; } } PKYg3] oo3Configuration/Value/DirectoryCollectionIterator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use function iterator_count; use Countable; use Iterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @template-implements Iterator */ final class DirectoryCollectionIterator implements Countable, Iterator { /** * @psalm-var list */ private readonly array $directories; private int $position = 0; public function __construct(DirectoryCollection $directories) { $this->directories = $directories->asArray(); } public function count(): int { return iterator_count($this); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->directories); } public function key(): int { return $this->position; } public function current(): Directory { return $this->directories[$this->position]; } public function next(): void { $this->position++; } } PKYg3]| <Configuration/Value/ExtensionBootstrapCollectionIterator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use function iterator_count; use Countable; use Iterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @template-implements Iterator */ final class ExtensionBootstrapCollectionIterator implements Countable, Iterator { /** * @psalm-var list */ private readonly array $extensionBootstraps; private int $position = 0; public function __construct(ExtensionBootstrapCollection $extensionBootstraps) { $this->extensionBootstraps = $extensionBootstraps->asArray(); } public function count(): int { return iterator_count($this); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->extensionBootstraps); } public function key(): int { return $this->position; } public function current(): ExtensionBootstrap { return $this->extensionBootstraps[$this->position]; } public function next(): void { $this->position++; } } PKYg3] 8__4Configuration/Value/ExtensionBootstrapCollection.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use IteratorAggregate; /** * @template-implements IteratorAggregate * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class ExtensionBootstrapCollection implements IteratorAggregate { /** * @psalm-var list */ private readonly array $extensionBootstraps; /** * @psalm-param list $extensionBootstraps */ public static function fromArray(array $extensionBootstraps): self { return new self(...$extensionBootstraps); } private function __construct(ExtensionBootstrap ...$extensionBootstraps) { $this->extensionBootstraps = $extensionBootstraps; } /** * @psalm-return list */ public function asArray(): array { return $this->extensionBootstraps; } public function getIterator(): ExtensionBootstrapCollectionIterator { return new ExtensionBootstrapCollectionIterator($this); } } PKYg3]W&+Configuration/Value/DirectoryCollection.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use Countable; use IteratorAggregate; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable * * @template-implements IteratorAggregate */ final class DirectoryCollection implements Countable, IteratorAggregate { /** * @psalm-var list */ private readonly array $directories; /** * @psalm-param list $directories */ public static function fromArray(array $directories): self { return new self(...$directories); } private function __construct(Directory ...$directories) { $this->directories = $directories; } /** * @psalm-return list */ public function asArray(): array { return $this->directories; } public function count(): int { return count($this->directories); } public function getIterator(): DirectoryCollectionIterator { return new DirectoryCollectionIterator($this); } public function isEmpty(): bool { return $this->count() === 0; } } PKYg3]Z!Configuration/Value/Directory.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Directory { private readonly string $path; public function __construct(string $path) { $this->path = $path; } public function path(): string { return $this->path; } } PKYg3]'Configuration/Value/GroupCollection.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use IteratorAggregate; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable * * @template-implements IteratorAggregate */ final class GroupCollection implements IteratorAggregate { /** * @psalm-var list */ private readonly array $groups; /** * @psalm-param list $groups */ public static function fromArray(array $groups): self { return new self(...$groups); } private function __construct(Group ...$groups) { $this->groups = $groups; } /** * @psalm-return list */ public function asArray(): array { return $this->groups; } /** * @psalm-return list */ public function asArrayOfStrings(): array { $result = []; foreach ($this->groups as $group) { $result[] = $group->name(); } return $result; } public function isEmpty(): bool { return empty($this->groups); } public function getIterator(): GroupCollectionIterator { return new GroupCollectionIterator($this); } } PKYg3]t Configuration/Value/Variable.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Variable { private readonly string $name; private readonly mixed $value; private readonly bool $force; public function __construct(string $name, mixed $value, bool $force) { $this->name = $name; $this->value = $value; $this->force = $force; } public function name(): string { return $this->name; } public function value(): mixed { return $this->value; } public function force(): bool { return $this->force; } } PKYg3]4Og1Configuration/Value/FilterDirectoryCollection.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use Countable; use IteratorAggregate; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable * * @template-implements IteratorAggregate */ final class FilterDirectoryCollection implements Countable, IteratorAggregate { /** * @psalm-var list */ private readonly array $directories; /** * @psalm-param list $directories */ public static function fromArray(array $directories): self { return new self(...$directories); } private function __construct(FilterDirectory ...$directories) { $this->directories = $directories; } /** * @psalm-return list */ public function asArray(): array { return $this->directories; } public function count(): int { return count($this->directories); } public function notEmpty(): bool { return !empty($this->directories); } public function getIterator(): FilterDirectoryCollectionIterator { return new FilterDirectoryCollectionIterator($this); } } PKYg3]ZE}ee,Configuration/Value/IniSettingCollection.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use Countable; use IteratorAggregate; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable * * @template-implements IteratorAggregate */ final class IniSettingCollection implements Countable, IteratorAggregate { /** * @psalm-var list */ private readonly array $iniSettings; /** * @psalm-param list $iniSettings */ public static function fromArray(array $iniSettings): self { return new self(...$iniSettings); } private function __construct(IniSetting ...$iniSettings) { $this->iniSettings = $iniSettings; } /** * @psalm-return list */ public function asArray(): array { return $this->iniSettings; } public function count(): int { return count($this->iniSettings); } public function getIterator(): IniSettingCollectionIterator { return new IniSettingCollectionIterator($this); } } PKYg3]ħ9Configuration/Value/FilterDirectoryCollectionIterator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use function iterator_count; use Countable; use Iterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @template-implements Iterator */ final class FilterDirectoryCollectionIterator implements Countable, Iterator { /** * @psalm-var list */ private readonly array $directories; private int $position = 0; public function __construct(FilterDirectoryCollection $directories) { $this->directories = $directories->asArray(); } public function count(): int { return iterator_count($this); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->directories); } public function key(): int { return $this->position; } public function current(): FilterDirectory { return $this->directories[$this->position]; } public function next(): void { $this->position++; } } PKYg3]Y==/Configuration/Value/GroupCollectionIterator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use function iterator_count; use Countable; use Iterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @template-implements Iterator */ final class GroupCollectionIterator implements Countable, Iterator { /** * @psalm-var list */ private readonly array $groups; private int $position = 0; public function __construct(GroupCollection $groups) { $this->groups = $groups->asArray(); } public function count(): int { return iterator_count($this); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->groups); } public function key(): int { return $this->position; } public function current(): Group { return $this->groups[$this->position]; } public function next(): void { $this->position++; } } PKYg3]1..Configuration/Value/File.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class File { /** * @psalm-var non-empty-string */ private readonly string $path; /** * @psalm-param non-empty-string $path */ public function __construct(string $path) { $this->path = $path; } /** * @psalm-return non-empty-string */ public function path(): string { return $this->path; } } PKYg3]W +Configuration/Value/TestSuiteCollection.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use Countable; use IteratorAggregate; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable * * @template-implements IteratorAggregate */ final class TestSuiteCollection implements Countable, IteratorAggregate { /** * @psalm-var list */ private readonly array $testSuites; /** * @psalm-param list $testSuites */ public static function fromArray(array $testSuites): self { return new self(...$testSuites); } private function __construct(TestSuite ...$testSuites) { $this->testSuites = $testSuites; } /** * @psalm-return list */ public function asArray(): array { return $this->testSuites; } public function count(): int { return count($this->testSuites); } public function getIterator(): TestSuiteCollectionIterator { return new TestSuiteCollectionIterator($this); } public function isEmpty(): bool { return $this->count() === 0; } } PKYg3]VB[tt4Configuration/Value/IniSettingCollectionIterator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use function iterator_count; use Countable; use Iterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @template-implements Iterator */ final class IniSettingCollectionIterator implements Countable, Iterator { /** * @psalm-var list */ private readonly array $iniSettings; private int $position = 0; public function __construct(IniSettingCollection $iniSettings) { $this->iniSettings = $iniSettings->asArray(); } public function count(): int { return iterator_count($this); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->iniSettings); } public function key(): int { return $this->position; } public function current(): IniSetting { return $this->iniSettings[$this->position]; } public function next(): void { $this->position++; } } PKYg3] VV&Configuration/Value/FileCollection.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use Countable; use IteratorAggregate; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable * * @template-implements IteratorAggregate */ final class FileCollection implements Countable, IteratorAggregate { /** * @psalm-var list */ private readonly array $files; /** * @psalm-param list $files */ public static function fromArray(array $files): self { return new self(...$files); } private function __construct(File ...$files) { $this->files = $files; } /** * @psalm-return list */ public function asArray(): array { return $this->files; } public function count(): int { return count($this->files); } public function notEmpty(): bool { return !empty($this->files); } public function getIterator(): FileCollectionIterator { return new FileCollectionIterator($this); } } PKYg3]X[!Configuration/Value/TestSuite.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class TestSuite { /** * @psalm-var non-empty-string */ private readonly string $name; private readonly TestDirectoryCollection $directories; private readonly TestFileCollection $files; private readonly FileCollection $exclude; /** * @psalm-param non-empty-string $name */ public function __construct(string $name, TestDirectoryCollection $directories, TestFileCollection $files, FileCollection $exclude) { $this->name = $name; $this->directories = $directories; $this->files = $files; $this->exclude = $exclude; } /** * @psalm-return non-empty-string */ public function name(): string { return $this->name; } public function directories(): TestDirectoryCollection { return $this->directories; } public function files(): TestFileCollection { return $this->files; } public function exclude(): FileCollection { return $this->exclude; } } PKYg3]zCC*Configuration/Value/ConstantCollection.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use Countable; use IteratorAggregate; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable * * @template-implements IteratorAggregate */ final class ConstantCollection implements Countable, IteratorAggregate { /** * @psalm-var list */ private readonly array $constants; /** * @psalm-param list $constants */ public static function fromArray(array $constants): self { return new self(...$constants); } private function __construct(Constant ...$constants) { $this->constants = $constants; } /** * @psalm-return list */ public function asArray(): array { return $this->constants; } public function count(): int { return count($this->constants); } public function getIterator(): ConstantCollectionIterator { return new ConstantCollectionIterator($this); } } PKYg3]322.Configuration/Value/FileCollectionIterator.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use function iterator_count; use Countable; use Iterator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @template-implements Iterator */ final class FileCollectionIterator implements Countable, Iterator { /** * @psalm-var list */ private readonly array $files; private int $position = 0; public function __construct(FileCollection $files) { $this->files = $files->asArray(); } public function count(): int { return iterator_count($this); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->files); } public function key(): int { return $this->position; } public function current(): File { return $this->files[$this->position]; } public function next(): void { $this->position++; } } PKYg3]e+111"Configuration/Value/IniSetting.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class IniSetting { private readonly string $name; private readonly string $value; public function __construct(string $name, string $value) { $this->name = $name; $this->value = $value; } public function name(): string { return $this->name; } public function value(): string { return $this->value; } } PKYg3]=^Configuration/Value/Source.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Source { /** * @psalm-var non-empty-string */ private readonly ?string $baseline; private readonly bool $ignoreBaseline; private readonly FilterDirectoryCollection $includeDirectories; private readonly FileCollection $includeFiles; private readonly FilterDirectoryCollection $excludeDirectories; private readonly FileCollection $excludeFiles; private readonly bool $restrictDeprecations; private readonly bool $restrictNotices; private readonly bool $restrictWarnings; private readonly bool $ignoreSuppressionOfDeprecations; private readonly bool $ignoreSuppressionOfPhpDeprecations; private readonly bool $ignoreSuppressionOfErrors; private readonly bool $ignoreSuppressionOfNotices; private readonly bool $ignoreSuppressionOfPhpNotices; private readonly bool $ignoreSuppressionOfWarnings; private readonly bool $ignoreSuppressionOfPhpWarnings; /** * @psalm-param non-empty-string $baseline */ public function __construct(?string $baseline, bool $ignoreBaseline, FilterDirectoryCollection $includeDirectories, FileCollection $includeFiles, FilterDirectoryCollection $excludeDirectories, FileCollection $excludeFiles, bool $restrictDeprecations, bool $restrictNotices, bool $restrictWarnings, bool $ignoreSuppressionOfDeprecations, bool $ignoreSuppressionOfPhpDeprecations, bool $ignoreSuppressionOfErrors, bool $ignoreSuppressionOfNotices, bool $ignoreSuppressionOfPhpNotices, bool $ignoreSuppressionOfWarnings, bool $ignoreSuppressionOfPhpWarnings) { $this->baseline = $baseline; $this->ignoreBaseline = $ignoreBaseline; $this->includeDirectories = $includeDirectories; $this->includeFiles = $includeFiles; $this->excludeDirectories = $excludeDirectories; $this->excludeFiles = $excludeFiles; $this->restrictDeprecations = $restrictDeprecations; $this->restrictNotices = $restrictNotices; $this->restrictWarnings = $restrictWarnings; $this->ignoreSuppressionOfDeprecations = $ignoreSuppressionOfDeprecations; $this->ignoreSuppressionOfPhpDeprecations = $ignoreSuppressionOfPhpDeprecations; $this->ignoreSuppressionOfErrors = $ignoreSuppressionOfErrors; $this->ignoreSuppressionOfNotices = $ignoreSuppressionOfNotices; $this->ignoreSuppressionOfPhpNotices = $ignoreSuppressionOfPhpNotices; $this->ignoreSuppressionOfWarnings = $ignoreSuppressionOfWarnings; $this->ignoreSuppressionOfPhpWarnings = $ignoreSuppressionOfPhpWarnings; } /** * @psalm-assert-if-true !null $this->baseline */ public function useBaseline(): bool { return $this->hasBaseline() && !$this->ignoreBaseline; } /** * @psalm-assert-if-true !null $this->baseline */ public function hasBaseline(): bool { return $this->baseline !== null; } /** * @throws NoBaselineException * * @psalm-return non-empty-string */ public function baseline(): string { if (!$this->hasBaseline()) { throw new NoBaselineException; } return $this->baseline; } public function includeDirectories(): FilterDirectoryCollection { return $this->includeDirectories; } public function includeFiles(): FileCollection { return $this->includeFiles; } public function excludeDirectories(): FilterDirectoryCollection { return $this->excludeDirectories; } public function excludeFiles(): FileCollection { return $this->excludeFiles; } public function notEmpty(): bool { return $this->includeDirectories->notEmpty() || $this->includeFiles->notEmpty(); } public function restrictDeprecations(): bool { return $this->restrictDeprecations; } public function restrictNotices(): bool { return $this->restrictNotices; } public function restrictWarnings(): bool { return $this->restrictWarnings; } public function ignoreSuppressionOfDeprecations(): bool { return $this->ignoreSuppressionOfDeprecations; } public function ignoreSuppressionOfPhpDeprecations(): bool { return $this->ignoreSuppressionOfPhpDeprecations; } public function ignoreSuppressionOfErrors(): bool { return $this->ignoreSuppressionOfErrors; } public function ignoreSuppressionOfNotices(): bool { return $this->ignoreSuppressionOfNotices; } public function ignoreSuppressionOfPhpNotices(): bool { return $this->ignoreSuppressionOfPhpNotices; } public function ignoreSuppressionOfWarnings(): bool { return $this->ignoreSuppressionOfWarnings; } public function ignoreSuppressionOfPhpWarnings(): bool { return $this->ignoreSuppressionOfPhpWarnings; } } PKYg3]͉ Configuration/Value/TestFile.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use PHPUnit\Util\VersionComparisonOperator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class TestFile { private readonly string $path; private readonly string $phpVersion; private readonly VersionComparisonOperator $phpVersionOperator; public function __construct(string $path, string $phpVersion, VersionComparisonOperator $phpVersionOperator) { $this->path = $path; $this->phpVersion = $phpVersion; $this->phpVersionOperator = $phpVersionOperator; } public function path(): string { return $this->path; } public function phpVersion(): string { return $this->phpVersion; } public function phpVersionOperator(): VersionComparisonOperator { return $this->phpVersionOperator; } } PKYg3]ĿCC*Configuration/Value/VariableCollection.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use function count; use Countable; use IteratorAggregate; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable * * @template-implements IteratorAggregate */ final class VariableCollection implements Countable, IteratorAggregate { /** * @psalm-var list */ private readonly array $variables; /** * @psalm-param list $variables */ public static function fromArray(array $variables): self { return new self(...$variables); } private function __construct(Variable ...$variables) { $this->variables = $variables; } /** * @psalm-return list */ public function asArray(): array { return $this->variables; } public function count(): int { return count($this->variables); } public function getIterator(): VariableCollectionIterator { return new VariableCollectionIterator($this); } } PKYg3]89U Configuration/Value/Php.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class Php { private readonly DirectoryCollection $includePaths; private readonly IniSettingCollection $iniSettings; private readonly ConstantCollection $constants; private readonly VariableCollection $globalVariables; private readonly VariableCollection $envVariables; private readonly VariableCollection $postVariables; private readonly VariableCollection $getVariables; private readonly VariableCollection $cookieVariables; private readonly VariableCollection $serverVariables; private readonly VariableCollection $filesVariables; private readonly VariableCollection $requestVariables; public function __construct(DirectoryCollection $includePaths, IniSettingCollection $iniSettings, ConstantCollection $constants, VariableCollection $globalVariables, VariableCollection $envVariables, VariableCollection $postVariables, VariableCollection $getVariables, VariableCollection $cookieVariables, VariableCollection $serverVariables, VariableCollection $filesVariables, VariableCollection $requestVariables) { $this->includePaths = $includePaths; $this->iniSettings = $iniSettings; $this->constants = $constants; $this->globalVariables = $globalVariables; $this->envVariables = $envVariables; $this->postVariables = $postVariables; $this->getVariables = $getVariables; $this->cookieVariables = $cookieVariables; $this->serverVariables = $serverVariables; $this->filesVariables = $filesVariables; $this->requestVariables = $requestVariables; } public function includePaths(): DirectoryCollection { return $this->includePaths; } public function iniSettings(): IniSettingCollection { return $this->iniSettings; } public function constants(): ConstantCollection { return $this->constants; } public function globalVariables(): VariableCollection { return $this->globalVariables; } public function envVariables(): VariableCollection { return $this->envVariables; } public function postVariables(): VariableCollection { return $this->postVariables; } public function getVariables(): VariableCollection { return $this->getVariables; } public function cookieVariables(): VariableCollection { return $this->cookieVariables; } public function serverVariables(): VariableCollection { return $this->serverVariables; } public function filesVariables(): VariableCollection { return $this->filesVariables; } public function requestVariables(): VariableCollection { return $this->requestVariables; } } PKYg3]~%Configuration/Value/TestDirectory.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use PHPUnit\Util\VersionComparisonOperator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @psalm-immutable */ final class TestDirectory { /** * @psalm-var non-empty-string */ private readonly string $path; private readonly string $prefix; private readonly string $suffix; private readonly string $phpVersion; private readonly VersionComparisonOperator $phpVersionOperator; /** * @psalm-param non-empty-string $path */ public function __construct(string $path, string $prefix, string $suffix, string $phpVersion, VersionComparisonOperator $phpVersionOperator) { $this->path = $path; $this->prefix = $prefix; $this->suffix = $suffix; $this->phpVersion = $phpVersion; $this->phpVersionOperator = $phpVersionOperator; } /** * @psalm-return non-empty-string */ public function path(): string { return $this->path; } public function prefix(): string { return $this->prefix; } public function suffix(): string { return $this->suffix; } public function phpVersion(): string { return $this->phpVersion; } public function phpVersionOperator(): VersionComparisonOperator { return $this->phpVersionOperator; } } PKYg3]3,,Configuration/PhpHandler.phpnu[ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\TextUI\Configuration; use const PATH_SEPARATOR; use function constant; use function define; use function defined; use function getenv; use function implode; use function ini_get; use function ini_set; use function putenv; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class PhpHandler { public function handle(Php $configuration): void { $this->handleIncludePaths($configuration->includePaths()); $this->handleIniSettings($configuration->iniSettings()); $this->handleConstants($configuration->constants()); $this->handleGlobalVariables($configuration->globalVariables()); $this->handleServerVariables($configuration->serverVariables()); $this->handleEnvVariables($configuration->envVariables()); $this->handleVariables('_POST', $configuration->postVariables()); $this->handleVariables('_GET', $configuration->getVariables()); $this->handleVariables('_COOKIE', $configuration->cookieVariables()); $this->handleVariables('_FILES', $configuration->filesVariables()); $this->handleVariables('_REQUEST', $configuration->requestVariables()); } private function handleIncludePaths(DirectoryCollection $includePaths): void { if (!$includePaths->isEmpty()) { $includePathsAsStrings = []; foreach ($includePaths as $includePath) { $includePathsAsStrings[] = $includePath->path(); } ini_set( 'include_path', implode(PATH_SEPARATOR, $includePathsAsStrings) . PATH_SEPARATOR . ini_get('include_path'), ); } } private function handleIniSettings(IniSettingCollection $iniSettings): void { foreach ($iniSettings as $iniSetting) { $value = $iniSetting->value(); if (defined($value)) { $value = (string) constant($value); } ini_set($iniSetting->name(), $value); } } private function handleConstants(ConstantCollection $constants): void { foreach ($constants as $constant) { if (!defined($constant->name())) { define($constant->name(), $constant->value()); } } } private function handleGlobalVariables(VariableCollection $variables): void { foreach ($variables as $variable) { $GLOBALS[$variable->name()] = $variable->value(); } } private function handleServerVariables(VariableCollection $variables): void { foreach ($variables as $variable) { $_SERVER[$variable->name()] = $variable->value(); } } private function handleVariables(string $target, VariableCollection $variables): void { foreach ($variables as $variable) { $GLOBALS[$target][$variable->name()] = $variable->value(); } } private function handleEnvVariables(VariableCollection $variables): void { foreach ($variables as $variable) { $name = $variable->name(); $value = $variable->value(); $force = $variable->force(); if ($force || getenv($name) === false) { putenv("{$name}={$value}"); } $value = getenv($name); if ($force || !isset($_ENV[$name])) { $_ENV[$name] = $value; } } } } PKYg3]K^ShellExitCodeCalculator.phpnu[PKYg3][\  1cCommand/Commands/GenerateConfigurationCommand.phpnu[PKYg3]yy*Command/Commands/ListTestSuitesCommand.phpnu[PKYg3]y*'Command/Commands/AtLeastVersionCommand.phpnu[PKYg3]jᧀtt$+Command/Commands/ShowHelpCommand.phpnu[PKYg3]0/Command/Commands/MigrateConfigurationCommand.phpnu[PKYg3]U"*6Command/Commands/ListTestsAsXmlCommand.phpnu[PKYg3]j:z +HCommand/Commands/ListTestsAsTextCommand.phpnu[PKYg3]rیc c (RCommand/Commands/VersionCheckCommand.phpnu[PKYg3]Xtt'[Command/Commands/ShowVersionCommand.phpnu[PKYg3]ˎ. . 1^Command/Commands/WarmCodeCoverageCacheCommand.phpnu[PKYg3]hw  &iCommand/Commands/ListGroupsCommand.phpnu[PKYg3]-bMM1rCommand/Commands/CheckPhpConfigurationCommand.phpnu[PKYg3]=D3Command/Result.phpnu[PKYg3]맳 **RCommand/Command.phpnu[PKYg3][ TestSuiteFilterProcessor.phpnu[PKYg3]P{]]'Exception/CannotOpenSocketException.phpnu[PKYg3]W==,rException/TestDirectoryNotFoundException.phpnu[PKYg3]e33' Exception/TestFileNotFoundException.phpnu[PKYg3]/d[OO$Exception/InvalidSocketException.phpnu[PKYg3]Z`##8Exception/Exception.phpnu[PKYg3]4)55Exception/RuntimeException.phpnu[PKYg3][[uGG%Help.phpnu[PKYg3]W%tt?Output/SummaryPrinter.phpnu[PKYg3]\r&& Output/TestDox/ResultPrinter.phpnu[PKYg3]55*10Output/Default/UnexpectedOutputPrinter.phpnu[PKYg3]!r'R'R 4Output/Default/ResultPrinter.phpnu[PKYg3]wkkS7Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitWarningSubscriber.phpnu[PKYg3]xڃW%Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.phpnu[PKYg3]2JqqS/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpDeprecationSubscriber.phpnu[PKYg3]FhAAL#Output/Default/ProgressPrinter/Subscriber/TestMarkedIncompleteSubscriber.phpnu[PKYg3];SSNOutput/Default/ProgressPrinter/Subscriber/TestTriggeredPhpNoticeSubscriber.phpnu[PKYg3]ADOutput/Default/ProgressPrinter/Subscriber/TestFinishedSubscriber.phpnu[PKYg3]% `__P6Output/Default/ProgressPrinter/Subscriber/TestTriggeredDeprecationSubscriber.phpnu[PKYg3]o]+8Output/Default/ProgressPrinter/Subscriber/Subscriber.phpnu[PKYg3]as__ROutput/Default/ProgressPrinter/Subscriber/TestRunnerExecutionStartedSubscriber.phpnu[PKYg3]xTwOutput/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.phpnu[PKYg3]`);;J|Output/Default/ProgressPrinter/Subscriber/TestTriggeredErrorSubscriber.phpnu[PKYg3]O  C1Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.phpnu[PKYg3]{DOutput/Default/ProgressPrinter/Subscriber/TestPreparedSubscriber.phpnu[PKYg3]HUBC4Output/Default/ProgressPrinter/Subscriber/TestErroredSubscriber.phpnu[PKYg3]jJBOutput/Default/ProgressPrinter/Subscriber/TestFailedSubscriber.phpnu[PKYg3];YYO/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpWarningSubscriber.phpnu[PKYg3] GGLOutput/Default/ProgressPrinter/Subscriber/TestTriggeredWarningSubscriber.phpnu[PKYg3]ɓ,l;;KOutput/Default/ProgressPrinter/Subscriber/TestConsideredRiskySubscriber.phpnu[PKYg3]SAAKOutput/Default/ProgressPrinter/Subscriber/TestTriggeredNoticeSubscriber.phpnu[PKYg3]d$//2<Output/Default/ProgressPrinter/ProgressPrinter.phpnu[PKYg3]u~[[aOutput/Printer/Printer.phpnu[PKYg3]ÆOutput/Printer/NullPrinter.phpnu[PKYg3]3C C !Output/Printer/DefaultPrinter.phpnu[PKYg3]l۵$$nOutput/Facade.phpnu[PKYg3]_i d5TestRunner.phpnu[PKYg3]^GfGf?Application.phpnu[PKYg3]?,Configuration/CodeCoverageFilterRegistry.phpnu[PKYg3], Configuration/SourceMapper.phpnu[PKYg3]"smm0AConfiguration/Cli/XmlConfigurationFileFinder.phpnu[PKYg3]kq>>#Configuration/Cli/Configuration.phpnu[PKYg3]tConfiguration/Cli/Builder.phpnu[PKYg3]CZZAConfiguration/Cli/Exception.phpnu[PKYg3] ܋Q Q CConfiguration/Registry.phpnu[PKYg3]&&HQConfiguration/Configuration.phpnu[PKYg3]xConfiguration/Builder.phpnu[PKYg3]5>rrConfiguration/Xml/Loader.phpnu[PKYg3]4&|"Configuration/Xml/SchemaFinder.phpnu[PKYg3]k.~1Configuration/Xml/LoadedFromFileConfiguration.phpnu[PKYg3]%~mm*įConfiguration/Xml/DefaultConfiguration.phpnu[PKYg3]Q #Configuration/Xml/Configuration.phpnu[PKYg3]L:@@0Configuration/Xml/Validator/ValidationResult.phpnu[PKYg3][[)WConfiguration/Xml/Validator/Validator.phpnu[PKYg3]; Configuration/Xml/Generator.phpnu[PKYg3]Et t 0&Configuration/Xml/Migration/MigrationBuilder.phpnu[PKYg3]f(Configuration/Xml/Migration/Migrator.phpnu[PKYg3]KNConfiguration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.phpnu[PKYg3]קk[?qConfiguration/Xml/Migration/Migrations/UpdateSchemaLocation.phpnu[PKYg3]a}DGConfiguration/Xml/Migration/Migrations/RemoveNoInteractionAttribute.phpnu[PKYg3]'AConfiguration/Xml/Migration/Migrations/CoverageCrap4jToReport.phpnu[PKYg3]#]?3Configuration/Xml/Migration/Migrations/CoverageHtmlToReport.phpnu[PKYg3]d^ Configuration/Xml/Migration/Migrations/RemoveCoverageElementProcessUncoveredFilesAttribute.phpnu[PKYg3],BRvv@ Configuration/Xml/Migration/Migrations/RemoveLoggingElements.phpnu[PKYg3]Q1>Configuration/Xml/Migration/Migrations/CoverageXmlToReport.phpnu[PKYg3]:NNCConfiguration/Xml/Migration/Migrations/IntroduceCoverageElement.phpnu[PKYg3]D??Configuration/Xml/Migration/Migrations/CoverageTextToReport.phpnu[PKYg3]mK"Configuration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.phpnu[PKYg3]R@B|(Configuration/Xml/Migration/Migrations/RemovePrinterAttributes.phpnu[PKYg3]?V,Configuration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.phpnu[PKYg3] m+W`3Configuration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.phpnu[PKYg3] E[rr:8Configuration/Xml/Migration/Migrations/RemoveListeners.phpnu[PKYg3]tY^<Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.phpnu[PKYg3]w``:@Configuration/Xml/Migration/Migrations/ConvertLogTypes.phpnu[PKYg3]t*hWiGConfiguration/Xml/Migration/Migrations/RemoveCoverageElementCacheDirectoryAttribute.phpnu[PKYg3]7T9KConfiguration/Xml/Migration/Migrations/RemoveLogTypes.phpnu[PKYg3]QdJPConfiguration/Xml/Migration/Migrations/MoveCoverageDirectoriesToSource.phpnu[PKYg3]qNJWConfiguration/Xml/Migration/Migrations/RemoveTestSuiteLoaderAttributes.phpnu[PKYg3]&9qqPR\Configuration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.phpnu[PKYg3]̨ZZ4CaConfiguration/Xml/Migration/Migrations/Migration.phpnu[PKYg3]Q!EdConfiguration/Xml/Migration/Migrations/RemoveTestDoxGroupsElement.phpnu[PKYg3]/"_dgConfiguration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.phpnu[PKYg3]'ӪRAdlConfiguration/Xml/Migration/Migrations/CoverageCloverToReport.phpnu[PKYg3]8 >xpConfiguration/Xml/Migration/Migrations/CoveragePhpToReport.phpnu[PKYg3] ]JvtConfiguration/Xml/Migration/Migrations/MoveWhitelistIncludesToCoverage.phpnu[PKYg3]J||EzConfiguration/Xml/Migration/Migrations/RemoveCacheTokensAttribute.phpnu[PKYg3]5ǖe?~Configuration/Xml/Migration/Migrations/LogToReportMigration.phpnu[PKYg3] ֺ7ZZQ)Configuration/Xml/Migration/Migrations/RemoveConversionToExceptionsAttributes.phpnu[PKYg3]t<Configuration/Xml/Migration/Migrations/RemoveEmptyFilter.phpnu[PKYg3]ppAConfiguration/Xml/Migration/Migrations/RemoveVerboseAttribute.phpnu[PKYg3]-ooOטConfiguration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.phpnu[PKYg3]NH;$JŝConfiguration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.phpnu[PKYg3]ЈIConfiguration/Xml/Migration/Migrations/RemoveCacheResultFileAttribute.phpnu[PKYg3]O$0Configuration/Xml/Migration/SnapshotNodeList.phpnu[PKYg3]z*uu2#Configuration/Xml/Migration/MigrationException.phpnu[PKYg3]}"m=''*Configuration/Xml/Logging/TestDox/Html.phpnu[PKYg3]v''*{Configuration/Xml/Logging/TestDox/Text.phpnu[PKYg3][}D##&Configuration/Xml/Logging/TeamCity.phpnu[PKYg3]8  #uConfiguration/Xml/Logging/Junit.phpnu[PKYg3]n=C C %Configuration/Xml/Logging/Logging.phpnu[PKYg3]<"JJ%Configuration/Xml/TestSuiteMapper.phpnu[PKYg3]:4uuDConfiguration/Xml/SchemaDetector/SuccessfulSchemaDetectionResult.phpnu[PKYg3]DZI[WW@Configuration/Xml/SchemaDetector/FailedSchemaDetectionResult.phpnu[PKYg3]N3Configuration/Xml/SchemaDetector/SchemaDetector.phpnu[PKYg3] :Configuration/Xml/SchemaDetector/SchemaDetectionResult.phpnu[PKYg3]/P^^Configuration/Xml/Exception.phpnu[PKYg3]VyConfiguration/Xml/Groups.phpnu[PKYg3]/Configuration/Xml/CodeCoverage/CodeCoverage.phpnu[PKYg3]\B003Configuration/Xml/CodeCoverage/Report/Cobertura.phpnu[PKYg3]\Ó .dConfiguration/Xml/CodeCoverage/Report/Html.phpnu[PKYg3]q#30U#Configuration/Xml/CodeCoverage/Report/Crap4j.phpnu[PKYg3]ު--0'Configuration/Xml/CodeCoverage/Report/Clover.phpnu[PKYg3]6=>>-!+Configuration/Xml/CodeCoverage/Report/Xml.phpnu[PKYg3]jz..Configuration/Xml/CodeCoverage/Report/Text.phpnu[PKYg3]&*q**-4Configuration/Xml/CodeCoverage/Report/Php.phpnu[PKYg3]G0=FF7Configuration/Xml/PHPUnit.phpnu[PKYg3]Ujj=~Configuration/Exception/NoPharExtensionDirectoryException.phpnu[PKYg3]al__2qConfiguration/Exception/NoCliArgumentException.phpnu[PKYg3],~Hdd72Configuration/Exception/NoDefaultTestSuiteException.phpnu[PKYg3] Tll?Configuration/Exception/ConfigurationCannotBeBuiltException.phpnu[PKYg3]c1Yee8؉Configuration/Exception/NoConfigurationFileException.phpnu[PKYg3]gZ3bb5Configuration/Exception/NoCacheDirectoryException.phpnu[PKYg3](U^5lConfiguration/Exception/CannotFindSchemaException.phpnu[PKYg3]mee8bConfiguration/Exception/FilterNotConfiguredException.phpnu[PKYg3]|"ff9/Configuration/Exception/LoggingNotConfiguredException.phpnu[PKYg3]aa4Configuration/Exception/NoCustomCssFileException.phpnu[PKYg3]Z@jj=ÚConfiguration/Exception/NoCoverageCacheDirectoryException.phpnu[PKYg3]^kqqDConfiguration/Exception/CodeCoverageReportNotConfiguredException.phpnu[PKYg3]da\\/Configuration/Exception/NoBaselineException.phpnu[PKYg3]5P11%:Configuration/Exception/Exception.phpnu[PKYg3]N&]]0Configuration/Exception/NoBootstrapException.phpnu[PKYg3] "}Configuration/TestSuiteBuilder.phpnu[PKYg3]Configuration/SourceFilter.phpnu[PKYg3]#ؾConfiguration/Merger.phpnu[PKYg3]ʃ7ZConfiguration/Value/TestDirectoryCollectionIterator.phpnu[PKYg3]W̋8`Configuration/Value/Group.phpnu[PKYg3]luu*cConfiguration/Value/TestFileCollection.phpnu[PKYg3]=|FF2ZiConfiguration/Value/TestFileCollectionIterator.phpnu[PKYg3]5O^^2oConfiguration/Value/VariableCollectionIterator.phpnu[PKYg3]mii3tConfiguration/Value/TestSuiteCollectionIterator.phpnu[PKYg3]r/zConfiguration/Value/TestDirectoryCollection.phpnu[PKYg3]'Configuration/Value/FilterDirectory.phpnu[PKYg3]ʅP^^2Configuration/Value/ConstantCollectionIterator.phpnu[PKYg3]Yȸ*^Configuration/Value/ExtensionBootstrap.phpnu[PKYg3]v!G>> nConfiguration/Value/Constant.phpnu[PKYg3] oo3Configuration/Value/DirectoryCollectionIterator.phpnu[PKYg3]| <ΙConfiguration/Value/ExtensionBootstrapCollectionIterator.phpnu[PKYg3] 8__4Configuration/Value/ExtensionBootstrapCollection.phpnu[PKYg3]W&+ɥConfiguration/Value/DirectoryCollection.phpnu[PKYg3]Z!׫Configuration/Value/Directory.phpnu[PKYg3]'Configuration/Value/GroupCollection.phpnu[PKYg3]t Configuration/Value/Variable.phpnu[PKYg3]4Og1Configuration/Value/FilterDirectoryCollection.phpnu[PKYg3]ZE}ee,OConfiguration/Value/IniSettingCollection.phpnu[PKYg3]ħ9Configuration/Value/FilterDirectoryCollectionIterator.phpnu[PKYg3]Y==/Configuration/Value/GroupCollectionIterator.phpnu[PKYg3]1..Configuration/Value/File.phpnu[PKYg3]W +Configuration/Value/TestSuiteCollection.phpnu[PKYg3]VB[tt4!Configuration/Value/IniSettingCollectionIterator.phpnu[PKYg3] VV&Configuration/Value/FileCollection.phpnu[PKYg3]X[!Configuration/Value/TestSuite.phpnu[PKYg3]zCC*Configuration/Value/ConstantCollection.phpnu[PKYg3]322.VConfiguration/Value/FileCollectionIterator.phpnu[PKYg3]e+111"Configuration/Value/IniSetting.phpnu[PKYg3]=^iConfiguration/Value/Source.phpnu[PKYg3]͉  Configuration/Value/TestFile.phpnu[PKYg3]ĿCC* Configuration/Value/VariableCollection.phpnu[PKYg3]89U + Configuration/Value/Php.phpnu[PKYg3]~%( Configuration/Value/TestDirectory.phpnu[PKYg3]3,,(/ Configuration/PhpHandler.phpnu[PKxR>