Skip to content

Commit 6fa53ef

Browse files
authored
[PHPUnit70] Add ScenarioToTestAnnotationRector to replace scenario annotation with test (#809)
1 parent 3558b70 commit 6fa53ef

6 files changed

Lines changed: 185 additions & 7 deletions

File tree

‎config/sets/composer-based.php‎

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
use Rector\PHPUnit\PHPUnit60\Rector\MethodCall\DelegateExceptionArgumentsRector;
4747
use Rector\PHPUnit\PHPUnit60\Rector\MethodCall\GetMockBuilderGetMockToCreateMockRector;
4848
use Rector\PHPUnit\PHPUnit70\Rector\Class_\RemoveDataProviderTestPrefixRector;
49+
use Rector\PHPUnit\PHPUnit70\Rector\ClassMethod\ScenarioToTestAnnotationRector;
4950
use Rector\PHPUnit\PHPUnit80\Rector\MethodCall\AssertEqualsParameterToSpecificMethodsTypeRector;
5051
use Rector\PHPUnit\PHPUnit80\Rector\MethodCall\SpecificAssertContainsRector;
5152
use Rector\PHPUnit\PHPUnit80\Rector\MethodCall\SpecificAssertInternalTypeRector;
@@ -54,11 +55,9 @@
5455
use Rector\PHPUnit\PHPUnit90\Rector\MethodCall\ExplicitPhpErrorApiRector;
5556
use Rector\PHPUnit\PHPUnit90\Rector\MethodCall\SpecificAssertContainsWithoutIdentityRector;
5657
use Rector\PHPUnit\ValueObject\AnnotationWithValueToAttribute;
57-
use Rector\Renaming\Rector\ClassMethod\RenameAnnotationRector;
5858
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
5959
use Rector\Renaming\Rector\Name\RenameClassRector;
6060
use Rector\Renaming\ValueObject\MethodCallRename;
61-
use Rector\Renaming\ValueObject\RenameAnnotationByType;
6261
use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeDeclarationRector;
6362
use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationRector;
6463
use Rector\TypeDeclaration\ValueObject\AddParamTypeDeclaration;
@@ -129,6 +128,8 @@
129128

130129
// PHPUnit 7.0
131130
RemoveDataProviderTestPrefixRector::class,
131+
// the "@scenario" annotation was dropped in PHPUnit 7.0
132+
ScenarioToTestAnnotationRector::class,
132133

133134
// the assertIsArray(), assertStringContainsString() and assertEqualsWithDelta() families, PHPUnit 7.5
134135
SpecificAssertInternalTypeRector::class,
@@ -391,11 +392,6 @@
391392
'PHPUnit_Util_Test' => 'PHPUnit\Util\Test',
392393
], 'phpunit/phpunit', '>=6.0');
393394

