Skip to content

Commit cb479ed

Browse files
committed
Similar reflection provider in Broker::getInstance() for unit tests via static reflection
1 parent f5de06d commit cb479ed

7 files changed

+143
-6
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
parameters:
2+
featureToggles:
3+
# these are needed only with "partial static reflection"
4+
disableRobotLoader: true
5+
disableRuntimeReflectionProvider: false
6+
enableScanningPaths: false
7+
8+
services:
9+
-
10+
class: PHPStan\Testing\TestCaseSourceLocatorFactory
11+
arguments:
12+
phpParser: @phpParserDecorator
13+
14+
testCaseBetterReflectionProvider:
15+
class: PHPStan\Reflection\BetterReflection\BetterReflectionProvider
16+
arguments:
17+
classReflector: @testCaseClassReflector
18+
functionReflector: @testCaseFunctionReflector
19+
constantReflector: @testCaseConstantReflector
20+
autowired: false
21+
22+
testCaseClassReflector:
23+
class: PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector
24+
arguments:
25+
sourceLocator: @testCaseSourceLocator
26+
autowired: false
27+
28+
testCaseFunctionReflector:
29+
class: PHPStan\Reflection\BetterReflection\Reflector\MemoizingFunctionReflector
30+
arguments:
31+
classReflector: @testCaseClassReflector
32+
sourceLocator: @testCaseSourceLocator
33+
autowired: false
34+
35+
testCaseConstantReflector:
36+
class: PHPStan\Reflection\BetterReflection\Reflector\MemoizingConstantReflector
37+
arguments:
38+
classReflector: @testCaseClassReflector
39+
sourceLocator: @testCaseSourceLocator
40+
autowired: false
41+
42+
testCaseSourceLocator:
43+
class: Roave\BetterReflection\SourceLocator\Type\SourceLocator
44+
factory: @PHPStan\Testing\TestCaseSourceLocatorFactory::create()
45+
autowired: false
46+
47+
# total static reflection without RuntimeReflectionProvider involved
48+
#reflectionProvider:
49+
# factory: @testCaseBetterReflectionProvider
50+
# autowired:
51+
# - PHPStan\Reflection\ReflectionProvider
52+
53+
# partial static reflection with RuntimeReflectionProvider involved
54+
phpParserReflectionProvider:
55+
factory: @testCaseBetterReflectionProvider
56+
arguments!: []

src/Testing/TestCase.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
use Roave\BetterReflection\SourceLocator\Ast\Locator;
6666
use Roave\BetterReflection\SourceLocator\SourceStubber\PhpStormStubsSourceStubber;
6767
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
68+
use Roave\BetterReflection\SourceLocator\Type\MemoizingSourceLocator;
6869
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;
6970

7071
abstract class TestCase extends \PHPUnit\Framework\TestCase
@@ -92,6 +93,10 @@ public static function getContainer(): Container
9293
self::fail(sprintf('Cannot create temp directory %s', $tmpDir));
9394
}
9495

96+
if (self::$useStaticReflectionProvider) {
97+
$additionalConfigFiles[] = __DIR__ . '/TestCase-staticReflection.neon';
98+
}
99+
95100
$rootDir = __DIR__ . '/../..';
96101
$containerFactory = new ContainerFactory($rootDir);
97102
self::$containers[$cacheKey] = $containerFactory->create($tmpDir, array_merge([
@@ -503,6 +508,8 @@ private static function getReflectors(): array
503508
self::fail('Could not create composer source locator');
504509
}
505510

511+
// these need to be synced with TestCase-staticReflection.neon file and TestCaseSourceLocatorFactory
512+
506513
$locators = [
507514
$composerSourceLocator,
508515
];
@@ -516,7 +523,7 @@ private static function getReflectors(): array
516523
});
517524
$locators[] = new AutoloadSourceLocator($astLocator);
518525
$locators[] = new PhpInternalSourceLocator($astLocator, new PhpStormStubsSourceStubber($phpParser));
519-
$sourceLocator = new AggregateSourceLocator($locators);
526+
$sourceLocator = new MemoizingSourceLocator(new AggregateSourceLocator($locators));
520527

