mirror of
https://github.com/pestphp/pest.git
synced 2026-09-07 07:13:35 +02:00
chore: upgrades to phpunit:13.3
This commit is contained in:
@@ -14,13 +14,14 @@ declare(strict_types=1);
|
||||
namespace PHPUnit\Runner;
|
||||
|
||||
use PHPUnit\Framework\DataProviderTestSuite;
|
||||
use PHPUnit\Framework\IterativeTestSuite;
|
||||
use PHPUnit\Framework\Reorderable;
|
||||
use PHPUnit\Framework\Test;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\TestSuite;
|
||||
use PHPUnit\Runner\ResultCache\NullResultCache;
|
||||
use PHPUnit\Runner\ResultCache\ResultCache;
|
||||
use PHPUnit\Runner\ResultCache\ResultCacheId;
|
||||
use PHPUnit\Runner\TestRunHistory\NullTestRunHistory;
|
||||
use PHPUnit\Runner\TestRunHistory\TestRunHistory;
|
||||
use PHPUnit\Runner\TestRunHistory\TestRunHistoryId;
|
||||
|
||||
use function array_diff;
|
||||
use function array_merge;
|
||||
@@ -46,9 +47,13 @@ final class TestSuiteSorter
|
||||
|
||||
public const int ORDER_DEFECTS_FIRST = 3;
|
||||
|
||||
public const int ORDER_DURATION = 4;
|
||||
public const int ORDER_DURATION_ASCENDING = 4;
|
||||
|
||||
public const int ORDER_SIZE = 5;
|
||||
public const int ORDER_SIZE_ASCENDING = 5;
|
||||
|
||||
public const int ORDER_DURATION_DESCENDING = 6;
|
||||
|
||||
public const int ORDER_SIZE_DESCENDING = 7;
|
||||
|
||||
/**
|
||||
* @var non-empty-array<non-empty-string, positive-int>
|
||||
@@ -65,11 +70,11 @@ final class TestSuiteSorter
|
||||
*/
|
||||
private array $defectSortOrder = [];
|
||||
|
||||
private readonly ResultCache $cache;
|
||||
private readonly TestRunHistory $testRunHistory;
|
||||
|
||||
public function __construct(?ResultCache $cache = null)
|
||||
public function __construct(?TestRunHistory $testRunHistory = null)
|
||||
{
|
||||
$this->cache = $cache ?? new NullResultCache;
|
||||
$this->testRunHistory = $testRunHistory ?? new NullTestRunHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,8 +86,10 @@ final class TestSuiteSorter
|
||||
self::ORDER_DEFAULT,
|
||||
self::ORDER_REVERSED,
|
||||
self::ORDER_RANDOMIZED,
|
||||
self::ORDER_DURATION,
|
||||
self::ORDER_SIZE,
|
||||
self::ORDER_DURATION_ASCENDING,
|
||||
self::ORDER_SIZE_ASCENDING,
|
||||
self::ORDER_DURATION_DESCENDING,
|
||||
self::ORDER_SIZE_DESCENDING,
|
||||
];
|
||||
|
||||
if (! in_array($order, $allowedOrders, true)) {
|
||||
@@ -102,6 +109,10 @@ final class TestSuiteSorter
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
if ($suite instanceof IterativeTestSuite) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($suite instanceof TestSuite) {
|
||||
foreach ($suite as $_suite) {
|
||||
$this->reorderTestsInSuite($_suite, $order, $resolveDependencies, $orderDefects);
|
||||
@@ -117,31 +128,37 @@ final class TestSuiteSorter
|
||||
|
||||
private function sort(TestSuite $suite, int $order, bool $resolveDependencies, int $orderDefects): void
|
||||
{
|
||||
if ($suite->tests() === []) {
|
||||
$tests = $suite->tests();
|
||||
|
||||
if ($tests === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($order === self::ORDER_REVERSED) {
|
||||
$suite->setTests($this->reverse($suite->tests()));
|
||||
$tests = $this->reverse($tests);
|
||||
} elseif ($order === self::ORDER_RANDOMIZED) {
|
||||
$suite->setTests($this->randomize($suite->tests()));
|
||||
} elseif ($order === self::ORDER_DURATION) {
|
||||
$suite->setTests($this->sortByDuration($suite->tests()));
|
||||
} elseif ($order === self::ORDER_SIZE) {
|
||||
$suite->setTests($this->sortBySize($suite->tests()));
|
||||
$tests = $this->randomize($tests);
|
||||
} elseif ($order === self::ORDER_DURATION_ASCENDING) {
|
||||
$tests = $this->sortByDuration($tests);
|
||||
} elseif ($order === self::ORDER_DURATION_DESCENDING) {
|
||||
$tests = $this->sortByDurationDescending($tests);
|
||||
} elseif ($order === self::ORDER_SIZE_ASCENDING) {
|
||||
$tests = $this->sortBySize($tests);
|
||||
} elseif ($order === self::ORDER_SIZE_DESCENDING) {
|
||||
$tests = $this->sortBySizeDescending($tests);
|
||||
}
|
||||
|
||||
if ($orderDefects === self::ORDER_DEFECTS_FIRST) {
|
||||
$suite->setTests($this->sortDefectsFirst($suite->tests()));
|
||||
$tests = $this->sortDefectsFirst($tests);
|
||||
}
|
||||
|
||||
if ($resolveDependencies && ! ($suite instanceof DataProviderTestSuite)) {
|
||||
$tests = $suite->tests();
|
||||
|
||||
/** @noinspection PhpParamsInspection */
|
||||
/** @phpstan-ignore argument.type */
|
||||
$suite->setTests($this->resolveDependencies($tests));
|
||||
$tests = $this->resolveDependencies($tests);
|
||||
}
|
||||
|
||||
$suite->setTests($tests);
|
||||
}
|
||||
|
||||
private function addSuiteToDefectSortOrder(TestSuite $suite): void
|
||||
@@ -154,9 +171,10 @@ final class TestSuiteSorter
|
||||
$sortId = $test->sortId();
|
||||
|
||||
if (! isset($this->defectSortOrder[$sortId])) {
|
||||
$this->defectSortOrder[$sortId] = $this->cache->status(ResultCacheId::fromReorderable($test))->asInt();
|
||||
$max = max($max, $this->defectSortOrder[$sortId]);
|
||||
$this->defectSortOrder[$sortId] = $this->testRunHistory->status(TestRunHistoryId::fromReorderable($test))->sortWeight();
|
||||
}
|
||||
|
||||
$max = max($max, $this->defectSortOrder[$sortId]);
|
||||
}
|
||||
|
||||
$this->defectSortOrder[$suite->sortId()] = $max;
|
||||
@@ -210,6 +228,20 @@ final class TestSuiteSorter
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<Test> $tests
|
||||
* @return list<Test>
|
||||
*/
|
||||
private function sortByDurationDescending(array $tests): array
|
||||
{
|
||||
usort(
|
||||
$tests,
|
||||
fn (Test $left, Test $right) => $this->cmpDuration($right, $left),
|
||||
);
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<Test> $tests
|
||||
* @return list<Test>
|
||||
@@ -224,6 +256,20 @@ final class TestSuiteSorter
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<Test> $tests
|
||||
* @return list<Test>
|
||||
*/
|
||||
private function sortBySizeDescending(array $tests): array
|
||||
{
|
||||
usort(
|
||||
$tests,
|
||||
fn (Test $left, Test $right) => $this->cmpSize($right, $left),
|
||||
);
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
private function cmpDefectPriorityAndTime(Test $a, Test $b): int
|
||||
{
|
||||
assert($a instanceof Reorderable);
|
||||
@@ -232,45 +278,72 @@ final class TestSuiteSorter
|
||||
$priorityA = $this->defectSortOrder[$a->sortId()] ?? 0;
|
||||
$priorityB = $this->defectSortOrder[$b->sortId()] ?? 0;
|
||||
|
||||
if ($priorityA !== $priorityB) {
|
||||
return $priorityB <=> $priorityA;
|
||||
}
|
||||
|
||||
if ($priorityA > 0 || $priorityB > 0) {
|
||||
return $this->cmpDuration($a, $b);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return $priorityB <=> $priorityA;
|
||||
}
|
||||
|
||||
private function cmpDuration(Test $a, Test $b): int
|
||||
{
|
||||
if (! ($a instanceof Reorderable && $b instanceof Reorderable)) {
|
||||
return 0;
|
||||
return $this->durationWeight($a) <=> $this->durationWeight($b);
|
||||
}
|
||||
|
||||
private function durationWeight(Test $test): float
|
||||
{
|
||||
if ($test instanceof TestSuite) {
|
||||
$sum = 0.0;
|
||||
|
||||
foreach ($test->tests() as $inner) {
|
||||
$sum += $this->durationWeight($inner);
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
return $this->cache->time(ResultCacheId::fromReorderable($a)) <=> $this->cache->time(ResultCacheId::fromReorderable($b));
|
||||
if ($test instanceof Reorderable) {
|
||||
return $this->testRunHistory->time(TestRunHistoryId::fromReorderable($test));
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
private function cmpSize(Test $a, Test $b): int
|
||||
{
|
||||
$sizeA = ($a instanceof TestCase || $a instanceof DataProviderTestSuite)
|
||||
? $a->size()->asString()
|
||||
: 'unknown';
|
||||
$sizeB = ($b instanceof TestCase || $b instanceof DataProviderTestSuite)
|
||||
? $b->size()->asString()
|
||||
: 'unknown';
|
||||
|
||||
return self::SIZE_SORT_WEIGHT[$sizeA] <=> self::SIZE_SORT_WEIGHT[$sizeB];
|
||||
return $this->sizeWeight($a) <=> $this->sizeWeight($b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<TestCase> $tests
|
||||
* @return array<TestCase>
|
||||
* @return positive-int
|
||||
*/
|
||||
private function sizeWeight(Test $test): int
|
||||
{
|
||||
if ($test instanceof TestCase || $test instanceof DataProviderTestSuite) {
|
||||
return self::SIZE_SORT_WEIGHT[$test->size()->asString()];
|
||||
}
|
||||
|
||||
if ($test instanceof TestSuite) {
|
||||
$max = 0;
|
||||
|
||||
foreach ($test->tests() as $inner) {
|
||||
$weight = $this->sizeWeight($inner);
|
||||
|
||||
if ($weight > $max) {
|
||||
$max = $weight;
|
||||
}
|
||||
}
|
||||
|
||||
if ($max > 0) {
|
||||
return $max;
|
||||
}
|
||||
}
|
||||
|
||||
return self::SIZE_SORT_WEIGHT['unknown'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<TestCase> $tests
|
||||
* @return list<TestCase>
|
||||
*/
|
||||
private function resolveDependencies(array $tests): array
|
||||
{
|
||||
// when no test uses `->depends()` / PHPUnit `@depends`.
|
||||
if (! $this->anyTestHasDependencies($tests)) {
|
||||
return $tests;
|
||||
}
|
||||
@@ -279,7 +352,7 @@ final class TestSuiteSorter
|
||||
$i = 0;
|
||||
$provided = [];
|
||||
|
||||
do {
|
||||
while ($tests !== [] && $i < count($tests)) {
|
||||
if (array_diff($tests[$i]->requires(), $provided) === []) {
|
||||
$provided = array_merge($provided, $tests[$i]->provides());
|
||||
$newTestOrder = array_merge($newTestOrder, array_splice($tests, $i, 1));
|
||||
@@ -287,14 +360,12 @@ final class TestSuiteSorter
|
||||
} else {
|
||||
$i++;
|
||||
}
|
||||
} while ($tests !== [] && ($i < count($tests)));
|
||||
}
|
||||
|
||||
return array_merge($newTestOrder, $tests);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cheaply determines whether any test in the tree declares @depends.
|
||||
*
|
||||
* @param iterable<Test> $tests
|
||||
*/
|
||||
private function anyTestHasDependencies(iterable $tests): bool
|
||||
|
||||
Reference in New Issue
Block a user