Repository: humbug/php-scoper (php)

Issue:
Add Configuration::withPrefix() method
And potentially a "isAutogenerated()" -> we want to easily change it in Box

Pull request description:
Add Configuration::withPrefix()
Closes #616

Patch:
diff --git a/src/Autoload/ScoperAutoloadGenerator.php b/src/Autoload/ScoperAutoloadGenerator.php
index 27843d3..f4f13ad 100644
--- a/src/Autoload/ScoperAutoloadGenerator.php
+++ b/src/Autoload/ScoperAutoloadGenerator.php
@@ -31,16 +31,14 @@ final class ScoperAutoloadGenerator
 {
     // TODO: aliasing functions could be done via a single function to reduce boiler-template.
 
-    // TODO: doc link
     private const EXPOSED_FUNCTIONS_DOC = <<<'EOF'
     // Exposed functions. For more information see:
-    // https://github.com/humbug/php-scoper/blob/master/README.md#functions-whitelisting
+    // https://github.com/humbug/php-scoper/blob/master/docs/configuration.md#exposing-functions
     EOF;
 
-    // TODO: doc link
     private const EXPOSED_CLASSES_DOC = <<<'EOF'
     // Exposed classes. For more information see:
-    // https://github.com/humbug/php-scoper/blob/master/README.md#class-whitelisting
+    // https://github.com/humbug/php-scoper/blob/master/docs/configuration.md#exposing-classes
     EOF;
 
     private static string $eol;
diff --git a/src/Configuration/Configuration.php b/src/Configuration/Configuration.php
index 5a0c233..79177d6 100644
--- a/src/Configuration/Configuration.php
+++ b/src/Configuration/Configuration.php
@@ -74,6 +74,21 @@ final class Configuration
         return $this->path;
     }
 
+    /**
+     * @param non-empty-string $prefix
+     */
+    public function withPrefix(string $prefix): self
+    {
+        return new self(
+            $this->path,
+            $prefix,
+            $this->filesWithContents,
+            $this->excludedFilesWithContents,
+            $this->patcher,
+            $this->symbolsConfiguration,
+        );
+    }
+
     /**
      * @return non-empty-string
      */
diff --git a/src/PhpParser/Node/PrefixedName.php b/src/PhpParser/Node/PrefixedName.php
index 95ef210..8dd97af 100644
--- a/src/PhpParser/Node/PrefixedName.php
+++ b/src/PhpParser/Node/PrefixedName.php
@@ -16,6 +16,7 @@ namespace Humbug\PhpScoper\PhpParser\Node;
 
 use PhpParser\Node\Name\FullyQualified;
 
