From 0ee857deca05705226b551c07766467be3955817 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 00:12:18 +0800 Subject: [PATCH 01/56] [6.x] Update `view.paths` configuration without waiting for `view` to be resolved via IoC (#229) * [6.x] Update `view.paths` configuration without waiting for `view` to be resolved via IoC Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki --- src/Workbench/Workbench.php | 44 ++++++++++--------- tests/Workbench/DiscoversTest.php | 9 ++++ .../resources/views/errors/418.blade.php | 1 + workbench/routes/web.php | 3 ++ 4 files changed, 36 insertions(+), 21 deletions(-) create mode 100644 workbench/resources/views/errors/418.blade.php diff --git a/src/Workbench/Workbench.php b/src/Workbench/Workbench.php index 84aae05c2..34df1e135 100644 --- a/src/Workbench/Workbench.php +++ b/src/Workbench/Workbench.php @@ -72,7 +72,7 @@ public static function discoverRoutes(ApplicationContract $app, ConfigContract $ tap($app->make('router'), static function (Router $router) use ($discoversConfig) { foreach (['web', 'api'] as $group) { if (($discoversConfig[$group] ?? false) === true) { - if (file_exists($route = workbench_path("routes/{$group}.php"))) { + if (file_exists($route = workbench_path('routes', "{$group}.php"))) { $router->middleware($group)->group($route); } } @@ -87,8 +87,8 @@ public static function discoverRoutes(ApplicationContract $app, ConfigContract $ after_resolving($app, 'translator', static function ($translator) { /** @var \Illuminate\Contracts\Translation\Loader $translator */ $path = Collection::make([ - workbench_path('/lang'), - workbench_path('/resources/lang'), + workbench_path('lang'), + workbench_path('resources', 'lang'), ])->filter(static function ($path) { return is_dir($path); })->first(); @@ -100,30 +100,32 @@ public static function discoverRoutes(ApplicationContract $app, ConfigContract $ $translator->addNamespace('workbench', $path); }); - after_resolving($app, 'view', static function ($view, $app) use ($discoversConfig) { - /** @var \Illuminate\Contracts\View\Factory|\Illuminate\View\Factory $view */ - if (! is_dir($path = workbench_path('/resources/views'))) { - return; - } - - if (($discoversConfig['views'] ?? false) === true && method_exists($view, 'addLocation')) { - $view->addLocation($path); - - tap($app->make('config'), function ($config) use ($path) { - /** @var \Illuminate\Contracts\Config\Repository $config */ - $config->set('view.paths', array_merge( - $config->get('view.paths', []), - [$path] - )); + if (is_dir($workbenchViewPath = workbench_path('resources', 'views'))) { + if (($discoversConfig['views'] ?? false) === true && is_dir($workbenchViewPath)) { + $app->booted(static function () use ($app, $workbenchViewPath) { + tap($app->make('config'), function ($config) use ($workbenchViewPath) { + /** @var \Illuminate\Contracts\Config\Repository $config */ + $config->set('view.paths', array_merge( + $config->get('view.paths', []), + [$workbenchViewPath] + )); + }); }); } - $view->addNamespace('workbench', $path); - }); + after_resolving($app, 'view', static function ($view, $app) use ($discoversConfig, $workbenchViewPath) { + /** @var \Illuminate\Contracts\View\Factory|\Illuminate\View\Factory $view */ + if (($discoversConfig['views'] ?? false) === true && method_exists($view, 'addLocation')) { + $view->addLocation($workbenchViewPath); + } + + $view->addNamespace('workbench', $workbenchViewPath); + }); + } after_resolving($app, 'blade.compiler', static function ($blade) use ($discoversConfig) { /** @var \Illuminate\View\Compilers\BladeCompiler $blade */ - if (($discoversConfig['components'] ?? false) === false && is_dir(workbench_path('/app/View/Components'))) { + if (($discoversConfig['components'] ?? false) === false && is_dir(workbench_path('app', 'View', 'Components'))) { $blade->componentNamespace('Workbench\\App\\View\\Components', 'workbench'); } }); diff --git a/tests/Workbench/DiscoversTest.php b/tests/Workbench/DiscoversTest.php index f7508fd57..fd64bd102 100644 --- a/tests/Workbench/DiscoversTest.php +++ b/tests/Workbench/DiscoversTest.php @@ -38,6 +38,15 @@ public function it_can_resolve_views_from_discovers() ->assertSee('Notification Component'); } + /** @test */ + public function it_can_resolve_errors_views_from_discovers() + { + $this->get('/root') + ->assertStatus(418) + ->assertSeeText('I\'m a teapot') + ->assertDontSeeText('412'); + } + /** @test */ public function it_can_resolve_route_name_from_discovers() { diff --git a/workbench/resources/views/errors/418.blade.php b/workbench/resources/views/errors/418.blade.php new file mode 100644 index 000000000..8fee9665b --- /dev/null +++ b/workbench/resources/views/errors/418.blade.php @@ -0,0 +1 @@ +I'm a teapot diff --git a/workbench/routes/web.php b/workbench/routes/web.php index 54f8fcd2e..3289daa50 100644 --- a/workbench/routes/web.php +++ b/workbench/routes/web.php @@ -19,3 +19,6 @@ Route::view('/testbench', 'workbench::testbench')->name('testbench'); Route::text('/hello-world', 'Hello world'); +Route::get('/root', function () { + abort(418); +}); From 9c1895db4117a642b62bc4e7cd1fce1e3a77dd9b Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 00:14:08 +0800 Subject: [PATCH 02/56] wip --- src/Workbench/Workbench.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Workbench/Workbench.php b/src/Workbench/Workbench.php index 34df1e135..b5d32b7f9 100644 --- a/src/Workbench/Workbench.php +++ b/src/Workbench/Workbench.php @@ -101,7 +101,7 @@ public static function discoverRoutes(ApplicationContract $app, ConfigContract $ }); if (is_dir($workbenchViewPath = workbench_path('resources', 'views'))) { - if (($discoversConfig['views'] ?? false) === true && is_dir($workbenchViewPath)) { + if (($discoversConfig['views'] ?? false) === true) { $app->booted(static function () use ($app, $workbenchViewPath) { tap($app->make('config'), function ($config) use ($workbenchViewPath) { /** @var \Illuminate\Contracts\Config\Repository $config */ From 29a61845077867f10521743a63bb4d5dcd3701d0 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 06:41:05 +0800 Subject: [PATCH 03/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Attributes/UsesVendor.php | 4 +- .../Bootstrap/CreateVendorSymlink.php | 31 +++++++++--- .../Bootstrap/CreateVendorSymlinkTest.php | 47 +++++++++++++++++++ 3 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php diff --git a/src/Attributes/UsesVendor.php b/src/Attributes/UsesVendor.php index ea24bc5da..ac12a3e8f 100644 --- a/src/Attributes/UsesVendor.php +++ b/src/Attributes/UsesVendor.php @@ -6,7 +6,7 @@ use Orchestra\Testbench\Contracts\Attributes\AfterEach as AfterEachContract; use Orchestra\Testbench\Contracts\Attributes\BeforeEach as BeforeEachContract; use Orchestra\Testbench\Foundation\Application; - +use Orchestra\Testbench\Foundation\Env; use function Orchestra\Testbench\package_path; #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)] @@ -29,7 +29,7 @@ public function beforeEach($app): void $laravel = Application::createVendorSymlink(base_path(), package_path('vendor')); - $this->vendorSymlinkCreated = $laravel['TESTBENCH_VENDOR_SYMLINK'] ?? false; + $this->vendorSymlinkCreated = Env::get('TESTBENCH_VENDOR_SYMLINK', false); } /** diff --git a/src/Foundation/Bootstrap/CreateVendorSymlink.php b/src/Foundation/Bootstrap/CreateVendorSymlink.php index 3ebcb5d49..26a572b83 100644 --- a/src/Foundation/Bootstrap/CreateVendorSymlink.php +++ b/src/Foundation/Bootstrap/CreateVendorSymlink.php @@ -5,7 +5,7 @@ use ErrorException; use Illuminate\Contracts\Foundation\Application; use Illuminate\Filesystem\Filesystem; - +use Orchestra\Testbench\Foundation\Env; use function Orchestra\Testbench\join_paths; /** @@ -42,10 +42,9 @@ public function bootstrap(Application $app): void $appVendorPath = $app->basePath('vendor'); - if ( - ! $filesystem->isFile(join_paths($appVendorPath, 'autoload.php')) || - $filesystem->hash(join_paths($appVendorPath, 'autoload.php')) !== $filesystem->hash(join_paths($this->workingPath, 'autoload.php')) - ) { + $vendorLinkCreated = false; + + if (! $this->vendorSymlinkExists($app)) { if ($filesystem->exists($app->bootstrapPath(join_paths('cache', 'packages.php')))) { $filesystem->delete($app->bootstrapPath(join_paths('cache', 'packages.php'))); } @@ -57,12 +56,30 @@ public function bootstrap(Application $app): void try { $filesystem->link($this->workingPath, $appVendorPath); - $app->instance('TESTBENCH_VENDOR_SYMLINK', true); + $vendorLinkCreated = true; } catch (ErrorException $e) { - $app->instance('TESTBENCH_VENDOR_SYMLINK', false); + // } } $app->flush(); + + $app->instance('TESTBENCH_VENDOR_SYMLINK', $vendorLinkCreated); + } + + /** + * Determine if vendor symlink exists on the skeleton. + * + * @param \Illuminate\Contracts\Foundation\Application $app + * @return bool + */ + public function vendorSymlinkExists(Application $app): bool + { + $filesystem = new Filesystem; + + $appVendorPath = $app->basePath('vendor'); + + return $filesystem->isFile(join_paths($appVendorPath, 'autoload.php')) && + $filesystem->hash(join_paths($appVendorPath, 'autoload.php')) === $filesystem->hash(join_paths($this->workingPath, 'autoload.php')); } } diff --git a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php new file mode 100644 index 000000000..07025ecb0 --- /dev/null +++ b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -0,0 +1,47 @@ +createApplication(); + + if ($stub->vendorSymlinkExists($laravel)) { + $filesystem->delete($laravel->basePath('vendor')); + } + + $stub->bootstrap($laravel); + + $this->assertTrue($laravel['TESTBENCH_VENDOR_SYMLINK']); + } + + /** @test */ + #[UsesVendor] + public function it_can_skip_existing_vendor_symlink() + { + $laravel = container()->createApplication(); + + (new CreateVendorSymlink(package_path('vendor')))->bootstrap($laravel); + + $this->assertFalse($laravel['TESTBENCH_VENDOR_SYMLINK']); + } +} From 6003bf31cea26891bc4f340fde33e2e350d28bdf Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 06:42:34 +0800 Subject: [PATCH 04/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Attributes/UsesVendor.php | 4 ++-- src/Foundation/Bootstrap/CreateVendorSymlink.php | 2 +- tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Attributes/UsesVendor.php b/src/Attributes/UsesVendor.php index ac12a3e8f..ea24bc5da 100644 --- a/src/Attributes/UsesVendor.php +++ b/src/Attributes/UsesVendor.php @@ -6,7 +6,7 @@ use Orchestra\Testbench\Contracts\Attributes\AfterEach as AfterEachContract; use Orchestra\Testbench\Contracts\Attributes\BeforeEach as BeforeEachContract; use Orchestra\Testbench\Foundation\Application; -use Orchestra\Testbench\Foundation\Env; + use function Orchestra\Testbench\package_path; #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)] @@ -29,7 +29,7 @@ public function beforeEach($app): void $laravel = Application::createVendorSymlink(base_path(), package_path('vendor')); - $this->vendorSymlinkCreated = Env::get('TESTBENCH_VENDOR_SYMLINK', false); + $this->vendorSymlinkCreated = $laravel['TESTBENCH_VENDOR_SYMLINK'] ?? false; } /** diff --git a/src/Foundation/Bootstrap/CreateVendorSymlink.php b/src/Foundation/Bootstrap/CreateVendorSymlink.php index 26a572b83..bae520344 100644 --- a/src/Foundation/Bootstrap/CreateVendorSymlink.php +++ b/src/Foundation/Bootstrap/CreateVendorSymlink.php @@ -5,7 +5,7 @@ use ErrorException; use Illuminate\Contracts\Foundation\Application; use Illuminate\Filesystem\Filesystem; -use Orchestra\Testbench\Foundation\Env; + use function Orchestra\Testbench\join_paths; /** diff --git a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php index 07025ecb0..b936bef6f 100644 --- a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php +++ b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -5,7 +5,6 @@ use Illuminate\Filesystem\Filesystem; use Orchestra\Testbench\Attributes\UsesVendor; use Orchestra\Testbench\Foundation\Bootstrap\CreateVendorSymlink; -use Orchestra\Testbench\Foundation\Env; use Orchestra\Testbench\TestCase; use function Orchestra\Testbench\container; From 2be27452f34bf9d8311fdbcfc38d7ccbdc124d8f Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 06:52:31 +0800 Subject: [PATCH 05/56] wip Signed-off-by: Mior Muhammad Zaki --- .../Bootstrap/CreateVendorSymlink.php | 19 ++----------------- src/functions.php | 19 +++++++++++++++++++ .../Bootstrap/CreateVendorSymlinkTest.php | 11 +++++------ 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/Foundation/Bootstrap/CreateVendorSymlink.php b/src/Foundation/Bootstrap/CreateVendorSymlink.php index bae520344..5b66e06c0 100644 --- a/src/Foundation/Bootstrap/CreateVendorSymlink.php +++ b/src/Foundation/Bootstrap/CreateVendorSymlink.php @@ -7,6 +7,7 @@ use Illuminate\Filesystem\Filesystem; use function Orchestra\Testbench\join_paths; +use function Orchestra\Testbench\laravel_vendor_exists; /** * @internal @@ -44,7 +45,7 @@ public function bootstrap(Application $app): void $vendorLinkCreated = false; - if (! $this->vendorSymlinkExists($app)) { + if (! laravel_vendor_exists($app, $this->workingPath)) { if ($filesystem->exists($app->bootstrapPath(join_paths('cache', 'packages.php')))) { $filesystem->delete($app->bootstrapPath(join_paths('cache', 'packages.php'))); } @@ -66,20 +67,4 @@ public function bootstrap(Application $app): void $app->instance('TESTBENCH_VENDOR_SYMLINK', $vendorLinkCreated); } - - /** - * Determine if vendor symlink exists on the skeleton. - * - * @param \Illuminate\Contracts\Foundation\Application $app - * @return bool - */ - public function vendorSymlinkExists(Application $app): bool - { - $filesystem = new Filesystem; - - $appVendorPath = $app->basePath('vendor'); - - return $filesystem->isFile(join_paths($appVendorPath, 'autoload.php')) && - $filesystem->hash(join_paths($appVendorPath, 'autoload.php')) === $filesystem->hash(join_paths($this->workingPath, 'autoload.php')); - } } diff --git a/src/functions.php b/src/functions.php index aa34a4bf8..b78eccea1 100644 --- a/src/functions.php +++ b/src/functions.php @@ -5,6 +5,7 @@ use Closure; use Illuminate\Contracts\Console\Kernel as ConsoleKernel; use Illuminate\Contracts\Foundation\Application as ApplicationContract; +use Illuminate\Filesystem\Filesystem; use Illuminate\Foundation\Application; use Illuminate\Routing\Router; use Illuminate\Support\Arr; @@ -329,6 +330,24 @@ function laravel_migration_path(?string $type = null): string return $path; } +/** + * Determine if vendor symlink exists on the laravel application. + * + * @param \Illuminate\Contracts\Foundation\Application $app + * @param string|null $workingPath + * @return bool + */ +function laravel_vendor_exists(ApplicationContract $app, ?string $workingPath = null): bool +{ + $filesystem = new Filesystem; + + $appVendorPath = $app->basePath('vendor'); + $workingPath ??= package_path('vendor'); + + return $filesystem->isFile(join_paths($appVendorPath, 'autoload.php')) && + $filesystem->hash(join_paths($appVendorPath, 'autoload.php')) === $filesystem->hash(join_paths($workingPath, 'autoload.php')); +} + /** * Laravel version compare. * diff --git a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php index b936bef6f..eecdda825 100644 --- a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php +++ b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -8,6 +8,7 @@ use Orchestra\Testbench\TestCase; use function Orchestra\Testbench\container; +use function Orchestra\Testbench\laravel_vendor_exists; use function Orchestra\Testbench\package_path; /** @@ -18,17 +19,15 @@ class CreateVendorSymlinkTest extends TestCase /** @test */ public function it_can_create_vendor_symlink() { - $filesystem = new Filesystem; - - $stub = (new CreateVendorSymlink(package_path('vendor'))); + $workingPath = package_path('vendor'); $laravel = container()->createApplication(); - if ($stub->vendorSymlinkExists($laravel)) { - $filesystem->delete($laravel->basePath('vendor')); + if (laravel_vendor_exists($laravel, $workingPath)) { + (new Filesystem)->delete($laravel->basePath('vendor')); } - $stub->bootstrap($laravel); + (new CreateVendorSymlink($workingPath))->bootstrap($laravel); $this->assertTrue($laravel['TESTBENCH_VENDOR_SYMLINK']); } From 45535a49a546ec7dec33d6594f687c1a2b5fe16c Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 06:52:39 +0800 Subject: [PATCH 06/56] wip Signed-off-by: Mior Muhammad Zaki --- tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php index eecdda825..375f1d8b9 100644 --- a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php +++ b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -27,7 +27,7 @@ public function it_can_create_vendor_symlink() (new Filesystem)->delete($laravel->basePath('vendor')); } - (new CreateVendorSymlink($workingPath))->bootstrap($laravel); + (new CreateVendorSymlink($workingPath))->bootstrap($laravel); $this->assertTrue($laravel['TESTBENCH_VENDOR_SYMLINK']); } From 5222c87534784d81654f8bc74c014a5df8fb133e Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 06:53:03 +0800 Subject: [PATCH 07/56] wip Signed-off-by: Mior Muhammad Zaki --- tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php index 375f1d8b9..cd83ce470 100644 --- a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php +++ b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -11,9 +11,6 @@ use function Orchestra\Testbench\laravel_vendor_exists; use function Orchestra\Testbench\package_path; -/** - * @requires OS Linux|DAR - */ class CreateVendorSymlinkTest extends TestCase { /** @test */ From 59c6bbe1ed1b3f38b1e983201b4fb2513be8dc2c Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 07:08:55 +0800 Subject: [PATCH 08/56] wip Signed-off-by: Mior Muhammad Zaki --- .../Bootstrap/CreateVendorSymlink.php | 13 +++-- src/functions.php | 21 +++++++++ .../Bootstrap/CreateVendorSymlinkTest.php | 47 +++++++++++++++++++ 3 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php diff --git a/src/Foundation/Bootstrap/CreateVendorSymlink.php b/src/Foundation/Bootstrap/CreateVendorSymlink.php index 54434e3d6..fc8cb9d34 100644 --- a/src/Foundation/Bootstrap/CreateVendorSymlink.php +++ b/src/Foundation/Bootstrap/CreateVendorSymlink.php @@ -6,6 +6,8 @@ use Illuminate\Contracts\Foundation\Application; use Illuminate\Filesystem\Filesystem; +use function Orchestra\Testbench\laravel_vendor_exists; + /** * @internal */ @@ -40,10 +42,9 @@ public function bootstrap(Application $app): void $appVendorPath = $app->basePath('vendor'); - if ( - ! $filesystem->isFile("{$appVendorPath}/autoload.php") || - $filesystem->hash("{$appVendorPath}/autoload.php") !== $filesystem->hash("{$this->workingPath}/autoload.php") - ) { + $vendorLinkCreated = false; + + if (! laravel_vendor_exists($app, $this->workingPath)) { if ($filesystem->exists($app->basePath('bootstrap/cache/packages.php'))) { $filesystem->delete($app->basePath('bootstrap/cache/packages.php')); } @@ -54,11 +55,15 @@ public function bootstrap(Application $app): void try { $filesystem->link($this->workingPath, $appVendorPath); + + $vendorLinkCreated = true; } catch (ErrorException $e) { // } } $app->flush(); + + $app->instance('TESTBENCH_VENDOR_SYMLINK', $vendorLinkCreated); } } diff --git a/src/functions.php b/src/functions.php index 90c2e88fb..1045fcd3d 100644 --- a/src/functions.php +++ b/src/functions.php @@ -5,6 +5,7 @@ use Closure; use Illuminate\Contracts\Console\Kernel as ConsoleKernel; use Illuminate\Contracts\Foundation\Application as ApplicationContract; +use Illuminate\Filesystem\Filesystem; use Illuminate\Foundation\Application; use Illuminate\Routing\Router; use Illuminate\Support\Arr; @@ -332,6 +333,26 @@ function laravel_migration_path(?string $type = null): string return $path; } +/** + * Determine if vendor symlink exists on the laravel application. + * + * @api + * + * @param \Illuminate\Contracts\Foundation\Application $app + * @param string|null $workingPath + * @return bool + */ +function laravel_vendor_exists(ApplicationContract $app, ?string $workingPath = null): bool +{ + $filesystem = new Filesystem; + + $appVendorPath = $app->basePath('vendor'); + $workingPath = $workingPath ?? package_path('vendor'); + + return $filesystem->isFile(join_paths($appVendorPath, 'autoload.php')) && + $filesystem->hash(join_paths($appVendorPath, 'autoload.php')) === $filesystem->hash(join_paths($workingPath, 'autoload.php')); +} + /** * Laravel version compare. * diff --git a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php new file mode 100644 index 000000000..8c45ee43d --- /dev/null +++ b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -0,0 +1,47 @@ +createApplication(); + + if (laravel_vendor_exists($laravel, $workingPath)) { + (new Filesystem)->delete($laravel->basePath('vendor')); + } + + (new CreateVendorSymlink($workingPath))->bootstrap($laravel); + + $this->assertTrue($laravel['TESTBENCH_VENDOR_SYMLINK']); + } + + /** @test */ + public function it_can_skip_existing_vendor_symlink() + { + $workingPath = package_path('vendor'); + + $laravel = container()->createApplication(); + + if (! laravel_vendor_exists($laravel, $workingPath)) { + (new Filesystem)->link($workingPath, $laravel->basePath('vendor')); + } + + (new CreateVendorSymlink($workingPath))->bootstrap($laravel); + + $this->assertFalse($laravel['TESTBENCH_VENDOR_SYMLINK']); + } +} From 70b564772a02e9a7ba781db7d0f96e0c8fbca98b Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 07:10:38 +0800 Subject: [PATCH 09/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Foundation/Bootstrap/CreateVendorSymlink.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Foundation/Bootstrap/CreateVendorSymlink.php b/src/Foundation/Bootstrap/CreateVendorSymlink.php index fc8cb9d34..917f5c9f1 100644 --- a/src/Foundation/Bootstrap/CreateVendorSymlink.php +++ b/src/Foundation/Bootstrap/CreateVendorSymlink.php @@ -6,6 +6,7 @@ use Illuminate\Contracts\Foundation\Application; use Illuminate\Filesystem\Filesystem; +use function Orchestra\Testbench\join_paths; use function Orchestra\Testbench\laravel_vendor_exists; /** @@ -45,8 +46,8 @@ public function bootstrap(Application $app): void $vendorLinkCreated = false; if (! laravel_vendor_exists($app, $this->workingPath)) { - if ($filesystem->exists($app->basePath('bootstrap/cache/packages.php'))) { - $filesystem->delete($app->basePath('bootstrap/cache/packages.php')); + if ($filesystem->exists($app->basePath(join_paths('bootstrap', 'cache', 'packages.php')))) { + $filesystem->delete($app->basePath(join_paths('bootstrap', 'cache', 'packages.php'))); } if (is_link($appVendorPath)) { From 6d4023de0ea68d4d6e0572e185527a81a19e34b2 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 07:25:16 +0800 Subject: [PATCH 10/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Foundation/Bootstrap/CreateVendorSymlink.php | 6 +++++- tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Foundation/Bootstrap/CreateVendorSymlink.php b/src/Foundation/Bootstrap/CreateVendorSymlink.php index 917f5c9f1..aaf9f50d9 100644 --- a/src/Foundation/Bootstrap/CreateVendorSymlink.php +++ b/src/Foundation/Bootstrap/CreateVendorSymlink.php @@ -51,7 +51,11 @@ public function bootstrap(Application $app): void } if (is_link($appVendorPath)) { - $filesystem->delete($appVendorPath); + if (windows_os()) { + rmdir($appVendorPath); + } else { + unlink($appVendorPath); + } } try { diff --git a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php index 8c45ee43d..5b6fbd6fb 100644 --- a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php +++ b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -21,7 +21,11 @@ public function it_can_create_vendor_symlink() $laravel = container()->createApplication(); if (laravel_vendor_exists($laravel, $workingPath)) { - (new Filesystem)->delete($laravel->basePath('vendor')); + if (windows_os()) { + rmdir($laravel->basePath('vendor')); + } else { + unlink($laravel->basePath('vendor')); + } } (new CreateVendorSymlink($workingPath))->bootstrap($laravel); From 755b725a1a1f097e2b9b818304afe0fa72758b03 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 07:30:37 +0800 Subject: [PATCH 11/56] wip Signed-off-by: Mior Muhammad Zaki --- .../Bootstrap/CreateVendorSymlink.php | 23 +++++++++++++------ .../Bootstrap/CreateVendorSymlinkTest.php | 10 ++++---- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/Foundation/Bootstrap/CreateVendorSymlink.php b/src/Foundation/Bootstrap/CreateVendorSymlink.php index aaf9f50d9..6d18a3470 100644 --- a/src/Foundation/Bootstrap/CreateVendorSymlink.php +++ b/src/Foundation/Bootstrap/CreateVendorSymlink.php @@ -50,13 +50,7 @@ public function bootstrap(Application $app): void $filesystem->delete($app->basePath(join_paths('bootstrap', 'cache', 'packages.php'))); } - if (is_link($appVendorPath)) { - if (windows_os()) { - rmdir($appVendorPath); - } else { - unlink($appVendorPath); - } - } + $this->deleteVendorSymlink($app); try { $filesystem->link($this->workingPath, $appVendorPath); @@ -71,4 +65,19 @@ public function bootstrap(Application $app): void $app->instance('TESTBENCH_VENDOR_SYMLINK', $vendorLinkCreated); } + + public function deleteVendorSymlink(Application $app): void + { + tap($app->basePath('vendor'), static function ($appVendorPath) use ($app) { + if (is_link($appVendorPath)) { + if (windows_os()) { + @rmdir($appVendorPath); + } else { + @unlink($appVendorPath); + } + + clearstatcache(false, $app->basePath()); + } + }); + } } diff --git a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php index 5b6fbd6fb..43c945321 100644 --- a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php +++ b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -20,15 +20,13 @@ public function it_can_create_vendor_symlink() $laravel = container()->createApplication(); + $stub = (new CreateVendorSymlink($workingPath)); + if (laravel_vendor_exists($laravel, $workingPath)) { - if (windows_os()) { - rmdir($laravel->basePath('vendor')); - } else { - unlink($laravel->basePath('vendor')); - } + $stub->deleteVendorSymlink($laravel); } - (new CreateVendorSymlink($workingPath))->bootstrap($laravel); + $stub->bootstrap($laravel); $this->assertTrue($laravel['TESTBENCH_VENDOR_SYMLINK']); } From ee57aef25d8b2c4b2b78c6d85d4c92ae0665d7d1 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 07:34:06 +0800 Subject: [PATCH 12/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Foundation/Bootstrap/CreateVendorSymlink.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Foundation/Bootstrap/CreateVendorSymlink.php b/src/Foundation/Bootstrap/CreateVendorSymlink.php index 6d18a3470..bbf77269e 100644 --- a/src/Foundation/Bootstrap/CreateVendorSymlink.php +++ b/src/Foundation/Bootstrap/CreateVendorSymlink.php @@ -69,15 +69,13 @@ public function bootstrap(Application $app): void public function deleteVendorSymlink(Application $app): void { tap($app->basePath('vendor'), static function ($appVendorPath) use ($app) { - if (is_link($appVendorPath)) { - if (windows_os()) { - @rmdir($appVendorPath); - } else { - @unlink($appVendorPath); - } - - clearstatcache(false, $app->basePath()); + if (windows_os()) { + @rmdir($appVendorPath); + } elseif (is_link($appVendorPath)) { + @unlink($appVendorPath); } }); + + clearstatcache(false, $app->basePath()); } } From 561e7b250c3c5d0708e62508d011acc0b9a4683a Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 07:35:49 +0800 Subject: [PATCH 13/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Foundation/Bootstrap/CreateVendorSymlink.php | 5 +++-- tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Foundation/Bootstrap/CreateVendorSymlink.php b/src/Foundation/Bootstrap/CreateVendorSymlink.php index bbf77269e..3d65b8ad9 100644 --- a/src/Foundation/Bootstrap/CreateVendorSymlink.php +++ b/src/Foundation/Bootstrap/CreateVendorSymlink.php @@ -68,14 +68,15 @@ public function bootstrap(Application $app): void public function deleteVendorSymlink(Application $app): void { - tap($app->basePath('vendor'), static function ($appVendorPath) use ($app) { + tap($app->basePath('vendor'), static function ($appVendorPath) { if (windows_os()) { @rmdir($appVendorPath); } elseif (is_link($appVendorPath)) { @unlink($appVendorPath); } + + clearstatcache(false, \dirname($appVendorPath)); }); - clearstatcache(false, $app->basePath()); } } diff --git a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php index 43c945321..7a0ab45f9 100644 --- a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php +++ b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -3,7 +3,6 @@ namespace Orchestra\Testbench\Tests\Foundation\Bootstrap; use Illuminate\Filesystem\Filesystem; -use Orchestra\Testbench\Attributes\UsesVendor; use Orchestra\Testbench\Foundation\Bootstrap\CreateVendorSymlink; use Orchestra\Testbench\TestCase; From 764ae21c54f004e1fee8ec7adbb4de5f9e82e1c9 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 10:51:11 +0800 Subject: [PATCH 14/56] [6.x] Improves vendor symlink on Windows (#230) * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki --- src/Foundation/Bootstrap/CreateVendorSymlink.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Foundation/Bootstrap/CreateVendorSymlink.php b/src/Foundation/Bootstrap/CreateVendorSymlink.php index 3d65b8ad9..635d337de 100644 --- a/src/Foundation/Bootstrap/CreateVendorSymlink.php +++ b/src/Foundation/Bootstrap/CreateVendorSymlink.php @@ -66,10 +66,16 @@ public function bootstrap(Application $app): void $app->instance('TESTBENCH_VENDOR_SYMLINK', $vendorLinkCreated); } + /** + * Safely remove symlink for Unix & Windows environment. + * + * @param \Illuminate\Contracts\Foundation\Application $app + * @return void + */ public function deleteVendorSymlink(Application $app): void { tap($app->basePath('vendor'), static function ($appVendorPath) { - if (windows_os()) { + if (windows_os() && is_dir($appVendorPath) && readlink($appVendorPath) !== $appVendorPath) { @rmdir($appVendorPath); } elseif (is_link($appVendorPath)) { @unlink($appVendorPath); From c5b3764292debafcef170d6e8b7e56016e138b3c Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 28 Aug 2024 10:58:35 +0800 Subject: [PATCH 15/56] wip Signed-off-by: Mior Muhammad Zaki --- tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php index 43c945321..7a0ab45f9 100644 --- a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php +++ b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -3,7 +3,6 @@ namespace Orchestra\Testbench\Tests\Foundation\Bootstrap; use Illuminate\Filesystem\Filesystem; -use Orchestra\Testbench\Attributes\UsesVendor; use Orchestra\Testbench\Foundation\Bootstrap\CreateVendorSymlink; use Orchestra\Testbench\TestCase; From 993cea1b2ca5539fbb3b0476c46016fa09c9f3b7 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 2 Sep 2024 12:25:48 +0800 Subject: [PATCH 16/56] [6.x] Add `Orchestra\Testbench\default_migration_path()` Signed-off-by: Mior Muhammad Zaki --- src/Attributes/WithMigration.php | 4 +- src/Concerns/InteractsWithMigrations.php | 4 +- src/Concerns/WithLaravelMigrations.php | 6 +-- .../Bootstrap/LoadMigrationsFromArray.php | 6 +-- src/functions.php | 37 +++++++++++++------ 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/Attributes/WithMigration.php b/src/Attributes/WithMigration.php index 9ece9468b..156ee6ec1 100644 --- a/src/Attributes/WithMigration.php +++ b/src/Attributes/WithMigration.php @@ -6,7 +6,7 @@ use Illuminate\Support\Collection; use Orchestra\Testbench\Contracts\Attributes\Invokable as InvokableContract; -use function Orchestra\Testbench\laravel_migration_path; +use function Orchestra\Testbench\default_migration_path; use function Orchestra\Testbench\load_migration_paths; #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] @@ -37,7 +37,7 @@ public function __invoke($app): void /** @var array $types */ $types = Collection::make($this->types) ->transform(static function ($type) { - return laravel_migration_path($type !== 'laravel' ? $type : null); + return default_migration_path($type !== 'laravel' ? $type : null); })->all(); load_migration_paths($app, $types); diff --git a/src/Concerns/InteractsWithMigrations.php b/src/Concerns/InteractsWithMigrations.php index 7d80a1971..6a0a52b56 100644 --- a/src/Concerns/InteractsWithMigrations.php +++ b/src/Concerns/InteractsWithMigrations.php @@ -9,7 +9,7 @@ use Orchestra\Testbench\Attributes\ResetRefreshDatabaseState; use Orchestra\Testbench\Database\MigrateProcessor; -use function Orchestra\Testbench\laravel_migration_path; +use function Orchestra\Testbench\default_migration_path; use function Orchestra\Testbench\load_migration_paths; /** @@ -124,7 +124,7 @@ protected function loadLaravelMigrations($database = []): void protected function loadLaravelMigrationsWithoutRollback($database = []): void { $options = $this->resolveLaravelMigrationsOptions($database); - $options['--path'] = laravel_migration_path(); + $options['--path'] = default_migration_path(); $options['--realpath'] = true; $migrator = new MigrateProcessor($this, $this->resolveLaravelMigrationsOptions($options)); diff --git a/src/Concerns/WithLaravelMigrations.php b/src/Concerns/WithLaravelMigrations.php index 30295600e..185bbcb53 100644 --- a/src/Concerns/WithLaravelMigrations.php +++ b/src/Concerns/WithLaravelMigrations.php @@ -6,7 +6,7 @@ use Illuminate\Foundation\Testing\RefreshDatabaseState; use function Orchestra\Testbench\after_resolving; -use function Orchestra\Testbench\laravel_migration_path; +use function Orchestra\Testbench\default_migration_path; /** * @api @@ -25,7 +25,7 @@ protected function setUpWithLaravelMigrations(): void /** @var bool $loadLaravelMigrations */ $loadLaravelMigrations = static::cachedConfigurationForWorkbench()->getWorkbenchAttributes()['install'] ?? false; - if (! ($loadLaravelMigrations && is_dir(laravel_migration_path()))) { + if (! ($loadLaravelMigrations && is_dir(default_migration_path()))) { return; } @@ -35,7 +35,7 @@ protected function setUpWithLaravelMigrations(): void ) { after_resolving($this->app, 'migrator', static function ($migrator, $app) { /** @var \Illuminate\Database\Migrations\Migrator $migrator */ - $migrator->path(laravel_migration_path()); + $migrator->path(default_migration_path()); }); } else { $this->loadLaravelMigrations(); diff --git a/src/Foundation/Bootstrap/LoadMigrationsFromArray.php b/src/Foundation/Bootstrap/LoadMigrationsFromArray.php index 0b8b69162..551b851ce 100644 --- a/src/Foundation/Bootstrap/LoadMigrationsFromArray.php +++ b/src/Foundation/Bootstrap/LoadMigrationsFromArray.php @@ -10,7 +10,7 @@ use Illuminate\Support\Collection; use Orchestra\Testbench\Foundation\Env; -use function Orchestra\Testbench\laravel_migration_path; +use function Orchestra\Testbench\default_migration_path; use function Orchestra\Testbench\load_migration_paths; use function Orchestra\Testbench\transform_relative_path; use function Orchestra\Testbench\workbench; @@ -101,7 +101,7 @@ protected function bootstrapMigrations(Application $app): void $paths = Collection::make( ! \is_bool($this->migrations) ? Arr::wrap($this->migrations) : [] )->when($this->includesDefaultMigrations($app), static function ($migrations) { - return $migrations->push(laravel_migration_path()); + return $migrations->push(default_migration_path()); })->filter(static function ($migration) { return \is_string($migration); })->transform(static function ($migration) use ($app) { @@ -123,7 +123,7 @@ protected function includesDefaultMigrations($app): bool workbench()['install'] === true && Env::get('TESTBENCH_WITHOUT_DEFAULT_MIGRATIONS') !== true && rescue(static function () { - return is_dir(laravel_migration_path()); + return is_dir(default_migration_path()); }, false, false); } } diff --git a/src/functions.php b/src/functions.php index 1045fcd3d..0b0f61a04 100644 --- a/src/functions.php +++ b/src/functions.php @@ -253,6 +253,30 @@ function default_skeleton_path($path = ''): string return (string) realpath(join_paths(__DIR__, '..', 'laravel', ...Arr::wrap(\func_num_args() > 1 ? \func_get_args() : $path))); } + +/** + * Get the migration path by type. + * + * @api + * + * @param string|null $type + * @return string + * + * @throws \InvalidArgumentException + */ +function default_migration_path(?string $type = null): string +{ + $path = realpath( + \is_null($type) ? base_path('migrations') : base_path(join_paths('migrations', $type)) + ); + + if ($path === false) { + throw new InvalidArgumentException(\sprintf('Unable to resolve migration path for type [%s]', $type ?? 'laravel')); + } + + return $path; +} + /** * Get the path to the package folder. * @@ -315,22 +339,13 @@ function workbench_path($path = ''): string * * @api * - * @param string|null $type * @return string * * @throws \InvalidArgumentException */ -function laravel_migration_path(?string $type = null): string +function laravel_migration_path(): string { - $path = realpath( - \is_null($type) ? base_path('migrations') : base_path(join_paths('migrations', $type)) - ); - - if ($path === false) { - throw new InvalidArgumentException(\sprintf('Unable to resolve migration path for type [%s]', $type ?? 'laravel')); - } - - return $path; + return realpath(base_path(join_paths('database', 'migrations'))); } /** From e50b2af0dccc273b4486dc176b56fabdaed47bdc Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 2 Sep 2024 12:27:26 +0800 Subject: [PATCH 17/56] wip Signed-off-by: Mior Muhammad Zaki --- src/functions.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/functions.php b/src/functions.php index 0b0f61a04..d6ce3823f 100644 --- a/src/functions.php +++ b/src/functions.php @@ -339,13 +339,16 @@ function workbench_path($path = ''): string * * @api * + * @param string|null $type * @return string * * @throws \InvalidArgumentException + * + * @deprecated */ -function laravel_migration_path(): string +function laravel_migration_path(?string $type = null): string { - return realpath(base_path(join_paths('database', 'migrations'))); + return default_migration_path($type); } /** From c5b2f489f9ae099e2a88d30d911816bbd7a01cba Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 2 Sep 2024 23:35:25 +0800 Subject: [PATCH 18/56] wip Signed-off-by: Mior Muhammad Zaki --- src/functions.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/functions.php b/src/functions.php index d6ce3823f..a1abd834b 100644 --- a/src/functions.php +++ b/src/functions.php @@ -253,7 +253,6 @@ function default_skeleton_path($path = ''): string return (string) realpath(join_paths(__DIR__, '..', 'laravel', ...Arr::wrap(\func_num_args() > 1 ? \func_get_args() : $path))); } - /** * Get the migration path by type. * @@ -343,7 +342,7 @@ function workbench_path($path = ''): string * @return string * * @throws \InvalidArgumentException - * + * * @deprecated */ function laravel_migration_path(?string $type = null): string From 6924642bbce73ed1e7b5f43b547f522b9d5ee696 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 2 Sep 2024 23:46:22 +0800 Subject: [PATCH 19/56] wip Signed-off-by: Mior Muhammad Zaki --- tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php index 7a0ab45f9..cf470eb0a 100644 --- a/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php +++ b/tests/Foundation/Bootstrap/CreateVendorSymlinkTest.php @@ -5,6 +5,7 @@ use Illuminate\Filesystem\Filesystem; use Orchestra\Testbench\Foundation\Bootstrap\CreateVendorSymlink; use Orchestra\Testbench\TestCase; +use PHPUnit\Framework\Attributes\Test; use function Orchestra\Testbench\container; use function Orchestra\Testbench\laravel_vendor_exists; @@ -12,7 +13,7 @@ class CreateVendorSymlinkTest extends TestCase { - /** @test */ + #[Test] public function it_can_create_vendor_symlink() { $workingPath = package_path('vendor'); @@ -30,7 +31,7 @@ public function it_can_create_vendor_symlink() $this->assertTrue($laravel['TESTBENCH_VENDOR_SYMLINK']); } - /** @test */ + #[Test] public function it_can_skip_existing_vendor_symlink() { $workingPath = package_path('vendor'); From d1312a4b7fb23f8d9b501a3cc05c84095c9f0b8b Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 9 Sep 2024 17:42:15 +0800 Subject: [PATCH 20/56] wip Signed-off-by: Mior Muhammad Zaki --- tests/Integrations/WithFakerTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/Integrations/WithFakerTest.php b/tests/Integrations/WithFakerTest.php index 8211398b2..fd6da5729 100644 --- a/tests/Integrations/WithFakerTest.php +++ b/tests/Integrations/WithFakerTest.php @@ -4,6 +4,7 @@ use Faker\Generator; use Illuminate\Foundation\Testing\WithFaker; +use Orchestra\Testbench\Attributes\WithConfig; use Orchestra\Testbench\TestCase; class WithFakerTest extends TestCase @@ -15,4 +16,18 @@ public function it_can_use_faker() { $this->assertInstanceOf(Generator::class, $this->faker); } + + /** + * @requires PHP >= 8.0 + * @test + */ + #[WithConfig('app.faker_locale', 'it_IT')] + public function it_can_override_faker_locale() + { + $providerNames = array_map(function ($p) { + return get_class($p); + }, $this->faker()->getProviders()); + + $this->assertContains('Faker\Provider\it_IT\Person', $providerNames); + } } From 9d144a80b4b41a30cf9d047a5589194cfb73beee Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 9 Sep 2024 18:02:21 +0800 Subject: [PATCH 21/56] wip Signed-off-by: Mior Muhammad Zaki --- tests/Integrations/WithFakerTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Integrations/WithFakerTest.php b/tests/Integrations/WithFakerTest.php index fd6da5729..3a9236f3f 100644 --- a/tests/Integrations/WithFakerTest.php +++ b/tests/Integrations/WithFakerTest.php @@ -19,13 +19,14 @@ public function it_can_use_faker() /** * @requires PHP >= 8.0 + * * @test */ #[WithConfig('app.faker_locale', 'it_IT')] - public function it_can_override_faker_locale() + public function it_can_override_faker_locale() { $providerNames = array_map(function ($p) { - return get_class($p); + return \get_class($p); }, $this->faker()->getProviders()); $this->assertContains('Faker\Provider\it_IT\Person', $providerNames); From 46ce464f88911f598a130842b1f549f60d1acd17 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Thu, 12 Sep 2024 18:49:51 +0800 Subject: [PATCH 22/56] wip Signed-off-by: Mior Muhammad Zaki --- laravel/config/concurrency.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 laravel/config/concurrency.php diff --git a/laravel/config/concurrency.php b/laravel/config/concurrency.php new file mode 100644 index 000000000..1d66b701f --- /dev/null +++ b/laravel/config/concurrency.php @@ -0,0 +1,20 @@ + env('CONCURRENCY_DRIVER', 'process'), + +]; From e19fb68b9b351c99d3acec16a8edddb4cda98d1b Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Thu, 12 Sep 2024 18:51:37 +0800 Subject: [PATCH 23/56] wip Signed-off-by: Mior Muhammad Zaki --- laravel/config/concurrency.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 laravel/config/concurrency.php diff --git a/laravel/config/concurrency.php b/laravel/config/concurrency.php new file mode 100644 index 000000000..1d66b701f --- /dev/null +++ b/laravel/config/concurrency.php @@ -0,0 +1,20 @@ + env('CONCURRENCY_DRIVER', 'process'), + +]; From b1f1a046cafd07d2a7b0cb96e9a2911aee160515 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Thu, 12 Sep 2024 18:54:24 +0800 Subject: [PATCH 24/56] Prepare 9.4.1 release Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-9.x.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG-9.x.md b/CHANGELOG-9.x.md index 7f7d922db..e2be6fa51 100644 --- a/CHANGELOG-9.x.md +++ b/CHANGELOG-9.x.md @@ -2,6 +2,14 @@ This changelog references the relevant changes (bug and security fixes) done to `orchestra/testbench-core`. +## 9.4.1 + +Released: 2024-09-12 + +### Changes + +* Add `concurrency.php` configuration based on Laravel Framework 11.23. + ## 9.4.0 Released: 2024-08-26 From ee37f7526827ee3f706085928b5502d5fe3abbf4 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 13 Sep 2024 23:32:54 +0800 Subject: [PATCH 25/56] wip Signed-off-by: Mior Muhammad Zaki --- tests/Integrations/WithFakerTest.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/Integrations/WithFakerTest.php b/tests/Integrations/WithFakerTest.php index 3a9236f3f..124eeea95 100644 --- a/tests/Integrations/WithFakerTest.php +++ b/tests/Integrations/WithFakerTest.php @@ -17,11 +17,7 @@ public function it_can_use_faker() $this->assertInstanceOf(Generator::class, $this->faker); } - /** - * @requires PHP >= 8.0 - * - * @test - */ + /** @test */ #[WithConfig('app.faker_locale', 'it_IT')] public function it_can_override_faker_locale() { From 068fccb20543fa32a73cc9c55048b8c5be1d7528 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 13 Sep 2024 23:40:13 +0800 Subject: [PATCH 26/56] [8.x] Add tests for `usesTestingFeature()` (#234) * [8.x] Move declared attributes via `usesTestingFeature()` above class and method declaration Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * Update .github/workflows/parallel-tests.yaml * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki --- .github/workflows/parallel-tests.yaml | 58 +++++++++++++++++--- tests/Attributes/UsesTestingFeaturesTest.php | 44 +++++++++++++++ 2 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 tests/Attributes/UsesTestingFeaturesTest.php diff --git a/.github/workflows/parallel-tests.yaml b/.github/workflows/parallel-tests.yaml index 6cf1df301..c7048c65a 100644 --- a/.github/workflows/parallel-tests.yaml +++ b/.github/workflows/parallel-tests.yaml @@ -14,12 +14,11 @@ jobs: os: - "ubuntu-latest" php: - - 8.1 - 8.2 collision: - "^7.4" paratest: - - "^7.1.4" + - "^7.4.0" dependencies: - "highest" experimental: @@ -40,7 +39,7 @@ jobs: - name: Install Paratest run: | - composer require "phpunit/phpunit:^10.1" --dev --no-interaction --no-update + composer require "phpunit/phpunit:^10.5" --dev --no-interaction --no-update composer require "nunomaduro/collision:${{ matrix.collision }}" "brianium/paratest:${{ matrix.paratest }}" --dev --no-interaction --no-update - name: Install dependencies @@ -57,11 +56,54 @@ jobs: run: ./testbench package:test --parallel --exclude-group commander,without-parallel,database,session --no-coverage env: RAY_ENABLED: false - if: matrix.dependencies == 'highest' - - name: Execute tests (without deprecations on PHPUnit 10) - run: ./testbench package:test --parallel --exclude-group commander,without-parallel,database,session,deprecations --no-coverage + tests-on-php-81: + runs-on: ${{ matrix.os }} + continue-on-error: ${{ matrix.experimental }} + strategy: + matrix: + os: + - "ubuntu-latest" + php: + - 8.1 + collision: + - "^7.4" + paratest: + - ">=7.1.0 <7.4.0" + dependencies: + - "highest" + experimental: + - false + + name: PHP${{ matrix.php }} on ${{ matrix.os }} (${{ matrix.dependencies }}) + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, mysql, mysqli, pdo_mysql, bcmath, intl, fileinfo, :php-psr + coverage: none + + - name: Install Paratest + run: | + composer require "phpunit/phpunit:<10.5.32" --dev --no-interaction --no-update + composer require "nunomaduro/collision:${{ matrix.collision }}" "brianium/paratest:${{ matrix.paratest }}" --dev --no-interaction --no-update + + - name: Install dependencies + uses: "ramsey/composer-install@v3" + with: + dependency-versions: "${{ matrix.dependencies }}" + composer-options: "--prefer-dist --prefer-stable --no-cache" + + - name: Installed dependencies + run: | + composer show -D + + - name: Execute tests (with deprecations on PHPUnit 10) + run: ./testbench package:test --parallel --exclude-group commander,without-parallel,database,session --no-coverage env: RAY_ENABLED: false - TESTBENCH_CONVERT_DEPRECATIONS_TO_EXCEPTIONS: false - if: matrix.dependencies != 'highest' diff --git a/tests/Attributes/UsesTestingFeaturesTest.php b/tests/Attributes/UsesTestingFeaturesTest.php new file mode 100644 index 000000000..d1bd5f06d --- /dev/null +++ b/tests/Attributes/UsesTestingFeaturesTest.php @@ -0,0 +1,44 @@ +assertSame(true, config('fake.parent_attribute')); + } + + /** @test */ + public function it_can_override_parent_attributes() + { + $this->assertSame('child', config('fake.override_attribute')); + $this->assertSame('child', config('fake.override_attribute_2')); + } +} From 6de8491bcee889be23337ffa6d70e0657f1f7f46 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 13 Sep 2024 23:48:36 +0800 Subject: [PATCH 27/56] [7.x] Add tests for `usesTestingFeature()` (#235) * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki --- tests/Attributes/UsesTestingFeaturesTest.php | 44 ++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tests/Attributes/UsesTestingFeaturesTest.php diff --git a/tests/Attributes/UsesTestingFeaturesTest.php b/tests/Attributes/UsesTestingFeaturesTest.php new file mode 100644 index 000000000..d1bd5f06d --- /dev/null +++ b/tests/Attributes/UsesTestingFeaturesTest.php @@ -0,0 +1,44 @@ +assertSame(true, config('fake.parent_attribute')); + } + + /** @test */ + public function it_can_override_parent_attributes() + { + $this->assertSame('child', config('fake.override_attribute')); + $this->assertSame('child', config('fake.override_attribute_2')); + } +} From 23f30ebdceb1e2bf28884dfb5aee1552ba62f346 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 13 Sep 2024 23:52:49 +0800 Subject: [PATCH 28/56] wip Signed-off-by: Mior Muhammad Zaki --- tests/Attributes/UsesTestingFeaturesTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Attributes/UsesTestingFeaturesTest.php b/tests/Attributes/UsesTestingFeaturesTest.php index d1bd5f06d..15215ec20 100644 --- a/tests/Attributes/UsesTestingFeaturesTest.php +++ b/tests/Attributes/UsesTestingFeaturesTest.php @@ -5,7 +5,7 @@ use Orchestra\Testbench\Attributes\WithConfig; use Orchestra\Testbench\TestCase; -abstract class BaseTestCase extends TestCase +abstract class UsesTestingFeaturesTestBaseTestCase extends TestCase { /** * @beforeClass @@ -19,7 +19,7 @@ public static function defineTestingFeatures() } #[WithConfig('fake.override_attribute', 'child')] -class UsesTestingFeaturesTest extends BaseTestCase +class UsesTestingFeaturesTest extends UsesTestingFeaturesTestBaseTestCase { /** * @beforeClass From f8bce6234ac3cfc919b5892c4c5d0d945940af0f Mon Sep 17 00:00:00 2001 From: BlackLanzer Date: Fri, 13 Sep 2024 18:12:49 +0200 Subject: [PATCH 29/56] [8.x] Inherits Attributes defined on parent TestCase (#233) * See parent class attributes * Update InheritanceTest.php * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki Co-authored-by: Mior Muhammad Zaki --- src/PHPUnit/AttributeParser.php | 9 +++- .../Attributes/AttributesInheritanceTest.php | 44 +++++++++++++++++++ tests/Attributes/UsesTestingFeaturesTest.php | 4 +- 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 tests/Attributes/AttributesInheritanceTest.php diff --git a/src/PHPUnit/AttributeParser.php b/src/PHPUnit/AttributeParser.php index f3b3bfdbe..8c2f2635f 100644 --- a/src/PHPUnit/AttributeParser.php +++ b/src/PHPUnit/AttributeParser.php @@ -27,8 +27,9 @@ class AttributeParser public static function forClass(string $className): array { $attributes = []; + $reflection = new ReflectionClass($className); - foreach ((new ReflectionClass($className))->getAttributes() as $attribute) { + foreach ($reflection->getAttributes() as $attribute) { if (! static::validAttribute($attribute->getName())) { continue; } @@ -40,6 +41,12 @@ public static function forClass(string $className): array } } + $parent = $reflection->getParentClass(); + + if ($parent && $parent->isSubclassOf(TestCase::class)) { + $attributes = [...static::forClass($parent->getName()), ...$attributes]; + } + return $attributes; } diff --git a/tests/Attributes/AttributesInheritanceTest.php b/tests/Attributes/AttributesInheritanceTest.php new file mode 100644 index 000000000..821227b36 --- /dev/null +++ b/tests/Attributes/AttributesInheritanceTest.php @@ -0,0 +1,44 @@ +assertSame(true, config('fake.parent_attribute')); + } + + /** @test */ + public function it_can_override_parent_attributes() + { + $this->assertSame('child', config('fake.override_attribute')); + $this->assertSame('child', config('fake.override_attribute_2')); + } +} diff --git a/tests/Attributes/UsesTestingFeaturesTest.php b/tests/Attributes/UsesTestingFeaturesTest.php index d1bd5f06d..15215ec20 100644 --- a/tests/Attributes/UsesTestingFeaturesTest.php +++ b/tests/Attributes/UsesTestingFeaturesTest.php @@ -5,7 +5,7 @@ use Orchestra\Testbench\Attributes\WithConfig; use Orchestra\Testbench\TestCase; -abstract class BaseTestCase extends TestCase +abstract class UsesTestingFeaturesTestBaseTestCase extends TestCase { /** * @beforeClass @@ -19,7 +19,7 @@ public static function defineTestingFeatures() } #[WithConfig('fake.override_attribute', 'child')] -class UsesTestingFeaturesTest extends BaseTestCase +class UsesTestingFeaturesTest extends UsesTestingFeaturesTestBaseTestCase { /** * @beforeClass From 1ea157190e3534da6955b6e14de68051278926b9 Mon Sep 17 00:00:00 2001 From: BlackLanzer Date: Fri, 13 Sep 2024 18:12:49 +0200 Subject: [PATCH 30/56] [8.x] Inherits Attributes defined on parent TestCase (#233) * See parent class attributes * Update InheritanceTest.php * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki Co-authored-by: Mior Muhammad Zaki --- src/PHPUnit/AttributeParser.php | 9 +++- .../Attributes/AttributesInheritanceTest.php | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/Attributes/AttributesInheritanceTest.php diff --git a/src/PHPUnit/AttributeParser.php b/src/PHPUnit/AttributeParser.php index a9fecd419..3bbe158e1 100644 --- a/src/PHPUnit/AttributeParser.php +++ b/src/PHPUnit/AttributeParser.php @@ -27,8 +27,9 @@ class AttributeParser public static function forClass(string $className): array { $attributes = []; + $reflection = new ReflectionClass($className); - foreach ((new ReflectionClass($className))->getAttributes() as $attribute) { + foreach ($reflection->getAttributes() as $attribute) { if (! static::validAttribute($attribute->getName())) { continue; } @@ -40,6 +41,12 @@ public static function forClass(string $className): array } } + $parent = $reflection->getParentClass(); + + if ($parent && $parent->isSubclassOf(TestCase::class)) { + $attributes = [...static::forClass($parent->getName()), ...$attributes]; + } + return $attributes; } diff --git a/tests/Attributes/AttributesInheritanceTest.php b/tests/Attributes/AttributesInheritanceTest.php new file mode 100644 index 000000000..821227b36 --- /dev/null +++ b/tests/Attributes/AttributesInheritanceTest.php @@ -0,0 +1,44 @@ +assertSame(true, config('fake.parent_attribute')); + } + + /** @test */ + public function it_can_override_parent_attributes() + { + $this->assertSame('child', config('fake.override_attribute')); + $this->assertSame('child', config('fake.override_attribute_2')); + } +} From 4945edaa36b61b599171304585cf793afde1a56b Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Sat, 14 Sep 2024 18:52:54 +0800 Subject: [PATCH 31/56] wip Signed-off-by: Mior Muhammad Zaki --- tests/Attributes/AttributesInheritanceTest.php | 14 ++++++-------- tests/Attributes/UsesTestingFeaturesTest.php | 14 ++++++-------- tests/Integrations/WithFakerTest.php | 2 +- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/tests/Attributes/AttributesInheritanceTest.php b/tests/Attributes/AttributesInheritanceTest.php index 821227b36..399d41b53 100644 --- a/tests/Attributes/AttributesInheritanceTest.php +++ b/tests/Attributes/AttributesInheritanceTest.php @@ -4,14 +4,14 @@ use Orchestra\Testbench\Attributes\WithConfig; use Orchestra\Testbench\TestCase; +use PHPUnit\Framework\Attributes\BeforeClass; +use PHPUnit\Framework\Attributes\Test; #[WithConfig('fake.parent_attribute', true)] #[WithConfig('fake.override_attribute', 'parent')] abstract class AttributesInheritanceTestBaseTestCase extends TestCase { - /** - * @beforeClass - */ + #[BeforeClass] public static function defineTestingFeatures() { static::usesTestingFeature(new WithConfig('fake.override_attribute_2', 'parent')); @@ -21,21 +21,19 @@ public static function defineTestingFeatures() #[WithConfig('fake.override_attribute', 'child')] class AttributesInheritanceTest extends AttributesInheritanceTestBaseTestCase { - /** - * @beforeClass - */ + #[BeforeClass] public static function defineChildTestingFeatures() { static::usesTestingFeature(new WithConfig('fake.override_attribute_2', 'child')); } - /** @test */ + #[Test] public function it_can_see_parent_attributes() { $this->assertSame(true, config('fake.parent_attribute')); } - /** @test */ + #[Test] public function it_can_override_parent_attributes() { $this->assertSame('child', config('fake.override_attribute')); diff --git a/tests/Attributes/UsesTestingFeaturesTest.php b/tests/Attributes/UsesTestingFeaturesTest.php index 15215ec20..80f546d0e 100644 --- a/tests/Attributes/UsesTestingFeaturesTest.php +++ b/tests/Attributes/UsesTestingFeaturesTest.php @@ -4,12 +4,12 @@ use Orchestra\Testbench\Attributes\WithConfig; use Orchestra\Testbench\TestCase; +use PHPUnit\Framework\Attributes\BeforeClass; +use PHPUnit\Framework\Attributes\Test; abstract class UsesTestingFeaturesTestBaseTestCase extends TestCase { - /** - * @beforeClass - */ + #[BeforeClass] public static function defineTestingFeatures() { static::usesTestingFeature(new WithConfig('fake.parent_attribute', true)); @@ -21,21 +21,19 @@ public static function defineTestingFeatures() #[WithConfig('fake.override_attribute', 'child')] class UsesTestingFeaturesTest extends UsesTestingFeaturesTestBaseTestCase { - /** - * @beforeClass - */ + #[BeforeClass] public static function defineChildTestingFeatures() { static::usesTestingFeature(new WithConfig('fake.override_attribute_2', 'child')); } - /** @test */ + #[Test] public function it_can_see_parent_attributes() { $this->assertSame(true, config('fake.parent_attribute')); } - /** @test */ + #[Test] public function it_can_override_parent_attributes() { $this->assertSame('child', config('fake.override_attribute')); diff --git a/tests/Integrations/WithFakerTest.php b/tests/Integrations/WithFakerTest.php index 2678ebce7..7345f047b 100644 --- a/tests/Integrations/WithFakerTest.php +++ b/tests/Integrations/WithFakerTest.php @@ -18,7 +18,7 @@ public function it_can_use_faker() $this->assertInstanceOf(Generator::class, $this->faker); } - /** @test */ + #[Test] #[WithConfig('app.faker_locale', 'it_IT')] public function it_can_override_faker_locale() { From 83ce9ed9dfc86bc990ee4ab1f53f8af9d5969cb7 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 20 Sep 2024 10:55:29 +0800 Subject: [PATCH 32/56] [6.x] Add `markTestSkippedWhen()` (#236) * [6.x] Add `markTestSkippedWhen()` Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki --- src/Concerns/HandlesAssertions.php | 20 ++++++++++++++++++++ src/Concerns/Testing.php | 1 + 2 files changed, 21 insertions(+) create mode 100644 src/Concerns/HandlesAssertions.php diff --git a/src/Concerns/HandlesAssertions.php b/src/Concerns/HandlesAssertions.php new file mode 100644 index 000000000..b2e6a9ed3 --- /dev/null +++ b/src/Concerns/HandlesAssertions.php @@ -0,0 +1,20 @@ +markTestSkipped($message); + } + } +} diff --git a/src/Concerns/Testing.php b/src/Concerns/Testing.php index d425da1a8..f343a808e 100644 --- a/src/Concerns/Testing.php +++ b/src/Concerns/Testing.php @@ -25,6 +25,7 @@ trait Testing { use CreatesApplication; use HandlesAnnotations; + use HandlesAssertions; use HandlesAttributes; use HandlesDatabases; use HandlesRoutes; From f826780e2954c3b415545bc5baeac516d87c77ca Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 20 Sep 2024 21:20:16 +0800 Subject: [PATCH 33/56] wip Signed-off-by: Mior Muhammad Zaki --- tests/Concerns/HandlesAssertionsTest.php | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/Concerns/HandlesAssertionsTest.php diff --git a/tests/Concerns/HandlesAssertionsTest.php b/tests/Concerns/HandlesAssertionsTest.php new file mode 100644 index 000000000..860084494 --- /dev/null +++ b/tests/Concerns/HandlesAssertionsTest.php @@ -0,0 +1,29 @@ +markTestSkippedWhen(true, 'Successfully skipped current test'); + + $this->assertTrue(false, 'Test incorrectly executed.'); + } + + /** @test */ + public function it_should_mark_the_tests_as_skipped_when_condition_() + { + $this->markTestSkippedWhen(function () { + return false; + }, 'Failed skipped current test'); + + $this->assertTrue(true, 'Test is correctly executed.'); + } +} From 41cde8cf0b477c98fdddbe1db979cc1bdc7d24ab Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 20 Sep 2024 22:15:55 +0800 Subject: [PATCH 34/56] wip Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-6.x.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG-6.x.md b/CHANGELOG-6.x.md index 3b76145d4..263dfdd1b 100644 --- a/CHANGELOG-6.x.md +++ b/CHANGELOG-6.x.md @@ -2,6 +2,22 @@ This changelog references the relevant changes (bug and security fixes) done to `orchestra/testbench-core`. +## Unreleased + +### Added + +* Added `markTestSkippedWhen()` assertion helper to conditionally handle `markTestSkipped()`. +* Added `Orchestra\Testbench\default_migration_path()` helper function. +* Added `Orchestra\Testbench\laravel_vendor_exists()` helper function. + +### Changes + +* Allow Testbench to delete `vendor` symlink directory if it was created while running tests. + +### Deprecated + +* Deprecated `Orchestra\Testbench\laravel_migration_path()`, use `default_migration_path()` instead. + ## 6.52.0 Released: 2024-08-26 From b61ba521024b2667e4ecda5c40ac0df9515876f1 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 10:23:54 +0800 Subject: [PATCH 35/56] [9.x] Add `Orchestra\Testbench\Attributes\RequiresDatabase` Attribute (#238) * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki --- src/Attributes/RequiresDatabase.php | 56 +++++++++++++++++++++++++++++ src/Concerns/HandlesDatabases.php | 6 ++++ 2 files changed, 62 insertions(+) create mode 100644 src/Attributes/RequiresDatabase.php diff --git a/src/Attributes/RequiresDatabase.php b/src/Attributes/RequiresDatabase.php new file mode 100644 index 000000000..e75268bbf --- /dev/null +++ b/src/Attributes/RequiresDatabase.php @@ -0,0 +1,56 @@ +):void $action + * @return void + */ + public function handle($app, Closure $action): void + { + $connection = DB::connection($this->driver); + + if ($this->default === true && (DB::connection() !== $connection)) { + \call_user_func($action, 'markTestSkipped', [\sprintf('Requires %s as the default database connection', $connection->getName())]); + } + + if ( + ! is_null($this->versionRequirement) + && preg_match('/(?P[<>=!]{0,2})\s*(?P[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m', $this->versionRequirement, $matches) + ) { + if (empty($matches['operator'])) { + $matches['operator'] = '>='; + } + + if (! version_compare($connection->getServerVersion(), $matches['version'], $matches['operator'])) { + \call_user_func($action, 'markTestSkipped', [\sprintf('Requires %s:%s', $connection->getName(), $this->versionRequirement)]); + } + } + } +} diff --git a/src/Concerns/HandlesDatabases.php b/src/Concerns/HandlesDatabases.php index 602d18d31..635d32d40 100644 --- a/src/Concerns/HandlesDatabases.php +++ b/src/Concerns/HandlesDatabases.php @@ -5,6 +5,7 @@ use Closure; use Illuminate\Database\Events\DatabaseRefreshed; use Orchestra\Testbench\Attributes\DefineDatabase; +use Orchestra\Testbench\Attributes\RequiresDatabase; use Orchestra\Testbench\Attributes\WithMigration; use Orchestra\Testbench\Exceptions\ApplicationNotAvailableException; use Orchestra\Testbench\Features\TestingFeature; @@ -27,6 +28,11 @@ protected function setUpDatabaseRequirements(Closure $callback): void throw ApplicationNotAvailableException::make(__METHOD__); } + TestingFeature::run( + testCase: $this, + attribute: fn () => $this->parseTestMethodAttributes($app, RequiresDatabase::class), + ); + $app['events']->listen(DatabaseRefreshed::class, function () { $this->defineDatabaseMigrationsAfterDatabaseRefreshed(); }); From 88b8035c5c0d06712f6cf16bb8ce9828216f1c94 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 12:21:15 +0800 Subject: [PATCH 36/56] Allow validation multiple drivers via `RequiresDatabase` attribute (#239) * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki --- src/Attributes/RequiresDatabase.php | 38 ++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/Attributes/RequiresDatabase.php b/src/Attributes/RequiresDatabase.php index e75268bbf..172b2379f 100644 --- a/src/Attributes/RequiresDatabase.php +++ b/src/Attributes/RequiresDatabase.php @@ -4,10 +4,12 @@ use Attribute; use Closure; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; +use InvalidArgumentException; use Orchestra\Testbench\Contracts\Attributes\Actionable as ActionableContract; -#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)] +#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] final class RequiresDatabase implements ActionableContract { /** @@ -18,11 +20,14 @@ final class RequiresDatabase implements ActionableContract * @param bool $default */ public function __construct( - public string $driver, + public array|string $driver, public ?string $versionRequirement = null, + public ?string $connection = null, public bool $default = true ) { - // + if (\is_array($driver) && $default === true) { + throw new InvalidArgumentException('Unable to validate default connection when given an array of database drivers'); + } } /** @@ -34,14 +39,35 @@ public function __construct( */ public function handle($app, Closure $action): void { - $connection = DB::connection($this->driver); + $connection = DB::connection($this->connection); - if ($this->default === true && (DB::connection() !== $connection)) { + if ( + $this->default === true + && \is_string($this->driver) + && $connection->getDriverName() !== $this->driver + ) { \call_user_func($action, 'markTestSkipped', [\sprintf('Requires %s as the default database connection', $connection->getName())]); } + $drivers = Arr::wrap($this->driver); + $usingCorrectConnection = false; + + foreach ($drivers as $driver) { + if ($connection->getDriverName() === $driver) { + $usingCorrectConnection = true; + } + } + + if ($usingCorrectConnection === false) { + \call_user_func( + $action, + 'markTestSkipped', + [\sprintf('Requires %s to use [%s] database connection', $connection->getName(), Arr::join($drivers, ','))] + ); + } + if ( - ! is_null($this->versionRequirement) + ! \is_null($this->versionRequirement) && preg_match('/(?P[<>=!]{0,2})\s*(?P[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m', $this->versionRequirement, $matches) ) { if (empty($matches['operator'])) { From 623ed4da64a71fe64dd7628a554f911bb50fe69d Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 12:26:50 +0800 Subject: [PATCH 37/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Concerns/HandlesAssertions.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Concerns/HandlesAssertions.php b/src/Concerns/HandlesAssertions.php index b2e6a9ed3..a24925bf8 100644 --- a/src/Concerns/HandlesAssertions.php +++ b/src/Concerns/HandlesAssertions.php @@ -4,10 +4,24 @@ trait HandlesAssertions { + /** + * Mark the test as skipped when condition is not equivalent to true. + * + * @param (\Closure($this): bool)|bool|null $condition + * @param string $message + * @return void + */ + protected function markTestSkippedUnless($condition, string $message): void + { + if (!value($condition)) { + $this->markTestSkipped($message); + } + } + /** * Mark the test as skipped when condition is equivalent to true. * - * @param (\Closure($this): mixed)|mixed|null $condition + * @param (\Closure($this): bool)|bool|null $condition * @param string $message * @return void */ From 6cce8cd1a8668c1d82f271d8744afc7d397c773f Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 12:27:19 +0800 Subject: [PATCH 38/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Concerns/HandlesAssertions.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Concerns/HandlesAssertions.php b/src/Concerns/HandlesAssertions.php index b2e6a9ed3..a24925bf8 100644 --- a/src/Concerns/HandlesAssertions.php +++ b/src/Concerns/HandlesAssertions.php @@ -4,10 +4,24 @@ trait HandlesAssertions { + /** + * Mark the test as skipped when condition is not equivalent to true. + * + * @param (\Closure($this): bool)|bool|null $condition + * @param string $message + * @return void + */ + protected function markTestSkippedUnless($condition, string $message): void + { + if (!value($condition)) { + $this->markTestSkipped($message); + } + } + /** * Mark the test as skipped when condition is equivalent to true. * - * @param (\Closure($this): mixed)|mixed|null $condition + * @param (\Closure($this): bool)|bool|null $condition * @param string $message * @return void */ From cea0bab412cb596b597d328ba46cb56b564a3b3f Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 12:28:04 +0800 Subject: [PATCH 39/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Concerns/HandlesAssertions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Concerns/HandlesAssertions.php b/src/Concerns/HandlesAssertions.php index a24925bf8..4c062d554 100644 --- a/src/Concerns/HandlesAssertions.php +++ b/src/Concerns/HandlesAssertions.php @@ -13,7 +13,7 @@ trait HandlesAssertions */ protected function markTestSkippedUnless($condition, string $message): void { - if (!value($condition)) { + if (! value($condition)) { $this->markTestSkipped($message); } } From 8eb47389b797f1df8bc222e48b3df5431071b4f3 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 12:40:59 +0800 Subject: [PATCH 40/56] wip Signed-off-by: Mior Muhammad Zaki --- tests/Concerns/HandlesAssertionsTest.php | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/Concerns/HandlesAssertionsTest.php b/tests/Concerns/HandlesAssertionsTest.php index 860084494..d9d4b3ca2 100644 --- a/tests/Concerns/HandlesAssertionsTest.php +++ b/tests/Concerns/HandlesAssertionsTest.php @@ -10,7 +10,7 @@ class HandlesAssertionsTest extends TestCase use HandlesAssertions; /** @test */ - public function it_should_mark_the_tests_as_skipped() + public function it_should_mark_the_tests_as_skipped_when_condition_is_true() { $this->markTestSkippedWhen(true, 'Successfully skipped current test'); @@ -18,7 +18,7 @@ public function it_should_mark_the_tests_as_skipped() } /** @test */ - public function it_should_mark_the_tests_as_skipped_when_condition_() + public function it_should_mark_the_tests_as_skipped_when_condition_is_false() { $this->markTestSkippedWhen(function () { return false; @@ -26,4 +26,22 @@ public function it_should_mark_the_tests_as_skipped_when_condition_() $this->assertTrue(true, 'Test is correctly executed.'); } + + /** @test */ + public function it_should_mark_the_tests_as_skipped_unless_condition_is_false() + { + $this->markTestSkippedUnless(false, 'Successfully skipped current test'); + + $this->assertTrue(false, 'Test incorrectly executed.'); + } + + /** @test */ + public function it_should_mark_the_tests_as_skipped_unless_condition_is_true() + { + $this->markTestSkippedUnless(function () { + return true; + }, 'Failed skipped current test'); + + $this->assertTrue(true, 'Test is correctly executed.'); + } } From 628d5373da29e1170d8122391ce5705888a4086d Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 13:20:53 +0800 Subject: [PATCH 41/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Attributes/RequiresDatabase.php | 11 ++++++++--- src/Concerns/HandlesAssertions.php | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Attributes/RequiresDatabase.php b/src/Attributes/RequiresDatabase.php index 172b2379f..02f33a76b 100644 --- a/src/Attributes/RequiresDatabase.php +++ b/src/Attributes/RequiresDatabase.php @@ -17,14 +17,19 @@ final class RequiresDatabase implements ActionableContract * * @param string $driver * @param string|null $versionRequirement - * @param bool $default + * @param string|null $connection + * @param bool|null $default */ public function __construct( public array|string $driver, public ?string $versionRequirement = null, public ?string $connection = null, - public bool $default = true + public ?bool $default = null ) { + if (\is_null($connection) && \is_string($driver)) { + $this->default = true; + } + if (\is_array($driver) && $default === true) { throw new InvalidArgumentException('Unable to validate default connection when given an array of database drivers'); } @@ -42,7 +47,7 @@ public function handle($app, Closure $action): void $connection = DB::connection($this->connection); if ( - $this->default === true + ($this->default ?? false) === true && \is_string($this->driver) && $connection->getDriverName() !== $this->driver ) { diff --git a/src/Concerns/HandlesAssertions.php b/src/Concerns/HandlesAssertions.php index a24925bf8..4c062d554 100644 --- a/src/Concerns/HandlesAssertions.php +++ b/src/Concerns/HandlesAssertions.php @@ -13,7 +13,7 @@ trait HandlesAssertions */ protected function markTestSkippedUnless($condition, string $message): void { - if (!value($condition)) { + if (! value($condition)) { $this->markTestSkipped($message); } } From 04a066f3fb909dab8c656296f24a5160e5050baf Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 13:21:44 +0800 Subject: [PATCH 42/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Concerns/HandlesAssertions.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Concerns/HandlesAssertions.php b/src/Concerns/HandlesAssertions.php index 4c062d554..860d55884 100644 --- a/src/Concerns/HandlesAssertions.php +++ b/src/Concerns/HandlesAssertions.php @@ -13,6 +13,7 @@ trait HandlesAssertions */ protected function markTestSkippedUnless($condition, string $message): void { + /** @phpstan-ignore argument.type */ if (! value($condition)) { $this->markTestSkipped($message); } @@ -27,6 +28,7 @@ protected function markTestSkippedUnless($condition, string $message): void */ protected function markTestSkippedWhen($condition, string $message): void { + /** @phpstan-ignore argument.type */ if (value($condition)) { $this->markTestSkipped($message); } From 3d92f1659898afcab193474b5dd128df0f966cfd Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 13:42:09 +0800 Subject: [PATCH 43/56] wip Signed-off-by: Mior Muhammad Zaki --- src/Attributes/RequiresDatabase.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/Attributes/RequiresDatabase.php b/src/Attributes/RequiresDatabase.php index 02f33a76b..e8102ca1f 100644 --- a/src/Attributes/RequiresDatabase.php +++ b/src/Attributes/RequiresDatabase.php @@ -5,6 +5,7 @@ use Attribute; use Closure; use Illuminate\Support\Arr; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use InvalidArgumentException; use Orchestra\Testbench\Contracts\Attributes\Actionable as ActionableContract; @@ -54,20 +55,15 @@ public function handle($app, Closure $action): void \call_user_func($action, 'markTestSkipped', [\sprintf('Requires %s as the default database connection', $connection->getName())]); } - $drivers = Arr::wrap($this->driver); - $usingCorrectConnection = false; + $drivers = Collection::make( + Arr::wrap($this->driver) + )->filter(fn ($driver) => $driver === $connection->getDriverName()); - foreach ($drivers as $driver) { - if ($connection->getDriverName() === $driver) { - $usingCorrectConnection = true; - } - } - - if ($usingCorrectConnection === false) { + if ($drivers->isEmpty()) { \call_user_func( $action, 'markTestSkipped', - [\sprintf('Requires %s to use [%s] database connection', $connection->getName(), Arr::join($drivers, ','))] + [\sprintf('Requires %s to use [%s] database connection', $connection->getName(), Arr::join(Arr::wrap($this->driver), ','))] ); } From f19ec4f027170671c1282c2319f2a9d1e97af2e3 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 18:28:12 +0800 Subject: [PATCH 44/56] Test Improvements (#240) * Test Improvements Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki --- src/Attributes/RequiresDatabase.php | 17 +++++-- tests/Attributes/RequiresDatabaseTest.php | 61 +++++++++++++++++++++++ tests/Concerns/HandlesAssertionsTest.php | 9 ++-- 3 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 tests/Attributes/RequiresDatabaseTest.php diff --git a/src/Attributes/RequiresDatabase.php b/src/Attributes/RequiresDatabase.php index e8102ca1f..df781c851 100644 --- a/src/Attributes/RequiresDatabase.php +++ b/src/Attributes/RequiresDatabase.php @@ -52,7 +52,9 @@ public function handle($app, Closure $action): void && \is_string($this->driver) && $connection->getDriverName() !== $this->driver ) { - \call_user_func($action, 'markTestSkipped', [\sprintf('Requires %s as the default database connection', $connection->getName())]); + \call_user_func($action, 'markTestSkipped', [\sprintf('Requires %s to configured for "%s" database connection', $this->driver, $connection->getName())]); + + return; } $drivers = Collection::make( @@ -63,12 +65,15 @@ public function handle($app, Closure $action): void \call_user_func( $action, 'markTestSkipped', - [\sprintf('Requires %s to use [%s] database connection', $connection->getName(), Arr::join(Arr::wrap($this->driver), ','))] + [\sprintf('Requires [%s] to be configured for "%s" database connection', Arr::join(Arr::wrap($this->driver), '/'), $connection->getName())] ); + + return; } if ( - ! \is_null($this->versionRequirement) + is_string($this->driver) + && ! \is_null($this->versionRequirement) && preg_match('/(?P[<>=!]{0,2})\s*(?P[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m', $this->versionRequirement, $matches) ) { if (empty($matches['operator'])) { @@ -76,7 +81,11 @@ public function handle($app, Closure $action): void } if (! version_compare($connection->getServerVersion(), $matches['version'], $matches['operator'])) { - \call_user_func($action, 'markTestSkipped', [\sprintf('Requires %s:%s', $connection->getName(), $this->versionRequirement)]); + \call_user_func( + $action, + 'markTestSkipped', + [\sprintf('Requires %s:%s to be configured for "%s" database connection', $this->driver, $this->versionRequirement, $connection->getName())] + ); } } } diff --git a/tests/Attributes/RequiresDatabaseTest.php b/tests/Attributes/RequiresDatabaseTest.php new file mode 100644 index 000000000..c359ea8fd --- /dev/null +++ b/tests/Attributes/RequiresDatabaseTest.php @@ -0,0 +1,61 @@ +handle($this->app, function () { + throw new \Exception; + }); + + $this->addToAssertionCount(1); + + $stub = new RequiresDatabase(['pgsql', 'sqlite']); + + $stub->handle($this->app, function () { + throw new \Exception; + }); + + $this->addToAssertionCount(1); + } + + #[Test] + public function it_can_invalidate_unmatched_database() + { + $stub = new RequiresDatabase('mysql'); + + $stub->handle($this->app, function ($method, $parameters) { + $this->assertSame('markTestSkipped', $method); + $this->assertSame(['Requires mysql to configured for "testing" database connection'], $parameters); + }); + + $stub = new RequiresDatabase(['mysql', 'mariadb']); + + $stub->handle($this->app, function ($method, $parameters) { + $this->assertSame('markTestSkipped', $method); + $this->assertSame(['Requires [mysql/mariadb] to be configured for "testing" database connection'], $parameters); + }); + } + + #[Test] + public function it_can_invalidate_unmatched_database_version() + { + $stub = new RequiresDatabase('sqlite', '<2.0.0'); + + $stub->handle($this->app, function ($method, $parameters) { + $this->assertSame('markTestSkipped', $method); + $this->assertSame(['Requires sqlite:<2.0.0 to be configured for "testing" database connection'], $parameters); + }); + } +} diff --git a/tests/Concerns/HandlesAssertionsTest.php b/tests/Concerns/HandlesAssertionsTest.php index d9d4b3ca2..51a5f153d 100644 --- a/tests/Concerns/HandlesAssertionsTest.php +++ b/tests/Concerns/HandlesAssertionsTest.php @@ -3,13 +3,14 @@ namespace Orchestra\Testbench\Tests\Concerns; use Orchestra\Testbench\Concerns\HandlesAssertions; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; class HandlesAssertionsTest extends TestCase { use HandlesAssertions; - /** @test */ + #[Test] public function it_should_mark_the_tests_as_skipped_when_condition_is_true() { $this->markTestSkippedWhen(true, 'Successfully skipped current test'); @@ -17,7 +18,7 @@ public function it_should_mark_the_tests_as_skipped_when_condition_is_true() $this->assertTrue(false, 'Test incorrectly executed.'); } - /** @test */ + #[Test] public function it_should_mark_the_tests_as_skipped_when_condition_is_false() { $this->markTestSkippedWhen(function () { @@ -27,7 +28,7 @@ public function it_should_mark_the_tests_as_skipped_when_condition_is_false() $this->assertTrue(true, 'Test is correctly executed.'); } - /** @test */ + #[Test] public function it_should_mark_the_tests_as_skipped_unless_condition_is_false() { $this->markTestSkippedUnless(false, 'Successfully skipped current test'); @@ -35,7 +36,7 @@ public function it_should_mark_the_tests_as_skipped_unless_condition_is_false() $this->assertTrue(false, 'Test incorrectly executed.'); } - /** @test */ + #[Test] public function it_should_mark_the_tests_as_skipped_unless_condition_is_true() { $this->markTestSkippedUnless(function () { From cdad4f7cc18ccf898efc4a086c4ce15c06551bf5 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 18:37:25 +0800 Subject: [PATCH 45/56] wip Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-6.x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG-6.x.md b/CHANGELOG-6.x.md index 263dfdd1b..00641d6e9 100644 --- a/CHANGELOG-6.x.md +++ b/CHANGELOG-6.x.md @@ -6,7 +6,7 @@ This changelog references the relevant changes (bug and security fixes) done to ### Added -* Added `markTestSkippedWhen()` assertion helper to conditionally handle `markTestSkipped()`. +* Added `markTestSkippedWhen()` and `markTestSkippedUnless()` assertion helper to conditionally handle `markTestSkipped()`. * Added `Orchestra\Testbench\default_migration_path()` helper function. * Added `Orchestra\Testbench\laravel_vendor_exists()` helper function. From bd584be92b7d0466f47373eafa5ec3ce47cf38f9 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 21:04:35 +0800 Subject: [PATCH 46/56] Prepare 6.53.0 release Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-6.x.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-6.x.md b/CHANGELOG-6.x.md index 00641d6e9..abc7ab0b3 100644 --- a/CHANGELOG-6.x.md +++ b/CHANGELOG-6.x.md @@ -2,7 +2,9 @@ This changelog references the relevant changes (bug and security fixes) done to `orchestra/testbench-core`. -## Unreleased +## 6.53.0 + +Released: 2024-09-23 ### Added @@ -14,6 +16,10 @@ This changelog references the relevant changes (bug and security fixes) done to * Allow Testbench to delete `vendor` symlink directory if it was created while running tests. +### Fixes + +* Fixes `view.paths` configuration not being updated to include `workbench/resources/views` due to IoC booting sequence. + ### Deprecated * Deprecated `Orchestra\Testbench\laravel_migration_path()`, use `default_migration_path()` instead. From 620c404531b4e3a339aebbf0d58103191e9b0f7f Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 21:10:37 +0800 Subject: [PATCH 47/56] Prepare 7.47.0 release Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-7.x.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CHANGELOG-7.x.md b/CHANGELOG-7.x.md index 20119cc04..e355102ca 100644 --- a/CHANGELOG-7.x.md +++ b/CHANGELOG-7.x.md @@ -2,6 +2,35 @@ This changelog references the relevant changes (bug and security fixes) done to `orchestra/testbench-core`. +## 7.47.0 + +Released: 2024-09-23 + +### Added + +* Added `markTestSkippedWhen()` and `markTestSkippedUnless()` assertion helper to conditionally handle `markTestSkipped()`. +* Added `Orchestra\Testbench\default_migration_path()` helper function. +* Added `Orchestra\Testbench\laravel_vendor_exists()` helper function. +* Allows TestCase to inherit Attributes defined on parent TestCase by @BlackLanzer in #221. + +### Changes + +* Allow Testbench to delete `vendor` symlink directory if it was created while running tests. + +### Fixes + +* Fixes `view.paths` configuration not being updated to include `workbench/resources/views` due to IoC booting sequence. + +### Deprecated + +* Deprecated `Orchestra\Testbench\laravel_migration_path()`, use `default_migration_path()` instead. + + + ## 7.46.0 Released: 2024-08-26 From b730b7350483d08a9e89bfc6b46bdb68dbdc0601 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 21:13:33 +0800 Subject: [PATCH 48/56] wip Signed-off-by: Mior Muhammad Zaki --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 1648e9264..45316f261 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,7 @@ }, "require-dev": { "fakerphp/faker": "^1.21", - "laravel/framework": "^10.48.20", + "laravel/framework": "^10.48.22", "laravel/pint": "^1.17", "mockery/mockery": "^1.5.1", "phpstan/phpstan": "^1.11", @@ -53,7 +53,7 @@ }, "conflict": { "brianium/paratest": "<6.4.0 || >=7.0.0 <7.1.4 || >=8.0.0", - "laravel/framework": "<10.48.20 || >=11.0.0", + "laravel/framework": "<10.48.22 || >=11.0.0", "laravel/serializable-closure": "<1.3.0 || >=2.0.0", "nunomaduro/collision": "<6.4.0 || >=7.0.0 <7.4.0 || >=8.0.0", "orchestra/testbench-dusk": "<8.21.0 || >=9.0.0", From da34fc0fc3afdb4a1beb407fc64731486cc4f418 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 21:15:59 +0800 Subject: [PATCH 49/56] Prepare 8.28.0 release Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-8.x.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CHANGELOG-8.x.md b/CHANGELOG-8.x.md index 21b2dd9e3..8e8d1f0f9 100644 --- a/CHANGELOG-8.x.md +++ b/CHANGELOG-8.x.md @@ -2,6 +2,35 @@ This changelog references the relevant changes (bug and security fixes) done to `orchestra/testbench-core`. +## 8.28.0 + +Released: 2024-09-23 + +### Added + +* Added `markTestSkippedWhen()` and `markTestSkippedUnless()` assertion helper to conditionally handle `markTestSkipped()`. +* Added `Orchestra\Testbench\default_migration_path()` helper function. +* Added `Orchestra\Testbench\laravel_vendor_exists()` helper function. +* Allows TestCase to inherit Attributes defined on parent TestCase by @BlackLanzer in #221. + +### Changes + +* Allow Testbench to delete `vendor` symlink directory if it was created while running tests. + +### Fixes + +* Fixes `view.paths` configuration not being updated to include `workbench/resources/views` due to IoC booting sequence. + +### Deprecated + +* Deprecated `Orchestra\Testbench\laravel_migration_path()`, use `default_migration_path()` instead. + + + ## 8.27.0 Released: 2024-08-26 From 4880c3f840cac2b9c0a26d46e927d1994aabc69f Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 21:18:23 +0800 Subject: [PATCH 50/56] Prepare 9.5.0 release Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-9.x.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/CHANGELOG-9.x.md b/CHANGELOG-9.x.md index e2be6fa51..9fde054c0 100644 --- a/CHANGELOG-9.x.md +++ b/CHANGELOG-9.x.md @@ -2,6 +2,36 @@ This changelog references the relevant changes (bug and security fixes) done to `orchestra/testbench-core`. +## 9.5.0 + +Released: 2024-09-23 + +### Added + +* Added `Orchestra\Testbench\Attributes\RequiresDatabase` attribute class. +* Added `markTestSkippedWhen()` and `markTestSkippedUnless()` assertion helper to conditionally handle `markTestSkipped()`. +* Added `Orchestra\Testbench\default_migration_path()` helper function. +* Added `Orchestra\Testbench\laravel_vendor_exists()` helper function. +* Allows TestCase to inherit Attributes defined on parent TestCase by @BlackLanzer in #221. + +### Changes + +* Allow Testbench to delete `vendor` symlink directory if it was created while running tests. + +### Fixes + +* Fixes `view.paths` configuration not being updated to include `workbench/resources/views` due to IoC booting sequence. + +### Deprecated + +* Deprecated `Orchestra\Testbench\laravel_migration_path()`, use `default_migration_path()` instead. + + + ## 9.4.1 Released: 2024-09-12 From 337f15ef6c7d7cc21b56a32f515e6c32a1744ec1 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 21:31:38 +0800 Subject: [PATCH 51/56] wip Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-7.x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG-7.x.md b/CHANGELOG-7.x.md index e355102ca..7fc187cc4 100644 --- a/CHANGELOG-7.x.md +++ b/CHANGELOG-7.x.md @@ -11,7 +11,7 @@ Released: 2024-09-23 * Added `markTestSkippedWhen()` and `markTestSkippedUnless()` assertion helper to conditionally handle `markTestSkipped()`. * Added `Orchestra\Testbench\default_migration_path()` helper function. * Added `Orchestra\Testbench\laravel_vendor_exists()` helper function. -* Allows TestCase to inherit Attributes defined on parent TestCase by @BlackLanzer in #221. +* Allows TestCase to inherit Attributes defined on parent TestCase by @BlackLanzer in #233. ### Changes From b98a0d3ccb6d290d2234d51758d42f5f54a7e579 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 23 Sep 2024 21:31:57 +0800 Subject: [PATCH 52/56] wip Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-8.x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG-8.x.md b/CHANGELOG-8.x.md index 8e8d1f0f9..5d4e811b2 100644 --- a/CHANGELOG-8.x.md +++ b/CHANGELOG-8.x.md @@ -11,7 +11,7 @@ Released: 2024-09-23 * Added `markTestSkippedWhen()` and `markTestSkippedUnless()` assertion helper to conditionally handle `markTestSkipped()`. * Added `Orchestra\Testbench\default_migration_path()` helper function. * Added `Orchestra\Testbench\laravel_vendor_exists()` helper function. -* Allows TestCase to inherit Attributes defined on parent TestCase by @BlackLanzer in #221. +* Allows TestCase to inherit Attributes defined on parent TestCase by @BlackLanzer in #233. ### Changes From 549eaf5c30cdf9460f68ece2f7d78f5965032694 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Tue, 24 Sep 2024 13:18:21 +0800 Subject: [PATCH 53/56] [8.x] Fixes Incompatibility with PHPUnit 10.3 (#241) * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki --- .github/workflows/strict-tests.yaml | 2 ++ .github/workflows/tests.yaml | 1 - composer.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/strict-tests.yaml b/.github/workflows/strict-tests.yaml index f31e03416..b2864d8af 100644 --- a/.github/workflows/strict-tests.yaml +++ b/.github/workflows/strict-tests.yaml @@ -21,6 +21,8 @@ jobs: - 8.3 phpunit: - "~10.1.0" + - "~10.2.0" + - "~10.3.0" - "~10.4.0" - "~10.5.0" - "10.5.4" diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 0a3d64ba2..8bf6172b3 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -22,7 +22,6 @@ jobs: - 8.3 phpunit: - "~10.1.0" - - "~10.4.0" - "~10.5.0" - "10.5.4" dependencies: diff --git a/composer.json b/composer.json index 45316f261..e6b27f518 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "nunomaduro/collision": "<6.4.0 || >=7.0.0 <7.4.0 || >=8.0.0", "orchestra/testbench-dusk": "<8.21.0 || >=9.0.0", "orchestra/workbench": "<1.0.0", - "phpunit/phpunit": "<9.6.0 || >=10.6.0" + "phpunit/phpunit": "<9.6.0 || >=10.3.0 <10.3.3 || >=10.6.0" }, "suggest": { "ext-pcntl": "Required to use all features of the console signal trapping.", From 0ccd5794f4d37da755887b856c4c78ef210971a9 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Tue, 24 Sep 2024 13:23:59 +0800 Subject: [PATCH 54/56] Prepare 8.28.1 release Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-8.x.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG-8.x.md b/CHANGELOG-8.x.md index 5d4e811b2..1d5f1994c 100644 --- a/CHANGELOG-8.x.md +++ b/CHANGELOG-8.x.md @@ -4,6 +4,14 @@ This changelog references the relevant changes (bug and security fixes) done to ## 8.28.0 +Released: 2024-09-24 + +### Fixes + +* Fixes compatibility with PHPUnit 10.3. + +## 8.28.0 + Released: 2024-09-23 ### Added From 105307ca26146a4914e23731d49bcf26e726afc8 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Tue, 24 Sep 2024 13:26:37 +0800 Subject: [PATCH 55/56] wip Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-8.x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG-8.x.md b/CHANGELOG-8.x.md index 1d5f1994c..323cfa49d 100644 --- a/CHANGELOG-8.x.md +++ b/CHANGELOG-8.x.md @@ -2,7 +2,7 @@ This changelog references the relevant changes (bug and security fixes) done to `orchestra/testbench-core`. -## 8.28.0 +## 8.28.1 Released: 2024-09-24 From a5ab70e78378363b69220ae5771dabe8c885a25e Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Tue, 24 Sep 2024 13:26:51 +0800 Subject: [PATCH 56/56] wip Signed-off-by: Mior Muhammad Zaki --- CHANGELOG-8.x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG-8.x.md b/CHANGELOG-8.x.md index 1d5f1994c..323cfa49d 100644 --- a/CHANGELOG-8.x.md +++ b/CHANGELOG-8.x.md @@ -2,7 +2,7 @@ This changelog references the relevant changes (bug and security fixes) done to `orchestra/testbench-core`. -## 8.28.0 +## 8.28.1 Released: 2024-09-24