mirror of
https://github.com/rectorphp/rector.git
synced 2025-04-20 07:22:43 +02:00
[NetteTesterToPHPUnit] Add NetteTesterClassToPHPUnitClassRector
This commit is contained in:
parent
8f8778124d
commit
cae6f2a760
@ -1524,8 +1524,8 @@ Change assertContains()/assertNotContains() method to new string and iterable al
|
||||
- $this->assertNotContains('foo', 'foo bar');
|
||||
- $this->assertContains('foo', ['foo', 'bar']);
|
||||
- $this->assertNotContains('foo', ['foo', 'bar']);
|
||||
+ $this->assertStringContains('foo', 'foo bar');
|
||||
+ $this->assertStringNotContains('foo', 'foo bar');
|
||||
+ $this->assertStringContainsString('foo', 'foo bar');
|
||||
+ $this->assertStringNotContainsString('foo', 'foo bar');
|
||||
+ $this->assertIterableContains('foo', ['foo', 'bar']);
|
||||
+ $this->assertIterableNotContains('foo', ['foo', 'bar']);
|
||||
}
|
||||
|
@ -219,17 +219,18 @@ final class CreateRectorCommand extends Command implements ContributorCommandInt
|
||||
*/
|
||||
private function processComposerAutoload(array $templateVariables): void
|
||||
{
|
||||
$composerJsonContent = FileSystem::read(getcwd() . '/composer.json');
|
||||
$composerJson = Json::decode($composerJsonContent, Json::FORCE_ARRAY);
|
||||
$composerJsonFilePath = getcwd() . '/composer.json';
|
||||
$composerJson = $this->loadFileToJson($composerJsonFilePath);
|
||||
|
||||
$package = $templateVariables['_Package_'];
|
||||
|
||||
// already autoloaded?
|
||||
// skip core, already autoloaded
|
||||
if ($package === 'Rector') {
|
||||
return;
|
||||
}
|
||||
|
||||
$package = $templateVariables['_Package_'];
|
||||
|
||||
$namespace = 'Rector\\' . $package . '\\';
|
||||
$namespaceTest = 'Rector\\' . $package . '\\Tests\\';
|
||||
|
||||
@ -241,13 +242,7 @@ final class CreateRectorCommand extends Command implements ContributorCommandInt
|
||||
$composerJson['autoload']['psr-4'][$namespace] = 'packages/' . $package . '/src';
|
||||
$composerJson['autoload-dev']['psr-4'][$namespaceTest] = 'packages/' . $package . '/tests';
|
||||
|
||||
$composerJsonContent = Json::encode($composerJson, Json::PRETTY);
|
||||
|
||||
$composerJsonContent = $this->inlineSections($composerJsonContent, ['keywords', 'bin']);
|
||||
|
||||
// inline short arrays
|
||||
|
||||
FileSystem::write(getcwd() . '/composer.json', $composerJsonContent);
|
||||
$this->saveJsonToFile($composerJsonFilePath, $composerJson);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -267,4 +262,23 @@ final class CreateRectorCommand extends Command implements ContributorCommandInt
|
||||
|
||||
return $jsonContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function loadFileToJson(string $filePath): array
|
||||
{
|
||||
$fileContent = FileSystem::read($filePath);
|
||||
return Json::decode($fileContent, Json::FORCE_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $json
|
||||
*/
|
||||
private function saveJsonToFile(string $filePath, array $json): void
|
||||
{
|
||||
$content = Json::encode($json, Json::PRETTY);
|
||||
$content = $this->inlineSections($content, ['keywords', 'bin']);
|
||||
FileSystem::write($filePath, $content);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,340 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteTesterToPHPUnit\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Cast\Bool_;
|
||||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\Expr\Include_;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
|
||||
use Rector\NodeTypeResolver\Node\Attribute;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\PhpParser\Node\Manipulator\ClassManipulator;
|
||||
use Rector\PhpParser\NodeTraverser\CallableNodeTraverser;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
|
||||
final class NetteTesterClassToPHPUnitClassRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $netteTesterTestCaseClass;
|
||||
|
||||
/**
|
||||
* @var ClassManipulator
|
||||
*/
|
||||
private $classManipulator;
|
||||
|
||||
/**
|
||||
* @var CallableNodeTraverser
|
||||
*/
|
||||
private $callableNodeTraverser;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $assertMethodsRemap = [
|
||||
'same' => 'assertSame',
|
||||
'notSame' => 'assertNotSame',
|
||||
'equal' => 'assertEqual',
|
||||
'notEqual' => 'assertNotEqual',
|
||||
'true' => 'assertTrue',
|
||||
'false' => 'assertFalse',
|
||||
'null' => 'assertNull',
|
||||
'notNull' => 'assertNotNull',
|
||||
'count' => 'assertCount',
|
||||
'match' => 'assertStringMatchesFormat',
|
||||
'matchFile' => 'assertStringMatchesFormatFile',
|
||||
'contains' => 'assertContains',
|
||||
'notContains' => 'assertNotContains',
|
||||
'nan' => 'assertIsNumeric',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var DocBlockManipulator
|
||||
*/
|
||||
private $docBlockManipulator;
|
||||
|
||||
public function __construct(
|
||||
ClassManipulator $classManipulator,
|
||||
CallableNodeTraverser $callableNodeTraverser,
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
string $netteTesterTestCaseClass = 'Tester\TestCase'
|
||||
) {
|
||||
$this->classManipulator = $classManipulator;
|
||||
$this->callableNodeTraverser = $callableNodeTraverser;
|
||||
$this->netteTesterTestCaseClass = $netteTesterTestCaseClass;
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Migrate Nette Tester test case to PHPUnit', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
namespace KdybyTests\Doctrine;
|
||||
|
||||
use Tester\TestCase;
|
||||
use Tester\Assert;
|
||||
|
||||
require_once __DIR__ . '/../bootstrap.php';
|
||||
|
||||
class ExtensionTest extends TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
}
|
||||
|
||||
public function testFunctionality()
|
||||
{
|
||||
Assert::true($default instanceof Kdyby\Doctrine\EntityManager);
|
||||
Assert::true(5);
|
||||
Assert::same($container->getService('kdyby.doctrine.default.entityManager'), $default);
|
||||
}
|
||||
}
|
||||
|
||||
(new \ExtensionTest())->run();
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
namespace KdybyTests\Doctrine;
|
||||
|
||||
use Tester\TestCase;
|
||||
use Tester\Assert;
|
||||
|
||||
class ExtensionTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
}
|
||||
|
||||
public function testFunctionality()
|
||||
{
|
||||
self::assertInstanceOf(\Kdyby\Doctrine\EntityManager::cllass, $default);
|
||||
self::assertTrue(5);
|
||||
self::same($container->getService('kdyby.doctrine.default.entityManager'), $default);
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Class_::class, Include_::class, MethodCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_|Include_|MethodCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($node instanceof Include_) {
|
||||
$this->processAboveTestInclude($node);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isType($node, $this->netteTesterTestCaseClass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($node instanceof MethodCall) {
|
||||
$this->processUnderTestRun($node);
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->processExtends($node);
|
||||
$this->processMethods($node);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function processExtends(Class_ $class): void
|
||||
{
|
||||
$class->extends = new FullyQualified('PHPUnit\Framework\TestCase');
|
||||
}
|
||||
|
||||
private function processAboveTestInclude(Include_ $include): void
|
||||
{
|
||||
if ($include->getAttribute(Attribute::CLASS_NODE) === null) {
|
||||
$this->removeNode($include);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private function processUnderTestRun(MethodCall $methodCall): void
|
||||
{
|
||||
if ($this->isName($methodCall, 'run')) {
|
||||
$this->removeNode($methodCall);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private function processMethods(Class_ $class): void
|
||||
{
|
||||
$methods = $this->classManipulator->getMethods($class);
|
||||
foreach ($methods as $method) {
|
||||
if ($this->isNamesInsensitive($method, ['setUp', 'tearDown'])) {
|
||||
$this->makeProtected($method);
|
||||
}
|
||||
|
||||
$this->processMethod($method);
|
||||
}
|
||||
}
|
||||
|
||||
private function renameMethods(StaticCall $staticCall): void
|
||||
{
|
||||
// special cases
|
||||
if ($this->isNames($staticCall, ['exception', 'throws'])) {
|
||||
$this->processExceptionStaticCall($staticCall);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->isName($staticCall, 'type')) {
|
||||
$this->processTypeStaticCall($staticCall);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->isName($staticCall, 'noError')) {
|
||||
$this->processNoErrorStaticCall($staticCall);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->isNames($staticCall, ['truthy', 'falsey'])) {
|
||||
$this->processTruthyOrFalseyStaticCall($staticCall);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->assertMethodsRemap as $oldMethod => $newMethod) {
|
||||
if ($this->isName($staticCall, $oldMethod)) {
|
||||
$staticCall->name = new Identifier($newMethod);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function processMethod(ClassMethod $classMethod): void
|
||||
{
|
||||
$this->callableNodeTraverser->traverseNodesWithCallable((array) $classMethod->stmts, function (Node $node) {
|
||||
if (! $node instanceof StaticCall) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isType($node->class, 'Tester\Assert')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$node->class = new Name('self');
|
||||
$this->renameMethods($node);
|
||||
});
|
||||
}
|
||||
|
||||
private function processExceptionStaticCall(StaticCall $staticCall): void
|
||||
{
|
||||
// expect exception
|
||||
$expectException = new StaticCall(new Name('self'), 'expectException');
|
||||
$expectException->args[] = $staticCall->args[1];
|
||||
$this->addNodeAfterNode($expectException, $staticCall);
|
||||
|
||||
// expect message
|
||||
if (isset($staticCall->args[2])) {
|
||||
$expectExceptionMessage = new StaticCall(new Name('self'), 'expectExceptionMessage');
|
||||
$expectExceptionMessage->args[] = $staticCall->args[2];
|
||||
$this->addNodeAfterNode($expectExceptionMessage, $staticCall);
|
||||
}
|
||||
|
||||
// expect code
|
||||
if (isset($staticCall->args[3])) {
|
||||
$expectExceptionMessage = new StaticCall(new Name('self'), 'expectExceptionCode');
|
||||
$expectExceptionMessage->args[] = $staticCall->args[3];
|
||||
$this->addNodeAfterNode($expectExceptionMessage, $staticCall);
|
||||
}
|
||||
|
||||
/** @var Closure $callable */
|
||||
$callable = $staticCall->args[0]->value;
|
||||
foreach ((array) $callable->stmts as $callableStmt) {
|
||||
$this->addNodeAfterNode($callableStmt, $staticCall);
|
||||
}
|
||||
|
||||
$this->removeNode($staticCall);
|
||||
}
|
||||
|
||||
private function processNoErrorStaticCall(StaticCall $staticCall): void
|
||||
{
|
||||
/** @var Closure $callable */
|
||||
$callable = $staticCall->args[0]->value;
|
||||
|
||||
foreach ((array) $callable->stmts as $callableStmt) {
|
||||
$this->addNodeAfterNode($callableStmt, $staticCall);
|
||||
}
|
||||
|
||||
$this->removeNode($staticCall);
|
||||
|
||||
$methodNode = $staticCall->getAttribute(Attribute::METHOD_NODE);
|
||||
if ($methodNode === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$phpDocTagNode = new PhpDocTextNode('@doesNotPerformAssertions');
|
||||
$this->docBlockManipulator->addTag($methodNode, $phpDocTagNode);
|
||||
}
|
||||
|
||||
private function processTruthyOrFalseyStaticCall(StaticCall $staticCall): void
|
||||
{
|
||||
if (! $this->isBoolType($staticCall->args[0]->value)) {
|
||||
$staticCall->args[0]->value = new Bool_($staticCall->args[0]->value);
|
||||
}
|
||||
|
||||
if ($this->isName($staticCall, 'truthy')) {
|
||||
$staticCall->name = new Identifier('assertTrue');
|
||||
} else {
|
||||
$staticCall->name = new Identifier('assertFalse');
|
||||
}
|
||||
}
|
||||
|
||||
private function processTypeStaticCall(StaticCall $staticCall): void
|
||||
{
|
||||
$value = $this->getValue($staticCall->args[0]->value);
|
||||
|
||||
$typeToMethod = [
|
||||
'list' => 'assertIsArray',
|
||||
'array' => 'assertIsArray',
|
||||
'bool' => 'assertIsBool',
|
||||
'callable' => 'assertIsCallable',
|
||||
'float' => 'assertIsFloat',
|
||||
'int' => 'assertIsInt',
|
||||
'integer' => 'assertIsInt',
|
||||
'object' => 'assertIsObject',
|
||||
'resource' => 'assertIsResource',
|
||||
'string' => 'assertIsString',
|
||||
'scalar' => 'assertIsScalar',
|
||||
];
|
||||
|
||||
if (isset($typeToMethod[$value])) {
|
||||
$staticCall->name = new Identifier($typeToMethod[$value]);
|
||||
unset($staticCall->args[0]);
|
||||
array_values($staticCall->args);
|
||||
} elseif ($value === 'null') {
|
||||
$staticCall->name = new Identifier('assertNull');
|
||||
unset($staticCall->args[0]);
|
||||
array_values($staticCall->args);
|
||||
} else {
|
||||
$staticCall->name = new Identifier('assertInstanceOf');
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
// just for the test
|
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
|
||||
|
||||
namespace KdybyTests\Doctrine;
|
||||
|
||||
use Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Source\NetteTesterTestCase;
|
||||
use Tester\Assert;
|
||||
|
||||
class AssertTypeTest extends NetteTesterTestCase
|
||||
{
|
||||
public function testFunctionality()
|
||||
{
|
||||
$value = 'SomeValue';
|
||||
|
||||
Assert::type('list', $value);
|
||||
Assert::type('array', $value);
|
||||
Assert::type('bool', $value);
|
||||
Assert::type('callable', $value);
|
||||
Assert::type('float', $value);
|
||||
Assert::type('int', $value);
|
||||
Assert::type('integer', $value);
|
||||
Assert::type('null', $value);
|
||||
Assert::type('object', $value);
|
||||
Assert::type('resource', $value);
|
||||
Assert::type('scalar', $value);
|
||||
Assert::type('string', $value);
|
||||
Assert::type(\stdClass::class, $value);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
|
||||
|
||||
namespace KdybyTests\Doctrine;
|
||||
|
||||
use Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Source\NetteTesterTestCase;
|
||||
use Tester\Assert;
|
||||
|
||||
class AssertTypeTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testFunctionality()
|
||||
{
|
||||
$value = 'SomeValue';
|
||||
|
||||
self::assertIsArray($value);
|
||||
self::assertIsArray($value);
|
||||
self::assertIsBool($value);
|
||||
self::assertIsCallable($value);
|
||||
self::assertIsFloat($value);
|
||||
self::assertIsInt($value);
|
||||
self::assertIsInt($value);
|
||||
self::assertNull($value);
|
||||
self::assertIsObject($value);
|
||||
self::assertIsResource($value);
|
||||
self::assertIsScalar($value);
|
||||
self::assertIsString($value);
|
||||
self::assertInstanceOf(\stdClass::class, $value);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
|
||||
|
||||
namespace KdybyTests\Doctrine;
|
||||
|
||||
use Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Source\NetteTesterTestCase;
|
||||
use Tester\Assert;
|
||||
|
||||
require_once __DIR__ . '/bootstrap.php';
|
||||
|
||||
class ExtensionTest extends NetteTesterTestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
}
|
||||
|
||||
public function testFunctionality()
|
||||
{
|
||||
$value = 'SomeValue';
|
||||
Assert::type(\Kdyby\Doctrine\EntityManager::class, $value);
|
||||
Assert::false(5);
|
||||
Assert::same('ExpectedValue', $value);
|
||||
}
|
||||
|
||||
public function testExceptions()
|
||||
{
|
||||
Assert::exception(function () {
|
||||
$builder = new DI\ContainerBuilder;
|
||||
$builder->run();
|
||||
}, 'ExceptionClass', "Service 'one': Class or interface 'X' not found.", 200);
|
||||
}
|
||||
|
||||
public function testNoError()
|
||||
{
|
||||
Assert::noError(function () {
|
||||
$value = 1;
|
||||
});
|
||||
}
|
||||
|
||||
public function testY()
|
||||
{
|
||||
Assert::falsey('value', 'some messsage');
|
||||
Assert::truthy(true);
|
||||
}
|
||||
}
|
||||
|
||||
(new ExtensionTest())->run();
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
|
||||
|
||||
namespace KdybyTests\Doctrine;
|
||||
|
||||
use Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Source\NetteTesterTestCase;
|
||||
use Tester\Assert;
|
||||
|
||||
class ExtensionTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
}
|
||||
|
||||
public function testFunctionality()
|
||||
{
|
||||
$value = 'SomeValue';
|
||||
self::assertInstanceOf(\Kdyby\Doctrine\EntityManager::class, $value);
|
||||
self::assertFalse(5);
|
||||
self::assertSame('ExpectedValue', $value);
|
||||
}
|
||||
|
||||
public function testExceptions()
|
||||
{
|
||||
self::expectException('ExceptionClass');
|
||||
self::expectExceptionMessage("Service 'one': Class or interface 'X' not found.");
|
||||
self::expectExceptionCode(200);
|
||||
$builder = new DI\ContainerBuilder;
|
||||
$builder->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @doesNotPerformAssertions
|
||||
*/
|
||||
public function testNoError()
|
||||
{
|
||||
$value = 1;
|
||||
}
|
||||
|
||||
public function testY()
|
||||
{
|
||||
self::assertFalse((bool) 'value', 'some messsage');
|
||||
self::assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,34 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector;
|
||||
|
||||
use Nette\Utils\FileSystem;
|
||||
use Rector\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector;
|
||||
use Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Source\NetteTesterTestCase;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
|
||||
final class NetteTesterClassToPHPUnitClassRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
public function test(): void
|
||||
{
|
||||
// prepare dummy data
|
||||
FileSystem::copy(__DIR__ . '/Copy', $this->getTempPath());
|
||||
|
||||
$this->doTestFiles([__DIR__ . '/Fixture/fixture.php.inc', __DIR__ . '/Fixture/assert_type.php.inc']);
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return NetteTesterClassToPHPUnitClassRector::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]|null
|
||||
*/
|
||||
protected function getRectorConfiguration(): ?array
|
||||
{
|
||||
return [
|
||||
'$netteTesterTestCaseClass' => NetteTesterTestCase::class,
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Source;
|
||||
|
||||
abstract class NetteTesterTestCase
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
}
|
||||
}
|
@ -51,8 +51,8 @@ final class SomeTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function test()
|
||||
{
|
||||
$this->assertStringContains('foo', 'foo bar');
|
||||
$this->assertStringNotContains('foo', 'foo bar');
|
||||
$this->assertStringContainsString('foo', 'foo bar');
|
||||
$this->assertStringNotContainsString('foo', 'foo bar');
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
|
@ -11,6 +11,7 @@ use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Namespace_;
|
||||
use Rector\Exception\ShouldNotHappenException;
|
||||
use Rector\NodeTypeResolver\Node\Attribute;
|
||||
use Rector\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\Util\RectorStrings;
|
||||
use Symplify\PackageBuilder\Strings\StringFormatConverter;
|
||||
|
||||
@ -21,13 +22,24 @@ final class PhpSpecRenaming
|
||||
*/
|
||||
private $stringFormatConverter;
|
||||
|
||||
public function __construct(StringFormatConverter $stringFormatConverter)
|
||||
/**
|
||||
* @var NameResolver
|
||||
*/
|
||||
private $nameResolver;
|
||||
|
||||
public function __construct(StringFormatConverter $stringFormatConverter, NameResolver $nameResolver)
|
||||
{
|
||||
$this->stringFormatConverter = $stringFormatConverter;
|
||||
$this->nameResolver = $nameResolver;
|
||||
}
|
||||
|
||||
public function renameMethod(ClassMethod $classMethod, string $name): void
|
||||
public function renameMethod(ClassMethod $classMethod): void
|
||||
{
|
||||
$name = $this->nameResolver->resolve($classMethod);
|
||||
if ($name === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$name = RectorStrings::removePrefixes(
|
||||
$name,
|
||||
['it_should_have_', 'it_should_be', 'it_should_', 'it_is_', 'it_', 'is_']
|
||||
|
@ -230,23 +230,21 @@ CODE_SAMPLE
|
||||
|
||||
private function processMethods(Class_ $class): void
|
||||
{
|
||||
$methods = $this->classManipulator->getMethodsByName($class);
|
||||
|
||||
// let → setUp
|
||||
foreach ($methods as $name => $method) {
|
||||
if ($name === 'let') {
|
||||
foreach ($this->classManipulator->getMethods($class) as $method) {
|
||||
if ($this->isName($method, 'let')) {
|
||||
$this->processLetMethod($method);
|
||||
} else {
|
||||
/** @var string $name */
|
||||
$this->processTestMethod($method, $name);
|
||||
$this->processTestMethod($method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function processTestMethod(ClassMethod $classMethod, string $name): void
|
||||
private function processTestMethod(ClassMethod $classMethod): void
|
||||
{
|
||||
// change name to phpunit test case format
|
||||
$this->phpSpecRenaming->renameMethod($classMethod, $name);
|
||||
$this->phpSpecRenaming->renameMethod($classMethod);
|
||||
|
||||
// replace "$this" with "$this->{testedObject}"
|
||||
$this->callableNodeTraverser->traverseNodesWithCallable((array) $classMethod->stmts, function (Node $node) {
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Rector\PhpParser\Node\Manipulator;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt;
|
||||
@ -232,15 +233,11 @@ final class ClassManipulator
|
||||
/**
|
||||
* @return ClassMethod[]
|
||||
*/
|
||||
public function getMethodsByName(Class_ $classNode): array
|
||||
public function getMethods(Class_ $class): array
|
||||
{
|
||||
$methodsByName = [];
|
||||
foreach ($classNode->stmts as $stmt) {
|
||||
if ($stmt instanceof ClassMethod) {
|
||||
$methodsByName[(string) $stmt->name] = $stmt;
|
||||
}
|
||||
}
|
||||
return $methodsByName;
|
||||
return array_filter($class->stmts, function (Node $node) {
|
||||
return $node instanceof ClassMethod;
|
||||
});
|
||||
}
|
||||
|
||||
private function tryInsertBeforeFirstMethod(Class_ $classNode, Stmt $stmt): bool
|
||||
|
@ -66,12 +66,8 @@ abstract class AbstractRectorTestCase extends AbstractKernelTestCase
|
||||
protected function provideConfig(): string
|
||||
{
|
||||
if ($this->getRectorClass() !== '') { // use local if not overloaded
|
||||
$hash = Strings::substring(
|
||||
md5($this->getRectorClass() . Json::encode($this->getRectorConfiguration())),
|
||||
0,
|
||||
10
|
||||
);
|
||||
$configFileTempPath = sprintf(sys_get_temp_dir() . '/rector_temp_tests/config_%s.yaml', $hash);
|
||||
$fixtureHash = $this->createFixtureHash();
|
||||
$configFileTempPath = sprintf(sys_get_temp_dir() . '/rector_temp_tests/config_%s.yaml', $fixtureHash);
|
||||
|
||||
// cache for 2nd run, similar to original config one
|
||||
if (file_exists($configFileTempPath)) {
|
||||
@ -121,6 +117,11 @@ abstract class AbstractRectorTestCase extends AbstractKernelTestCase
|
||||
$this->autoloadTestFixture = true;
|
||||
}
|
||||
|
||||
protected function getTempPath(): string
|
||||
{
|
||||
return sys_get_temp_dir() . '/rector_temp_tests';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
@ -170,11 +171,15 @@ abstract class AbstractRectorTestCase extends AbstractKernelTestCase
|
||||
{
|
||||
$hash = Strings::substring(md5($smartFileInfo->getRealPath()), 0, 5);
|
||||
|
||||
return sprintf(
|
||||
sys_get_temp_dir() . '/rector_temp_tests/%s_%s_%s',
|
||||
$prefix,
|
||||
$hash,
|
||||
$smartFileInfo->getBasename('.inc')
|
||||
return sprintf($this->getTempPath() . '/%s_%s_%s', $prefix, $hash, $smartFileInfo->getBasename('.inc'));
|
||||
}
|
||||
|
||||
private function createFixtureHash(): string
|
||||
{
|
||||
return Strings::substring(
|
||||
md5($this->getRectorClass() . Json::encode($this->getRectorConfiguration())),
|
||||
0,
|
||||
10
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user