Skip to content

Commit 0e3d7dd

Browse files
Merge branch '11.5' into 12.2
2 parents dda16e2 + a97eacc commit 0e3d7dd

File tree

10 files changed

+178
-62
lines changed

10 files changed

+178
-62
lines changed

src/Runner/ResultCache/DefaultResultCache.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,28 +56,28 @@ public function __construct(?string $filepath = null)
5656
$this->cacheFilename = $filepath ?? $_ENV['PHPUNIT_RESULT_CACHE'] ?? self::DEFAULT_RESULT_CACHE_FILENAME;
5757
}
5858

59-
public function setStatus(string $id, TestStatus $status): void
59+
public function setStatus(ResultCacheId $id, TestStatus $status): void
6060
{
6161
if ($status->isSuccess()) {
6262
return;
6363
}
6464

65-
$this->defects[$id] = $status;
65+
$this->defects[$id->asString()] = $status;
6666
}
6767

68-
public function status(string $id): TestStatus
68+
public function status(ResultCacheId $id): TestStatus
6969
{
70-
return $this->defects[$id] ?? TestStatus::unknown();
70+
return $this->defects[$id->asString()] ?? TestStatus::unknown();
7171
}
7272

73-
public function setTime(string $id, float $time): void
73+
public function setTime(ResultCacheId $id, float $time): void
7474
{
75-
$this->times[$id] = $time;
75+
$this->times[$id->asString()] = $time;
7676
}
7777

78-
public function time(string $id): float
78+
public function time(ResultCacheId $id): float
7979
{
80-
return $this->times[$id] ?? 0.0;
80+
return $this->times[$id->asString()] ?? 0.0;
8181
}
8282

8383
public function mergeWith(self $other): void

