Create AssertInstanceOfComparisonRector

This commit is contained in:
Gabriel Caruso 2018-01-03 04:41:54 -02:00
parent db2df82191
commit 34c909dbc5
5 changed files with 164 additions and 0 deletions

View File

@ -0,0 +1,108 @@
<?php declare(strict_types=1);
namespace Rector\Rector\Contrib\PHPUnit\SpecificMethod;
use PhpParser\Node;
use PhpParser\Node\Expr\Instanceof_;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Identifier;
use Rector\Node\NodeFactory;
use Rector\NodeAnalyzer\MethodCallAnalyzer;
use Rector\NodeChanger\IdentifierRenamer;
use Rector\Rector\AbstractRector;
/**
* - Before:
* - $this->assertTrue($foo instanceof Foo, 'message');
* - $this->assertFalse($foo instanceof Foo, 'message');
*
* - After:
* - $this->assertInstanceOf(Foo::class, $foo, 'message');
* - $this->assertNotInstanceOf(Foo::class, $foo, 'message');
*/
final class AssertInstanceOfComparisonRector extends AbstractRector
{
/**
* @var MethodCallAnalyzer
*/
private $methodCallAnalyzer;
/**
* @var IdentifierRenamer
*/
private $identifierRenamer;
/**
* @var NodeFactory
*/
private $nodeFactory;
public function __construct(
MethodCallAnalyzer $methodCallAnalyzer,
IdentifierRenamer $identifierRenamer,
NodeFactory $nodeFactory
) {
$this->methodCallAnalyzer = $methodCallAnalyzer;
$this->identifierRenamer = $identifierRenamer;
$this->nodeFactory = $nodeFactory;
}
public function isCandidate(Node $node): bool
{
if (! $this->methodCallAnalyzer->isTypesAndMethods(
$node,
['PHPUnit\Framework\TestCase', 'PHPUnit_Framework_TestCase'],
['assertTrue', 'assertFalse']
)) {
return false;
}
/** @var MethodCall $methodCallNode */
$methodCallNode = $node;
$firstArgumentValue = $methodCallNode->args[0]->value;
return $firstArgumentValue instanceof Instanceof_;
}
/**
* @param MethodCall $methodCallNode
*/
public function refactor(Node $methodCallNode): ?Node
{
$this->renameMethod($methodCallNode);
$this->changeOrderArguments($methodCallNode);
return $methodCallNode;
}
public function changeOrderArguments(MethodCall $methodCallNode): void
{
$oldArguments = $methodCallNode->args;
/** @var Instanceof_ $comparison */
$comparison = $oldArguments[0]->value;
$className = $comparison->class->toString();
$argument = $comparison->expr;
unset($oldArguments[0]);
$methodCallNode->args = array_merge([
$this->nodeFactory->createString($className),
$argument,
], $oldArguments);
}
private function renameMethod(MethodCall $methodCallNode): void
{
/** @var Identifier $identifierNode */
$identifierNode = $methodCallNode->name;
$oldMethodName = $identifierNode->toString();
if ($oldMethodName === 'assertTrue') {
$this->identifierRenamer->renameNode($methodCallNode, 'assertInstanceOf');
} else {
$this->identifierRenamer->renameNode($methodCallNode, 'assertNotInstanceOf');
}
}
}

View File

@ -6,3 +6,4 @@ rectors:
Rector\Rector\Contrib\PHPUnit\SpecificMethod\AssertTrueFalseInternalTypeToSpecificMethodRector: ~
Rector\Rector\Contrib\PHPUnit\SpecificMethod\AssertCompareToSpecificMethodRector: ~
Rector\Rector\Contrib\PHPUnit\SpecificMethod\AssertTrueIssetToObjectHasAttributeRector: ~
Rector\Rector\Contrib\PHPUnit\SpecificMethod\AssertInstanceOfComparisonRector: ~

View File

@ -0,0 +1,35 @@
<?php declare(strict_types=1);
namespace Rector\Tests\Rector\Contrib\PHPUnit\SpecificMethod\AssertInstanceOfComparisonRector;
use Rector\Rector\Contrib\PHPUnit\SpecificMethod\AssertInstanceOfComparisonRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
final class AssertInstanceOfComparisonRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideWrongToFixedFiles()
*/
public function test(string $wrong, string $fixed): void
{
$this->doTestFileMatchesExpectedContent($wrong, $fixed);
}
/**
* @return string[][]
*/
public function provideWrongToFixedFiles(): array
{
return [
[__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc'],
];
}
/**
* @return string[]
*/
protected function getRectorClasses(): array
{
return [AssertInstanceOfComparisonRector::class];
}
}

View File

@ -0,0 +1,10 @@
<?php declare(strict_types=1);
final class MyTest extends \PHPUnit\Framework\TestCase
{
public function test()
{
$this->assertInstanceOf('Foo', $something);
$this->assertNotInstanceOf('Foo', $something);
}
}

View File

@ -0,0 +1,10 @@
<?php declare(strict_types=1);
final class MyTest extends \PHPUnit\Framework\TestCase
{
public function test()
{
$this->assertTrue($something instanceof Foo);
$this->assertFalse($something instanceof Foo);
}
}