Skip to content

Commit

Permalink
Similar reflection provider in Broker::getInstance() for unit tests v…
Browse files Browse the repository at this point in the history
…ia static reflection
  • Loading branch information
ondrejmirtes committed May 14, 2020
1 parent f5de06d commit cb479ed
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 6 deletions.
56 changes: 56 additions & 0 deletions src/Testing/TestCase-staticReflection.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
parameters:
featureToggles:
# these are needed only with "partial static reflection"
disableRobotLoader: true
disableRuntimeReflectionProvider: false
enableScanningPaths: false

services:
-
class: PHPStan\Testing\TestCaseSourceLocatorFactory
arguments:
phpParser: @phpParserDecorator

testCaseBetterReflectionProvider:
class: PHPStan\Reflection\BetterReflection\BetterReflectionProvider
arguments:
classReflector: @testCaseClassReflector
functionReflector: @testCaseFunctionReflector
constantReflector: @testCaseConstantReflector
autowired: false

testCaseClassReflector:
class: PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector
arguments:
sourceLocator: @testCaseSourceLocator
autowired: false

testCaseFunctionReflector:
class: PHPStan\Reflection\BetterReflection\Reflector\MemoizingFunctionReflector
arguments:
classReflector: @testCaseClassReflector
sourceLocator: @testCaseSourceLocator
autowired: false

testCaseConstantReflector:
class: PHPStan\Reflection\BetterReflection\Reflector\MemoizingConstantReflector
arguments:
classReflector: @testCaseClassReflector
sourceLocator: @testCaseSourceLocator
autowired: false

testCaseSourceLocator:
class: Roave\BetterReflection\SourceLocator\Type\SourceLocator
factory: @PHPStan\Testing\TestCaseSourceLocatorFactory::create()
autowired: false

# total static reflection without RuntimeReflectionProvider involved
#reflectionProvider:
# factory: @testCaseBetterReflectionProvider
# autowired:
# - PHPStan\Reflection\ReflectionProvider

# partial static reflection with RuntimeReflectionProvider involved
phpParserReflectionProvider:
factory: @testCaseBetterReflectionProvider
arguments!: []
9 changes: 8 additions & 1 deletion src/Testing/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
use Roave\BetterReflection\SourceLocator\Ast\Locator;
use Roave\BetterReflection\SourceLocator\SourceStubber\PhpStormStubsSourceStubber;
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\MemoizingSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;

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

if (self::$useStaticReflectionProvider) {
$additionalConfigFiles[] = __DIR__ . '/TestCase-staticReflection.neon';
}

$rootDir = __DIR__ . '/../..';
$containerFactory = new ContainerFactory($rootDir);
self::$containers[$cacheKey] = $containerFactory->create($tmpDir, array_merge([
Expand Down Expand Up @@ -503,6 +508,8 @@ private static function getReflectors(): array
self::fail('Could not create composer source locator');
}

// these need to be synced with TestCase-staticReflection.neon file and TestCaseSourceLocatorFactory

$locators = [
$composerSourceLocator,
];
Expand All @@ -516,7 +523,7 @@ private static function getReflectors(): array
});
$locators[] = new AutoloadSourceLocator($astLocator);
$locators[] = new PhpInternalSourceLocator($astLocator, new PhpStormStubsSourceStubber($phpParser));
$sourceLocator = new AggregateSourceLocator($locators);
$sourceLocator = new MemoizingSourceLocator(new AggregateSourceLocator($locators));

$classReflector = new MemoizingClassReflector($sourceLocator);
$functionReflector = new MemoizingFunctionReflector($sourceLocator, $classReflector);
Expand Down
71 changes: 71 additions & 0 deletions src/Testing/TestCaseSourceLocatorFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php declare(strict_types = 1);

namespace PHPStan\Testing;

use Composer\Autoload\ClassLoader;
use PHPStan\DependencyInjection\Container;
use PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadSourceLocator;
use PHPStan\Reflection\BetterReflection\SourceLocator\ComposerJsonAndInstalledJsonSourceLocatorMaker;
use Roave\BetterReflection\Reflector\FunctionReflector;
use Roave\BetterReflection\SourceLocator\Ast\Locator;
use Roave\BetterReflection\SourceLocator\SourceStubber\PhpStormStubsSourceStubber;
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\MemoizingSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\SourceLocator;

class TestCaseSourceLocatorFactory
{

private Container $container;

private ComposerJsonAndInstalledJsonSourceLocatorMaker $composerJsonAndInstalledJsonSourceLocatorMaker;

private \PhpParser\Parser $phpParser;

private PhpStormStubsSourceStubber $phpStormStubsSourceStubber;

public function __construct(
Container $container,
ComposerJsonAndInstalledJsonSourceLocatorMaker $composerJsonAndInstalledJsonSourceLocatorMaker,
\PhpParser\Parser $phpParser,
PhpStormStubsSourceStubber $phpStormStubsSourceStubber
)
{
$this->container = $container;
$this->composerJsonAndInstalledJsonSourceLocatorMaker = $composerJsonAndInstalledJsonSourceLocatorMaker;
$this->phpParser = $phpParser;
$this->phpStormStubsSourceStubber = $phpStormStubsSourceStubber;
}

public function create(): SourceLocator
{
$classLoaderReflection = new \ReflectionClass(ClassLoader::class);
if ($classLoaderReflection->getFileName() === false) {
throw new \PHPStan\ShouldNotHappenException('Unknown ClassLoader filename');
}

$composerProjectPath = dirname($classLoaderReflection->getFileName(), 3);
if (!is_file($composerProjectPath . '/composer.json')) {
throw new \PHPStan\ShouldNotHappenException(sprintf('composer.json not found in directory %s', $composerProjectPath));
}

$composerSourceLocator = $this->composerJsonAndInstalledJsonSourceLocatorMaker->create($composerProjectPath);
if ($composerSourceLocator === null) {
throw new \PHPStan\ShouldNotHappenException('Could not create composer source locator');
}

$locators = [
$composerSourceLocator,
];
$astLocator = new Locator($this->phpParser, function (): FunctionReflector {
return $this->container->getService('testCaseFunctionReflector');
});

$locators[] = new AutoloadSourceLocator($astLocator);
$locators[] = new PhpInternalSourceLocator($astLocator, $this->phpStormStubsSourceStubber);

return new MemoizingSourceLocator(new AggregateSourceLocator($locators));
}

}
5 changes: 5 additions & 0 deletions tests/bootstrap-runtime-reflection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php declare(strict_types = 1);

require_once __DIR__ . '/bootstrap.php';

\PHPStan\Testing\TestCase::getContainer();
2 changes: 2 additions & 0 deletions tests/bootstrap-static-reflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
require_once __DIR__ . '/bootstrap.php';

\PHPStan\Testing\TestCase::$useStaticReflectionProvider = true;

\PHPStan\Testing\TestCase::getContainer();
4 changes: 0 additions & 4 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<?php declare(strict_types = 1);

use PHPStan\Testing\TestCase;

error_reporting(E_ALL);

require_once __DIR__ . '/../vendor/autoload.php';
Expand All @@ -22,5 +20,3 @@ public function doFoo($i)
}
}');

TestCase::getContainer();
2 changes: 1 addition & 1 deletion tests/phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="phpunit.xsd"
bootstrap="bootstrap.php"
bootstrap="bootstrap-runtime-reflection.php"
colors="true"
failOnRisky="true"
failOnWarning="true"
Expand Down

0 comments on commit cb479ed

Please sign in to comment.