Skip to content
Merged

cleanup #2013

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
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ PRs and issues are linked, so you can find more about it. Thanks to [ChangelogLi
- [#1753] [DeadCode] Rector `RemoveDeadConstructorRector` should skip `private` method, Thanks to [@stloyd]
- [#1687] [Symfony] Set few default common service names for Symfony App Analyzer, Thanks to [@stloyd]
- [#1675] [Symfony] Make set symfony42 refactor get(...) in former container aware commands
- [#1666] Skip session in `MultipleServiceGetToSetUpMethodRector`
- [#1666] Skip session in `SelfContainerGetMethodCallFromTestToSetUpMethodRector`
- [#1757] make SymfonyContainer factory configurable with "kernel_environment" parameter in rector.yaml
- [#1707] Don't mess with lines between docblock comment and var type., Thanks to [@ravanscafi]
- [#1699] Update composer scripts, Thanks to [@ravanscafi]
Expand Down Expand Up @@ -233,7 +233,7 @@ PRs and issues are linked, so you can find more about it. Thanks to [ChangelogLi
- [#1584] [DeadCode] Add `RemoveDeadZeroAndOneOperationRector`
- [#1586] [DeadCode] Add `RemoveDelegatingParentCallRector`
- [#1603] [DeadCode] Add `RemoveDuplicatedInstanceOfRector`
- [#1656] [SymfonyPHPUnit] Add `MultipleServiceGetToSetUpMethodRector`
- [#1656] [SymfonyPHPUnit] Add `SelfContainerGetMethodCallFromTestToSetUpMethodRector`
- [#1589] Add assign ref support to `AddDefaultValueForUndefinedVariableRector`
- [#1609] Add `ElasticSearchDSL` package, Thanks to [@shyim]
- [#1611] Add rector for ShopRegistration, Thanks to [@shyim]
Expand Down
2 changes: 1 addition & 1 deletion config/set/symfony/symfony-phpunit.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
services:
Rector\SymfonyPHPUnit\Rector\Class_\MultipleServiceGetToSetUpMethodRector: ~
Rector\SymfonyPHPUnit\Rector\Class_\SelfContainerGetMethodCallFromTestToSetUpMethodRector: ~
4 changes: 2 additions & 2 deletions docs/AllRectorsOverview.md
Original file line number Diff line number Diff line change
Expand Up @@ -5830,9 +5830,9 @@ Change Symfony Event listener class to Event Subscriber based on configuration i

## SymfonyPHPUnit

### `MultipleServiceGetToSetUpMethodRector`
### `SelfContainerGetMethodCallFromTestToSetUpMethodRector`

- class: `Rector\SymfonyPHPUnit\Rector\Class_\MultipleServiceGetToSetUpMethodRector`
- class: `Rector\SymfonyPHPUnit\Rector\Class_\SelfContainerGetMethodCallFromTestToSetUpMethodRector`

```diff
use ItemRepository;
Expand Down
2 changes: 1 addition & 1 deletion packages/NetteTesterToPHPUnit/src/AssertManipulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ private function processTruthyOrFalseyCall(StaticCall $staticCall): Expr

private function processTypeCall(StaticCall $staticCall): void
{
$value = $this->valueResolver->resolve($staticCall->args[0]->value);
$value = $this->valueResolver->getValue($staticCall->args[0]->value);

$typeToMethod = [
'list' => 'assertIsArray',
Expand Down
2 changes: 1 addition & 1 deletion packages/NetteToSymfony/src/Route/RouteInfoFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public function createFromNode(Node $node): ?RouteInfo
private function createRouteInfoFromArgs(Node $node, array $methods = []): ?RouteInfo
{
$pathArgument = $node->args[0]->value;
$routePath = $this->valueResolver->resolve($pathArgument);
$routePath = $this->valueResolver->getValue($pathArgument);

// route path is needed
if ($routePath === null || ! is_string($routePath)) {
Expand Down
7 changes: 7 additions & 0 deletions packages/SymfonyPHPUnit/config/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
services:
_defaults:
public: true
autowire: true

Rector\SymfonyPHPUnit\:
resource: '../src/'
29 changes: 29 additions & 0 deletions packages/SymfonyPHPUnit/src/Naming/ServiceNaming.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php declare(strict_types=1);

namespace Rector\SymfonyPHPUnit\Naming;

use Nette\Utils\Strings;
use PHPStan\Type\ObjectType;
use Rector\Naming\PropertyNaming;

final class ServiceNaming
{
/**
* @var PropertyNaming
*/
private $propertyNaming;

public function __construct(PropertyNaming $propertyNaming)
{
$this->propertyNaming = $propertyNaming;
}

public function resolvePropertyNameFromServiceType(string $serviceType): string
{
if (Strings::contains($serviceType, '_') && ! Strings::contains($serviceType, '\\')) {
return $this->propertyNaming->underscoreToName($serviceType);
}

return $this->propertyNaming->fqnToVariableName(new ObjectType($serviceType));
}
}
46 changes: 46 additions & 0 deletions packages/SymfonyPHPUnit/src/Node/KernelTestCaseNodeAnalyzer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php declare(strict_types=1);

namespace Rector\SymfonyPHPUnit\Node;

use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticPropertyFetch;
use Rector\PhpParser\Node\Resolver\NameResolver;

final class KernelTestCaseNodeAnalyzer
{
/**
* @var NameResolver
*/
private $nameResolver;

public function __construct(NameResolver $nameResolver)
{
$this->nameResolver = $nameResolver;
}

/**
* Matches:
* self::$container->get()
*/
public function isSelfContainerGetMethodCall(Node $node): bool
{
if (! $node instanceof MethodCall) {
return false;
}

if (! $node->var instanceof StaticPropertyFetch) {
return false;
}

if (! $this->nameResolver->isName($node->var->class, 'self')) {
return false;
}

if (! $this->nameResolver->isName($node->var->name, 'container')) {
return false;
}

return $this->nameResolver->isName($node->name, 'get');
}
}
157 changes: 157 additions & 0 deletions packages/SymfonyPHPUnit/src/Node/KernelTestCaseNodeFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
<?php declare(strict_types=1);

namespace Rector\SymfonyPHPUnit\Node;

use Nette\Utils\Strings;
use PhpParser\BuilderFactory;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Property;
use PHPStan\Type\ObjectType;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PhpParser\Node\NodeFactory;
use Rector\PhpSpecToPHPUnit\PHPUnitTypeDeclarationDecorator;
use Rector\SymfonyPHPUnit\Naming\ServiceNaming;

final class KernelTestCaseNodeFactory
{
/**
* @var BuilderFactory
*/
private $builderFactory;

/**
* @var PHPUnitTypeDeclarationDecorator
*/
private $phpUnitTypeDeclarationDecorator;

/**
* @var NodeFactory
*/
private $nodeFactory;

/**
* @var ServiceNaming
*/
private $serviceNaming;

public function __construct(
BuilderFactory $builderFactory,
PHPUnitTypeDeclarationDecorator $phpUnitTypeDeclarationDecorator,
NodeFactory $nodeFactory,
ServiceNaming $serviceNaming
) {
$this->builderFactory = $builderFactory;
$this->phpUnitTypeDeclarationDecorator = $phpUnitTypeDeclarationDecorator;
$this->nodeFactory = $nodeFactory;
$this->serviceNaming = $serviceNaming;
}

/**
* @param string[] $serviceTypes
*/
public function createSetUpClassMethodWithGetTypes(Class_ $class, array $serviceTypes): ?ClassMethod
{
$assigns = $this->createSelfContainerGetWithTypeAssigns($class, $serviceTypes);
if (count($assigns) === 0) {
return null;
}

$stmts = array_merge([new StaticCall(new Name('parent'), 'setUp')], $assigns);

$classMethodBuilder = $this->builderFactory->method('setUp');
$classMethodBuilder->makeProtected();
$classMethodBuilder->addStmts($stmts);
$classMethod = $classMethodBuilder->getNode();

$this->phpUnitTypeDeclarationDecorator->decorate($classMethod);

return $classMethod;
}

/**
* @param string[] $serviceTypes
*
* @return Property[]
*/
public function createPrivatePropertiesFromTypes(Class_ $class, array $serviceTypes): array
{
$properties = [];

/** @var string $className */
$className = $class->getAttribute(AttributeKey::CLASS_NAME);

foreach ($serviceTypes as $serviceType) {
$propertyName = $this->serviceNaming->resolvePropertyNameFromServiceType($serviceType);

// skip existing properties
if (property_exists($className, $propertyName)) {
continue;
}

$serviceType = new ObjectType($serviceType);
$properties[] = $this->nodeFactory->createPrivatePropertyFromNameAndType($propertyName, $serviceType);
}

return $properties;
}

/**
* @param string[] $serviceTypes
*
* @return Expression[]
*
* E.g. "['SomeService']" → "$this->someService = self::$container->get(SomeService::class);"
*/
public function createSelfContainerGetWithTypeAssigns(Class_ $class, array $serviceTypes): array
{
$stmts = [];

/** @var string $className */
$className = $class->getAttribute(AttributeKey::CLASS_NAME);

foreach ($serviceTypes as $serviceType) {
$propertyName = $this->serviceNaming->resolvePropertyNameFromServiceType($serviceType);
// skip existing properties
if (property_exists($className, $propertyName)) {
continue;
}

$propertyFetch = new PropertyFetch(new Variable('this'), $propertyName);
$methodCall = $this->createSelfContainerGetWithTypeMethodCall($serviceType);

$assign = new Assign($propertyFetch, $methodCall);
$stmts[] = new Expression($assign);
}
return $stmts;
}

private function createSelfContainerGetWithTypeMethodCall(string $serviceType): MethodCall
{
$staticPropertyFetch = new StaticPropertyFetch(new Name('self'), 'container');
$methodCall = new MethodCall($staticPropertyFetch, 'get');

if (Strings::contains($serviceType, '_') && ! Strings::contains($serviceType, '\\')) {
// keep string
$getArgumentValue = new String_($serviceType);
} else {
$getArgumentValue = new ClassConstFetch(new FullyQualified($serviceType), 'class');
}

$methodCall->args[] = new Arg($getArgumentValue);

return $methodCall;
}
}
Loading