521528
$classReflector = new MemoizingClassReflector($sourceLocator);
522529
$functionReflector = new MemoizingFunctionReflector($sourceLocator, $classReflector);
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Testing;
4+
5+
use Composer\Autoload\ClassLoader;
6+
use PHPStan\DependencyInjection\Container;
7+
use PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadSourceLocator;
8+
use PHPStan\Reflection\BetterReflection\SourceLocator\ComposerJsonAndInstalledJsonSourceLocatorMaker;
9+
use Roave\BetterReflection\Reflector\FunctionReflector;
10+
use Roave\BetterReflection\SourceLocator\Ast\Locator;
11+
use Roave\BetterReflection\SourceLocator\SourceStubber\PhpStormStubsSourceStubber;
12+
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
13+
use Roave\BetterReflection\SourceLocator\Type\MemoizingSourceLocator;
14+
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;
15+
use Roave\BetterReflection\SourceLocator\Type\SourceLocator;
16+
17+
class TestCaseSourceLocatorFactory
18+
{
19+
20+
private Container $container;
21+
22+
private ComposerJsonAndInstalledJsonSourceLocatorMaker $composerJsonAndInstalledJsonSourceLocatorMaker;
23+
24+
private \PhpParser\Parser $phpParser;
25+
26+
private PhpStormStubsSourceStubber $phpStormStubsSourceStubber;
27+
28+
public function __construct(
29+
Container $container,
30+
ComposerJsonAndInstalledJsonSourceLocatorMaker $composerJsonAndInstalledJsonSourceLocatorMaker,
31+
\PhpParser\Parser $phpParser,
32+
PhpStormStubsSourceStubber $phpStormStubsSourceStubber
33+
)
34+
{
35+
$this->container = $container;
36+
$this->composerJsonAndInstalledJsonSourceLocatorMaker = $composerJsonAndInstalledJsonSourceLocatorMaker;
37+
$this->phpParser = $phpParser;
38+
$this->phpStormStubsSourceStubber = $phpStormStubsSourceStubber;
39+
}
40+
41+
public function create(): SourceLocator
42+
{
43+
$classLoaderReflection = new \ReflectionClass(ClassLoader::class);
44+
if ($classLoaderReflection->getFileName() === false) {
45+
throw new \PHPStan\ShouldNotHappenException('Unknown ClassLoader filename');
46+
}
47+
48+
$composerProjectPath = dirname($classLoaderReflection->getFileName(), 3);
49+
if (!is_file($composerProjectPath . '/composer.json')) {
50+
throw new \PHPStan\ShouldNotHappenException(sprintf('composer.json not found in directory %s', $composerProjectPath));
51+
}
52+
53+
$composerSourceLocator = $this->composerJsonAndInstalledJsonSourceLocatorMaker->create($composerProjectPath);
54+
if ($composerSourceLocator === null) {
55+
throw new \PHPStan\ShouldNotHappenException('Could not create composer source locator');
56+
}
57+
58+
$locators = [
59+
$composerSourceLocator,
60+
];
61+
$astLocator = new Locator($this->phpParser, function (): FunctionReflector {
62+
return $this->container->getService('testCaseFunctionReflector');
63+
});
64+
65+
$locators[] = new AutoloadSourceLocator($astLocator);
66+
$locators[] = new PhpInternalSourceLocator($astLocator, $this->phpStormStubsSourceStubber);
67+
68+
return new MemoizingSourceLocator(new AggregateSourceLocator($locators));
69+
}
70+
71+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php declare(strict_types = 1);
2+
3+
require_once __DIR__ . '/bootstrap.php';
4+
5+
\PHPStan\Testing\TestCase::getContainer();

tests/bootstrap-static-reflection.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
require_once __DIR__ . '/bootstrap.php';
44

55
\PHPStan\Testing\TestCase::$useStaticReflectionProvider = true;
6+
7+
\PHPStan\Testing\TestCase::getContainer();

tests/bootstrap.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
<?php declare(strict_types = 1);
22

3-
use PHPStan\Testing\TestCase;
4-
53
error_reporting(E_ALL);
64

75
require_once __DIR__ . '/../vendor/autoload.php';
@@ -22,5 +20,3 @@ public function doFoo($i)
2220
}
2321
2422
}');
25-
26-
TestCase::getContainer();

tests/phpunit.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
33
xsi:noNamespaceSchemaLocation="phpunit.xsd"
4-
bootstrap="bootstrap.php"
4+
bootstrap="bootstrap-runtime-reflection.php"
55
colors="true"
66
failOnRisky="true"
77
failOnWarning="true"

0 commit comments

Comments
 (0)