diff --git a/CHANGELOG.md b/CHANGELOG.md index ad51581e7..26e90d13a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [unreleased] Unreleased +## Fixed + +- Fallback for missing `$_composer_autoload_path` file. (thanks @andronocean) + + ## [3.7.6] 2024-10-18; ### Changed diff --git a/src/Utils/Composer.php b/src/Utils/Composer.php index 337d7bbad..1d9ce5ac8 100644 --- a/src/Utils/Composer.php +++ b/src/Utils/Composer.php @@ -4,6 +4,7 @@ namespace lucatume\WPBrowser\Utils; +use Codeception\Codecept; use JsonException; use lucatume\WPBrowser\Adapters\Symfony\Component\Process\Process; use lucatume\WPBrowser\Exceptions\RuntimeException; @@ -33,8 +34,21 @@ public static function vendorDir(?string $path = null): string public static function autoloadPath(): string { + /** + * If `$_composer_autoload_path` is undefined, fall back to `vendor/autoload.php` + * in the parent project's directory. + * + * @link https://getcomposer.org/doc/articles/vendor-binaries.md#finding-the-composer-autoloader-from-a-binary + */ global $_composer_autoload_path; - return realpath($_composer_autoload_path) ?: $_composer_autoload_path; + if (isset($_composer_autoload_path)) { + $autoloadPath = $_composer_autoload_path; + } else { + // We use the Codecept class to find the location of Composer's vendor-dir. + $vendorDir = dirname((string)(new \ReflectionClass(Codecept::class))->getFilename(), 5); + $autoloadPath = $vendorDir . DIRECTORY_SEPARATOR . 'autoload.php'; + } + return realpath($autoloadPath) ?: $autoloadPath; } public static function binDir(?string $path = null): string diff --git a/tests/unit/lucatume/WPBrowser/Utils/ComposerTest.php b/tests/unit/lucatume/WPBrowser/Utils/ComposerTest.php index caae55f04..25e371599 100644 --- a/tests/unit/lucatume/WPBrowser/Utils/ComposerTest.php +++ b/tests/unit/lucatume/WPBrowser/Utils/ComposerTest.php @@ -228,4 +228,36 @@ public function should_build_on_the_project_composer_file_if_no_composer_file_sp $composer->getDecodedContents() ); } + + /** + * The `autoloadPath` static method should return `$_composer_autoload_path` if it is defined + * + * @test + * @backupGlobals enabled + */ + public function static_autoload_path_should_return_global_composer_autoload_path(): void + { + // Ensure that it's set for this test. + global $_composer_autoload_path; + $_composer_autoload_path = codecept_root_dir() . 'vendor/autoload.php'; + + $this->assertSame($_composer_autoload_path, Composer::autoloadPath() ); + } + + /** + * The `autoloadPath` static method should find the autoload.php file itself if the global `$_composer_autoload_path` is undefined + * + * @test + * @backupGlobals enabled + */ + public function static_autoload_path_should_use_fallback(): void + { + // clear value to enable fallback + unset($GLOBALS['_composer_autoload_path']); + + $autoloadPath = Composer::autoloadPath(); + + $this->assertSame(codecept_root_dir() . 'vendor/autoload.php', $autoloadPath ); + $this->assertFileExists( $autoloadPath ); + } }