-
-
Notifications
You must be signed in to change notification settings - Fork 333
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added test for Rectors making additional changes (#545)
* Added test for Rectors making additional changes * Fix empty expected content * fix - added missing parameter * Moved multiple files change to trait and added docs * Rewritten test for Update file name by class name * Separate test using multiple files changed trait * Separated test * Created separated test with separated rector * Fix phpstan * Changed namespace for dummy rector
- Loading branch information
Showing
7 changed files
with
347 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
# Multiple files changed | ||
|
||
Sometimes Rector does changes in multiple files. How to test it? | ||
|
||
## Rector | ||
Add file with content in Rector: | ||
|
||
```php | ||
$addedFileWithContent = new \Rector\FileSystemRector\ValueObject\AddedFileWithContent($filePath, $content); | ||
$this->removedAndAddedFilesCollector->addAddedFile($addedFileWithContent); | ||
``` | ||
|
||
## RectorTest | ||
In RectorTest just use | ||
```php | ||
$this->doTestFileInfoWithAdditionalChanges($fileInfo); | ||
``` | ||
instead of | ||
|
||
```php | ||
$this->doTestFileInfo($fileInfo); | ||
``` | ||
|
||
## Test fixtures | ||
Fixture contains more parts separated by `-----` like in classic tests: | ||
``` | ||
1) original content | ||
----- | ||
2) expected content (keep empty if no change should happen) | ||
----- | ||
3) path to another changed file (relative to file processed) | ||
----- | ||
4) original content of another file (keep empty if file doesn't exist yet) | ||
----- | ||
5) expected content of another file | ||
``` | ||
|
||
Parts 3-5 can be multiplied in case there are more files created / updated. | ||
|
||
### Fixture examples | ||
Example #1: Rector is not changing processed PHP file, but changes corresponding template file (adds {varType} for each variable). | ||
``` | ||
<?php | ||
namespace Rector\Nette\Tests\Rector\Class_\LatteVarTypesBasedOnPresenterTemplateParametersRector\Fixture; | ||
use Nette\Application\UI\Presenter; | ||
class SomePresenter extends Presenter | ||
{ | ||
public function renderDefault(): void | ||
{ | ||
$this->template->title = 'My title'; | ||
$this->template->count = 123; | ||
} | ||
} | ||
?> | ||
----- | ||
----- | ||
templates/Some/default.latte | ||
----- | ||
<h1>{$title}</h1> | ||
<span class="count">{$count}</span> | ||
----- | ||
{varType string $title} | ||
{varType int $count} | ||
<h1>{$title}</h1> | ||
<span class="count">{$count}</span> | ||
``` | ||
|
||
Example #2: Rector creates Template class, uses it in processed PHP file, and also in corresponding template file (adds {templateType}). | ||
``` | ||
<?php | ||
namespace Rector\Nette\Tests\Rector\Class_\LatteVarTypesBasedOnPresenterTemplateParametersRector\Fixture; | ||
use Nette\Application\UI\Presenter; | ||
class SomePresenter extends Presenter | ||
{ | ||
public function renderDefault(): void | ||
{ | ||
$this->template->title = 'My title'; | ||
$this->template->count = 123; | ||
} | ||
} | ||
?> | ||
----- | ||
<?php | ||
namespace Rector\Nette\Tests\Rector\Class_\LatteVarTypesBasedOnPresenterTemplateParametersRector\Fixture; | ||
use Nette\Application\UI\Presenter; | ||
/** | ||
* @property-read SomeTemplate $template | ||
*/ | ||
class SomePresenter extends Presenter | ||
{ | ||
public function renderDefault(): void | ||
{ | ||
$this->template->title = 'My title'; | ||
$this->template->count = 123; | ||
} | ||
} | ||
?> | ||
----- | ||
SomeTemplate.php | ||
----- | ||
----- | ||
<?php | ||
namespace Rector\Nette\Tests\Rector\Class_\LatteVarTypesBasedOnPresenterTemplateParametersRector\Fixture; | ||
use Nette\Bridges\ApplicationLatte\Template; | ||
class SomeTemplate extends Template | ||
{ | ||
public string $title; | ||
public int $count; | ||
} | ||
----- | ||
templates/Some/default.latte | ||
----- | ||
<h1>{$title}</h1> | ||
<span class="count">{$count}</span> | ||
----- | ||
{templateType \Rector\Nette\Tests\Rector\Class_\LatteVarTypesBasedOnPresenterTemplateParametersRector\Fixture\SomeTemplate} | ||
<h1>{$title}</h1> | ||
<span class="count">{$count}</span> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
packages/Testing/PHPUnit/Behavior/MultipleFilesChangedTrait.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Testing\PHPUnit\Behavior; | ||
|
||
use Rector\Core\Exception\ShouldNotHappenException; | ||
use Symplify\SmartFileSystem\SmartFileInfo; | ||
|
||
trait MultipleFilesChangedTrait | ||
{ | ||
protected function doTestFileInfoWithAdditionalChanges( | ||
SmartFileInfo $fixtureFileInfo, | ||
bool $allowMatches = true | ||
): void { | ||
$separator = '-----'; | ||
[$originalContent, $expectedContent, $additionalInfo] = explode( | ||
$separator, | ||
$fixtureFileInfo->getContents(), | ||
3 | ||
); | ||
|
||
$additionalChanges = explode($separator, $additionalInfo); | ||
/** @var array<array{0: ?string, 1: ?string, 2: ?string}> $additionalFileChanges */ | ||
$additionalFileChanges = array_chunk($additionalChanges, 3); | ||
$expectedFileChanges = $this->prepareAdditionalChangedFiles($additionalFileChanges); | ||
|
||
$fixturePath = $this->getFixtureTempDirectory() . '/' . $fixtureFileInfo->getFilename(); | ||
$this->createFixtureDir($fixturePath); | ||
$fixtureContent = $originalContent; | ||
if (trim($expectedContent)) { | ||
$fixtureContent .= $separator . $expectedContent; | ||
} | ||
file_put_contents($fixturePath, $fixtureContent); | ||
$newFileInfo = new SmartFileInfo($fixturePath); | ||
$this->doTestFileInfo($newFileInfo, $allowMatches); | ||
|
||
$this->checkAdditionalChanges($expectedFileChanges); | ||
|
||
if (file_exists($fixturePath)) { | ||
unlink($fixturePath); | ||
} | ||
} | ||
|
||
/** | ||
* @param array<array{0: ?string, 1: ?string, 2: ?string}> $additionalFileChanges | ||
* @return array<string, string> | ||
*/ | ||
private function prepareAdditionalChangedFiles(array $additionalFileChanges): array | ||
{ | ||
$expectedFileChanges = []; | ||
foreach ($additionalFileChanges as $additionalFileChange) { | ||
$path = isset($additionalFileChange[0]) ? trim($additionalFileChange[0]) : null; | ||
if ($path === null) { | ||
throw new ShouldNotHappenException('Path for additional change must be set'); | ||
} | ||
$fullPath = $this->getFixtureTempDirectory() . '/' . $path; | ||
|
||
$input = isset($additionalFileChange[1]) ? trim($additionalFileChange[1]) : null; | ||
if ($input) { | ||
$this->createFixtureDir($fullPath); | ||
file_put_contents($fullPath, $input); | ||
} | ||
|
||
$expectedFileChanges[$fullPath] = isset($additionalFileChange[2]) ? trim($additionalFileChange[2]) : ''; | ||
} | ||
return $expectedFileChanges; | ||
} | ||
|
||
/** | ||
* @param array<string, string> $expectedFileChanges | ||
*/ | ||
private function checkAdditionalChanges(array $expectedFileChanges): void | ||
{ | ||
$addedFilesWithContent = $this->removedAndAddedFilesCollector->getAddedFilesWithContent(); | ||
$addedFiles = []; | ||
foreach ($addedFilesWithContent as $addedFileWithContent) { | ||
$addedFiles[$addedFileWithContent->getFilePath()] = $addedFileWithContent; | ||
} | ||
|
||
foreach ($expectedFileChanges as $path => $expectedFileChange) { | ||
$addedFile = $addedFiles[$path] ?? null; | ||
$this->assertSame($path, $addedFile ? $addedFile->getFilePath() : null); | ||
$realFileContent = $addedFile ? trim($addedFile->getFileContent()) : null; | ||
$this->assertSame($expectedFileChange, $realFileContent); | ||
if (file_exists($path)) { | ||
unlink($path); | ||
} | ||
} | ||
} | ||
|
||
private function createFixtureDir(string $fileName): void | ||
{ | ||
$dirName = dirname($fileName); | ||
if (! file_exists($dirName)) { | ||
mkdir($dirName, 0777, true); | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
tests/PhpUnit/MultipleFilesChangedTrait/Fixture/fixture.php.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Core\Tests\PhpUnit\MultipleFilesChangedTrait\Fixture; | ||
|
||
final class MyClassName | ||
{ | ||
|
||
} | ||
----- | ||
----- | ||
names.json | ||
----- | ||
----- | ||
{ | ||
"short": "MyClassName", | ||
"fqn": "Rector\\Core\\Tests\\PhpUnit\\MultipleFilesChangedTrait\\Fixture\\MyClassName" | ||
} |
33 changes: 33 additions & 0 deletions
33
tests/PhpUnit/MultipleFilesChangedTrait/MultipleFilesChangedTraitTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Core\Tests\PhpUnit\MultipleFilesChangedTrait; | ||
|
||
use Iterator; | ||
use Rector\Testing\PHPUnit\AbstractRectorTestCase; | ||
use Symplify\SmartFileSystem\SmartFileInfo; | ||
|
||
final class MultipleFilesChangedTraitTest extends AbstractRectorTestCase | ||
{ | ||
/** | ||
* @dataProvider provideData() | ||
*/ | ||
public function test(SmartFileInfo $smartFileInfo): void | ||
{ | ||
$this->doTestFileInfoWithAdditionalChanges($smartFileInfo); | ||
} | ||
|
||
/** | ||
* @return Iterator<SmartFileInfo> | ||
*/ | ||
public function provideData(): Iterator | ||
{ | ||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); | ||
} | ||
|
||
public function provideConfigFilePath(): string | ||
{ | ||
return __DIR__ . '/config/configured_rule.php'; | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
tests/PhpUnit/MultipleFilesChangedTrait/Rector/Class_/CreateJsonWithNamesForClassRector.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Core\Tests\PhpUnit\MultipleFilesChangedTrait\Rector\Class_; | ||
|
||
use Nette\Utils\Json; | ||
use PhpParser\Node; | ||
use PhpParser\Node\Stmt\Class_; | ||
use Rector\Core\Rector\AbstractRector; | ||
use Rector\FileSystemRector\ValueObject\AddedFileWithContent; | ||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; | ||
|
||
/** | ||
* @see \Rector\Core\Tests\PhpUnit\MultipleFilesChangedTrait\MultipleFilesChangedTraitTest | ||
*/ | ||
final class CreateJsonWithNamesForClassRector extends AbstractRector | ||
{ | ||
public function getRuleDefinition(): RuleDefinition | ||
{ | ||
return new RuleDefinition('Creates json with names for class', []); | ||
} | ||
|
||
public function getNodeTypes(): array | ||
{ | ||
return [Class_::class]; | ||
} | ||
|
||
/** | ||
* @param Class_ $node | ||
*/ | ||
public function refactor(Node $node) | ||
{ | ||
$smartFileInfo = $this->file->getSmartFileInfo(); | ||
$targetFilePath = $smartFileInfo->getRealPathDirectory() . '/names.json'; | ||
|
||
$content = Json::encode([ | ||
'short' => $this->nodeNameResolver->getShortName($node), | ||
'fqn' => $this->getName($node), | ||
], Json::PRETTY); | ||
|
||
$addedFileWithContent = new AddedFileWithContent($targetFilePath, $content); | ||
$this->removedAndAddedFilesCollector->addAddedFile($addedFileWithContent); | ||
return null; | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
tests/PhpUnit/MultipleFilesChangedTrait/config/configured_rule.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
use Rector\Core\Tests\PhpUnit\MultipleFilesChangedTrait\Rector\Class_\CreateJsonWithNamesForClassRector; | ||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; | ||
|
||
return static function (ContainerConfigurator $containerConfigurator): void { | ||
$services = $containerConfigurator->services(); | ||
$services->set(CreateJsonWithNamesForClassRector::class); | ||
}; |