+// TODO:review
 final class PrefixedName extends FullyQualified
 {
     private FullyQualified $prefixedName;


Test patch:
diff --git a/tests/Autoload/ScoperAutoloadGeneratorTest.php b/tests/Autoload/ScoperAutoloadGeneratorTest.php
index 6537d35..81d4f24 100644
--- a/tests/Autoload/ScoperAutoloadGeneratorTest.php
+++ b/tests/Autoload/ScoperAutoloadGeneratorTest.php
@@ -64,7 +64,7 @@ class ScoperAutoloadGeneratorTest extends TestCase
             $loader = require_once __DIR__.'/autoload.php';
             
             // Exposed functions. For more information see:
-            // https://github.com/humbug/php-scoper/blob/master/README.md#functions-whitelisting
+            // https://github.com/humbug/php-scoper/blob/master/docs/configuration.md#exposing-functions
             if (!function_exists('foo')) {
                 function foo() {
                     return \Humbug\foo(...func_get_args());
@@ -100,7 +100,7 @@ class ScoperAutoloadGeneratorTest extends TestCase
             }
             
             // Exposed functions. For more information see:
-            // https://github.com/humbug/php-scoper/blob/master/README.md#functions-whitelisting
+            // https://github.com/humbug/php-scoper/blob/master/docs/configuration.md#exposing-functions
             namespace Acme {
                 if (!function_exists('Acme\foo')) {
                     function foo() {
@@ -145,7 +145,7 @@ class ScoperAutoloadGeneratorTest extends TestCase
             $loader = require_once __DIR__.'/autoload.php';
             
             // Exposed classes. For more information see:
-            // https://github.com/humbug/php-scoper/blob/master/README.md#class-whitelisting
+            // https://github.com/humbug/php-scoper/blob/master/docs/configuration.md#exposing-classes
             if (!class_exists('A\Foo', false) && !interface_exists('A\Foo', false) && !trait_exists('A\Foo', false)) {
                 spl_autoload_call('Humbug\A\Foo');
             }
@@ -171,7 +171,7 @@ class ScoperAutoloadGeneratorTest extends TestCase
             $loader = require_once __DIR__.'/autoload.php';
             
             // Exposed classes. For more information see:
-            // https://github.com/humbug/php-scoper/blob/master/README.md#class-whitelisting
+            // https://github.com/humbug/php-scoper/blob/master/docs/configuration.md#exposing-classes
             if (!class_exists('Foo', false) && !interface_exists('Foo', false) && !trait_exists('Foo', false)) {
                 spl_autoload_call('Humbug\Foo');
             }
@@ -207,7 +207,7 @@ class ScoperAutoloadGeneratorTest extends TestCase
             }
             
             // Exposed classes. For more information see:
-            // https://github.com/humbug/php-scoper/blob/master/README.md#class-whitelisting
+            // https://github.com/humbug/php-scoper/blob/master/docs/configuration.md#exposing-classes
             namespace {
                 if (!class_exists('A\Foo', false) && !interface_exists('A\Foo', false) && !trait_exists('A\Foo', false)) {
                     spl_autoload_call('Humbug\A\Foo');
@@ -215,7 +215,7 @@ class ScoperAutoloadGeneratorTest extends TestCase
             }
             
             // Exposed functions. For more information see:
-            // https://github.com/humbug/php-scoper/blob/master/README.md#functions-whitelisting
+            // https://github.com/humbug/php-scoper/blob/master/docs/configuration.md#exposing-functions
             namespace {
                 if (!function_exists('foo')) {
                     function foo() {
@@ -275,7 +275,7 @@ class ScoperAutoloadGeneratorTest extends TestCase
             $loader = require_once __DIR__.'/autoload.php';
             
             // Exposed functions. For more information see:
-            // https://github.com/humbug/php-scoper/blob/master/README.md#functions-whitelisting
+            // https://github.com/humbug/php-scoper/blob/master/docs/configuration.md#exposing-functions
             if (!function_exists('__autoload')) {
                 function __autoload($className) {
                     return \Humbug\__autoload(...func_get_args());
@@ -306,7 +306,7 @@ class ScoperAutoloadGeneratorTest extends TestCase
             }
             
             // Exposed functions. For more information see:
-            // https://github.com/humbug/php-scoper/blob/master/README.md#functions-whitelisting
+            // https://github.com/humbug/php-scoper/blob/master/docs/configuration.md#exposing-functions
             namespace {
                 if (!function_exists('__autoload')) {
                     function __autoload($className) {
diff --git a/tests/Configuration/ConfigurationTest.php b/tests/Configuration/ConfigurationTest.php
index 13061a3..f57f8e7 100644
--- a/tests/Configuration/ConfigurationTest.php
+++ b/tests/Configuration/ConfigurationTest.php
@@ -14,8 +14,9 @@ declare(strict_types=1);
 
 namespace Humbug\PhpScoper\Configuration;
 
+use Humbug\PhpScoper\Patcher\FakePatcher;
+use Humbug\PhpScoper\Patcher\Patcher;
 use Humbug\PhpScoper\Patcher\PatcherChain;
-use Humbug\PhpScoper\Whitelist;
 use InvalidArgumentException;
 use PHPUnit\Framework\TestCase;
 
@@ -42,12 +43,34 @@ final class ConfigurationTest extends TestCase
             [],
             new PatcherChain([]),
             SymbolsConfiguration::create(),
-            [],
-            [],
-            [],
         );
     }
 
+    public function test_it_can_create_a_new_instance_with_a_different_prefix(): void
+    {
+        $values = [
+            '/path/to/config',
+            'initialPrefix',
+            ['/path/to/fileA' => ['/path/to/fileA', 'fileAContent']],
+            ['/path/to/fileB' => ['/path/to/fileB', 'fileBContent']],
+            new FakePatcher(),
+            SymbolsConfiguration::create(),
+        ];
+
+        $config = new Configuration(...$values);
+
+        // Sanity check
+        self::assertStateIs($config, ...$values);
+
+        $newConfig = $config->withPrefix('newPrefix');
+
+        $expectedNewConfigValues = $values;
+        $expectedNewConfigValues[1] = 'newPrefix';
+
+        self::assertStateIs($config, ...$values);
+        self::assertStateIs($newConfig, ...$expectedNewConfigValues);
+    }
+
     public static function prefixProvider(): iterable
     {
         yield [
@@ -60,4 +83,30 @@ final class ConfigurationTest extends TestCase
             'Invalid namespace separator sequence. Got "App\\\\Foo"',
         ];
     }
+
+    private static function assertStateIs(
+        Configuration $configuration,
+        ?string $expectedPath,
+        string $expectedPrefix,
+        array $expectedFilesWithContents,
+        array $expectedExcludedFilesWithContents,
+        Patcher $expectedPatcher,
+        SymbolsConfiguration $expectedSymbolsConfiguration
+    ): void {
+        self::assertSame($expectedPath, $configuration->getPath());
+        self::assertSame($expectedPrefix, $configuration->getPrefix());
+        self::assertEqualsCanonicalizing(
+            $expectedFilesWithContents,
+            $configuration->getFilesWithContents(),
+        );
+        self::assertEqualsCanonicalizing(
+            $expectedExcludedFilesWithContents,
+            $configuration->getExcludedFilesWithContents(),
+        );
+        self::assertEquals($expectedPatcher, $configuration->getPatcher());
+        self::assertEquals(
+            $expectedSymbolsConfiguration,
+            $configuration->getSymbolsConfiguration(),
+        );
+    }
 }