*/ public array $tests; public function __construct( private Options $options, OutputInterface $output, CodeCoverageFilterRegistry $codeCoverageFilterRegistry, ) { (new PhpHandler())->handle($this->options->configuration->php()); if ($this->options->configuration->hasBootstrap()) { $bootstrapFilename = $this->options->configuration->bootstrap(); include_once $bootstrapFilename; EventFacade::emitter()->testRunnerBootstrapFinished($bootstrapFilename); } if (! $this->options->configuration->noExtensions()) { if ($this->options->configuration->hasPharExtensionDirectory()) { (new PharLoader())->loadPharExtensionsInDirectory( $this->options->configuration->pharExtensionDirectory(), ); } $extensionFacade = new ExtensionFacade(); $extensionBootstrapper = new ExtensionBootstrapper( $this->options->configuration, $extensionFacade, ); foreach ($this->options->configuration->extensionBootstrappers() as $bootstrapper) { $extensionBootstrapper->bootstrap( $bootstrapper['className'], $bootstrapper['parameters'], ); } } TestResultFacade::init(); EventFacade::instance()->seal(); $testSuite = (new TestSuiteBuilder())->build($this->options->configuration); if ($this->options->configuration->executionOrder() === TestSuiteSorter::ORDER_RANDOMIZED) { mt_srand($this->options->configuration->randomOrderSeed()); } if ( $this->options->configuration->executionOrder() !== TestSuiteSorter::ORDER_DEFAULT || $this->options->configuration->executionOrderDefects() !== TestSuiteSorter::ORDER_DEFAULT || $this->options->configuration->resolveDependencies() ) { $resultCache = new NullResultCache(); if ($this->options->configuration->cacheResult()) { $resultCache = new DefaultResultCache($this->options->configuration->testResultCacheFile()); $resultCache->load(); } (new TestSuiteSorter($resultCache))->reorderTestsInSuite( $testSuite, $this->options->configuration->executionOrder(), $this->options->configuration->resolveDependencies(), $this->options->configuration->executionOrderDefects(), ); } (new TestSuiteFilterProcessor())->process($this->options->configuration, $testSuite); $this->testCount = count($testSuite); $files = []; $tests = []; foreach ($this->loadFiles($testSuite) as $file => $test) { $files[$file] = null; if ($test instanceof PhptTestCase) { $tests[] = $file; } else { $name = $test->name(); if ($test->providedData() !== []) { $dataName = $test->dataName(); if ($this->options->functional) { $name = sprintf('/%s%s$/', preg_quote($name, '/'), preg_quote($test->dataSetAsString(), '/')); } else { if (is_int($dataName)) { $name .= '#' . $dataName; } else { $name .= '@' . $dataName; } } } else { $name = sprintf('/%s$/', $name); } $tests[] = "$file\0$name"; } } $this->tests = $this->options->functional ? $tests : array_keys($files); if (! $this->options->configuration->hasCoverageReport()) { return; } ob_start(); $result = (new WarmCodeCoverageCacheCommand( $this->options->configuration, $codeCoverageFilterRegistry, ))->execute(); $ob_get_clean = ob_get_clean(); assert($ob_get_clean !== false); $output->write($ob_get_clean); $output->write($result->output()); if ($result->shellExitCode() !== Result::SUCCESS) { exit($result->shellExitCode()); } } /** @return Generator */ private function loadFiles(TestSuite $testSuite): Generator { foreach ($testSuite as $test) { if ($test instanceof TestSuite) { yield from $this->loadFiles($test); continue; } if ($test instanceof PhptTestCase) { $refProperty = new ReflectionProperty(PhptTestCase::class, 'filename'); $filename = $refProperty->getValue($test); assert(is_string($filename) && $filename !== ''); $filename = $this->stripCwd($filename); yield $filename => $test; continue; } if ($test instanceof TestCase) { $refClass = new ReflectionClass($test); $filename = $refClass->getFileName(); assert(is_string($filename)); $filename = $this->stripCwd($filename); yield $filename => $test; continue; } } } /** * @param non-empty-string $filename * * @return non-empty-string */ private function stripCwd(string $filename): string { if (! str_starts_with($filename, $this->options->cwd)) { return $filename; } $substr = substr($filename, 1 + strlen($this->options->cwd)); assert($substr !== ''); return $substr; } }