Skip to content

Commit 4d60ec7

Browse files
committed
Fix attribute services tests on PHP < 8.1 and Windows
The fixtures with attributes are not valid PHP 7.4 and a class with new in attribute arguments cannot be loaded on PHP 8.0, so lint skips the fixtures, the integration test requires PHP 8.0 and the new fixture lives in its own directory discovered only on PHP 8.1+. The resolver tests pass PHP 8.0 to the resolver so that they run everywhere. Expected paths use forward slashes like the resolver does. Amp-Thread-ID: https://ampcode.com/threads/T-01a19cd4-be31-75b4-bd15-67786eff5983
1 parent feeebeb commit 4d60ec7

6 files changed

Lines changed: 47 additions & 10 deletions

File tree

‎Makefile‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ lint:
4040
--exclude tests/PHPStan/Rules/Operators/data/invalid-assign-var.php \
4141
--exclude tests/PHPStan/Rules/Functions/data/arrow-function-nullsafe-by-ref.php \
4242
--exclude tests/PHPStan/Levels/data/namedArguments.php \
43+
--exclude tests/PHPStan/DependencyInjection/AttributeServices/data \
4344
--exclude tests/PHPStan/Reflection/BetterReflection/SourceLocator/data/symbol-finder/class-name-before-global-constant.php \
4445
--exclude tests/PHPStan/Rules/Keywords/data/continue-break.php \
4546
--exclude tests/PHPStan/Rules/Keywords/data/continue-break-property-hook.php \

‎build/baseline-pre-8.0.neon‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,16 @@ parameters:
3737
path: ../src/DependencyInjection/AttributeServices/AttributeServicesDiscoverer.php
3838

3939
-
40-
message: '#^(Parameter \$attribute of method .+ has invalid type|Call to method \w+\(\) on an unknown class) ReflectionAttribute\.$#'
41-
count: 5
42-
path: ../src/DependencyInjection/AttributeServices/AttributeServicesDiscoverer.php
40+
rawMessage: 'Class AttributeServicesFixtures\DiscoveredConditionalRuleNotMet not found.'
41+
identifier: class.notFound
42+
count: 3
43+
path: ../tests/PHPStan/DependencyInjection/AttributeServices/AttributeServicesIntegrationTest.php
44+
45+
-
46+
rawMessage: 'Class AttributeServicesFixtures\DiscoveredConditionalService not found.'
47+
identifier: class.notFound
48+
count: 1
49+
path: ../tests/PHPStan/DependencyInjection/AttributeServices/AttributeServicesIntegrationTest.php
4350

4451
-
4552
rawMessage: 'Call to an undefined method ReflectionClass::isReadOnly().'

‎tests/PHPStan/DependencyInjection/AttributeServices/AttributeServicesDirectoriesResolverTest.php‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,23 @@
99
use function dirname;
1010
use function hash_file;
1111
use function str_starts_with;
12-
use const PHP_VERSION_ID;
12+
use function strtr;
1313

