mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-13 12:33:52 +01:00
Merge pull request #2144 from rectorphp/phpunit-provider
[PHPUnit] Add RemoveDataProviderTestPrefixRector
This commit is contained in:
commit
4fd1cde4b7
@ -5,3 +5,4 @@ services:
|
||||
Rector\Renaming\Rector\Annotation\RenameAnnotationRector:
|
||||
PHPUnit\Framework\TestCase:
|
||||
scenario: 'test'
|
||||
Rector\PHPUnit\Rector\Class_\RemoveDataProviderTestPrefixRector: ~
|
||||
|
@ -0,0 +1,147 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\PHPUnit\Rector\Class_;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Comment\Doc;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Rector\AbstractPHPUnitRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
|
||||
/**
|
||||
* @see https://stackoverflow.com/a/46693675/1348344
|
||||
*
|
||||
* @see \Rector\PHPUnit\Tests\Rector\Class_\RemoveDataProviderTestPrefixRector\RemoveDataProviderTestPrefixRectorTest
|
||||
*/
|
||||
final class RemoveDataProviderTestPrefixRector extends AbstractPHPUnitRector
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const DATA_PROVIDER_ANNOTATION_PATTERN = '#(@dataProvider\s+)(?<providerMethodName>test\w+)#';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const DATA_PROVIDER_EXACT_NAME_PATTERN = '#(@dataProvider\s+)(%s)#';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $providerMethodNamesToNewNames = [];
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Data provider methods cannot start with "test" prefix', [
|
||||
new CodeSample(
|
||||
<<<'PHP'
|
||||
class SomeClass extends PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider testProvideData()
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
$nothing = 5;
|
||||
}
|
||||
|
||||
public function testProvideData()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
}
|
||||
PHP
|
||||
,
|
||||
<<<'PHP'
|
||||
class SomeClass extends PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
$nothing = 5;
|
||||
}
|
||||
|
||||
public function provideData()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
}
|
||||
PHP
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isInTestClass($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->providerMethodNamesToNewNames = [];
|
||||
|
||||
$this->renameDataProviderAnnotationsAndCollectRenamedMethods($node);
|
||||
|
||||
$this->renameProviderMethods($node);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function renameDataProviderAnnotationsAndCollectRenamedMethods(Class_ $class): void
|
||||
{
|
||||
foreach ($class->getMethods() as $classMethod) {
|
||||
if ($classMethod->getDocComment() === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$docCommentText = $classMethod->getDocComment()->getText();
|
||||
if (! Strings::match($docCommentText, self::DATA_PROVIDER_ANNOTATION_PATTERN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// replace the name in the doc
|
||||
$matches = Strings::matchAll($docCommentText, self::DATA_PROVIDER_ANNOTATION_PATTERN);
|
||||
foreach ($matches as $match) {
|
||||
$currentProviderMethodName = $match['providerMethodName'];
|
||||
|
||||
$newMethodName = Strings::substring($currentProviderMethodName, strlen('test'));
|
||||
$newMethodName = lcfirst($newMethodName);
|
||||
|
||||
$currentMethodPattern = sprintf(self::DATA_PROVIDER_EXACT_NAME_PATTERN, $currentProviderMethodName);
|
||||
|
||||
$docCommentText = Strings::replace($docCommentText, $currentMethodPattern, '$1' . $newMethodName);
|
||||
|
||||
$this->providerMethodNamesToNewNames[$currentProviderMethodName] = $newMethodName;
|
||||
}
|
||||
|
||||
$classMethod->setDocComment(new Doc($docCommentText));
|
||||
}
|
||||
}
|
||||
|
||||
private function renameProviderMethods(Class_ $class): void
|
||||
{
|
||||
foreach ($class->getMethods() as $classMethod) {
|
||||
foreach ($this->providerMethodNamesToNewNames as $oldName => $newName) {
|
||||
if (! $this->isName($classMethod, $oldName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$classMethod->name = new Node\Identifier($newName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\PHPUnit\Tests\Rector\Class_\RemoveDataProviderTestPrefixRector\Fixture;
|
||||
|
||||
class SomeClass extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider testProvideData()
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
$nothing = 5;
|
||||
}
|
||||
|
||||
public function testProvideData()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\PHPUnit\Tests\Rector\Class_\RemoveDataProviderTestPrefixRector\Fixture;
|
||||
|
||||
class SomeClass extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
$nothing = 5;
|
||||
}
|
||||
|
||||
public function provideData()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\PHPUnit\Tests\Rector\Class_\RemoveDataProviderTestPrefixRector\Fixture;
|
||||
|
||||
class MultipleDataProviders extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider testProvideData()
|
||||
* @dataProvider testNextProvideData2()
|
||||
* @dataProvider testNextProvideData()
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
$nothing = 5;
|
||||
}
|
||||
|
||||
public function testProvideData()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
|
||||
public function testNextProvideData2()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
|
||||
public function testNextProvideData()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\PHPUnit\Tests\Rector\Class_\RemoveDataProviderTestPrefixRector\Fixture;
|
||||
|
||||
class MultipleDataProviders extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
* @dataProvider nextProvideData2()
|
||||
* @dataProvider nextProvideData()
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
$nothing = 5;
|
||||
}
|
||||
|
||||
public function provideData()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
|
||||
public function nextProvideData2()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
|
||||
public function nextProvideData()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\PHPUnit\Tests\Rector\Class_\RemoveDataProviderTestPrefixRector\Fixture;
|
||||
|
||||
class WithTestAnnotation extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
* @dataProvider testProvideDataForWithATestAnnotation()
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
$nothing = 5;
|
||||
}
|
||||
|
||||
public function testProvideDataForWithATestAnnotation()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\PHPUnit\Tests\Rector\Class_\RemoveDataProviderTestPrefixRector\Fixture;
|
||||
|
||||
class WithTestAnnotation extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
* @dataProvider provideDataForWithATestAnnotation()
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
$nothing = 5;
|
||||
}
|
||||
|
||||
public function provideDataForWithATestAnnotation()
|
||||
{
|
||||
return ['123'];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,30 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\PHPUnit\Tests\Rector\Class_\RemoveDataProviderTestPrefixRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\PHPUnit\Rector\Class_\RemoveDataProviderTestPrefixRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
|
||||
final class RemoveDataProviderTestPrefixRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideDataForTest()
|
||||
*/
|
||||
public function test(string $file): void
|
||||
{
|
||||
$this->doTestFile($file);
|
||||
}
|
||||
|
||||
public function provideDataForTest(): Iterator
|
||||
{
|
||||
yield [__DIR__ . '/Fixture/fixture.php.inc'];
|
||||
yield [__DIR__ . '/Fixture/with_test_annotation.php.inc'];
|
||||
yield [__DIR__ . '/Fixture/multiple_data_providers.php.inc'];
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return RemoveDataProviderTestPrefixRector::class;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user