mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 07:47:22 +01:00
WIP
This commit is contained in:
committed by
Nuno Maduro
parent
48309931ef
commit
2929af4715
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use ParaTest\WrapperRunner\ApplicationForWrapperWorker;
|
||||||
|
use ParaTest\WrapperRunner\WrapperWorker;
|
||||||
|
use Pest\ConfigLoader;
|
||||||
|
use Pest\TestSuite;
|
||||||
|
use Symfony\Component\Console\Input\ArgvInput;
|
||||||
|
|
||||||
|
(static function (): void {
|
||||||
|
$getopt = getopt('', [
|
||||||
|
'status-file:',
|
||||||
|
'progress-file:',
|
||||||
|
'testresult-file:',
|
||||||
|
'teamcity-file:',
|
||||||
|
'testdox-file:',
|
||||||
|
'testdox-color',
|
||||||
|
'phpunit-argv:',
|
||||||
|
]);
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../overrides/Runner/TestSuiteLoader.php';
|
||||||
|
require_once __DIR__ . '/../overrides/Runner/Filter/NameFilterIterator.php';
|
||||||
|
|
||||||
|
$composerAutoloadFiles = [
|
||||||
|
dirname(__DIR__, 3) . DIRECTORY_SEPARATOR . 'autoload.php',
|
||||||
|
dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php',
|
||||||
|
dirname(__DIR__) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($composerAutoloadFiles as $file) {
|
||||||
|
if (file_exists($file)) {
|
||||||
|
require_once $file;
|
||||||
|
define('PHPUNIT_COMPOSER_INSTALL', $file);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(isset($getopt['status-file']) && is_string($getopt['status-file']));
|
||||||
|
$statusFile = fopen($getopt['status-file'], 'wb');
|
||||||
|
assert(is_resource($statusFile));
|
||||||
|
|
||||||
|
assert(isset($getopt['progress-file']) && is_string($getopt['progress-file']));
|
||||||
|
assert(isset($getopt['testresult-file']) && is_string($getopt['testresult-file']));
|
||||||
|
assert(!isset($getopt['teamcity-file']) || is_string($getopt['teamcity-file']));
|
||||||
|
assert(!isset($getopt['testdox-file']) || is_string($getopt['testdox-file']));
|
||||||
|
|
||||||
|
assert(isset($getopt['phpunit-argv']) && is_string($getopt['phpunit-argv']));
|
||||||
|
$phpunitArgv = unserialize($getopt['phpunit-argv'], ['allowed_classes' => false]);
|
||||||
|
assert(is_array($phpunitArgv));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need to instantiate the Pest Test suite instance
|
||||||
|
* so that Pest is able to execute correctly.
|
||||||
|
*/
|
||||||
|
$argv = new ArgvInput();
|
||||||
|
$rootPath = dirname(PHPUNIT_COMPOSER_INSTALL, 2);
|
||||||
|
TestSuite::getInstance(
|
||||||
|
$rootPath,
|
||||||
|
$argv->getParameterOption('--test-directory', (new ConfigLoader($rootPath))->getTestsDirectory()),
|
||||||
|
);
|
||||||
|
|
||||||
|
$application = new ApplicationForWrapperWorker(
|
||||||
|
$phpunitArgv,
|
||||||
|
$getopt['progress-file'],
|
||||||
|
$getopt['testresult-file'],
|
||||||
|
$getopt['teamcity-file'] ?? null,
|
||||||
|
$getopt['testdox-file'] ?? null,
|
||||||
|
isset($getopt['testdox-color']),
|
||||||
|
);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (feof(STDIN)) {
|
||||||
|
$application->end();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$testPath = fgets(STDIN);
|
||||||
|
if ($testPath === false || $testPath === WrapperWorker::COMMAND_EXIT) {
|
||||||
|
$application->end();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It must be a 1 byte string to ensure filesize() is equal to the number of tests executed
|
||||||
|
$exitCode = $application->runTest(trim($testPath));
|
||||||
|
|
||||||
|
fwrite($statusFile, (string) $exitCode);
|
||||||
|
fflush($statusFile);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|||||||
@ -12,6 +12,7 @@ use ParaTest\RunnerInterface;
|
|||||||
use ParaTest\WrapperRunner\ResultPrinter;
|
use ParaTest\WrapperRunner\ResultPrinter;
|
||||||
use ParaTest\WrapperRunner\SuiteLoader;
|
use ParaTest\WrapperRunner\SuiteLoader;
|
||||||
use ParaTest\WrapperRunner\WrapperWorker;
|
use ParaTest\WrapperRunner\WrapperWorker;
|
||||||
|
use Pest\TestSuite;
|
||||||
use PHPUnit\Event\Facade as EventFacade;
|
use PHPUnit\Event\Facade as EventFacade;
|
||||||
use PHPUnit\Runner\CodeCoverage;
|
use PHPUnit\Runner\CodeCoverage;
|
||||||
use PHPUnit\TestRunner\TestResult\Facade as TestResultFacade;
|
use PHPUnit\TestRunner\TestResult\Facade as TestResultFacade;
|
||||||
@ -31,6 +32,7 @@ use function dirname;
|
|||||||
use function file_get_contents;
|
use function file_get_contents;
|
||||||
use function max;
|
use function max;
|
||||||
use function realpath;
|
use function realpath;
|
||||||
|
use function unlink;
|
||||||
use function unserialize;
|
use function unserialize;
|
||||||
use function usleep;
|
use function usleep;
|
||||||
|
|
||||||
@ -50,15 +52,15 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
/** @var array<int,int> */
|
/** @var array<int,int> */
|
||||||
private array $batches = [];
|
private array $batches = [];
|
||||||
|
|
||||||
/** @var SplFileInfo */
|
/** @var list<SplFileInfo> */
|
||||||
private array $testresultFiles = [];
|
private array $testresultFiles = [];
|
||||||
/** @var SplFileInfo */
|
/** @var list<SplFileInfo> */
|
||||||
private array $coverageFiles = [];
|
private array $coverageFiles = [];
|
||||||
/** @var SplFileInfo */
|
/** @var list<SplFileInfo> */
|
||||||
private array $junitFiles = [];
|
private array $junitFiles = [];
|
||||||
/** @var SplFileInfo */
|
/** @var list<SplFileInfo> */
|
||||||
private array $teamcityFiles = [];
|
private array $teamcityFiles = [];
|
||||||
/** @var SplFileInfo */
|
/** @var list<SplFileInfo> */
|
||||||
private array $testdoxFiles = [];
|
private array $testdoxFiles = [];
|
||||||
|
|
||||||
/** @var non-empty-string[] */
|
/** @var non-empty-string[] */
|
||||||
@ -71,7 +73,7 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
$this->printer = new ResultPrinter($output, $options);
|
$this->printer = new ResultPrinter($output, $options);
|
||||||
|
|
||||||
$wrapper = realpath(
|
$wrapper = realpath(
|
||||||
dirname(__DIR__, 5) . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'phpunit-wrapper.php',
|
dirname(__DIR__, 4) . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'pest-wrapper.php',
|
||||||
);
|
);
|
||||||
assert($wrapper !== false);
|
assert($wrapper !== false);
|
||||||
$phpFinder = new PhpExecutableFinder();
|
$phpFinder = new PhpExecutableFinder();
|
||||||
@ -89,21 +91,23 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
$this->parameters = $parameters;
|
$this->parameters = $parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run(): void
|
public function run(): int
|
||||||
{
|
{
|
||||||
ExcludeList::addDirectory(dirname(__DIR__));
|
ExcludeList::addDirectory(dirname(__DIR__));
|
||||||
TestResultFacade::init();
|
TestResultFacade::init();
|
||||||
EventFacade::seal();
|
EventFacade::seal();
|
||||||
$suiteLoader = new SuiteLoader($this->options, $this->output);
|
$suiteLoader = new SuiteLoader($this->options, $this->output);
|
||||||
|
$this->pending = $this->getTestFiles($suiteLoader);
|
||||||
|
|
||||||
$result = TestResultFacade::result();
|
$result = TestResultFacade::result();
|
||||||
|
|
||||||
$this->pending = $suiteLoader->files;
|
|
||||||
$this->printer->setTestCount($suiteLoader->testCount);
|
$this->printer->setTestCount($suiteLoader->testCount);
|
||||||
$this->printer->start();
|
$this->printer->start();
|
||||||
$this->startWorkers();
|
$this->startWorkers();
|
||||||
$this->assignAllPendingTests();
|
$this->assignAllPendingTests();
|
||||||
$this->waitForAllToFinish();
|
$this->waitForAllToFinish();
|
||||||
$this->complete($result);
|
|
||||||
|
return $this->complete($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getExitCode(): int
|
public function getExitCode(): int
|
||||||
@ -141,10 +145,7 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
$this->exitcode > 0
|
$this->exitcode > 0
|
||||||
&& (
|
&& $this->options->configuration->stopOnFailure()
|
||||||
$this->options->configuration->stopOnFailure()
|
|
||||||
|| $this->options->configuration->stopOnError()
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
$this->pending = [];
|
$this->pending = [];
|
||||||
} elseif (($pending = array_shift($this->pending)) !== null) {
|
} elseif (($pending = array_shift($this->pending)) !== null) {
|
||||||
@ -160,7 +161,10 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
private function flushWorker(WrapperWorker $worker): void
|
private function flushWorker(WrapperWorker $worker): void
|
||||||
{
|
{
|
||||||
$this->exitcode = max($this->exitcode, $worker->getExitCode());
|
$this->exitcode = max($this->exitcode, $worker->getExitCode());
|
||||||
$this->printer->printFeedback($worker->progressFile);
|
$this->printer->printFeedback(
|
||||||
|
$worker->progressFile,
|
||||||
|
$this->teamcityFiles,
|
||||||
|
);
|
||||||
$worker->reset();
|
$worker->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +236,7 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
unset($this->workers[$token]);
|
unset($this->workers[$token]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function complete(TestResult $testResultSum): void
|
private function complete(TestResult $testResultSum): int
|
||||||
{
|
{
|
||||||
foreach ($this->testresultFiles as $testresultFile) {
|
foreach ($this->testresultFiles as $testresultFile) {
|
||||||
if (! $testresultFile->isFile()) {
|
if (! $testresultFile->isFile()) {
|
||||||
@ -251,6 +255,7 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
array_merge_recursive($testResultSum->testErroredEvents(), $testResult->testErroredEvents()),
|
array_merge_recursive($testResultSum->testErroredEvents(), $testResult->testErroredEvents()),
|
||||||
array_merge_recursive($testResultSum->testFailedEvents(), $testResult->testFailedEvents()),
|
array_merge_recursive($testResultSum->testFailedEvents(), $testResult->testFailedEvents()),
|
||||||
array_merge_recursive($testResultSum->testConsideredRiskyEvents(), $testResult->testConsideredRiskyEvents()),
|
array_merge_recursive($testResultSum->testConsideredRiskyEvents(), $testResult->testConsideredRiskyEvents()),
|
||||||
|
array_merge_recursive($testResultSum->testSuiteSkippedEvents(), $testResult->testSuiteSkippedEvents()),
|
||||||
array_merge_recursive($testResultSum->testSkippedEvents(), $testResult->testSkippedEvents()),
|
array_merge_recursive($testResultSum->testSkippedEvents(), $testResult->testSkippedEvents()),
|
||||||
array_merge_recursive($testResultSum->testMarkedIncompleteEvents(), $testResult->testMarkedIncompleteEvents()),
|
array_merge_recursive($testResultSum->testMarkedIncompleteEvents(), $testResult->testMarkedIncompleteEvents()),
|
||||||
array_merge_recursive($testResultSum->testTriggeredDeprecationEvents(), $testResult->testTriggeredDeprecationEvents()),
|
array_merge_recursive($testResultSum->testTriggeredDeprecationEvents(), $testResult->testTriggeredDeprecationEvents()),
|
||||||
@ -268,11 +273,15 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->printer->printResults($testResultSum);
|
$this->printer->printResults(
|
||||||
|
$testResultSum,
|
||||||
|
$this->teamcityFiles,
|
||||||
|
$this->testdoxFiles,
|
||||||
|
);
|
||||||
$this->generateCodeCoverageReports();
|
$this->generateCodeCoverageReports();
|
||||||
$this->generateLogs();
|
$this->generateLogs();
|
||||||
|
|
||||||
$this->exitcode = (new ShellExitCodeCalculator())->calculate(
|
$exitcode = (new ShellExitCodeCalculator())->calculate(
|
||||||
$this->options->configuration->failOnEmptyTestSuite(),
|
$this->options->configuration->failOnEmptyTestSuite(),
|
||||||
$this->options->configuration->failOnRisky(),
|
$this->options->configuration->failOnRisky(),
|
||||||
$this->options->configuration->failOnWarning(),
|
$this->options->configuration->failOnWarning(),
|
||||||
@ -280,6 +289,14 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
$this->options->configuration->failOnSkipped(),
|
$this->options->configuration->failOnSkipped(),
|
||||||
$testResultSum,
|
$testResultSum,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->clearFiles($this->testresultFiles);
|
||||||
|
$this->clearFiles($this->coverageFiles);
|
||||||
|
$this->clearFiles($this->junitFiles);
|
||||||
|
$this->clearFiles($this->teamcityFiles);
|
||||||
|
$this->clearFiles($this->testdoxFiles);
|
||||||
|
|
||||||
|
return $exitcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function generateCodeCoverageReports(): void
|
protected function generateCodeCoverageReports(): void
|
||||||
@ -312,4 +329,33 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
$this->options->configuration->logfileJunit(),
|
$this->options->configuration->logfileJunit(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @param list<SplFileInfo> $files */
|
||||||
|
private function clearFiles(array $files): void
|
||||||
|
{
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if (! $file->isFile()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink($file->getPathname());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getTestFiles(SuiteLoader $suiteLoader): array
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* TODO: Clean this up
|
||||||
|
*
|
||||||
|
* We are doing this because the SuiteLoader returns filenames incorrectly
|
||||||
|
* for Pest tests. We need to find a better way to do this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$tests = array_filter(
|
||||||
|
$suiteLoader->files,
|
||||||
|
fn(string $filename) => ! str_ends_with($filename, "eval()'d code")
|
||||||
|
);
|
||||||
|
|
||||||
|
return [...$tests, ...TestSuite::getInstance()->tests->getFilenames()];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user