diff --git a/rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/skip_twig_integration_test_case.php.inc b/rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/skip_twig_integration_test_case.php.inc new file mode 100644 index 00000000..abea8c05 --- /dev/null +++ b/rules-tests/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector/Fixture/skip_twig_integration_test_case.php.inc @@ -0,0 +1,13 @@ +doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs); + } +} diff --git a/rules/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector.php b/rules/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector.php index 8e90f397..e2314088 100644 --- a/rules/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector.php +++ b/rules/PHPUnit60/Rector/ClassMethod/AddDoesNotPerformAssertionToNonAssertingTestRector.php @@ -8,13 +8,16 @@ use PhpParser\Node\Stmt\ClassMethod; use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; +use PHPStan\Reflection\ClassReflection; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; use Rector\Comments\NodeDocBlock\DocBlockUpdater; use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer; +use Rector\PHPUnit\Enum\PHPUnitClassName; use Rector\PHPUnit\NodeAnalyzer\AssertCallAnalyzer; use Rector\PHPUnit\NodeAnalyzer\MockedVariableAnalyzer; use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer; use Rector\Rector\AbstractRector; +use Rector\Reflection\ReflectionResolver; use Rector\VersionBonding\Contract\ComposerPackageConstraintInterface; use Rector\VersionBonding\ValueObject\ComposerPackageConstraint; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -43,6 +46,7 @@ public function __construct( private readonly PhpAttributeAnalyzer $phpAttributeAnalyzer, private readonly DocBlockUpdater $docBlockUpdater, private readonly PhpDocInfoFactory $phpDocInfoFactory, + private readonly ReflectionResolver $reflectionResolver, ) { } @@ -122,6 +126,11 @@ private function shouldSkipClassMethod(ClassMethod $classMethod): bool return true; } + // the parent test case asserts in its own integration methods + if ($this->isInTwigIntegrationTestCase($classMethod)) { + return true; + } + if ($this->hasAssertingAnnotationOrAttribute($classMethod)) { return true; } @@ -134,6 +143,16 @@ private function shouldSkipClassMethod(ClassMethod $classMethod): bool return $this->mockedVariableAnalyzer->containsMockAsUsedVariable($classMethod); } + private function isInTwigIntegrationTestCase(ClassMethod $classMethod): bool + { + $classReflection = $this->reflectionResolver->resolveClassReflection($classMethod); + if (! $classReflection instanceof ClassReflection) { + return false; + } + + return $classReflection->is(PHPUnitClassName::TWIG_INTEGRATION_TEST_CASE); + } + private function hasAssertingAnnotationOrAttribute(ClassMethod $classMethod): bool { $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod); diff --git a/src/Enum/PHPUnitClassName.php b/src/Enum/PHPUnitClassName.php index 421fd706..83044c73 100644 --- a/src/Enum/PHPUnitClassName.php +++ b/src/Enum/PHPUnitClassName.php @@ -34,6 +34,8 @@ final class PHPUnitClassName public const string SYMFONY_TYPE_TEST_CASE = 'Symfony\Component\Form\Test\TypeTestCase'; + public const string TWIG_INTEGRATION_TEST_CASE = 'Twig\Test\IntegrationTestCase'; + /** * @var string[] */ diff --git a/stubs/Twig/Test/IntegrationTestCase.php b/stubs/Twig/Test/IntegrationTestCase.php new file mode 100644 index 00000000..56601b88 --- /dev/null +++ b/stubs/Twig/Test/IntegrationTestCase.php @@ -0,0 +1,23 @@ + $templates + * @param array $outputs + */ + protected function doIntegrationTest( + string $file, + string $message, + string $condition, + array $templates, + string $exception, + array $outputs, + string $deprecation = '' + ): void { + } +}