From 0c5eec9ac3d60bb14d59668f56421aed20676141 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 2 Feb 2026 12:20:45 +0100 Subject: [PATCH] improve direct assert rule --- .../Fixture/that_assert_true.php.inc | 6 +++ .../AssertThatToDirectAssertRector.php | 39 ++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/rules-tests/CodeQuality/Rector/MethodCall/AssertThatToDirectAssertRector/Fixture/that_assert_true.php.inc b/rules-tests/CodeQuality/Rector/MethodCall/AssertThatToDirectAssertRector/Fixture/that_assert_true.php.inc index 7fcea43f..a94d0293 100644 --- a/rules-tests/CodeQuality/Rector/MethodCall/AssertThatToDirectAssertRector/Fixture/that_assert_true.php.inc +++ b/rules-tests/CodeQuality/Rector/MethodCall/AssertThatToDirectAssertRector/Fixture/that_assert_true.php.inc @@ -9,6 +9,9 @@ final class ThatAssertTrue extends \PHPUnit\Framework\TestCase public function test() { $this->assertThat('value', $this->isTrue()); + + $this->assertThat('name', $this->isType('string')); + $this->assertThat('age', $this->isString()); } } @@ -25,6 +28,9 @@ final class ThatAssertTrue extends \PHPUnit\Framework\TestCase public function test() { $this->assertTrue('value'); + + $this->assertIsString('name'); + $this->assertIsString('age'); } } diff --git a/rules/CodeQuality/Rector/MethodCall/AssertThatToDirectAssertRector.php b/rules/CodeQuality/Rector/MethodCall/AssertThatToDirectAssertRector.php index 4bdae872..ca5f7fea 100644 --- a/rules/CodeQuality/Rector/MethodCall/AssertThatToDirectAssertRector.php +++ b/rules/CodeQuality/Rector/MethodCall/AssertThatToDirectAssertRector.php @@ -7,6 +7,7 @@ use PhpParser\Node; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Identifier; +use Rector\PhpParser\Node\Value\ValueResolver; use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer; use Rector\Rector\AbstractRector; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -17,8 +18,25 @@ */ final class AssertThatToDirectAssertRector extends AbstractRector { + /** + * @var array + */ + private const array IS_TO_ASSERT_METHOD_MAP = [ + 'isTrue' => 'assertTrue', + 'isFalse' => 'assertFalse', + 'isNull' => 'assertNull', + 'isEmpty' => 'assertEmpty', + 'isCountable' => 'assertIsCountable', + 'isArray' => 'assertIsArray', + 'isString' => 'assertIsString', + 'isInt' => 'assertIsInt', + 'isFloat' => 'assertIsFloat', + 'isBool' => 'assertIsBool', + ]; + public function __construct( private readonly TestsNodeAnalyzer $testsNodeAnalyzer, + private readonly ValueResolver $valueResolver, ) { } @@ -95,8 +113,25 @@ public function refactor(Node $node): ?Node return $node; } - if ($exactAssertName === 'isTrue') { - $node->name = new Identifier('assertTrue'); + foreach (self::IS_TO_ASSERT_METHOD_MAP as $isName => $assertName) { + if (! $this->isName($exactAssertMethodCall->name, $isName)) { + continue; + } + + $node->name = new Identifier($assertName); + unset($node->args[1]); + + return $node; + } + + if ($this->isName($exactAssertMethodCall->name, 'isType')) { + $exactFirstArg = $exactAssertMethodCall->getArgs()[0]; + $expectedType = $this->valueResolver->getValue($exactFirstArg->value); + if (! is_string($expectedType)) { + return null; + } + + $node->name = new Identifier('assertIs' . ucfirst($expectedType)); unset($node->args[1]); return $node;