src/Runner/ResultCache/NullResultCache.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,20 @@
1818
*/
1919
final readonly class NullResultCache implements ResultCache
2020
{
21-
public function setStatus(string $id, TestStatus $status): void
21+
public function setStatus(ResultCacheId $id, TestStatus $status): void
2222
{
2323
}
2424

25-
public function status(string $id): TestStatus
25+
public function status(ResultCacheId $id): TestStatus
2626
{
2727
return TestStatus::unknown();
2828
}
2929

30-
public function setTime(string $id, float $time): void
30+
public function setTime(ResultCacheId $id, float $time): void
3131
{
3232
}
3333

34-
public function time(string $id): float
34+
public function time(ResultCacheId $id): float
3535
{
3636
return 0;
3737
}

src/Runner/ResultCache/ResultCache.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
*/
1919
interface ResultCache
2020
{
21-
public function setStatus(string $id, TestStatus $status): void;
21+
public function setStatus(ResultCacheId $id, TestStatus $status): void;
2222

23-
public function status(string $id): TestStatus;
23+
public function status(ResultCacheId $id): TestStatus;
2424

25-
public function setTime(string $id, float $time): void;
25+
public function setTime(ResultCacheId $id, float $time): void;
2626

27-
public function time(string $id): float;
27+
public function time(ResultCacheId $id): float;
2828

2929
public function load(): void;
3030

src/Runner/ResultCache/ResultCacheHandler.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,31 +63,31 @@ public function testPrepared(Prepared $event): void
6363
public function testMarkedIncomplete(MarkedIncomplete $event): void
6464
{
6565
$this->cache->setStatus(
66-
$event->test()->id(),
66+
ResultCacheId::fromTest($event->test()),
6767
TestStatus::incomplete($event->throwable()->message()),
6868
);
6969
}
7070

7171
public function testConsideredRisky(ConsideredRisky $event): void
7272
{
7373
$this->cache->setStatus(
74-
$event->test()->id(),
74+
ResultCacheId::fromTest($event->test()),
7575
TestStatus::risky($event->message()),
7676
);
7777
}
7878

7979
public function testErrored(Errored $event): void
8080
{
8181
$this->cache->setStatus(
82-
$event->test()->id(),
82+
ResultCacheId::fromTest($event->test()),
8383
TestStatus::error($event->throwable()->message()),
8484
);
8585
}
8686

8787
public function testFailed(Failed $event): void
8888
{
8989
$this->cache->setStatus(
90-
$event->test()->id(),
90+
ResultCacheId::fromTest($event->test()),
9191
TestStatus::failure($event->throwable()->message()),
9292
);
9393
}
@@ -99,11 +99,11 @@ public function testFailed(Failed $event): void
9999
public function testSkipped(Skipped $event): void
100100
{
101101
$this->cache->setStatus(
102-
$event->test()->id(),
102+
ResultCacheId::fromTest($event->test()),
103103
TestStatus::skipped($event->message()),
104104
);
105105

106-
$this->cache->setTime($event->test()->id(), $this->duration($event));
106+
$this->cache->setTime(ResultCacheId::fromTest($event->test()), $this->duration($event));
107107
}
108108

109109
/**
@@ -112,7 +112,7 @@ public function testSkipped(Skipped $event): void
112112
*/
113113
public function testFinished(Finished $event): void
114114
{
115-
$this->cache->setTime($event->test()->id(), $this->duration($event));
115+
$this->cache->setTime(ResultCacheId::fromTest($event->test()), $this->duration($event));
116116

117117
$this->time = null;
118118
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\Runner\ResultCache;
11+
12+
use PHPUnit\Event\Code\Test;
13+
use PHPUnit\Framework\Reorderable;
14+
use PHPUnit\Framework\TestCase;
15+
16+
/**
17+
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
18+
*
19+
* @internal This class is not covered by the backward compatibility promise for PHPUnit
20+
*/
21+
final readonly class ResultCacheId
22+
{
23+
public static function fromTest(Test $test): self
24+
{
25+
return new self($test->id());
26+
}
27+
28+
public static function fromReorderable(Reorderable $reorderable): self
29+
{
30+
return new self($reorderable->sortId());
31+
}
32+
33+
/**
34+
* For use in PHPUnit tests only!
35+
*
36+
* @param class-string<TestCase> $class
37+
*/
38+
public static function fromTestClassAndMethodName(string $class, string $methodName): self
39+
{
40+
return new self($class . '::' . $methodName);
41+
}
42+
43+
private function __construct(
44+
private string $id,
45+
) {
46+
}
47+
48+
public function asString(): string
49+
{
50+
return $this->id;
51+
}
52+
}

src/Runner/TestSuiteSorter.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use PHPUnit\Framework\TestSuite;
2626
use PHPUnit\Runner\ResultCache\NullResultCache;
2727
use PHPUnit\Runner\ResultCache\ResultCache;
28+
use PHPUnit\Runner\ResultCache\ResultCacheId;
2829

2930
/**
3031
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
@@ -172,9 +173,11 @@ private function addSuiteToDefectSortOrder(TestSuite $suite): void
172173
continue;
173174
}
174175

175-
if (!isset($this->defectSortOrder[$test->sortId()])) {
176-
$this->defectSortOrder[$test->sortId()] = $this->cache->status($test->sortId())->asInt();
177-
$max = max($max, $this->defectSortOrder[$test->sortId()]);
176+
$sortId = $test->sortId();
177+
178+
if (!isset($this->defectSortOrder[$sortId])) {
179+
$this->defectSortOrder[$sortId] = $this->cache->status(ResultCacheId::fromReorderable($test))->asInt();
180+
$max = max($max, $this->defectSortOrder[$sortId]);
178181
}
179182
}
180183

@@ -286,7 +289,7 @@ private function cmpDuration(Test $a, Test $b): int
286289
return 0;
287290
}
288291

289-
return $this->cache->time($a->sortId()) <=> $this->cache->time($b->sortId());
292+
return $this->cache->time(ResultCacheId::fromReorderable($a)) <=> $this->cache->time(ResultCacheId::fromReorderable($b));
290293
}
291294

292295
/**

tests/unit/Runner/ResultCache/DefaultResultCacheTest.php

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ final class DefaultResultCacheTest extends TestCase
2525
{
2626
public function testGetTimeForNonExistentTestNameReturnsFloatZero(): void
2727
{
28-
$this->assertSame(0.0, (new DefaultResultCache)->time('doesNotExist'));
28+
$this->assertSame(0.0, (new DefaultResultCache)->time(ResultCacheId::fromTestClassAndMethodName(self::class, 'doesNotExist')));
2929
}
3030

3131
public function testReadsCacheFromProvidedFilename(): void
@@ -34,66 +34,67 @@ public function testReadsCacheFromProvidedFilename(): void
3434
$cache = new DefaultResultCache($cacheFile);
3535
$cache->load();
3636

37-
$this->assertTrue($cache->status(MultiDependencyTest::class . '::testOne')->isUnknown());
38-
$this->assertTrue($cache->status(MultiDependencyTest::class . '::testFive')->isSkipped());
37+
$this->assertTrue($cache->status(ResultCacheId::fromTestClassAndMethodName(MultiDependencyTest::class, 'testOne'))->isUnknown());
38+
$this->assertTrue($cache->status(ResultCacheId::fromTestClassAndMethodName(MultiDependencyTest::class, 'testFive'))->isSkipped());
3939
}
4040

4141
public function testDoesClearCacheBeforeLoad(): void
4242
{
43-
$cacheFile = TEST_FILES_PATH . '../end-to-end/execution-order/_files/MultiDependencyTest_result_cache.txt';
44-
$cache = new DefaultResultCache($cacheFile);
45-
$cache->setStatus('someTest', TestStatus::failure());
43+
$cacheFile = TEST_FILES_PATH . '../end-to-end/execution-order/_files/MultiDependencyTest_result_cache.txt';
44+
$cache = new DefaultResultCache($cacheFile);
45+
$resultCacheId = ResultCacheId::fromTestClassAndMethodName(self::class, 'someTest');
46+
$cache->setStatus($resultCacheId, TestStatus::failure());
4647

47-
$this->assertTrue($cache->status(MultiDependencyTest::class . '::testFive')->isUnknown());
48+
$this->assertTrue($cache->status(ResultCacheId::fromTestClassAndMethodName(MultiDependencyTest::class, 'testFive'))->isUnknown());
4849

4950
$cache->load();
5051

51-
$this->assertTrue($cache->status(MultiDependencyTest::class . '::someTest')->isUnknown());
52-
$this->assertTrue($cache->status(MultiDependencyTest::class . '::testFive')->isSkipped());
52+
$this->assertTrue($cache->status(ResultCacheId::fromTestClassAndMethodName(MultiDependencyTest::class, 'someTest'))->isUnknown());
53+
$this->assertTrue($cache->status(ResultCacheId::fromTestClassAndMethodName(MultiDependencyTest::class, 'testFive'))->isSkipped());
5354
}
5455

5556
public function testCanPersistCacheToFile(): void
5657
{
57-
$cacheFile = tempnam(sys_get_temp_dir(), 'phpunit_');
58-
$cache = new DefaultResultCache($cacheFile);
59-
$testName = 'test' . uniqid('', true);
58+
$cacheFile = tempnam(sys_get_temp_dir(), 'phpunit_');
59+
$cache = new DefaultResultCache($cacheFile);
60+
$resultCacheId = ResultCacheId::fromTestClassAndMethodName(self::class, 'test' . uniqid('', true));
6061

61-
$cache->setStatus($testName, TestStatus::skipped());
62+
$cache->setStatus($resultCacheId, TestStatus::skipped());
6263
$cache->persist();
6364

6465
$cache = new DefaultResultCache($cacheFile);
6566
$cache->load();
6667

67-
$this->assertTrue($cache->status($testName)->isSkipped());
68+
$this->assertTrue($cache->status($resultCacheId)->isSkipped());
6869

6970
unlink($cacheFile);
7071
}
7172

7273
public function testCanBeMerged(): void
7374
{
7475
$cacheSourceOne = new DefaultResultCache;
75-
$cacheSourceOne->setStatus('status.a', TestStatus::skipped());
76-
$cacheSourceOne->setStatus('status.b', TestStatus::incomplete());
77-
$cacheSourceOne->setTime('time.a', 1);
78-
$cacheSourceOne->setTime('time.b', 2);
76+
$cacheSourceOne->setStatus(ResultCacheId::fromTestClassAndMethodName(self::class, 'status.a'), TestStatus::skipped());
77+
$cacheSourceOne->setStatus(ResultCacheId::fromTestClassAndMethodName(self::class, 'status.b'), TestStatus::incomplete());
78+
$cacheSourceOne->setTime(ResultCacheId::fromTestClassAndMethodName(self::class, 'time.a'), 1);
79+
$cacheSourceOne->setTime(ResultCacheId::fromTestClassAndMethodName(self::class, 'time.b'), 2);
7980
$cacheSourceTwo = new DefaultResultCache;
80-
$cacheSourceTwo->setStatus('status.c', TestStatus::failure());
81-
$cacheSourceTwo->setTime('time.c', 4);
81+
$cacheSourceTwo->setStatus(ResultCacheId::fromTestClassAndMethodName(self::class, 'status.c'), TestStatus::failure());
82+
$cacheSourceTwo->setTime(ResultCacheId::fromTestClassAndMethodName(self::class, 'time.c'), 4);
8283

8384
$sum = new DefaultResultCache;
8485
$sum->mergeWith($cacheSourceOne);
8586

86-
$this->assertSame(TestStatus::skipped()->asString(), $sum->status('status.a')->asString());
87-
$this->assertSame(TestStatus::incomplete()->asString(), $sum->status('status.b')->asString());
88-
$this->assertNotSame(TestStatus::failure()->asString(), $sum->status('status.c')->asString());
87+
$this->assertSame(TestStatus::skipped()->asString(), $sum->status(ResultCacheId::fromTestClassAndMethodName(self::class, 'status.a'))->asString());
88+
$this->assertSame(TestStatus::incomplete()->asString(), $sum->status(ResultCacheId::fromTestClassAndMethodName(self::class, 'status.b'))->asString());
89+
$this->assertNotSame(TestStatus::failure()->asString(), $sum->status(ResultCacheId::fromTestClassAndMethodName(self::class, 'status.c'))->asString());
8990

90-
$this->assertSame(1.0, $sum->time('time.a'));
91-
$this->assertSame(2.0, $sum->time('time.b'));
92-
$this->assertNotSame(4.0, $sum->time('time.c'));
91+
$this->assertSame(1.0, $sum->time(ResultCacheId::fromTestClassAndMethodName(self::class, 'time.a')));
92+
$this->assertSame(2.0, $sum->time(ResultCacheId::fromTestClassAndMethodName(self::class, 'time.b')));
93+
$this->assertNotSame(4.0, $sum->time(ResultCacheId::fromTestClassAndMethodName(self::class, 'time.c')));
9394

9495
$sum->mergeWith($cacheSourceTwo);
9596

96-
$this->assertSame(TestStatus::failure()->asString(), $sum->status('status.c')->asString());
97-
$this->assertSame(4.0, $sum->time('time.c'));
97+
$this->assertSame(TestStatus::failure()->asString(), $sum->status(ResultCacheId::fromTestClassAndMethodName(self::class, 'status.c'))->asString());
98+
$this->assertSame(4.0, $sum->time(ResultCacheId::fromTestClassAndMethodName(self::class, 'time.c')));
9899
}
99100
}

tests/unit/Runner/ResultCache/NullTestResultCacheTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public function testHasWorkingStubs(): void
2323
$cache->load();
2424
$cache->persist();
2525

26-
$this->assertTrue($cache->status('testName')->isUnknown());
27-
$this->assertSame(0.0, $cache->time('testName'));
26+
$this->assertTrue($cache->status(ResultCacheId::fromTestClassAndMethodName(self::class, 'testName'))->isUnknown());
27+
$this->assertSame(0.0, $cache->time(ResultCacheId::fromTestClassAndMethodName(self::class, 'testName')));
2828
}
2929
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\Runner\ResultCache;
11+
12+
use PHPUnit\Event\Code\TestDox;
13+
use PHPUnit\Event\Code\TestMethod;
14+
use PHPUnit\Event\TestData\TestDataCollection;
15+
use PHPUnit\Framework\Attributes\CoversClass;
16+
use PHPUnit\Framework\Attributes\DataProvider;
17+
use PHPUnit\Framework\Attributes\Small;
18+
use PHPUnit\Framework\Reorderable;
19+
use PHPUnit\Framework\TestCase;
20+
use PHPUnit\Metadata\MetadataCollection;
21+
22+
#[CoversClass(ResultCacheId::class)]
23+
#[Small]
24+
final class ResultCacheIdTest extends TestCase
25+
{
26+
public static function provideResultCacheIds(): iterable
27+
{
28+
yield ['PHPUnit\Runner\ResultCache\ResultCacheIdTest::a method', ResultCacheId::fromTestClassAndMethodName(self::class, 'a method')];
29+
30+
yield ['PHPUnit\Runner\ResultCache\ResultCacheIdTest::testMethod', ResultCacheId::fromTest(self::testMethod())];
31+
}
32+
33+
#[DataProvider('provideResultCacheIds')]
34+
public function testResultCacheId(string $expectedString, ResultCacheId $cacheId): void
35+
{
36+
$this->assertSame($expectedString, $cacheId->asString());
37+
}
38+
39+
public function testReorderableResultCacheId(): void
40+
{
41+
$reorderable = $this;
42+
$this->assertInstanceOf(Reorderable::class, $reorderable);
43+
44+
$this->assertSame('PHPUnit\Runner\ResultCache\ResultCacheIdTest::testReorderableResultCacheId', ResultCacheId::fromReorderable($reorderable)->asString());
45+
}
46+
47+
private static function testMethod(): TestMethod
48+
{
49+
return new TestMethod(
50+
self::class,
51+
'testMethod',
52+
'TestClass.php',
53+
1,
54+
new TestDox('', '', ''),
55+
MetadataCollection::fromArray([]),
56+
TestDataCollection::fromArray([]),
57+
);
58+
}
59+
}

0 commit comments

Comments
 (0)