Skip to content

Commit 8207d5a

Browse files
committed
[PHPUnit12] Add AssertIsTypeMethodCallRector
1 parent 7f75f1d commit 8207d5a

File tree

6 files changed

+285
-1
lines changed

6 files changed

+285
-1
lines changed

config/sets/phpunit120.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
declare(strict_types=1);
44

55
use Rector\Config\RectorConfig;
6+
use Rector\PHPUnit\PHPUnit120\Rector\Class_\AssertIsTypeMethodCallRector;
67
use Rector\PHPUnit\PHPUnit120\Rector\Class_\RemoveOverrideFinalConstructTestCaseRector;
78

89
return static function (RectorConfig $rectorConfig): void {
9-
$rectorConfig->rule(RemoveOverrideFinalConstructTestCaseRector::class);
10+
$rectorConfig->rules([RemoveOverrideFinalConstructTestCaseRector::class, AssertIsTypeMethodCallRector::class]);
1011
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\MethodCall\AssertIsTypeMethodCallRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
10+
11+
final class AssertIsTypeMethodCallRectorTest extends AbstractRectorTestCase
12+
{
13+
#[DataProvider('provideData')]
14+
public function test(string $filePath): void
15+
{
16+
$this->doTestFile($filePath);
17+
}
18+
19+
public static function provideData(): Iterator
20+
{
21+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22+
}
23+
24+
public function provideConfigFilePath(): string
25+
{
26+
return __DIR__ . '/config/configured_rule.php';
27+
}
28+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\MethodCall\AssertIsTypeMethodCallRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class Fixture extends TestCase
8+
{
9+
public function testMethod(): void
10+
{
11+
$this->assertThat([], $this->isType('array'));
12+
$this->assertThat(true, $this->isType('bool'));
13+
$this->assertThat(true, $this->isType('boolean'));
14+
$this->assertThat(fn () => 0, $this->isType('callable'));
15+
$this->assertThat(1.0, $this->isType('float'));
16+
$this->assertThat(1.0, $this->isType('double'));
17+
$this->assertThat(1, $this->isType('int'));
18+
$this->assertThat(1, $this->isType('integer'));
19+
$this->assertThat([], $this->isType('iterable'));
20+
$this->assertThat(null, $this->isType('null'));
21+
$this->assertThat(12, $this->isType('numeric'));
22+
$this->assertThat(new \stdClass(), $this->isType('object'));
23+
$this->assertThat(1.0, $this->isType('real'));
24+
$this->assertThat($resource, $this->isType('resource'));
25+
$this->assertThat($closedResource, $this->isType('resource (closed)'));
26+
$this->assertThat('', $this->isType('scalar'));
27+
$this->assertThat('', $this->isType('string'));
28+
}
29+
}
30+
?>
31+
-----
32+
<?php
33+
34+
namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\MethodCall\AssertIsTypeMethodCallRector\Fixture;
35+
36+
use PHPUnit\Framework\TestCase;
37+
38+
final class Fixture extends TestCase
39+
{
40+
public function testMethod(): void
41+
{
42+
$this->assertThat([], $this->isArray());
43+
$this->assertThat(true, $this->isBool());
44+
$this->assertThat(true, $this->isBool());
45+
$this->assertThat(fn () => 0, $this->isCallable());
46+
$this->assertThat(1.0, $this->isFloat());
47+
$this->assertThat(1.0, $this->isFloat());
48+
$this->assertThat(1, $this->isInt());
49+
$this->assertThat(1, $this->isInt());
50+
$this->assertThat([], $this->isIterable());
51+
$this->assertThat(null, $this->isNull());
52+
$this->assertThat(12, $this->isNumeric());
53+
$this->assertThat(new \stdClass(), $this->isObject());
54+
$this->assertThat(1.0, $this->isFloat());
55+
$this->assertThat($resource, $this->isResource());
56+
$this->assertThat($closedResource, $this->isClosedResource());
57+
$this->assertThat('', $this->isScalar());
58+
$this->assertThat('', $this->isString());
59+
}
60+
}
61+
?>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\MethodCall\AssertIsTypeMethodCallRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class StaticFixture extends TestCase
8+
{
9+
public function testMethod(): void
10+
{
11+
$this->assertThat([], self::isType('array'));
12+
$this->assertThat(true, self::isType('bool'));
13+
$this->assertThat(true, self::isType('boolean'));
14+
$this->assertThat(fn () => 0, self::isType('callable'));
15+
$this->assertThat(1.0, self::isType('float'));
16+
$this->assertThat(1.0, self::isType('double'));
17+
$this->assertThat(1, self::isType('int'));
18+
$this->assertThat(1, self::isType('integer'));
19+
$this->assertThat([], self::isType('iterable'));
20+
$this->assertThat(null, self::isType('null'));
21+
$this->assertThat(12, self::isType('numeric'));
22+
$this->assertThat(new \stdClass(), self::isType('object'));
23+
$this->assertThat(1.0, self::isType('real'));
24+
$this->assertThat($resource, self::isType('resource'));
25+
$this->assertThat($closedResource, self::isType('resource (closed)'));
26+
$this->assertThat('', self::isType('scalar'));
27+
$this->assertThat('', self::isType('string'));
28+
}
29+
}
30+
?>
31+
-----
32+
<?php
33+
34+
namespace Rector\PHPUnit\Tests\PHPUnit120\Rector\MethodCall\AssertIsTypeMethodCallRector\Fixture;
35+
36+
use PHPUnit\Framework\TestCase;
37+
38+
final class StaticFixture extends TestCase
39+
{
40+
public function testMethod(): void
41+
{
42+
$this->assertThat([], self::isArray());
43+
$this->assertThat(true, self::isBool());
44+
$this->assertThat(true, self::isBool());
45+
$this->assertThat(fn () => 0, self::isCallable());
46+
$this->assertThat(1.0, self::isFloat());
47+
$this->assertThat(1.0, self::isFloat());
48+
$this->assertThat(1, self::isInt());
49+
$this->assertThat(1, self::isInt());
50+
$this->assertThat([], self::isIterable());
51+
$this->assertThat(null, self::isNull());
52+
$this->assertThat(12, self::isNumeric());
53+
$this->assertThat(new \stdClass(), self::isObject());
54+
$this->assertThat(1.0, self::isFloat());
55+
$this->assertThat($resource, self::isResource());
56+
$this->assertThat($closedResource, self::isClosedResource());
57+
$this->assertThat('', self::isScalar());
58+
$this->assertThat('', self::isString());
59+
}
60+
}
61+
?>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
use Rector\PHPUnit\PHPUnit120\Rector\Class_\AssertIsTypeMethodCallRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig->rule(AssertIsTypeMethodCallRector::class);
10+
};
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\PHPUnit\PHPUnit120\Rector\Class_;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Arg;
9+
use PhpParser\Node\Expr\MethodCall;
10+
use PhpParser\Node\Expr\StaticCall;
11+
use Rector\PhpParser\Node\Value\ValueResolver;
12+
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
13+
use Rector\Rector\AbstractRector;
14+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
15+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
16+
17+
/**
18+
* @see https://github.com/sebastianbergmann/phpunit/issues/6053
19+
* @see https://github.com/sebastianbergmann/phpunit/blob/12.0.0/ChangeLog-12.0.md
20+
* @see \Rector\PHPUnit\Tests\PHPUnit120\Rector\MethodCall\AssertIsTypeMethodCallRector\AssertIsTypeMethodCallRectorTest
21+
*/
22+
final class AssertIsTypeMethodCallRector extends AbstractRector
23+
{
24+
private const IS_TYPE_VALUE_TO_METHOD = [
25+
'array' => 'isArray',
26+
'bool' => 'isBool',
27+
'boolean' => 'isBool',
28+
'callable' => 'isCallable',
29+
'double' => 'isFloat',
30+
'float' => 'isFloat',
31+
'integer' => 'isInt',
32+
'int' => 'isInt',
33+
'iterable' => 'isIterable',
34+
'null' => 'isNull',
35+
'numeric' => 'isNumeric',
36+
'object' => 'isObject',
37+
'real' => 'isFloat',
38+
'resource' => 'isResource',
39+
'resource (closed)' => 'isClosedResource',
40+
'scalar' => 'isScalar',
41+
'string' => 'isString',
42+
];
43+
44+
public function __construct(
45+
private readonly ValueResolver $valueResolver,
46+
private readonly TestsNodeAnalyzer $testsNodeAnalyzer,
47+
) {
48+
}
49+
50+
public function getRuleDefinition(): RuleDefinition
51+
{
52+
return new RuleDefinition(
53+
'Replaces `Assert::isType()` calls with type-specific `Assert::is*()` calls',
54+
[
55+
new CodeSample(
56+
<<<'CODE_SAMPLE'
57+
use PHPUnit\Framework\TestCase;
58+
59+
final class SomeClass extends TestCase
60+
{
61+
public function testMethod(): void
62+
{
63+
$this->assertThat([], $this->isType('array'));
64+
}
65+
}
66+
CODE_SAMPLE
67+
,
68+
<<<'CODE_SAMPLE'
69+
use PHPUnit\Framework\TestCase;
70+
71+
final class SomeClass extends TestCase
72+
{
73+
public function testMethod(): void
74+
{
75+
$this->assertThat([], $this->isArray());
76+
}
77+
}
78+
CODE_SAMPLE
79+
,
80+
),
81+
],
82+
);
83+
}
84+
85+
/**
86+
* @return array<class-string<Node>>
87+
*/
88+
public function getNodeTypes(): array
89+
{
90+
return [MethodCall::class, StaticCall::class];
91+
}
92+
93+
/**
94+
* @param MethodCall|StaticCall $node
95+
*/
96+
public function refactor(Node $node): Node|null
97+
{
98+
if (! $this->testsNodeAnalyzer->isPHPUnitTestCaseCall($node) || ! $this->isName($node->name, 'isType')) {
99+
return null;
100+
}
101+
102+
if (count($node->getArgs()) !== 1) {
103+
return null;
104+
}
105+
106+
$arg = $node->getArg('type', 0);
107+
if (! $arg instanceof Arg) {
108+
return null;
109+
}
110+
111+
$argValue = $this->valueResolver->getValue($arg);
112+
if (isset(self::IS_TYPE_VALUE_TO_METHOD[$argValue])) {
113+
if ($node instanceof MethodCall) {
114+
return new MethodCall($node->var, self::IS_TYPE_VALUE_TO_METHOD[$argValue]);
115+
}
116+
117+
return new StaticCall($node->class, self::IS_TYPE_VALUE_TO_METHOD[$argValue]);
118+
119+
}
120+
121+
return null;
122+
}
123+
}

0 commit comments

Comments
 (0)