Skip to content

Commit c78d415

Browse files
committed
[PHPUnit] Improve DelegateExceptionArgumentsRector to work with setExpectedExceptionRegExp()
1 parent fbc79b4 commit c78d415

11 files changed

+93
-62
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
services:
2+
# handles 2nd and 3rd argument of setExpectedException
3+
Rector\PHPUnit\Rector\DelegateExceptionArgumentsRector: ~
4+
5+
# @expectedException → $this->expectException()
6+
Rector\PHPUnit\Rector\ExceptionAnnotationRector: ~
7+
8+
Rector\Rector\MethodCall\RenameMethodRector:
9+
PHPUnit\Framework\TestClass:
10+
setExpectedException: 'expectedException'
11+
setExpectedExceptionRegExp: 'expectedException'

config/level/phpunit/phpunit60.yaml

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1+
imports:
2+
- { resource: 'phpunit-exception.yaml' }
3+
14
services:
2-
Rector\PHPUnit\Rector\ExceptionAnnotationRector: ~
35
Rector\PHPUnit\Rector\GetMockRector: ~
46

57
# ref. https://github.com/sebastianbergmann/phpunit/compare/5.7.9...6.0.0
68
Rector\Rector\Namespace_\PseudoNamespaceToNamespaceRector:
79
PHPUnit_:
810
# exclude this class, since it has no namespaced replacement
911
- 'PHPUnit_Framework_MockObject_MockObject'
10-
11-
# handles 2nd and 3rd argument of setExpectedException
12-
Rector\PHPUnit\Rector\DelegateExceptionArgumentsRector: ~
13-
14-
Rector\Rector\MethodCall\RenameMethodRector:
15-
'PHPUnit\Framework\TestClass':
16-
'setExpectedException': 'expectedException'
17-
'setExpectedExceptionRegExp': 'expectedException'

config/level/phpunit/phpunit70.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
imports:
2+
- { resource: 'phpunit-exception.yaml' }
3+
14
services:
25
Rector\Rector\Annotation\RenameAnnotationRector:
36
PHPUnit\Framework\TestCase:

config/level/phpunit/phpunit80.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
imports:
2+
- { resource: 'phpunit-exception.yaml' }
3+
14
services:
25
# https://github.com/rectorphp/rector/issues/1024
36
Rector\Rector\Typehint\ParentTypehintedArgumentRector:

packages/PHPUnit/src/Rector/DelegateExceptionArgumentsRector.php

+21-26
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
namespace Rector\PHPUnit\Rector;
44

55
use PhpParser\Node;
6-
use PhpParser\Node\Arg;
76
use PhpParser\Node\Expr\MethodCall;
7+
use PhpParser\Node\Expr\StaticCall;
88
use PhpParser\Node\Identifier;
99
use Rector\Rector\AbstractPHPUnitRector;
1010
use Rector\RectorDefinition\CodeSample;
@@ -42,46 +42,41 @@ public function getDefinition(): RectorDefinition
4242
*/
4343
public function getNodeTypes(): array
4444
{
45-
return [MethodCall::class];
45+
return [MethodCall::class, StaticCall::class];
4646
}
4747

