Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e905b8d

Browse files
minor #39644 [PhpUnitBridge] Modernize CoverageListener (derrabus)
This PR was merged into the 5.3-dev branch. Discussion ---------- [PhpUnitBridge] Modernize CoverageListener | Q | A | ------------- | --- | Branch? | 5.x | Bug fix? | no | New feature? | no | Deprecations? | no | Tickets | N/A | License | MIT | Doc PR | N/A This PR proposes to merge `CoverageListener`, `CoverageListenerForV7` and `CoverageListenerTrait` into a single class because we don't have to deal with multiple implementations anymore. Additionally, I've removed compat code for PHPUnit < 7.5 and added type declarations where possible. Commits ------- eb16690 [PhpUnitBridge] Modernize CoverageListener
2 parents ec9ed2f + eb16690 commit e905b8d

File tree

4 files changed

+102
-206
lines changed

4 files changed

+102
-206
lines changed

src/Symfony/Bridge/PhpUnit/CoverageListener.php

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,109 @@
1111

1212
namespace Symfony\Bridge\PhpUnit;
1313

14-
class_alias('Symfony\Bridge\PhpUnit\Legacy\CoverageListenerForV7', 'Symfony\Bridge\PhpUnit\CoverageListener');
14+
use PHPUnit\Framework\Test;
15+
use PHPUnit\Framework\TestCase;
16+
use PHPUnit\Framework\TestListener;
17+
use PHPUnit\Framework\TestListenerDefaultImplementation;
18+
use PHPUnit\Framework\Warning;
19+
use PHPUnit\Util\Annotation\Registry;
20+
use PHPUnit\Util\Test as TestUtil;
1521

16-
if (false) {
17-
class CoverageListener
22+
class CoverageListener implements TestListener
23+
{
24+
use TestListenerDefaultImplementation;
25+
26+
private $sutFqcnResolver;
27+
private $warningOnSutNotFound;
28+
29+
public function __construct(callable $sutFqcnResolver = null, bool $warningOnSutNotFound = false)
30+
{
31+
$this->sutFqcnResolver = $sutFqcnResolver ?? static function (Test $test): ?string {
32+
$class = \get_class($test);
33+
34+
$sutFqcn = str_replace('\\Tests\\', '\\', $class);
35+
$sutFqcn = preg_replace('{Test$}', '', $sutFqcn);
36+
37+
return class_exists($sutFqcn) ? $sutFqcn : null;
38+
};
39+
40+
$this->warningOnSutNotFound = $warningOnSutNotFound;
41+
}
42+
43+
public function startTest(Test $test): void
1844
{
45+
if (!$test instanceof TestCase) {
46+
return;
47+
}
48+
49+
$annotations = TestUtil::parseTestMethodAnnotations(\get_class($test), $test->getName(false));
50+
51+
$ignoredAnnotations = ['covers', 'coversDefaultClass', 'coversNothing'];
52+
53+
foreach ($ignoredAnnotations as $annotation) {
54+
if (isset($annotations['class'][$annotation]) || isset($annotations['method'][$annotation])) {
55+
return;
56+
}
57+
}
58+
59+
$sutFqcn = ($this->sutFqcnResolver)($test);
60+
if (!$sutFqcn) {
61+
if ($this->warningOnSutNotFound) {
62+
$test->getTestResultObject()->addWarning($test, new Warning('Could not find the tested class.'), 0);
63+
}
64+
65+
return;
66+
}
67+
68+
$covers = $sutFqcn;
69+
if (!\is_array($sutFqcn)) {
70+
$covers = [$sutFqcn];
71+
while ($parent = get_parent_class($sutFqcn)) {
72+
$covers[] = $parent;
73+
$sutFqcn = $parent;
74+
}
75+
}
76+
77+
if (class_exists(Registry::class)) {
78+
$this->addCoversForDocBlockInsideRegistry($test, $covers);
79+
80+
return;
81+
}
82+
83+
$this->addCoversForClassToAnnotationCache($test, $covers);
84+
}
85+
86+
private function addCoversForClassToAnnotationCache(Test $test, array $covers): void
87+
{
88+
$r = new \ReflectionProperty(TestUtil::class, 'annotationCache');
89+
$r->setAccessible(true);
90+
91+
$cache = $r->getValue();
92+
$cache = array_replace_recursive($cache, [
93+
\get_class($test) => [
94+
'covers' => $covers,
95+
],
96+
]);
97+
98+
$r->setValue(TestUtil::class, $cache);
99+
}
100+
101+
private function addCoversForDocBlockInsideRegistry(Test $test, array $covers): void
102+
{
103+
$docBlock = Registry::getInstance()->forClassName(\get_class($test));
104+
105+
$symbolAnnotations = new \ReflectionProperty($docBlock, 'symbolAnnotations');
106+
$symbolAnnotations->setAccessible(true);
107+
108+
// Exclude internal classes; PHPUnit 9.1+ is picky about tests covering, say, a \RuntimeException
109+
$covers = array_filter($covers, function (string $class) {
110+
$reflector = new \ReflectionClass($class);
111+
112+
return $reflector->isUserDefined();
113+
});
114+
115+
$symbolAnnotations->setValue($docBlock, array_replace($docBlock->symbolAnnotations(), [
116+
'covers' => $covers,
117+
]));
19118
}
20119
}

src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV7.php

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php

Lines changed: 0 additions & 160 deletions
This file was deleted.

src/Symfony/Bridge/PhpUnit/Tests/Fixtures/coverage/tests/bootstrap.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,4 @@
1212
require __DIR__.'/../src/BarCov.php';
1313
require __DIR__.'/../src/FooCov.php';
1414

15-
require __DIR__.'/../../../../Legacy/CoverageListenerTrait.php';
16-
require_once __DIR__.'/../../../../Legacy/CoverageListenerForV7.php';
1715
require __DIR__.'/../../../../CoverageListener.php';

0 commit comments

Comments
 (0)