2019-10-13 07:59:52 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
2019-03-15 11:53:06 +01:00
|
|
|
|
|
|
|
namespace Rector\PhpSpecToPHPUnit\Naming;
|
|
|
|
|
|
|
|
use Nette\Utils\Strings;
|
2019-03-22 11:48:41 +01:00
|
|
|
use PhpParser\Node;
|
2019-03-15 11:53:06 +01:00
|
|
|
use PhpParser\Node\Identifier;
|
|
|
|
use PhpParser\Node\Name;
|
|
|
|
use PhpParser\Node\Name\FullyQualified;
|
|
|
|
use PhpParser\Node\Stmt\Class_;
|
|
|
|
use PhpParser\Node\Stmt\ClassMethod;
|
|
|
|
use PhpParser\Node\Stmt\Namespace_;
|
2020-02-06 22:48:18 +01:00
|
|
|
use Rector\Core\Exception\ShouldNotHappenException;
|
|
|
|
use Rector\Core\Util\RectorStrings;
|
2020-02-09 23:47:00 +01:00
|
|
|
use Rector\NodeNameResolver\NodeNameResolver;
|
2019-04-13 11:20:27 +02:00
|
|
|
use Rector\NodeTypeResolver\Node\AttributeKey;
|
2019-03-15 11:53:06 +01:00
|
|
|
use Symplify\PackageBuilder\Strings\StringFormatConverter;
|
|
|
|
|
|
|
|
final class PhpSpecRenaming
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var StringFormatConverter
|
|
|
|
*/
|
|
|
|
private $stringFormatConverter;
|
|
|
|
|
2019-03-16 17:01:40 +01:00
|
|
|
/**
|
2020-02-09 12:31:31 +01:00
|
|
|
* @var NodeNameResolver
|
2019-03-16 17:01:40 +01:00
|
|
|
*/
|
2020-02-09 12:31:31 +01:00
|
|
|
private $nodeNameResolver;
|
2019-03-16 17:01:40 +01:00
|
|
|
|
2020-02-09 12:31:31 +01:00
|
|
|
public function __construct(StringFormatConverter $stringFormatConverter, NodeNameResolver $nodeNameResolver)
|
2019-03-15 11:53:06 +01:00
|
|
|
{
|
|
|
|
$this->stringFormatConverter = $stringFormatConverter;
|
2020-02-09 12:31:31 +01:00
|
|
|
$this->nodeNameResolver = $nodeNameResolver;
|
2019-03-15 11:53:06 +01:00
|
|
|
}
|
|
|
|
|
2019-03-16 17:01:40 +01:00
|
|
|
public function renameMethod(ClassMethod $classMethod): void
|
2019-03-15 11:53:06 +01:00
|
|
|
{
|
2020-02-09 12:31:31 +01:00
|
|
|
$name = $this->nodeNameResolver->getName($classMethod);
|
2019-03-16 17:01:40 +01:00
|
|
|
if ($name === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-23 15:43:12 +01:00
|
|
|
if ($classMethod->isPrivate()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$name = $this->removeNamePrefixes($name);
|
2019-03-15 11:53:06 +01:00
|
|
|
|
|
|
|
// from PhpSpec to PHPUnit method naming convention
|
2019-05-28 18:34:40 +02:00
|
|
|
$name = $this->stringFormatConverter->underscoreAndHyphenToCamelCase($name);
|
2019-03-15 11:53:06 +01:00
|
|
|
|
|
|
|
// add "test", so PHPUnit runs the method
|
|
|
|
if (! Strings::startsWith($name, 'test')) {
|
|
|
|
$name = 'test' . ucfirst($name);
|
|
|
|
}
|
|
|
|
|
|
|
|
$classMethod->name = new Identifier($name);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function renameExtends(Class_ $class): void
|
|
|
|
{
|
|
|
|
$class->extends = new FullyQualified('PHPUnit\Framework\TestCase');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function renameNamespace(Class_ $class): void
|
|
|
|
{
|
|
|
|
/** @var Namespace_ $namespace */
|
2019-04-13 11:20:27 +02:00
|
|
|
$namespace = $class->getAttribute(AttributeKey::NAMESPACE_NODE);
|
2019-03-15 11:53:06 +01:00
|
|
|
if ($namespace->name === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$newNamespaceName = RectorStrings::removePrefixes($namespace->name->toString(), ['spec\\']);
|
|
|
|
|
|
|
|
$namespace->name = new Name('Tests\\' . $newNamespaceName);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function renameClass(Class_ $class): void
|
|
|
|
{
|
|
|
|
// anonymous class?
|
|
|
|
if ($class->name === null) {
|
2019-09-21 13:03:30 +02:00
|
|
|
throw new ShouldNotHappenException();
|
2019-03-15 11:53:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// 2. change class name
|
|
|
|
$newClassName = RectorStrings::removeSuffixes($class->name->toString(), ['Spec']);
|
|
|
|
$newTestClassName = $newClassName . 'Test';
|
|
|
|
|
|
|
|
$class->name = new Identifier($newTestClassName);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function resolveObjectPropertyName(Class_ $class): string
|
|
|
|
{
|
|
|
|
// anonymous class?
|
|
|
|
if ($class->name === null) {
|
2019-09-21 13:03:30 +02:00
|
|
|
throw new ShouldNotHappenException();
|
2019-03-15 11:53:06 +01:00
|
|
|
}
|
|
|
|
|
2019-03-22 11:48:41 +01:00
|
|
|
$bareClassName = RectorStrings::removeSuffixes($class->name->toString(), ['Spec', 'Test']);
|
2019-03-15 11:53:06 +01:00
|
|
|
|
|
|
|
return lcfirst($bareClassName);
|
|
|
|
}
|
2019-03-22 11:48:41 +01:00
|
|
|
|
|
|
|
public function resolveTestedClass(Node $node): string
|
|
|
|
{
|
|
|
|
/** @var string $className */
|
2019-04-13 11:20:27 +02:00
|
|
|
$className = $node->getAttribute(AttributeKey::CLASS_NAME);
|
2019-03-22 11:48:41 +01:00
|
|
|
|
|
|
|
$newClassName = RectorStrings::removePrefixes($className, ['spec\\']);
|
|
|
|
|
|
|
|
return RectorStrings::removeSuffixes($newClassName, ['Spec']);
|
|
|
|
}
|
2019-03-23 15:43:12 +01:00
|
|
|
|
|
|
|
private function removeNamePrefixes(string $name): string
|
|
|
|
{
|
|
|
|
$originalName = $name;
|
|
|
|
|
|
|
|
$name = RectorStrings::removePrefixes(
|
|
|
|
$name,
|
|
|
|
['it_should_have_', 'it_should_be', 'it_should_', 'it_is_', 'it_', 'is_']
|
|
|
|
);
|
|
|
|
|
|
|
|
return $name ?: $originalName;
|
|
|
|
}
|
2019-03-15 11:53:06 +01:00
|
|
|
}
|