8000 [PhpUnitBridge] Added a CoverageListener to enhance the code coverage… · symfony/symfony@ac1bfe6 · GitHub
[go: up one dir, main page]

Skip to co 8000 ntent

Commit ac1bfe6

Browse files
committed
[PhpUnitBridge] Added a CoverageListener to enhance the code coverage report
1 parent 701d41c commit ac1bfe6

File tree

3 files changed

+160
-0
lines changed

3 files changed

+160
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\PhpUnit;
13+
14+
use PHPUnit\Framework\BaseTestListener;
15+
use PHPUnit\Framework\Test;
16+
use Symfony\Bridge\PhpUnit\Legacy\CoverageListenerTrait;
17+
18+
if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) {
19+
class_alias('Symfony\Bridge\PhpUnit\Legacy\CoverageListener', 'Symfony\Bridge\PhpUnit\CoverageListener');
20+
// Using an early return instead of a else does not work when using the PHPUnit
21+
// phar due to some weird PHP behavior (the class gets defined without executing
22+
// the code before it and so the definition is not properly conditional)
23+
} else {
24+
/**
25+
* CoverageListener adds `@covers <className>` on each test suite when possible
26+
* to make the code coverage more accurate.
27+
*
28+
* @author Grégoire Pineau <lyrixx@lyrixx.info>
29+
*/
30+
class CoverageListener extends BaseTestListener
31+
{
32+
private $trait;
33+
34+
public function __construct(callable $sutFqcnResolver = null)
35+
{
36+
$this->trait = new CoverageListenerTrait($sutFqcnResolver);
37+
}
38+
39+
public function startTest(Test $test)
40+
{
41+
$this->trait->startTest($test);
42+
}
43+
}
44+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\PhpUnit\Legacy;
13+
14+
/**
15+
* CoverageListener adds `@covers <className>` on each test suite when possible
16+
* to make the code coverage more accurate.
17+
*
18+
* @author Grégoire Pineau <lyrixx@lyrixx.info>
19+
*
20+
* @internal
21+
*/
22+
class CoverageListener extends \PHPUnit_Framework_BaseTestListener
23+
{
24+
private $trait;
25+
26+
public function __construct(callable $sutFqcnResolver = null)
27+
{
28+
$this->trait = new CoverageListenerTrait($sutFqcnResolver);
29+
}
30+
31+
public function startTest(\PHPUnit_Framework_Test $test)
32+
{
33+
$this->trait->startTest($test);
34+
}
35+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\PhpUnit\Legacy;
13+
14+
use PHPUnit\Framework\Test;
15+
16+
/**
17+
* PHP 5.3 compatible trait-like shared implementation.
18+
*
19+
* @author Grégoire Pineau <lyrixx@lyrixx.info>
20+
*
21+
* @internal
22+
*/
23+
class CoverageListenerTrait
24+
{
25+
private $sutFqcnResolver;
26+
27+
public function __construct(callable $sutFqcnResolver = null)
28+
{
29+
$this->sutFqcnResolver = $sutFqcnResolver;
30+
}
31+
32+
public function startTest($test)
33+
{
34+
$annotations = $test->getAnnotations();
35+
36+
if (isset($annotations['class']['covers']) || isset($annotations['method']['covers'])) {
37+
return;
38+
}
39+
40+
$sutFqcn = $this->findSutFqcn($test);
41+
if (!$sutFqcn) {
42+
return;
43+
}
44+
45+
$testClass = \PHPUnit\Util\Test::class;
46+
if (!class_exists($testClass, false)) {
47+
$testClass = \PHPUnit_Util_Test::class;
48+
}
49+
50+
$r = new \ReflectionProperty($testClass, 'annotationCache');
51+
$r->setAccessible(true);
52+
53+
$cache = $r->getValue();
54+
$cache = array_replace_recursive($cache, array(
55+
get_class($test) => array(
56+
'covers' => array($sutFqcn),
57+
),
58+
));
59+
$r->setValue($testClass, $cache);
60+
}
61+
62+
private function findSutFqcn($test)
63+
{
64+
if ($this->sutFqcnResolver) {
65+
$resolver = $this->sutFqcnResolver;
66+
67+
return $resolver($test);
68+
}
69+
70+
$class = get_class($test);
71+
72+
$sutFqcn = str_replace('Tests\\', '', $class);
73+
$sutFqcn = preg_replace('{Test$}', '', $sutFqcn);
74+
75+
if (!class_exists($sutFqcn)) {
76+
return;
77+
}
78+
79+
return $sutFqcn;
80+
}
81+
}

0 commit comments

Comments
 (0)
0