Skip to content

Commit b64beb8

Browse files
committed
add exception support to PreferPHPUnitSelfCallRector
1 parent 5c046ae commit b64beb8

File tree

4 files changed

+91
-24
lines changed

4 files changed

+91
-24
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\Class_\PreferPHPUnitSelfCallRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class IncludeExceptions extends TestCase
8+
{
9+
public function testMe()
10+
{
11+
$this->expectException(\RuntimeException::class);
12+
$this->expectExceptionMessage('foo');
13+
$this->expectExceptionCode(123);
14+
}
15+
}
16+
17+
?>
18+
-----
19+
<?php
20+
21+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\Class_\PreferPHPUnitSelfCallRector\Fixture;
22+
23+
use PHPUnit\Framework\TestCase;
24+
25+
final class IncludeExceptions extends TestCase
26+
{
27+
public function testMe()
28+
{
29+
self::expectException(\RuntimeException::class);
30+
self::expectExceptionMessage('foo');
31+
self::expectExceptionCode(123);
32+
}
33+
}
34+
35+
?>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\PHPUnit\CodeQuality\Enum;
6+
7+
final class NonAssertStaticableMethods
8+
{
9+
/**
10+
* @var string[]
11+
*/
12+
public const ALL = [
13+
'createMock',
14+
'atLeast',
15+
'atLeastOnce',
16+
'once',
17+
'never',
18+
'expectException',
19+
'expectExceptionMessage',
20+
'expectExceptionCode',
21+
'expectExceptionMessageMatches',
22+
];
23+
}

rules/CodeQuality/Rector/Class_/PreferPHPUnitSelfCallRector.php

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@
1010
use PhpParser\Node\Stmt\Class_;
1111
use PHPStan\Reflection\ClassReflection;
1212
use PHPStan\Type\ObjectType;
13+
use Rector\Enum\ClassName;
14+
use Rector\PHPUnit\CodeQuality\Enum\NonAssertStaticableMethods;
15+
use Rector\PHPUnit\Enum\PHPUnitClassName;
1316
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
1417
use Rector\Rector\AbstractRector;
1518
use Rector\Reflection\ReflectionResolver;
1619
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
1720
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
1821

1922
/**
20-
* @see \Rector\PHPUnit\Tests\Rector\Class_\PreferPHPUnitSelfCallRector\PreferPHPUnitSelfCallRectorTest
23+
* @see \Rector\PHPUnit\Tests\CodeQuality\Rector\Class_\PreferPHPUnitSelfCallRector\PreferPHPUnitSelfCallRectorTest
2124
*/
2225
final class PreferPHPUnitSelfCallRector extends AbstractRector
2326
{
@@ -86,31 +89,36 @@ public function refactor(Node $node): ?Node
8689
return null;
8790
}
8891

89-
if (! str_starts_with($methodName, 'assert')) {
92+
if (! str_starts_with($methodName, 'assert') && ! in_array($methodName, NonAssertStaticableMethods::ALL)) {
9093
return null;
9194
}
9295

9396
if (! $this->isName($node->var, 'this')) {
9497
return null;
9598
}
9699

97-
if (! $this->isObjectType($node->var, new ObjectType('PHPUnit\Framework\TestCase'))) {
100+
if (! $this->isObjectType($node->var, new ObjectType(ClassName::TEST_CASE_CLASS))) {
98101
return null;
99102
}
100103

101104
$classReflection = $this->reflectionResolver->resolveClassReflection($node);
102105
if ($classReflection instanceof ClassReflection && $classReflection->hasNativeMethod($methodName)) {
103-
$method = $classReflection->getNativeMethod($methodName);
104-
105106
if ($node->isFirstClassCallable()) {
106107
return null;
107108
}
108109

109-
if ($method->isStatic()) {
110-
$hasChanged = true;
111-
112-
return $this->nodeFactory->createStaticCall('self', $methodName, $node->getArgs());
110+
// only handle methods in TestCase class
111+
$methodReflection = $classReflection->getNativeMethod($methodName);
112+
if (! in_array(
113+
$methodReflection->getDeclaringClass()
114+
->getName(),
115+
[PHPUnitClassName::TEST_CASE, PHPUnitClassName::ASSERT]
116+
)) {
117+
return null;
113118
}
119+
120+
$hasChanged = true;
121+
return $this->nodeFactory->createStaticCall('self', $methodName, $node->getArgs());
114122
}
115123

116124
return null;

rules/CodeQuality/Rector/Class_/PreferPHPUnitThisCallRector.php

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use PhpParser\Node\Stmt\Class_;
1212
use PhpParser\Node\Stmt\ClassMethod;
1313
use PhpParser\NodeVisitor;
14+
use Rector\PHPUnit\CodeQuality\Enum\NonAssertStaticableMethods;
1415
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
1516
use Rector\Rector\AbstractRector;
1617
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@@ -21,20 +22,20 @@
2122
*/
2223
final class PreferPHPUnitThisCallRector extends AbstractRector
2324
{
24-
/**
25-
* @var string[]
26-
*/
27-
private const NON_ASSERT_STATIC_METHODS = [
28-
'createMock',
29-
'atLeast',
30-
'atLeastOnce',
31-
'once',
32-
'never',
33-
'expectException',
34-
'expectExceptionMessage',
35-
'expectExceptionCode',
36-
'expectExceptionMessageMatches',
37-
];
25+
// /**
26+
// * @var string[]
27+
// */
28+
// private const NON_ASSERT_STATIC_METHODS = [
29+
// 'createMock',
30+
// 'atLeast',
31+
// 'atLeastOnce',
32+
// 'once',
33+
// 'never',
34+
// 'expectException',
35+
// 'expectExceptionMessage',
36+
// 'expectExceptionCode',
37+
// 'expectExceptionMessageMatches',
38+
// ];
3839

3940
public function __construct(
4041
private readonly TestsNodeAnalyzer $testsNodeAnalyzer,
@@ -114,7 +115,7 @@ public function refactor(Node $node): ?Node
114115
return null;
115116
}
116117

117-
if (! str_starts_with($methodName, 'assert') && ! in_array($methodName, self::NON_ASSERT_STATIC_METHODS)) {
118+
if (! str_starts_with($methodName, 'assert') && ! in_array($methodName, NonAssertStaticableMethods::ALL)) {
118119
return null;
119120
}
120121

0 commit comments

Comments
 (0)