Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion build/PHPStan/Build/SkipTestsWithRequiresPhpAttributeRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use function array_values;
use function count;
use function get_class;
use function preg_match;
use function sprintf;

/**
Expand Down Expand Up @@ -43,6 +44,21 @@ public function processNode(Node $node, Scope $scope): array
return [];
}

foreach ($originalNode->attrGroups as $attrGroup) {
foreach ($attrGroup->attrs as $attr) {
if ($attr->name->toString() === 'PHPUnit\\Framework\\Attributes\\RequiresPhp') {
// RequiresPhp is not repeatable
return [];
}
}
}

// the code downgrade for PHPUnit 9 turns #[RequiresPhp] into @requires PHP
$docComment = $originalNode->getDocComment();
if ($docComment !== null && preg_match('/@requires\s+PHP\s/', $docComment->getText()) === 1) {
return [];
}

$firstStmt = $originalNode->stmts[0];
if (!$firstStmt instanceof Node\Stmt\If_) {
return [];
Expand Down Expand Up @@ -116,7 +132,7 @@ public function processNode(Node $node, Scope $scope): array
$node->stmts = array_values($stmts);
$node->attrGroups[] = new Node\AttributeGroup([
new Attribute(new Node\Name\FullyQualified('PHPUnit\\Framework\\Attributes\\RequiresPhp'), [
new Node\Arg(new Node\Scalar\String_(sprintf('%s %s', $inverseBinaryOpSigil, $phpVersion->getVersionString()))),
new Node\Arg(new Node\Scalar\String_(sprintf('%s %d.%d.%d', $inverseBinaryOpSigil, $phpVersion->getMajorVersionId(), $phpVersion->getMinorVersionId(), $phpVersion->getPatchVersionId()))),
]),
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function testRule(): void
$this->analyse([__DIR__ . '/data/skip-tests-requires-php.php'], [
[
'Skip tests with #[RequiresPhp] attribute instead.',
13,
14,
],
]);
}
Expand Down
19 changes: 19 additions & 0 deletions tests/PHPStan/Build/data/skip-tests-requires-php.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace SkipTestsWithRequiresPhpAttributeRule;

use PHPUnit\Framework\Attributes\RequiresPhp;
use PHPUnit\Framework\TestCase;
use const PHP_VERSION_ID;

Expand Down Expand Up @@ -29,6 +30,24 @@ public function testUnrelatedCondition(bool $a, bool $b): void
}
}

#[RequiresPhp('< 8.4.0')]
public function testVersionCheckWithExistingAttribute(): void
{
if (PHP_VERSION_ID < 80000) {
$this->markTestSkipped();
}
}

/**
* @requires PHP < 8.4.0
*/
public function testVersionCheckWithExistingAnnotation(): void
{
if (PHP_VERSION_ID < 80000) {
$this->markTestSkipped();
}
}

public function testUnrelatedComparison(int $a): void
{
if ($a < 80000) {
Expand Down
21 changes: 20 additions & 1 deletion tests/PHPStan/Build/data/skip-tests-requires-php.php.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

namespace SkipTestsWithRequiresPhpAttributeRule;

use PHPUnit\Framework\Attributes\RequiresPhp;
use PHPUnit\Framework\TestCase;
use const PHP_VERSION_ID;

class FooTest extends TestCase
{

#[\PHPUnit\Framework\Attributes\RequiresPhp('>= 8.0')]
#[\PHPUnit\Framework\Attributes\RequiresPhp('>= 8.0.0')]
public function testVersionCheck(): void
{
}
Expand All @@ -27,6 +28,24 @@ class FooTest extends TestCase
}
}

#[RequiresPhp('< 8.4.0')]
public function testVersionCheckWithExistingAttribute(): void
{
if (PHP_VERSION_ID < 80000) {
$this->markTestSkipped();
}
}

/**
* @requires PHP < 8.4.0
*/
public function testVersionCheckWithExistingAnnotation(): void
{
if (PHP_VERSION_ID < 80000) {
$this->markTestSkipped();
}
}

public function testUnrelatedComparison(int $a): void
{
if ($a < 80000) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,9 @@ protected function getRule(): Rule
return new PropertiesInInterfaceRule();
}

#[RequiresPhp('>= 8.0.0')]
public function testPhpVersionNarrowedScope(): void
{
// @phpstan-ignore phpstan.skipTestsRequiresPhp
if (PHP_VERSION_ID < 80000) {
$this->markTestSkipped('Property hooks cause syntax error on PHP 7.4');
}

$errors = [
[
'Interfaces can include properties only on PHP 8.4 and later.',
Expand All @@ -44,7 +40,6 @@ public function testPhpVersionNarrowedScope(): void
#[RequiresPhp('< 8.4.0')]
public function testPhp83AndPropertiesInInterface(): void
{
// @phpstan-ignore phpstan.skipTestsRequiresPhp
if (PHP_VERSION_ID < 80000) {
$this->markTestSkipped('Property hooks cause syntax error on PHP 7.4');
}
Expand All @@ -71,7 +66,6 @@ public function testPhp83AndPropertiesInInterface(): void
#[RequiresPhp('< 8.4.0')]
public function testPhp83AndPropertyHooksInInterface(): void
{
// @phpstan-ignore phpstan.skipTestsRequiresPhp
if (PHP_VERSION_ID < 80000) {
$this->markTestSkipped('Property hooks cause syntax error on PHP 7.4');
}
Expand Down
2 changes: 0 additions & 2 deletions tests/PHPStan/Rules/Properties/PropertyInClassRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ public function testPhpVersionNarrowedScope(): void
#[RequiresPhp('< 8.4.0')]
public function testPhpLessThan84AndHookedPropertiesInClass(): void
{
// @phpstan-ignore phpstan.skipTestsRequiresPhp
if (PHP_VERSION_ID < 80000) {
$this->markTestSkipped('Property hooks cause syntax error on PHP 7.4');
}
Expand All @@ -60,7 +59,6 @@ public function testPhpLessThan84AndHookedPropertiesInClass(): void
#[RequiresPhp('>= 8.4.0')]
public function testPhp84AndHookedPropertiesWithoutBodiesInClass(): void
{
// @phpstan-ignore phpstan.skipTestsRequiresPhp
if (PHP_VERSION_ID < 80000) {
$this->markTestSkipped('Property hooks cause syntax error on PHP 7.4');
}
Expand Down
Loading