Skip to content

Commit 547b419

Browse files
authored
[PHPUnit60] Add DoesNotPerformAssertions attribute directly and skip traits (#765)
1 parent ed6bbc7 commit 547b419

10 files changed

Lines changed: 53 additions & 22 deletions

File tree

‎rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/fixture.php.inc‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ namespace Rector\PHPUnit\Tests\PHPUnit60\Rector\ClassMethod\AddDoesNotPerformAss
1818

1919
class SomeClass extends \PHPUnit\Framework\TestCase
2020
{
21-
/**
22-
* @doesNotPerformAssertions
23-
*/
21+
#[\PHPUnit\Framework\Attributes\DoesNotPerformAssertions]
2422
public function test()
2523
{
2624
$nothing = 5;

‎rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/remove_add_to_assertion_count.php.inc‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ namespace Rector\PHPUnit\Tests\PHPUnit60\Rector\ClassMethod\AddDoesNotPerformAss
2323

2424
class RemoveAddToAssertionCount extends \PHPUnit\Framework\TestCase
2525
{
26-
/**
27-
* @doesNotPerformAssertions
28-
*/
26+
#[\PHPUnit\Framework\Attributes\DoesNotPerformAssertions]
2927
public function test()
3028
{
3129
$this->someMethodCall();

‎rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/remove_add_to_assertion_count_in_try_catch.php.inc‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ namespace Rector\PHPUnit\Tests\PHPUnit60\Rector\ClassMethod\AddDoesNotPerformAss
2626

2727
class RemoveAddToAssertionCountInTryCatch extends \PHPUnit\Framework\TestCase
2828
{
29-
/**
30-
* @doesNotPerformAssertions
31-
*/
29+
#[\PHPUnit\Framework\Attributes\DoesNotPerformAssertions]
3230
public function test()
3331
{
3432
try {

‎rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/remove_add_to_assertion_count_with_comment.php.inc‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ namespace Rector\PHPUnit\Tests\PHPUnit60\Rector\ClassMethod\AddDoesNotPerformAss
2424

2525
class RemoveAddToAssertionCountWithComment extends \PHPUnit\Framework\TestCase
2626
{
27-
/**
28-
* @doesNotPerformAssertions
29-
*/
27+
#[\PHPUnit\Framework\Attributes\DoesNotPerformAssertions]
3028
public function test()
3129
{
3230
$this->someMethodCall();
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\PHPUnit60\Rector\ClassMethod\AddDoesNotPerformAssertionToNonAssertingTestRector\Fixture;
4+
5+
trait SomeNonAssertingTrait
6+
{
7+
public function testSomething()
8+
{
9+
$nothing = 5;
10+
}
11+
}

‎rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/test_in_annotation.php.inc‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class TestInAnnotation extends \PHPUnit\Framework\TestCase
2323
{
2424
/**
2525
* @test
26-
* @doesNotPerformAssertions
2726
*/
27+
#[\PHPUnit\Framework\Attributes\DoesNotPerformAssertions]
2828
public function thisIsTest()
2929
{
3030
$nothing = 5;

‎rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/test_in_annotation_with_test_attribute.php.inc‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ namespace Rector\PHPUnit\Tests\PHPUnit60\Rector\ClassMethod\AddDoesNotPerformAss
1919

2020
class TestInAnnotationWithTestAttribute extends \PHPUnit\Framework\TestCase
2121
{
22-
/**
23-
* @doesNotPerformAssertions
24-
*/
2522
#[\PHPUnit\Framework\Attributes\Test]
23+
#[\PHPUnit\Framework\Attributes\DoesNotPerformAssertions]
2624
public function thisIsTest()
2725
{
2826
$nothing = 5;

‎rules/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector.php‎

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,22 @@
55
namespace Rector\PHPUnit\PHPUnit60\Rector\ClassMethod;
66

77
use PhpParser\Node;
8+
use PhpParser\Node\Attribute;
9+
use PhpParser\Node\AttributeGroup;
810
use PhpParser\Node\Expr\MethodCall;
11+
use PhpParser\Node\Name\FullyQualified;
912
use PhpParser\Node\Stmt\ClassMethod;
1013
use PhpParser\Node\Stmt\Expression;
1114
use PhpParser\Node\Stmt\Nop;
1215
use PhpParser\NodeVisitor;
1316
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
1417
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
1518
use PHPStan\Reflection\ClassReflection;
19+
use PHPStan\Reflection\ReflectionProvider;
1620
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
1721
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
1822
use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer;
23+
use Rector\PHPUnit\Enum\PHPUnitAttribute;
1924
use Rector\PHPUnit\Enum\PHPUnitClassName;
2025
use Rector\PHPUnit\NodeAnalyzer\AssertCallAnalyzer;
2126
use Rector\PHPUnit\NodeAnalyzer\MockedVariableAnalyzer;
@@ -51,13 +56,14 @@ public function __construct(
5156
private readonly DocBlockUpdater $docBlockUpdater,
5257
private readonly PhpDocInfoFactory $phpDocInfoFactory,
5358
private readonly ReflectionResolver $reflectionResolver,
59+
private readonly ReflectionProvider $reflectionProvider,
5460
) {
5561
}
5662

5763
public function getRuleDefinition(): RuleDefinition
5864
{
5965
return new RuleDefinition(
60-
'Tests without assertion will have @doesNotPerformAssertion',
66+
'Tests without assertion will have #[DoesNotPerformAssertions] attribute, or @doesNotPerformAssertions annotation on PHPUnit below 10',
6167
[
6268
new CodeSample(
6369
<<<'CODE_SAMPLE'
@@ -77,9 +83,7 @@ public function test()
7783
7884
class SomeClass extends TestCase
7985
{
80-
/**
81-
* @doesNotPerformAssertions
82-
*/
86+
#[\PHPUnit\Framework\Attributes\DoesNotPerformAssertions]
8387
public function test()
8488
{
8589
$nothing = 5;
@@ -110,6 +114,15 @@ public function refactor(Node $node): ?Node
110114

111115
$this->removeAddToAssertionCountCalls($node);
112116

117+
// the attribute is available since PHPUnit 10, prefer it over the annotation
118+
if ($this->reflectionProvider->hasClass(PHPUnitAttribute::DOES_NOT_PERFORM_ASSERTIONS)) {
119+
$node->attrGroups[] = new AttributeGroup([
120+
new Attribute(new FullyQualified(PHPUnitAttribute::DOES_NOT_PERFORM_ASSERTIONS)),
121+
]);
122+
123+
return $node;
124+
}
125+
113126
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
114127
$phpDocInfo->addPhpDocTagNode(new PhpDocTagNode('@doesNotPerformAssertions', new GenericTagValueNode('')));
115128

@@ -132,6 +145,11 @@ private function shouldSkipClassMethod(ClassMethod $classMethod): bool
132145
return true;
133146
}
134147

148+
// we have no idea how the trait is used, the using class can assert on its own
149+
if ($this->isInTrait($classMethod)) {
150+
return true;
151+
}
152+
135153
// the parent test case asserts in its own integration methods
136154
if ($this->isInTwigIntegrationTestCase($classMethod)) {
137155
return true;
@@ -192,6 +210,16 @@ private function isAddToAssertionCountExpression(Node $node): bool
192210
return $this->isName($methodCall->name, 'addToAssertionCount');
193211
}
194212

213+
private function isInTrait(ClassMethod $classMethod): bool
214+
{
215+
$classReflection = $this->reflectionResolver->resolveClassReflection($classMethod);
216+
if (! $classReflection instanceof ClassReflection) {
217+
return false;
218+
}
219+
220+
return $classReflection->isTrait();
221+
}
222+
195223
private function isInTwigIntegrationTestCase(ClassMethod $classMethod): bool
196224
{
197225
$classReflection = $this->reflectionResolver->resolveClassReflection($classMethod);
@@ -212,7 +240,7 @@ private function hasAssertingAnnotationOrAttribute(ClassMethod $classMethod): bo
212240

213241
return $this->phpAttributeAnalyzer->hasPhpAttribute(
214242
$classMethod,
215-
'PHPUnit\Framework\Attributes\DoesNotPerformAssertions'
243+
PHPUnitAttribute::DOES_NOT_PERFORM_ASSERTIONS
216244
);
217245
}
218246
}

‎src/Enum/PHPUnitAttribute.php‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ final class PHPUnitAttribute
2424

2525
public const string TEST = 'PHPUnit\Framework\Attributes\Test';
2626

27+
public const string DOES_NOT_PERFORM_ASSERTIONS = 'PHPUnit\Framework\Attributes\DoesNotPerformAssertions';
28+
2729
/**
2830
* Since PHPUnit 12.5.2
2931
* @see https://github.com/sebastianbergmann/phpunit/commit/24c208d6a340c3071f28a9b5cce02b9377adfd43

‎tests/Issues/PHPUnit10DataProvider/Fixture/some_test.php.inc‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ namespace Rector\PHPUnit\Tests\Issues\PHPUnit10DataProvider\Fixture;
2727
final class SomeTest extends \PHPUnit\Framework\TestCase
2828
{
2929
#[\PHPUnit\Framework\Attributes\DataProvider('fooProvider')]
30-
#[\PHPUnit\Framework\Attributes\Test]
3130
#[\PHPUnit\Framework\Attributes\DoesNotPerformAssertions]
31+
#[\PHPUnit\Framework\Attributes\Test]
3232
public function it_should_do_stuff(string $foo): void
3333
{
3434
}

0 commit comments

Comments
 (0)