From f663fc39a1acdbf84baa9ed98bb428c9374571cc Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 10 Jul 2026 18:03:24 +0700 Subject: [PATCH 1/2] Fix scoper to clean up prefix under getRuleDefinition() method --- scoper.php | 22 +++++ tests/Scoper/ScoperPatchersTest.php | 130 ++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 tests/Scoper/ScoperPatchersTest.php diff --git a/scoper.php b/scoper.php index e9af1de3cfe..d6da45ea9e7 100644 --- a/scoper.php +++ b/scoper.php @@ -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')) { diff --git a/tests/Scoper/ScoperPatchersTest.php b/tests/Scoper/ScoperPatchersTest.php new file mode 100644 index 00000000000..5b2494ac0d4 --- /dev/null +++ b/tests/Scoper/ScoperPatchersTest.php @@ -0,0 +1,130 @@ +provideScoperConfig(); + + $content = <<<'PHP' +__invoke( + __DIR__ . '/../../rules/Assert/Rector/ClassMethod/AddAssertArrayFromClassMethodDocblockRector.php', + 'RectorPrefix202607', + $content + ); + } + + $this->assertStringContainsString('use Webmozart\Assert\Assert;', $content); + $this->assertStringContainsString('use RectorPrefix202607\Webmozart\Assert\Assert;', $content); + $this->assertStringContainsString('\Webmozart\Assert\Assert::allString($items);', $content); + $this->assertStringContainsString("'SomeVendor\ValueObject::class'", $content); + $this->assertStringContainsString("'new SomeVendor\ValueObject()'", $content); + $this->assertStringContainsString('$metadata = \'Webmozart\Assert\Assert\';', $content); + $this->assertStringContainsString('\RectorPrefix202607\SomeVendor\Runtime::class;', $content); + $this->assertStringNotContainsString('namespace RectorPrefix202607;', $content); + } + + public function testRemovesPrefixedNamespaceInGetRuleDefinitionWithWindowsLineEndings(): void + { + $scoperConfig = $this->provideScoperConfig(); + + $content = str_replace( + "\n", + "\r\n", + <<<'PHP' +__invoke( + __DIR__ . '/../../rules/Some/Rector/SomeRector.php', + 'RectorPrefix202607', + $content + ); + } + + $this->assertStringNotContainsString('namespace RectorPrefix202607;', $content); + $this->assertStringContainsString('SomeVendor\ValueObject::class;', $content); + } + + /** + * @return array{patchers: list} + */ + private function provideScoperConfig(): array + { + if (! self::$isFinderAliased) { + class_alias(Finder::class, 'Isolated\Symfony\Component\Finder\Finder'); + self::$isFinderAliased = true; + } + + return require __DIR__ . '/../../scoper.php'; + } +} From a198215eabe448de31fe50a0d4fe6d76bba511da Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 10 Jul 2026 11:06:03 +0000 Subject: [PATCH 2/2] [ci-review] Rector Rectify --- tests/Scoper/ScoperPatchersTest.php | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/Scoper/ScoperPatchersTest.php b/tests/Scoper/ScoperPatchersTest.php index 5b2494ac0d4..860db4d4a63 100644 --- a/tests/Scoper/ScoperPatchersTest.php +++ b/tests/Scoper/ScoperPatchersTest.php @@ -4,6 +4,7 @@ namespace Rector\Tests\Scoper; +use Webmozart\Assert\Assert; use Closure; use PHPUnit\Framework\TestCase; use Symfony\Component\Finder\Finder; @@ -68,14 +69,14 @@ public function refactor(): void ); } - $this->assertStringContainsString('use Webmozart\Assert\Assert;', $content); - $this->assertStringContainsString('use RectorPrefix202607\Webmozart\Assert\Assert;', $content); - $this->assertStringContainsString('\Webmozart\Assert\Assert::allString($items);', $content); - $this->assertStringContainsString("'SomeVendor\ValueObject::class'", $content); - $this->assertStringContainsString("'new SomeVendor\ValueObject()'", $content); - $this->assertStringContainsString('$metadata = \'Webmozart\Assert\Assert\';', $content); - $this->assertStringContainsString('\RectorPrefix202607\SomeVendor\Runtime::class;', $content); - $this->assertStringNotContainsString('namespace 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 @@ -111,8 +112,8 @@ public function getRuleDefinition(): RuleDefinition ); } - $this->assertStringNotContainsString('namespace RectorPrefix202607;', $content); - $this->assertStringContainsString('SomeVendor\ValueObject::class;', $content); + $this->assertStringNotContainsString('namespace RectorPrefix202607;', (string) $content); + $this->assertStringContainsString('SomeVendor\ValueObject::class;', (string) $content); } /**