diff --git a/src/Roots/Acorn/Bootloader.php b/src/Roots/Acorn/Bootloader.php index 34d8764a..16dcfa48 100644 --- a/src/Roots/Acorn/Bootloader.php +++ b/src/Roots/Acorn/Bootloader.php @@ -26,6 +26,13 @@ class Bootloader */ protected $app; + /** + * Filesystem helper + * + * @var \Roots\Acorn\Filesystem\Filesystem + */ + protected $files; + /** * Base path for the application * @@ -61,9 +68,10 @@ public static function getInstance(ApplicationContract $app = null) /** * Create a new bootloader instance. */ - public function __construct(ApplicationContract $app = null) + public function __construct(ApplicationContract $app = null, Filesystem $files = null) { $this->app = $app; + $this->files = $files ?? new Filesystem; static::$instance ??= $this; } @@ -301,7 +309,7 @@ protected function basePath(): string is_dir($app_path = get_theme_file_path('app')) => dirname($app_path), - $vendor_path = (new Filesystem())->closest(dirname(__DIR__, 4), 'composer.json') => dirname($vendor_path), + is_file($vendor_path = $this->files->closest(dirname(__DIR__, 4), 'composer.json')) => dirname($vendor_path), default => dirname(__DIR__, 3) }; @@ -399,12 +407,11 @@ protected function fallbackPath(string $path): string */ protected function fallbackStoragePath() { - $files = new Filesystem(); $path = WP_CONTENT_DIR.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.'acorn'; - $files->ensureDirectoryExists($path.DIRECTORY_SEPARATOR.'framework'.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.'data', 0755, true); - $files->ensureDirectoryExists($path.DIRECTORY_SEPARATOR.'framework'.DIRECTORY_SEPARATOR.'views', 0755, true); - $files->ensureDirectoryExists($path.DIRECTORY_SEPARATOR.'framework'.DIRECTORY_SEPARATOR.'sessions', 0755, true); - $files->ensureDirectoryExists($path.DIRECTORY_SEPARATOR.'logs', 0755, true); + $this->files->ensureDirectoryExists($path.DIRECTORY_SEPARATOR.'framework'.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.'data', 0755, true); + $this->files->ensureDirectoryExists($path.DIRECTORY_SEPARATOR.'framework'.DIRECTORY_SEPARATOR.'views', 0755, true); + $this->files->ensureDirectoryExists($path.DIRECTORY_SEPARATOR.'framework'.DIRECTORY_SEPARATOR.'sessions', 0755, true); + $this->files->ensureDirectoryExists($path.DIRECTORY_SEPARATOR.'logs', 0755, true); return $path; } diff --git a/tests/Application/BootloaderTest.php b/tests/Application/BootloaderTest.php index 7133916d..e7ac06aa 100644 --- a/tests/Application/BootloaderTest.php +++ b/tests/Application/BootloaderTest.php @@ -3,8 +3,63 @@ use Roots\Acorn\Bootloader; use Roots\Acorn\Tests\Test\TestCase; +use function Roots\Acorn\Tests\mock; + uses(TestCase::class); +beforeEach(function () { + unset($_ENV['APP_BASE_PATH']); +}); + it('should get a new instance', function () { expect(Bootloader::getInstance())->toBeInstanceOf(Bootloader::class); }); + +it('should reuse the same instance', function () { + expect(Bootloader::getInstance())->toBe(Bootloader::getInstance()); +}); + +it('should get a new application instance', function () { + expect((new Bootloader)->getApplication())->toBeInstanceOf(\Illuminate\Contracts\Foundation\Application::class); +}); + +it('should set the basePath if env var is set', function () { + $_ENV['APP_BASE_PATH'] = $path = $this->fixture('base_path/base_empty'); + + $app = (new Bootloader)->getApplication(); + + expect($app->basePath())->toBe($path); +}); + +it('should set the basePath if composer.json exists in theme', function () { + $composer_path = $this->fixture('base_path/base_composer'); + + $this->stub('get_theme_file_path', fn ($path) => "{$composer_path}/{$path}"); + + $app = (new Bootloader)->getApplication(); + + expect($app->basePath())->toBe($composer_path); +}); + +it('should set the basePath if app exists in theme', function () { + $app_path = $this->fixture('base_path/base_app'); + $this->stub('get_theme_file_path', fn () => $app_path); + + $app = Bootloader::getInstance()->getApplication(); + + expect($app->basePath())->toBe(dirname($app_path)); +}); + +it('should set the basePath if composer.json exists as ancestor of ../../../', function () { + $files = mock(\Roots\Acorn\Filesystem\Filesystem::class); + $this->stub('get_theme_file_path', fn () => ''); + + $composer_path = $this->fixture('base_path/base_composer'); + + $files->shouldReceive('closest')->andReturn("{$composer_path}/composer.json"); + $files->shouldReceive('ensureDirectoryExists'); + + $app = (new Bootloader(null, $files))->getApplication(); + + expect($app->basePath())->toBe($composer_path); +}); diff --git a/tests/Application/__fixtures__/base_path/base_app/app/.gitignore b/tests/Application/__fixtures__/base_path/base_app/app/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/Application/__fixtures__/base_path/base_app/app/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Application/__fixtures__/base_path/base_composer/composer.json b/tests/Application/__fixtures__/base_path/base_composer/composer.json new file mode 100644 index 00000000..e69de29b diff --git a/tests/Application/__fixtures__/base_path/base_empty/.gitignore b/tests/Application/__fixtures__/base_path/base_empty/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/Application/__fixtures__/base_path/base_empty/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Application/__fixtures__/use_paths/composer.json b/tests/Application/__fixtures__/use_paths/composer.json new file mode 100644 index 00000000..e69de29b diff --git a/tests/Helpers.php b/tests/Helpers.php index 6ebb0962..d114e0cd 100644 --- a/tests/Helpers.php +++ b/tests/Helpers.php @@ -28,9 +28,7 @@ function temp(string $path = null) if (! $temp) { $temp = (new TemporaryDirectory())->create(); - register_shutdown_function(function () use ($temp) { - $temp->delete(); - }); + register_shutdown_function(fn () => $temp->delete()); } if ($path !== null) {