1414
class AttributeServicesDirectoriesResolverTest extends TestCase
1515
{
1616

17+
/**
18+
* With forward slashes like the paths the resolver returns, also on Windows.
19+
*/
1720
private static function getRepoRoot(): string
1821
{
19-
return dirname(__DIR__, 4);
22+
return strtr(dirname(__DIR__, 4), '\\', '/');
2023
}
2124

22-
private function createResolver(int $phpVersionId = PHP_VERSION_ID): AttributeServicesDirectoriesResolver
25+
/**
26+
* PHP 8.0 by default so that the tests run on every PHP version - resolving needs no runtime attributes.
27+
*/
28+
private function createResolver(int $phpVersionId = 80000): AttributeServicesDirectoriesResolver
2329
{
2430
$repoRoot = self::getRepoRoot();
2531

@@ -83,7 +89,7 @@ public function testMissingDirectory(): void
8389

8490
public function testDirectoryOutsideComposerProjects(): void
8591
{
86-
$resolver = new AttributeServicesDirectoriesResolver(new FileHelper(self::getRepoRoot()), []);
92+
$resolver = new AttributeServicesDirectoriesResolver(new FileHelper(self::getRepoRoot()), [], 80000);
8793
$this->expectException(InvalidAttributeServicesDirectoriesException::class);
8894
$this->expectExceptionMessage('is not inside any project with Composer metadata known to PHPStan');
8995
$resolver->resolve([__DIR__]);

‎tests/PHPStan/DependencyInjection/AttributeServices/AttributeServicesIntegrationTest.php‎

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,18 @@
2020
use PHPStan\Rules\LazyRegistry;
2121
use PHPStan\Rules\Properties\ReadWritePropertiesExtension;
2222
use PHPUnit\Framework\Attributes\DataProvider;
23+
use PHPUnit\Framework\Attributes\RequiresPhp;
2324
use PHPUnit\Framework\TestCase;
2425
use function array_filter;
2526
use function dirname;
2627
use function md5;
2728
use function mkdir;
29+
use function strtr;
2830
use function sys_get_temp_dir;
2931
use function uniqid;
32+
use const PHP_VERSION_ID;
3033

34+
#[RequiresPhp('>= 8.0.0')]
3135
class AttributeServicesIntegrationTest extends TestCase
3236
{
3337

@@ -44,7 +48,10 @@ private static function createContainer(): Container
4448
self::$tmpDir = self::createTmpDir();
4549
$containerFactory = new ContainerFactory(__DIR__);
4650

47-
return self::$container = $containerFactory->create(self::$tmpDir, [__DIR__ . '/attributeServices.neon'], [], [dirname(__DIR__, 4)]);
51+
// PHP 8.0 cannot even load a class with `new` in attribute arguments
52+
$configFile = PHP_VERSION_ID >= 80100 ? 'attributeServicesNewInInitializers.neon' : 'attributeServices.neon';
53+
54+
return self::$container = $containerFactory->create(self::$tmpDir, [__DIR__ . '/' . $configFile], [], [dirname(__DIR__, 4)]);
4855
}
4956

5057
private static function createTmpDir(): string
@@ -91,11 +98,18 @@ public function testDiscoveredRulesFollowTheLevel(): void
9198
$this->assertCount(0, array_filter($rules, static fn ($rule): bool => $rule instanceof DiscoveredRuleLevelEight));
9299
}
93100

94-
public function testDiscoveredConditional(): void
101+
#[RequiresPhp('>= 8.1.0')]
102+
public function testDiscoveredConditionalWithNewInAttributeArguments(): void
95103
{
96104
$container = self::createContainer();
97105
$rules = $container->getServicesByTag(LazyRegistry::RULE_TAG);
98106
$this->assertCount(1, array_filter($rules, static fn ($rule): bool => $rule instanceof DiscoveredConditionalRule));
107+
}
108+
109+
public function testDiscoveredConditional(): void
110+
{
111+
$container = self::createContainer();
112+
$rules = $container->getServicesByTag(LazyRegistry::RULE_TAG);
99113
$this->assertCount(0, array_filter($rules, static fn ($rule): bool => $rule instanceof DiscoveredConditionalRuleNotMet));
100114

101115
// the services are registered even when the condition is not met, only their tags are skipped
@@ -122,7 +136,11 @@ public function testDiscoveredGeneratedFactory(): void
122136
public function testDirectoriesParameterIsAbsolutized(): void
123137
{
124138
$container = self::createContainer();
125-
$this->assertSame([__DIR__ . '/data/services'], $container->getParameter('attributeServicesDirectories'));
139+
$expected = [strtr(__DIR__, '\\', '/') . '/data/services'];
140+
if (PHP_VERSION_ID >= 80100) {
141+
$expected[] = strtr(__DIR__, '\\', '/') . '/data/servicesNewInInitializers';
142+
}
143+
$this->assertSame($expected, $container->getParameter('attributeServicesDirectories'));
126144
}
127145

128146
public function testRegisteredDiscoveredClassesParameter(): void
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
includes:
2+
- attributeServices.neon
3+
4+
attributeServicesDirectories:
5+
- data/servicesNewInInitializers

tests/PHPStan/DependencyInjection/AttributeServices/data/services/DiscoveredConditionalRule.php renamed to tests/PHPStan/DependencyInjection/AttributeServices/data/servicesNewInInitializers/DiscoveredConditionalRule.php

File renamed without changes.

0 commit comments

Comments
 (0)