Skip to content

Commit e48811f

Browse files
committed
Implement ClassAttributeRequiresPhpVersionRule
1 parent 2312495 commit e48811f

5 files changed

Lines changed: 139 additions & 0 deletions

File tree

rules.neon

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ conditionalTags:
1616
PHPStan\Rules\PHPUnit\DataProviderDataRule:
1717
phpstan.rules.rule: %featureToggles.bleedingEdge%
1818

19+
PHPStan\Rules\PHPUnit\ClassAttributeRequiresPhpVersionRule:
20+
phpstan.rules.rule: %featureToggles.bleedingEdge%
21+
1922
services:
2023
-
2124
class: PHPStan\Rules\PHPUnit\DataProviderDeclarationRule
@@ -30,6 +33,9 @@ services:
3033
tags:
3134
- phpstan.rules.rule
3235

36+
-
37+
class: PHPStan\Rules\PHPUnit\ClassAttributeRequiresPhpVersionRule
38+
3339
-
3440
class: PHPStan\Rules\PHPUnit\AssertEqualsIsDiscouragedRule
3541

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\PHPUnit;
4+
5+
use PhpParser\Node;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Node\InClassNode;
8+
use PHPStan\Rules\Rule;
9+
use PHPUnit\Framework\TestCase;
10+
11+
/**
12+
* @implements Rule<InClassNode>
13+
*/
14+
class ClassAttributeRequiresPhpVersionRule implements Rule
15+
{
16+
17+
private AttributeVersionRequirementHelper $attributeVersionRequirementHelper;
18+
19+
public function __construct(
20+
AttributeVersionRequirementHelper $attributeVersionRequirementHelper
21+
)
22+
{
23+
$this->attributeVersionRequirementHelper = $attributeVersionRequirementHelper;
24+
}
25+
26+
public function getNodeType(): string
27+
{
28+
return InClassNode::class;
29+
}
30+
31+
public function processNode(Node $node, Scope $scope): array
32+
{
33+
$classReflection = $scope->getClassReflection();
34+
if ($classReflection === null || $classReflection->is(TestCase::class) === false) {
35+
return [];
36+
}
37+
38+
return $this->attributeVersionRequirementHelper->checkRequiresPhpVersion(
39+
$classReflection->getNativeReflection()->getBetterReflection()->getAttributesByName('PHPUnit\Framework\Attributes\RequiresPhp'),
40+
$scope,
41+
);
42+
}
43+
44+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
parameters:
2+
phpVersion: 80500
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\PHPUnit;
4+
5+
use PHPStan\Php\PhpVersion;
6+
use PHPStan\Rules\Rule;
7+
use PHPStan\Testing\RuleTestCase;
8+
9+
/**
10+
* @extends RuleTestCase<ClassAttributeRequiresPhpVersionRule>
11+
*/
12+
final class ClassAttributeRequiresPhpVersionRuleTest extends RuleTestCase
13+
{
14+
15+
private int $phpVersion = 80500;
16+
17+
private int $phpunitMajorVersion;
18+
19+
private int $phpunitMinorVersion;
20+
21+
private bool $warnAboutIncompleteVersion = false;
22+
23+
public function testWarnAboutIncompleteVersion(): void
24+
{
25+
$this->phpunitMajorVersion = 12;
26+
$this->phpunitMinorVersion = 5;
27+
$this->warnAboutIncompleteVersion = true;
28+
29+
$this->analyse([__DIR__ . '/data/requires-php-version-on-class.php'], [
30+
[
31+
'Version requirement will always evaluate to false.',
32+
10,
33+
],
34+
[
35+
'Version requirement is incomplete.',
36+
10,
37+
],
38+
]);
39+
}
40+
41+
protected function getRule(): Rule
42+
{
43+
$phpunitVersion = new PHPUnitVersion($this->phpunitMajorVersion, $this->phpunitMinorVersion);
44+
45+
return new ClassAttributeRequiresPhpVersionRule(
46+
new AttributeVersionRequirementHelper(
47+
$phpunitVersion,
48+
false,
49+
new PhpVersion($this->phpVersion),
50+
true,
51+
$this->warnAboutIncompleteVersion,
52+
),
53+
);
54+
}
55+
56+
public static function getAdditionalConfigFiles(): array
57+
{
58+
return [
59+
__DIR__ . '/ClassAttributeRequiresPhpVersionRule.neon',
60+
];
61+
}
62+
63+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace RequiresPhpVersionOnClass;
4+
5+
use PHPUnit\Framework\Attributes\DataProvider;
6+
use PHPUnit\Framework\Attributes\Test;
7+
use PHPUnit\Framework\TestCase;
8+
use PHPUnit\Framework\Attributes\RequiresPhp;
9+
10+
#[RequiresPhp('< 7.0')]
11+
class RequiresPhpOnClass extends TestCase
12+
{
13+
public function testBar(): void {
14+
15+
}
16+
}
17+
18+
#[RequiresPhp('>=8.0.0')]
19+
class CorrectRequirementOnClass extends TestCase
20+
{
21+
public function testBar(): void {
22+
23+
}
24+
}

0 commit comments

Comments
 (0)