394-
// the "scenario" annotation was dropped in PHPUnit 7.0
395-
$rectorConfig->ruleWithConfigurationComposerVersionBound(RenameAnnotationRector::class, [
396-
new RenameAnnotationByType('PHPUnit\Framework\TestCase', 'scenario', 'test'),
397-
], 'phpunit/phpunit', '>=7.0');
398-
399395
// the TestCase methods were given native types in PHPUnit 8.0
400396
$rectorConfig->ruleWithConfigurationComposerVersionBound(AddParamTypeDeclarationRector::class, [
401397
// @see https://github.com/rectorphp/rector/issues/1024 - no type, $dataName
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\PHPUnit70\Rector\ClassMethod\ScenarioToTestAnnotationRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class SomeScenarioTest extends TestCase
8+
{
9+
/**
10+
* @scenario
11+
*/
12+
public function someMethod()
13+
{
14+
}
15+
}
16+
17+
?>
18+
-----
19+
<?php
20+
21+
namespace Rector\PHPUnit\Tests\PHPUnit70\Rector\ClassMethod\ScenarioToTestAnnotationRector\Fixture;
22+
23+
use PHPUnit\Framework\TestCase;
24+
25+
final class SomeScenarioTest extends TestCase
26+
{
27+
/**
28+
* @test
29+
*/
30+
public function someMethod()
31+
{
32+
}
33+
}
34+
35+
?>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\PHPUnit70\Rector\ClassMethod\ScenarioToTestAnnotationRector\Fixture;
4+
5+
final class SomeRegularClass
6+
{
7+
/**
8+
* @scenario
9+
*/
10+
public function someMethod()
11+
{
12+
}
13+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\PHPUnit\Tests\PHPUnit70\Rector\ClassMethod\ScenarioToTestAnnotationRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
10+
11+
final class ScenarioToTestAnnotationRectorTest extends AbstractRectorTestCase
12+
{
13+
#[DataProvider('provideData')]
14+
public function test(string $filePath): void
15+
{
16+
$this->doTestFile($filePath);
17+
}
18+
19+
public static function provideData(): Iterator
20+
{
21+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22+
}
23+
24+
public function provideConfigFilePath(): string
25+
{
26+
return __DIR__ . '/config/configured_rule.php';
27+
}
28+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
use Rector\PHPUnit\PHPUnit70\Rector\ClassMethod\ScenarioToTestAnnotationRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig->rule(ScenarioToTestAnnotationRector::class);
10+
};
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\PHPUnit\PHPUnit70\Rector\ClassMethod;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Stmt\ClassMethod;
9+
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
10+
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
11+
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
12+
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockTagReplacer;
13+
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
14+
use Rector\Rector\AbstractRector;
15+
use Rector\RuleDoc\CodeSample\CodeSample;
16+
use Rector\RuleDoc\RuleDefinition;
17+
use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface;
18+
use Rector\VersionBonding\ValueObject\ComposerPackageConstraint;
19+
20+
/**
21+
* @see \Rector\PHPUnit\Tests\PHPUnit70\Rector\ClassMethod\ScenarioToTestAnnotationRector\ScenarioToTestAnnotationRectorTest
22+
*/
23+
final class ScenarioToTestAnnotationRector extends AbstractRector implements ComposerPackageConstraintInterface
24+
{
25+
public function __construct(
26+
private readonly DocBlockTagReplacer $docBlockTagReplacer,
27+
private readonly DocBlockUpdater $docBlockUpdater,
28+
private readonly PhpDocInfoFactory $phpDocInfoFactory,
29+
private readonly TestsNodeAnalyzer $testsNodeAnalyzer,
30+
) {
31+
}
32+
33+
/**
34+
* the "@scenario" annotation was dropped in PHPUnit 7.0
35+
*/
36+
public function provideComposerPackageConstraint(): ComposerPackageConstraint
37+
{
38+
return new ComposerPackageConstraint('phpunit/phpunit', '>=7.0');
39+
}
40+
41+
public function getRuleDefinition(): RuleDefinition
42+
{
43+
return new RuleDefinition('Change `@scenario` annotation to `@test` in a test class', [
44+
new CodeSample(
45+
<<<'CODE_SAMPLE'
46+
/**
47+
* @scenario
48+
*/
49+
public function someMethod()
50+
{
51+
}
52+
CODE_SAMPLE
53+
,
54+
<<<'CODE_SAMPLE'
55+
/**
56+
* @test
57+
*/
58+
public function someMethod()
59+
{
60+
}
61+
CODE_SAMPLE
62+
),
63+
]);
64+
}
65+
66+
/**
67+
* @return array<class-string<Node>>
68+
*/
69+
public function getNodeTypes(): array
70+
{
71+
return [ClassMethod::class];
72+
}
73+
74+
/**
75+
* @param ClassMethod $node
76+
*/
77+
public function refactor(Node $node): ?Node
78+
{
79+
if (! $this->testsNodeAnalyzer->isInTestClass($node)) {
80+
return null;
81+
}
82+
83+
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($node);
84+
if (! $phpDocInfo instanceof PhpDocInfo) {
85+
return null;
86+
}
87+
88+
if (! $this->docBlockTagReplacer->replaceTagByAnother($phpDocInfo, 'scenario', 'test')) {
89+
return null;
90+
}
91+
92+
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node);
93+
94+
return $node;
95+
}
96+
}

0 commit comments

Comments
 (0)