Skip to content
Merged
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
22 changes: 22 additions & 0 deletions scoper.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,28 @@ static function (string $filePath, string $prefix, string $content): string {
);
},

// keep public documentation examples readable
static function (string $filePath, string $prefix, string $content): string {
if (! \str_contains($filePath, 'rules/')) {
return $content;
}

if (! \str_ends_with($filePath, 'Rector.php')) {
return $content;
}

return Strings::replace(
$content,
'#(public function getRuleDefinition\(\): RuleDefinition\s+\{\R)(.*?)(\R \})#s',
static function (array $match) use ($prefix): string {
$body = str_replace($prefix . '\\', '', $match[2]);
$body = Strings::replace($body, '#^\s*namespace ' . preg_quote($prefix, '#') . ';\R\R?#m', '');

return $match[1] . $body . $match[3];
}
);
},

// un-prefix composer plugin
static function (string $filePath, string $prefix, string $content): string {
if (! \str_ends_with($filePath, 'vendor/rector/extension-installer/src/Plugin.php')) {
Expand Down
131 changes: 131 additions & 0 deletions tests/Scoper/ScoperPatchersTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Scoper;

use Webmozart\Assert\Assert;
use Closure;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Finder\Finder;

final class ScoperPatchersTest extends TestCase
{
private static bool $isFinderAliased = false;

public function testKeepsPrefixedClassesInGetRuleDefinitionUnprefixed(): void
{
$scoperConfig = $this->provideScoperConfig();

$content = <<<'PHP'
<?php

namespace Rector\Assert\Rector\ClassMethod;

use RectorPrefix202607\Webmozart\Assert\Assert;

final class AddAssertArrayFromClassMethodDocblockRector
{
public function getRuleDefinition(): RuleDefinition
{
$metadata = 'RectorPrefix202607\Webmozart\Assert\Assert';

new ConfiguredCodeSample(
<<<'CODE_SAMPLE'
<?php

namespace RectorPrefix202607;

use RectorPrefix202607\Webmozart\Assert\Assert;
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
<?php

\RectorPrefix202607\Webmozart\Assert\Assert::allString($items);
CODE_SAMPLE
,
[]
);

new CodeSample(
'RectorPrefix202607\SomeVendor\ValueObject::class',
'new RectorPrefix202607\SomeVendor\ValueObject()'
);
}

public function refactor(): void
{
\RectorPrefix202607\SomeVendor\Runtime::class;
}
}
PHP;

foreach ($scoperConfig['patchers'] as $patcher) {
$content = $patcher->__invoke(
__DIR__ . '/../../rules/Assert/Rector/ClassMethod/AddAssertArrayFromClassMethodDocblockRector.php',
'RectorPrefix202607',
$content
);
}

$this->assertStringContainsString('use Webmozart\Assert\Assert;', (string) $content);
$this->assertStringContainsString('use RectorPrefix202607\Webmozart\Assert\Assert;', (string) $content);
$this->assertStringContainsString(Assert::class . '::allString($items);', (string) $content);
$this->assertStringContainsString("'SomeVendor\ValueObject::class'", (string) $content);
$this->assertStringContainsString("'new SomeVendor\ValueObject()'", (string) $content);
$this->assertStringContainsString('$metadata = \'Webmozart\Assert\Assert\';', (string) $content);
$this->assertStringContainsString('\RectorPrefix202607\SomeVendor\Runtime::class;', (string) $content);
$this->assertStringNotContainsString('namespace RectorPrefix202607;', (string) $content);
}

public function testRemovesPrefixedNamespaceInGetRuleDefinitionWithWindowsLineEndings(): void
{
$scoperConfig = $this->provideScoperConfig();

$content = str_replace(
"\n",
"\r\n",
<<<'PHP'
<?php

final class SomeRector
{
public function getRuleDefinition(): RuleDefinition
{
return new CodeSample(
'<?php
namespace RectorPrefix202607;

RectorPrefix202607\SomeVendor\ValueObject::class;'
);
}
}
PHP
);

foreach ($scoperConfig['patchers'] as $patcher) {
$content = $patcher->__invoke(
__DIR__ . '/../../rules/Some/Rector/SomeRector.php',
'RectorPrefix202607',
$content
);
}

$this->assertStringNotContainsString('namespace RectorPrefix202607;', (string) $content);
$this->assertStringContainsString('SomeVendor\ValueObject::class;', (string) $content);
}

/**
* @return array{patchers: list<Closure(string, string, string): string>}
*/
private function provideScoperConfig(): array
{
if (! self::$isFinderAliased) {
class_alias(Finder::class, 'Isolated\Symfony\Component\Finder\Finder');
self::$isFinderAliased = true;
}

return require __DIR__ . '/../../scoper.php';
}
}
Loading