diff --git a/rules-tests/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector/Fixture/fixture_static.php.inc b/rules-tests/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector/Fixture/fixture_static.php.inc new file mode 100644 index 00000000..91356cba --- /dev/null +++ b/rules-tests/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector/Fixture/fixture_static.php.inc @@ -0,0 +1,37 @@ +assertClassHasStaticAttribute('property', 'stdClass'); + $this->assertClassHasStaticAttribute('property', stdClass::class); + $this->classHasStaticAttribute('property', stdClass::class, 'message'); + $this->assertClassNotHasStaticAttribute('property', 'Namespaced\stdClass', 'message'); + } +} + +?> +----- +assertTrue(property_exists('stdClass', 'property')); + $this->assertTrue(property_exists(stdClass::class, 'property')); + $this->assertTrue(property_exists(stdClass::class, 'property'), 'message'); + $this->assertFalse(property_exists('Namespaced\stdClass', 'property'), 'message'); + } +} + +?> diff --git a/rules-tests/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector/PropertyExistsWithoutAssertRectorTest.php b/rules-tests/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector/PropertyExistsWithoutAssertRectorTest.php new file mode 100644 index 00000000..ac544b8c --- /dev/null +++ b/rules-tests/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector/PropertyExistsWithoutAssertRectorTest.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/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector/config/configured_rule.php b/rules-tests/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector/config/configured_rule.php new file mode 100644 index 00000000..b002cf4d --- /dev/null +++ b/rules-tests/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(PropertyExistsWithoutAssertRector::class); +}; diff --git a/rules/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector.php b/rules/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector.php new file mode 100644 index 00000000..f45c2976 --- /dev/null +++ b/rules/PHPUnit100/Rector/MethodCall/PropertyExistsWithoutAssertRector.php @@ -0,0 +1,104 @@ + + */ + private const RENAME_METHODS_WITH_OBJECT_MAP = [ + 'assertClassHasStaticAttribute' => 'assertTrue', + 'classHasStaticAttribute' => 'assertTrue', + 'assertClassNotHasStaticAttribute' => 'assertFalse', + ]; + + public function __construct( + private readonly IdentifierManipulator $identifierManipulator, + private readonly TestsNodeAnalyzer $testsNodeAnalyzer + ) { + } + + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition( + 'Replace delited PHPUnit methods: assertClassHasStaticAttribute, classHasStaticAttribute and assertClassNotHasStaticAttribute by property_exists()', + [ + new CodeSample( + <<<'CODE_SAMPLE' +$this->assertClassHasStaticAttribute("Class", "property"); +$this->classHasStaticAttribute("Class", "property"); +$this->assertClassNotHasStaticAttribute("Class", "property"); +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +$this->assertTrue(property_exists("Class", "property")); +$this->assertTrue(property_exists("Class", "property")); +$this->assertFalse(property_exists("Class", "property")); +CODE_SAMPLE + ), + ] + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [MethodCall::class]; + } + + /** + * @param MethodCall $node + */ + public function refactor(Node $node): ?Node + { + $map = self::RENAME_METHODS_WITH_OBJECT_MAP; + if (! $this->testsNodeAnalyzer->isPHPUnitMethodCallNames($node, array_keys($map))) { + return null; + } + + if ($node->isFirstClassCallable() || ! isset($node->getArgs()[0], $node->getArgs()[1])) { + return null; + } + + $firstNode = new Arg($node->getArgs()[0]->value); + + if ($node->getArgs()[1]->value instanceof ClassConstFetch) { + $secondNode = $node->getArgs()[1]; + } else { + $secondNode = new Arg($node->getArgs()[1]->value); + } + + $funcCall = new FuncCall(new Name('property_exists'), [$secondNode, $firstNode]); + + $newArgs = $this->nodeFactory->createArgs([$funcCall]); + + unset($node->args[0], $node->args[1]); + $node->args = array_merge($newArgs, $node->getArgs()); + + $this->identifierManipulator->renameNodeWithMap($node, $map); + + return $node; + } +}