4848
/**
49-
* @param MethodCall $node
49+
* @param MethodCall|StaticCall $node
5050
*/
5151
public function refactor(Node $node): ?Node
5252
{
53-
if (! $this->isInTestClass($node)) {
53+
if (! $this->isPHPUnitMethodNames($node, array_keys($this->oldToNewMethod))) {
5454
return null;
5555
}
5656

57-
if (! $this->isNames($node, array_keys($this->oldToNewMethod))) {
58-
return null;
59-
}
57+
if (isset($node->args[1])) {
58+
/** @var Identifier $identifierNode */
59+
$identifierNode = $node->name;
60+
$oldMethodName = $identifierNode->name;
6061

61-
if (! isset($node->args[1])) {
62-
return null;
63-
}
62+
$call = $this->createPHPUnitCallWithName($node, $this->oldToNewMethod[$oldMethodName]);
63+
$call->args[] = $node->args[1];
64+
$this->addNodeAfterNode($call, $node);
6465

65-
/** @var Identifier $identifierNode */
66-
$identifierNode = $node->name;
67-
$oldMethodName = $identifierNode->name;
66+
unset($node->args[1]);
6867

69-
$this->addNewMethodCall($node, $this->oldToNewMethod[$oldMethodName], $node->args[1]);
70-
unset($node->args[1]);
68+
// add exception code method call
69+
if (isset($node->args[2])) {
70+
$call = $this->createPHPUnitCallWithName($node, 'expectExceptionCode');
71+
$call->args[] = $node->args[2];
72+
$this->addNodeAfterNode($call, $node);
7173

72-
// add exception code method call
73-
if (isset($node->args[2])) {
74-
$this->addNewMethodCall($node, 'expectExceptionCode', $node->args[2]);
75-
unset($node->args[2]);
74+
unset($node->args[2]);
75+
}
7676
}
7777

78-
return $node;
79-
}
80-
81-
private function addNewMethodCall(MethodCall $methodCall, string $methodName, Arg $arg): void
82-
{
83-
$expectExceptionMessageMethodCall = $this->createMethodCall('this', $methodName, [$arg]);
78+
$node->name = new Identifier('expectException');
8479

85-
$this->addNodeAfterNode($expectExceptionMessageMethodCall, $methodCall);
80+
return $node;
8681
}
8782
}

packages/PHPUnit/src/Rector/MethodCall/ReplaceAssertArraySubsetRector.php

+4-13
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public function getNodeTypes(): array
8080
*/
8181
public function refactor(Node $node): ?Node
8282
{
83-
if (! $this->isAssertMethod($node, 'assertArraySubset')) {
83+
if (! $this->isPHPUnitMethodName($node, 'assertArraySubset')) {
8484
return null;
8585
}
8686

@@ -101,7 +101,7 @@ public function refactor(Node $node): ?Node
101101

102102
$identical = new Identical($arrayIntersect, $expectedArray);
103103

104-
$assertTrue = $this->createCallWithName($node, 'assertTrue');
104+
$assertTrue = $this->createPHPUnitCallWithName($node, 'assertTrue');
105105
$assertTrue->args[] = new Arg($identical);
106106

107107
$this->addNodeAfterNode($assertTrue, $node);
@@ -121,7 +121,7 @@ public function refactor(Node $node): ?Node
121121
private function addKeyAsserts(Node $node): void
122122
{
123123
foreach ($this->expectedKeys as $expectedKey) {
124-
$assertArrayHasKey = $this->createCallWithName($node, 'assertArrayHasKey');
124+
$assertArrayHasKey = $this->createPHPUnitCallWithName($node, 'assertArrayHasKey');
125125
$assertArrayHasKey->args[0] = new Arg($expectedKey);
126126
$assertArrayHasKey->args[1] = $node->args[1];
127127

@@ -135,7 +135,7 @@ private function addKeyAsserts(Node $node): void
135135
private function addValueAsserts(Node $node): void
136136
{
137137
foreach ($this->expectedValuesByKeys as $key => $expectedValue) {
138-
$assertSame = $this->createCallWithName($node, 'assertSame');
138+
$assertSame = $this->createPHPUnitCallWithName($node, 'assertSame');
139139
$assertSame->args[0] = new Arg($expectedValue);
140140

141141
$arrayDimFetch = new ArrayDimFetch($node->args[1]->value, BuilderHelpers::normalizeValue($key));
@@ -145,15 +145,6 @@ private function addValueAsserts(Node $node): void
145145
}
146146
}
147147

148-
/**
149-
* @param StaticCall|MethodCall $node
150-
* @return StaticCall|MethodCall
151-
*/
152-
private function createCallWithName(Node $node, string $name): Node
153-
{
154-
return $node instanceof MethodCall ? new MethodCall($node->var, $name) : new StaticCall($node->class, $name);
155-
}
156-
157148
private function collectExpectedKeysAndValues(Array_ $expectedArray): void
158149
{
159150
foreach ($expectedArray->items as $arrayItem) {

packages/PHPUnit/tests/Rector/DelegateExceptionArgumentsRector/DelegateExceptionArgumentsRectorTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ final class DelegateExceptionArgumentsRectorTest extends AbstractRectorTestCase
1010
public function test(): void
1111
{
1212
$this->doTestFiles([
13-
__DIR__ . '/Fixture/fixture.php.inc',
14-
__DIR__ . '/Fixture/fixture2.php.inc',
15-
__DIR__ . '/Fixture/fixture3.php.inc',
13+
__DIR__ . '/Fixture/message.php.inc',
14+
__DIR__ . '/Fixture/regexp.php.inc',
15+
__DIR__ . '/Fixture/self_nested.php.inc',
1616
]);
1717
}
1818

packages/PHPUnit/tests/Rector/DelegateExceptionArgumentsRector/Fixture/fixture.php.inc packages/PHPUnit/tests/Rector/DelegateExceptionArgumentsRector/Fixture/message.php.inc

+10-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ final class MyTest extends \PHPUnit\Framework\TestCase
77
public function test()
88
{
99
$this->setExpectedException('SomeException');
10+
// with message
1011
$this->setExpectedException('SomeException', $message);
12+
// with code
13+
self::setExpectedException('SomeException', $message, 101);
1114
}
1215
}
1316

@@ -21,9 +24,14 @@ final class MyTest extends \PHPUnit\Framework\TestCase
2124
{
2225
public function test()
2326
{
24-
$this->setExpectedException('SomeException');
25-
$this->setExpectedException('SomeException');
27+
$this->expectException('SomeException');
28+
// with message
29+
$this->expectException('SomeException');
2630
$this->expectExceptionMessage($message);
31+
// with code
32+
self::expectException('SomeException');
33+
self::expectExceptionMessage($message);
34+
self::expectExceptionCode(101);
2735
}
2836
}
2937

packages/PHPUnit/tests/Rector/DelegateExceptionArgumentsRector/Fixture/fixture2.php.inc packages/PHPUnit/tests/Rector/DelegateExceptionArgumentsRector/Fixture/regexp.php.inc

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ final class MyTest extends \PHPUnit\Framework\TestCase
44
{
55
public function test()
66
{
7-
$this->setExpectedExceptionRegExp('SomeException', 'SomREGEPX');
7+
self::setExpectedExceptionRegExp('SomeException', 'SomREGEPX');
88
}
99
}
1010

@@ -16,8 +16,8 @@ final class MyTest extends \PHPUnit\Framework\TestCase
1616
{
1717
public function test()
1818
{
19-
$this->setExpectedExceptionRegExp('SomeException');
20-
$this->expectExceptionMessageRegExp('SomREGEPX');
19+
self::expectException('SomeException');
20+
self::expectExceptionMessageRegExp('SomREGEPX');
2121
}
2222
}
2323

packages/PHPUnit/tests/Rector/DelegateExceptionArgumentsRector/Fixture/fixture3.php.inc packages/PHPUnit/tests/Rector/DelegateExceptionArgumentsRector/Fixture/self_nested.php.inc

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ class ArrayInputTest extends TestCase
2525
public function testParseInvalidInput($expectedExceptionMessage)
2626
{
2727
if (method_exists($this, 'expectException')) {
28-
$this->setExpectedException('SomeException');
28+
$this->expectException('SomeException');
2929
$this->expectExceptionMessage($message);
3030
} else {
31-
$this->setExpectedException('InvalidArgumentException');
31+
$this->expectException('InvalidArgumentException');
3232
$this->expectExceptionMessage($expectedExceptionMessage);
3333
}
3434
}

src/Rector/AbstractPHPUnitRector.php

+30-4
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,25 @@
99

1010
abstract class AbstractPHPUnitRector extends AbstractRector
1111
{
12-
protected function isAssertMethod(Node $node, string $name): bool
12+
protected function isPHPUnitMethodName(Node $node, string $name): bool
1313
{
14-
if (! $this->isInTestClass($node)) {
14+
if (! $this->isPHPUnitTestCaseCall($node)) {
1515
return false;
1616
}
1717

18-
if (! $node instanceof MethodCall && ! $node instanceof StaticCall) {
18+
return $this->isName($node, $name);
19+
}
20+
21+
/**
22+
* @param string[] $names
23+
*/
24+
protected function isPHPUnitMethodNames(Node $node, array $names): bool
25+
{
26+
if (! $this->isPHPUnitTestCaseCall($node)) {
1927
return false;
2028
}
2129

22-
return $this->isName($node, $name);
30+
return $this->isNames($node, $names);
2331
}
2432

2533
protected function isInTestClass(Node $node): bool
@@ -31,4 +39,22 @@ protected function isInTestClass(Node $node): bool
3139

3240
return $this->isTypes($classNode, ['PHPUnit\Framework\TestCase', 'PHPUnit_Framework_TestCase']);
3341
}
42+
43+
/**
44+
* @param StaticCall|MethodCall $node
45+
* @return StaticCall|MethodCall
46+
*/
47+
protected function createPHPUnitCallWithName(Node $node, string $name): Node
48+
{
49+
return $node instanceof MethodCall ? new MethodCall($node->var, $name) : new StaticCall($node->class, $name);
50+
}
51+
52+
private function isPHPUnitTestCaseCall(Node $node): bool
53+
{
54+
if (! $this->isInTestClass($node)) {
55+
return false;
56+
}
57+
58+
return $node instanceof MethodCall || $node instanceof StaticCall;
59+
}
3460
}

0 commit comments

Comments
 (0)