diff --git a/config/sets/phpunit-code-quality.php b/config/sets/phpunit-code-quality.php index f17c27d7..9ac2ba9f 100644 --- a/config/sets/phpunit-code-quality.php +++ b/config/sets/phpunit-code-quality.php @@ -31,6 +31,7 @@ use Rector\PHPUnit\CodeQuality\Rector\MethodCall\AssertSameTrueFalseToAssertTrueFalseRector; use Rector\PHPUnit\CodeQuality\Rector\MethodCall\AssertTrueFalseToSpecificMethodRector; use Rector\PHPUnit\CodeQuality\Rector\MethodCall\FlipAssertRector; +use Rector\PHPUnit\CodeQuality\Rector\MethodCall\MatchAssertSameExpectedTypeRector; use Rector\PHPUnit\CodeQuality\Rector\MethodCall\NarrowIdenticalWithConsecutiveRector; use Rector\PHPUnit\CodeQuality\Rector\MethodCall\NarrowSingleWillReturnCallbackRector; use Rector\PHPUnit\CodeQuality\Rector\MethodCall\RemoveExpectAnyFromMockRector; @@ -43,7 +44,10 @@ return static function (RectorConfig $rectorConfig): void { $rectorConfig->rules([ ConstructClassMethodToSetUpTestCaseRector::class, + AssertSameTrueFalseToAssertTrueFalseRector::class, + MatchAssertSameExpectedTypeRector::class, + AssertEqualsToSameRector::class, PreferPHPUnitThisCallRector::class, YieldDataProviderRector::class, diff --git a/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/Fixture/match_assert_type.php.inc b/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/Fixture/match_assert_type.php.inc new file mode 100644 index 00000000..1c537c53 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/Fixture/match_assert_type.php.inc @@ -0,0 +1,41 @@ +assertSame('123', $this->getOrderId()); + } + + private function getOrderId(): int + { + return 123; + } +} + +?> +----- +assertSame(123, $this->getOrderId()); + } + + private function getOrderId(): int + { + return 123; + } +} + +?> diff --git a/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/Fixture/match_integer_to_string.php.inc b/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/Fixture/match_integer_to_string.php.inc new file mode 100644 index 00000000..4f0d419e --- /dev/null +++ b/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/Fixture/match_integer_to_string.php.inc @@ -0,0 +1,41 @@ +assertSame(123, $this->getOrderId()); + } + + private function getOrderId(): string + { + return '123'; + } +} + +?> +----- +assertSame('123', $this->getOrderId()); + } + + private function getOrderId(): string + { + return '123'; + } +} + +?> diff --git a/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/Fixture/nullable_match_assert_type.php.inc b/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/Fixture/nullable_match_assert_type.php.inc new file mode 100644 index 00000000..db905973 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/Fixture/nullable_match_assert_type.php.inc @@ -0,0 +1,41 @@ +assertSame('123', $this->getOrderId()); + } + + private function getOrderId(): ?int + { + return 123; + } +} + +?> +----- +assertSame(123, $this->getOrderId()); + } + + private function getOrderId(): ?int + { + return 123; + } +} + +?> diff --git a/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/MatchAssertSameExpectedTypeRectorTest.php b/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/MatchAssertSameExpectedTypeRectorTest.php new file mode 100644 index 00000000..fdd13a92 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/MatchAssertSameExpectedTypeRectorTest.php @@ -0,0 +1,28 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/config/configured_rule.php b/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/config/configured_rule.php new file mode 100644 index 00000000..bc288d66 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(MatchAssertSameExpectedTypeRector::class); +}; diff --git a/rules/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector.php b/rules/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector.php new file mode 100644 index 00000000..24f0dee1 --- /dev/null +++ b/rules/CodeQuality/Rector/MethodCall/MatchAssertSameExpectedTypeRector.php @@ -0,0 +1,118 @@ +assertSame('123', $this->getOrderId()); + } + + private function getOrderId(): int + { + return 123; + } +} +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +use PHPUnit\Framework\TestCase; + +class SomeTest extends TestCase +{ + public function run() + { + $this->assertSame(123, $this->getOrderId()); + } + + private function getOrderId(): int + { + return 123; + } +} +CODE_SAMPLE + ), + ] + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [MethodCall::class, StaticCall::class]; + } + + /** + * @param MethodCall|StaticCall $node + */ + public function refactor(Node $node): ?Node + { + if (! $this->testsNodeAnalyzer->isPHPUnitMethodCallNames($node, ['assertSame', 'assertEquals'])) { + return null; + } + + $expectedArg = $node->getArgs()[0]; + if (! $expectedArg->value instanceof String_ && ! $expectedArg->value instanceof LNumber) { + return null; + } + + $expectedType = $this->getType($expectedArg->value); + + $variableExpr = $node->getArgs()[1] + ->value; + $variableType = $this->getType($variableExpr); + + $directVariableType = TypeCombinator::removeNull($variableType); + + if ($expectedType->isLiteralString()->yes() && $directVariableType->isInteger()->yes()) { + // update expected type to provided type + $expectedArg->value = new LNumber((int) $expectedArg->value->value); + + return $node; + } + + if ($expectedType->isInteger()->yes() && $directVariableType->isString()->yes()) { + // update expected type to provided type + $expectedArg->value = new String_((string) $expectedArg->value->value); + + return $node; + } + + return null; + } +}