diff --git a/docs/Shared/Upgrade/FromV6.md b/docs/Shared/Upgrade/FromV6.md new file mode 100644 index 000000000..922f296b9 --- /dev/null +++ b/docs/Shared/Upgrade/FromV6.md @@ -0,0 +1 @@ +* [ ] Direct usages of `Container::getInstances()` were replaced by explicit constructor parameters. You may need to update your code accordingly (#151). diff --git a/packages/core/UPGRADE.md b/packages/core/UPGRADE.md index e0923624f..afed3828d 100644 --- a/packages/core/UPGRADE.md +++ b/packages/core/UPGRADE.md @@ -27,6 +27,18 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases) [//]: # (end: c70a9a43c0a80bd2e7fa6010a9b2c0fbcab4cb4d536d7a498216d9df7431f7e2) +# Upgrade from v6 + +[include:file]: ../../docs/Shared/Upgrade/FromV6.md +[//]: # (start: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) +[//]: # (warning: Generated automatically. Do not edit.) + +* [ ] Direct usages of `Container::getInstances()` were replaced by explicit constructor parameters. You may need to update your code accordingly (#151). + +[//]: # (end: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) + +* [ ] `\LastDragon_ru\LaraASP\Core\Provider\WithRoutes::bootRoutes()` requires settings. + # Upgrade from v5 [include:file]: ../../docs/Shared/Upgrade/FromV5.md diff --git a/packages/core/src/Helpers/Translator.php b/packages/core/src/Helpers/Translator.php index 53598945e..f274c8ca2 100644 --- a/packages/core/src/Helpers/Translator.php +++ b/packages/core/src/Helpers/Translator.php @@ -16,12 +16,15 @@ abstract class Translator { public function __construct( protected TranslatorContract $translator, - protected string $package, - protected string|null $group = 'messages', ) { // empty } + /** + * Should return the name of the package. + */ + abstract protected function getName(): string; + /** * @param list|string $key * @param array $replace @@ -59,9 +62,7 @@ public function setLocale(string $locale): static { } protected function key(string $key): string { - return $this->group - ? "{$this->package}::{$this->group}.{$key}" - : "{$this->package}::{$key}"; + return "{$this->getName()}::messages.{$key}"; } /** diff --git a/packages/core/src/Helpers/TranslatorTest.php b/packages/core/src/Helpers/TranslatorTest.php index 00f6ba247..421e7c421 100644 --- a/packages/core/src/Helpers/TranslatorTest.php +++ b/packages/core/src/Helpers/TranslatorTest.php @@ -2,12 +2,12 @@ namespace LastDragon_ru\LaraASP\Core\Helpers; -use Illuminate\Container\Container; use Illuminate\Contracts\Translation\Translator; use LastDragon_ru\LaraASP\Core\Helpers\Translator as PackageTranslator; use LastDragon_ru\LaraASP\Core\Package; use LastDragon_ru\LaraASP\Core\Testing\Package\TestCase; use LastDragon_ru\LaraASP\Testing\Utils\WithTranslations; +use Override; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; @@ -36,9 +36,12 @@ public function testChoice( ): void { $this->setTranslations($translations); - $implementation = Container::getInstance()->make(Translator::class); - $translator = new class($implementation, Package::Name, null) extends PackageTranslator { - // empty + $implementation = $this->app()->make(Translator::class); + $translator = new class($implementation) extends PackageTranslator { + #[Override] + protected function getName(): string { + return Package::Name; + } }; self::assertEquals($expected, $translator->choice($key, $number, $replace, $locale)); @@ -59,9 +62,12 @@ public function testGet( ): void { $this->setTranslations($translations); - $implementation = Container::getInstance()->make(Translator::class); - $translator = new class($implementation, Package::Name, null) extends PackageTranslator { - // empty + $implementation = $this->app()->make(Translator::class); + $translator = new class($implementation) extends PackageTranslator { + #[Override] + protected function getName(): string { + return Package::Name; + } }; self::assertEquals($expected, $translator->get($key, $replace, $locale)); @@ -89,7 +95,7 @@ public static function dataProviderGet(): array { static function (TestCase $test, string $currentLocale, string $fallbackLocale): array { return [ $currentLocale => [ - Package::Name.'::should.be.translated' => 'translated :value', + Package::Name.'::messages.should.be.translated' => 'translated :value', ], ]; }, @@ -104,7 +110,7 @@ static function (TestCase $test, string $currentLocale, string $fallbackLocale): static function (TestCase $test, string $currentLocale, string $fallbackLocale): array { return [ $currentLocale => [ - Package::Name.'::should.be.translated' => 'translated', + Package::Name.'::messages.should.be.translated' => 'translated', ], ]; }, @@ -119,7 +125,7 @@ static function (TestCase $test, string $currentLocale, string $fallbackLocale): static function (TestCase $test, string $currentLocale, string $fallbackLocale): array { return [ 'unk' => [ - Package::Name.'::should.be.translated' => 'translated :value', + Package::Name.'::messages.should.be.translated' => 'translated :value', ], ]; }, @@ -152,7 +158,7 @@ public static function dataProviderChoice(): array { static function (TestCase $test, string $currentLocale, string $fallbackLocale): array { return [ $currentLocale => [ - Package::Name.'::should.be.translated' => '{1} one |[2,*] translated :value', + Package::Name.'::messages.should.be.translated' => '{1} one |[2,*] translated :value', ], ]; }, @@ -168,7 +174,7 @@ static function (TestCase $test, string $currentLocale, string $fallbackLocale): static function (TestCase $test, string $currentLocale, string $fallbackLocale): array { return [ $currentLocale => [ - Package::Name.'::should.be.translated' => '{1} one |[2,*] translated :value', + Package::Name.'::messages.should.be.translated' => '{1} one |[2,*] translated :value', ], ]; }, @@ -184,7 +190,7 @@ static function (TestCase $test, string $currentLocale, string $fallbackLocale): static function (TestCase $test, string $currentLocale, string $fallbackLocale): array { return [ 'unk' => [ - Package::Name.'::should.be.translated' => '{1} one |[2,*] translated :value', + Package::Name.'::messages.should.be.translated' => '{1} one |[2,*] translated :value', ], ]; }, diff --git a/packages/core/src/Helpers/Viewer.php b/packages/core/src/Helpers/Viewer.php index f8e8f004e..e15b5b7b9 100644 --- a/packages/core/src/Helpers/Viewer.php +++ b/packages/core/src/Helpers/Viewer.php @@ -10,21 +10,21 @@ */ abstract class Viewer { public function __construct( - protected readonly Translator $translator, protected readonly ViewFactoryContract $factory, - protected readonly string $package, ) { // empty } + /** + * Should return the name of the package. + */ + abstract protected function getName(): string; + /** * @param array $data */ public function get(string $view, array $data = []): ViewContract { - return $this->factory->make( - "{$this->package}::{$view}", - $this->getDefaultData() + $data, - ); + return $this->factory->make("{$this->getName()}::{$view}", $data); } /** @@ -33,13 +33,4 @@ public function get(string $view, array $data = []): ViewContract { public function render(string $view, array $data = []): string { return $this->get($view, $data)->render(); } - - /** - * @return array - */ - protected function getDefaultData(): array { - return [ - 'translator' => $this->translator, - ]; - } } diff --git a/packages/core/src/Helpers/ViewerTest.php b/packages/core/src/Helpers/ViewerTest.php index 4d423b7b7..0805fda2b 100644 --- a/packages/core/src/Helpers/ViewerTest.php +++ b/packages/core/src/Helpers/ViewerTest.php @@ -6,6 +6,7 @@ use Illuminate\Contracts\View\View as ViewContract; use LastDragon_ru\LaraASP\Core\Testing\Package\TestCase; use Mockery; +use Override; use PHPUnit\Framework\Attributes\CoversClass; /** @@ -14,40 +15,48 @@ #[CoversClass(Viewer::class)] final class ViewerTest extends TestCase { public function testGet(): void { - $view = 'view'; - $data = ['a' => 123]; - $package = 'package'; - $translator = Mockery::mock(Translator::class); - $factory = Mockery::mock(ViewFactory::class); + $view = 'view'; + $data = ['a' => 123]; + $package = 'package'; + $factory = Mockery::mock(ViewFactory::class); $factory ->shouldReceive('make') - ->with("{$package}::{$view}", ['translator' => $translator] + $data) + ->with("{$package}::{$view}", $data) ->once() ->andReturn( Mockery::mock(ViewContract::class), ); - $viewer = new class($translator, $factory, $package) extends Viewer { - // empty + $viewer = new class($factory, $package) extends Viewer { + public function __construct( + ViewFactory $factory, + private readonly string $package, + ) { + parent::__construct($factory); + } + + #[Override] + protected function getName(): string { + return $this->package; + } }; $viewer->get($view, $data); } public function testRender(): void { - $view = 'view'; - $data = ['a' => 123]; - $package = 'package'; - $content = 'content'; - $translator = Mockery::mock(Translator::class); - $factory = Mockery::mock(ViewFactory::class); - $template = Mockery::mock(ViewContract::class); + $view = 'view'; + $data = ['a' => 123]; + $package = 'package'; + $content = 'content'; + $factory = Mockery::mock(ViewFactory::class); + $template = Mockery::mock(ViewContract::class); $template ->shouldReceive('render') ->once() ->andReturn($content); - $viewer = Mockery::mock(Viewer::class, [$translator, $factory, $package]); + $viewer = Mockery::mock(Viewer::class, [$factory, $package]); $viewer->makePartial(); $viewer ->shouldReceive('get') diff --git a/packages/core/src/Provider/Helper.php b/packages/core/src/Provider/Helper.php index 38b62dc13..c9baa4a54 100644 --- a/packages/core/src/Provider/Helper.php +++ b/packages/core/src/Provider/Helper.php @@ -2,15 +2,11 @@ namespace LastDragon_ru\LaraASP\Core\Provider; -use Illuminate\Support\ServiceProvider; use ReflectionClass; use function dirname; use function ltrim; -/** - * @mixin ServiceProvider - */ trait Helper { /** * Should return the name of the package. diff --git a/packages/core/src/Provider/WithConfig.php b/packages/core/src/Provider/WithConfig.php index d1666a92f..08055bc4b 100644 --- a/packages/core/src/Provider/WithConfig.php +++ b/packages/core/src/Provider/WithConfig.php @@ -2,14 +2,13 @@ namespace LastDragon_ru\LaraASP\Core\Provider; -use Illuminate\Container\Container; use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Foundation\CachesConfiguration; use Illuminate\Support\ServiceProvider; use LastDragon_ru\LaraASP\Core\Utils\ConfigMerger; /** - * @mixin ServiceProvider + * @phpstan-require-extends ServiceProvider */ trait WithConfig { use Helper; @@ -26,7 +25,7 @@ protected function bootConfig(): void { protected function loadConfigFrom(string $path, string $key): void { if (!($this->app instanceof CachesConfiguration && $this->app->configurationIsCached())) { - $repository = Container::getInstance()->make(Repository::class); + $repository = $this->app->make(Repository::class); $merger = new ConfigMerger(); $target = (array) require $path; $current = (array) $repository->get($key, []); diff --git a/packages/core/src/Provider/WithRoutes.php b/packages/core/src/Provider/WithRoutes.php index 62c7be19d..beeb0e600 100644 --- a/packages/core/src/Provider/WithRoutes.php +++ b/packages/core/src/Provider/WithRoutes.php @@ -2,15 +2,41 @@ namespace LastDragon_ru\LaraASP\Core\Provider; +use Closure; +use Illuminate\Contracts\Foundation\CachesRoutes; +use Illuminate\Contracts\Routing\Registrar; use Illuminate\Support\ServiceProvider; /** - * @mixin ServiceProvider + * @phpstan-require-extends ServiceProvider */ trait WithRoutes { use Helper; - protected function bootRoutes(): void { - $this->loadRoutesFrom($this->getPath('../defaults/routes.php')); + /** + * @param Closure(): array{enabled: bool, attributes: array} $settings + */ + protected function bootRoutes(Closure $settings): void { + // Cached? + if ($this->app instanceof CachesRoutes && $this->app->routesAreCached()) { + return; + } + + // Load (config may be incomplete until boot) + $this->booted(function () use ($settings): void { + // Enabled? + $settings = $settings(); + + if (!$settings['enabled'] || !$this->app->bound(Registrar::class)) { + return; + } + + // Add + $path = $this->getPath('../defaults/routes.php'); + $routes = require $path; + $registrar = $this->app->make(Registrar::class); + + $registrar->group($settings['attributes'], $routes); + }); } } diff --git a/packages/core/src/Provider/WithSchedule.php b/packages/core/src/Provider/WithSchedule.php index 6597a06fb..039501372 100644 --- a/packages/core/src/Provider/WithSchedule.php +++ b/packages/core/src/Provider/WithSchedule.php @@ -3,12 +3,12 @@ namespace LastDragon_ru\LaraASP\Core\Provider; use Illuminate\Console\Scheduling\Schedule; -use Illuminate\Container\Container; +use Illuminate\Contracts\Container\Container; use Illuminate\Support\ServiceProvider; use LastDragon_ru\LaraASP\Core\Utils\Scheduler; /** - * @mixin ServiceProvider + * @phpstan-require-extends ServiceProvider */ trait WithSchedule { /** @@ -21,8 +21,8 @@ protected function bootSchedule(string ...$jobs): void { $this->callAfterResolving( Schedule::class, - static function (Schedule $schedule) use ($jobs): void { - $scheduler = Container::getInstance()->make(Scheduler::class); + static function (Schedule $schedule, Container $container) use ($jobs): void { + $scheduler = $container->make(Scheduler::class); foreach ($jobs as $job) { $scheduler->register($schedule, $job); diff --git a/packages/core/src/Provider/WithScheduleTest.php b/packages/core/src/Provider/WithScheduleTest.php index 308186731..e97e74ffe 100644 --- a/packages/core/src/Provider/WithScheduleTest.php +++ b/packages/core/src/Provider/WithScheduleTest.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\Core\Provider; use Illuminate\Console\Scheduling\Schedule; -use Illuminate\Container\Container; use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\ServiceProvider; use LastDragon_ru\LaraASP\Core\Testing\Package\TestCase; @@ -26,13 +25,13 @@ public function testRegistration(): void { ->andReturn(true); }); - $provider = Container::getInstance()->make(WithScheduleTest_Provider::class, [ - 'app' => $this->app, + $provider = $this->app()->make(WithScheduleTest_Provider::class, [ + 'app' => $this->app(), ]); $provider->boot(); - Container::getInstance()->make(Schedule::class); + $this->app()->make(Schedule::class); } public function testApplication(): void { @@ -46,7 +45,7 @@ public function testApplication(): void { ->with(Schedule::class, Mockery::any()) ->never(); - $provider = Container::getInstance()->make(WithScheduleTest_Provider::class, [ + $provider = $this->app()->make(WithScheduleTest_Provider::class, [ 'app' => $app, ]); @@ -69,7 +68,7 @@ public function testConsoleApplication(): void { ->once() ->andReturns(); - $provider = Container::getInstance()->make(WithScheduleTest_Provider::class, [ + $provider = $this->app()->make(WithScheduleTest_Provider::class, [ 'app' => $app, ]); diff --git a/packages/core/src/Provider/WithTranslations.php b/packages/core/src/Provider/WithTranslations.php index 8fc44b103..98b3f3436 100644 --- a/packages/core/src/Provider/WithTranslations.php +++ b/packages/core/src/Provider/WithTranslations.php @@ -8,7 +8,7 @@ /** * @see Translator * - * @mixin ServiceProvider + * @phpstan-require-extends ServiceProvider */ trait WithTranslations { use Helper; diff --git a/packages/core/src/Provider/WithViews.php b/packages/core/src/Provider/WithViews.php index c72a197a6..03326a443 100644 --- a/packages/core/src/Provider/WithViews.php +++ b/packages/core/src/Provider/WithViews.php @@ -8,7 +8,7 @@ /** * @see Viewer * - * @mixin ServiceProvider + * @phpstan-require-extends ServiceProvider */ trait WithViews { use Helper; diff --git a/packages/core/src/Testing/Package/TestCase.php b/packages/core/src/Testing/Package/TestCase.php index 8dbda9943..84ec5c662 100644 --- a/packages/core/src/Testing/Package/TestCase.php +++ b/packages/core/src/Testing/Package/TestCase.php @@ -2,11 +2,23 @@ namespace LastDragon_ru\LaraASP\Core\Testing\Package; +use LastDragon_ru\LaraASP\Core\Provider; use LastDragon_ru\LaraASP\Testing\Package\TestCase as PackageTestCase; +use Override; + +use function array_merge; /** * @internal */ abstract class TestCase extends PackageTestCase { - // empty + /** + * @inheritDoc + */ + #[Override] + protected function getPackageProviders(mixed $app): array { + return array_merge(parent::getPackageProviders($app), [ + Provider::class, + ]); + } } diff --git a/packages/core/src/Utils/Scheduler.php b/packages/core/src/Utils/Scheduler.php index dd09c1b31..3c803fbc7 100644 --- a/packages/core/src/Utils/Scheduler.php +++ b/packages/core/src/Utils/Scheduler.php @@ -4,9 +4,9 @@ use DateTimeZone; use Illuminate\Console\Scheduling\Schedule; -use Illuminate\Container\Container; use Illuminate\Contracts\Queue\ShouldQueue; use InvalidArgumentException; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use LastDragon_ru\LaraASP\Core\Contracts\Schedulable; use function array_intersect_key; @@ -24,7 +24,9 @@ * } */ class Scheduler { - public function __construct() { + public function __construct( + private readonly ContainerResolver $container, + ) { // empty } @@ -33,7 +35,7 @@ public function __construct() { */ public function register(Schedule $schedule, string $class): bool { // Config - $instance = Container::getInstance()->make($class); + $instance = $this->container->getInstance()->make($class); $settings = $this->getSettings($class, $instance); // Enabled? diff --git a/packages/core/src/Utils/SchedulerTest.php b/packages/core/src/Utils/SchedulerTest.php index 50dbedaa2..da2061b4e 100644 --- a/packages/core/src/Utils/SchedulerTest.php +++ b/packages/core/src/Utils/SchedulerTest.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\Core\Utils; use Illuminate\Console\Scheduling\Schedule; -use Illuminate\Container\Container; use Illuminate\Contracts\Queue\ShouldQueue; use LastDragon_ru\LaraASP\Core\Contracts\Schedulable; use LastDragon_ru\LaraASP\Core\Testing\Package\TestCase; @@ -66,8 +65,8 @@ public function __invoke(): void { ->andReturnSelf(); }); - $schedule = Container::getInstance()->make(Schedule::class); - $scheduler = Container::getInstance()->make(Scheduler::class); + $schedule = $this->app()->make(Schedule::class); + $scheduler = $this->app()->make(Scheduler::class); self::assertTrue( $scheduler->register($schedule, $job::class), @@ -111,8 +110,8 @@ public function getSchedule(): array { ->never(); }); - $schedule = Container::getInstance()->make(Schedule::class); - $scheduler = Container::getInstance()->make(Scheduler::class); + $schedule = $this->app()->make(Schedule::class); + $scheduler = $this->app()->make(Scheduler::class); self::assertTrue( $scheduler->register($schedule, $job::class), @@ -134,7 +133,7 @@ public function getSchedule(): array { }; $schedule = Mockery::mock(Schedule::class); - $scheduler = Container::getInstance()->make(Scheduler::class); + $scheduler = $this->app()->make(Scheduler::class); self::assertFalse( $scheduler->register($schedule, $job::class), @@ -156,7 +155,7 @@ public function getSchedule(): array { }; $schedule = Mockery::mock(Schedule::class); - $scheduler = Container::getInstance()->make(Scheduler::class); + $scheduler = $this->app()->make(Scheduler::class); self::assertFalse( $scheduler->register($schedule, $job::class), @@ -169,7 +168,7 @@ public function testRegisterDefaultSettings(): void { }; $schedule = Mockery::mock(Schedule::class); - $scheduler = Container::getInstance()->make(Scheduler::class); + $scheduler = $this->app()->make(Scheduler::class); self::assertFalse( $scheduler->register($schedule, $job::class), diff --git a/packages/dev/composer.json b/packages/dev/composer.json index ae9ceec22..799068231 100644 --- a/packages/dev/composer.json +++ b/packages/dev/composer.json @@ -19,7 +19,6 @@ }, "require": { "php": "^8.1|^8.2|^8.3", - "illuminate/container": "^10.34.0|^11.0.0", "illuminate/console": "^10.34.0|^11.0.0", "illuminate/contracts": "^10.34.0|^11.0.0", "illuminate/support": "^10.34.0|^11.0.0", diff --git a/packages/dev/src/App/Example.php b/packages/dev/src/App/Example.php index 755c6a7a4..8a442ff32 100644 --- a/packages/dev/src/App/Example.php +++ b/packages/dev/src/App/Example.php @@ -3,8 +3,8 @@ namespace LastDragon_ru\LaraASP\Dev\App; use Illuminate\Console\Command; -use Illuminate\Container\Container; use Illuminate\Contracts\Config\Repository; +use Illuminate\Contracts\Foundation\Application; use LastDragon_ru\LaraASP\Core\Utils\Cast; use LastDragon_ru\LaraASP\Core\Utils\ConfigMerger; use LogicException; @@ -37,7 +37,8 @@ final class Example extends Command { private const Name = 'dev:example'; - private static ?Dumper $dumper = null; + private static ?Application $app = null; + private static ?Dumper $dumper = null; /** * @phpcsSuppress SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint @@ -62,12 +63,9 @@ protected static function getDumper(): Dumper { public function __invoke(Dumper $dumper): void { self::$dumper = $dumper; - $container = Container::getInstance(); - $config = $container->make(Repository::class); + self::$app = $this->laravel; $file = Cast::toString($this->argument('file')); - $container[Repository::class] = clone $config; - try { // Run (static function () use ($file): void { @@ -82,10 +80,8 @@ public function __invoke(Dumper $dumper): void { $this->output->writeln("{$output}"); } } finally { - Container::setInstance($container); - - $container[Repository::class] = $config; - self::$dumper = null; + self::$app = null; + self::$dumper = null; } } @@ -97,15 +93,25 @@ public static function raw(Stringable|string $value, string $type, string $expre self::getDumper()->raw($value, $expression ?? self::getExpression(__FUNCTION__), $type); } + protected static function app(): Application { + if (!self::$app) { + throw new LogicException( + sprintf( + 'The `%s` can be called only within example context.', + __METHOD__, + ), + ); + } + + return self::$app; + } + /** * @param array $settings */ public static function config(string $root, array $settings): void { - // Example? - self::getDumper(); - // Update - $repository = Container::getInstance()->make(Repository::class); + $repository = self::app()->make(Repository::class); $config = (array) $repository->get($root, []); $config = (new ConfigMerger())->merge([ConfigMerger::Strict => false], $config, $settings); diff --git a/packages/dev/src/PhpStan/Container/Extension.php b/packages/dev/src/PhpStan/Container/Extension.php index f0021cfda..02cbb2da4 100644 --- a/packages/dev/src/PhpStan/Container/Extension.php +++ b/packages/dev/src/PhpStan/Container/Extension.php @@ -2,8 +2,6 @@ namespace LastDragon_ru\LaraASP\Dev\PhpStan\Container; -use Illuminate\Container\Container; -use Illuminate\Contracts\Container\BindingResolutionException; use Illuminate\Contracts\Container\Container as ContainerContract; use Override; use PhpParser\Node\Arg; @@ -11,14 +9,10 @@ use PhpParser\Node\Expr\MethodCall; use PHPStan\Analyser\Scope; use PHPStan\Reflection\MethodReflection; -use PHPStan\Type\Constant\ConstantStringType; use PHPStan\Type\DynamicMethodReturnTypeExtension; -use PHPStan\Type\ObjectType; use PHPStan\Type\Type; -use function count; use function in_array; -use function is_object; /** * Provides proper return types for {@see Container::make()} without resolving @@ -62,42 +56,8 @@ public function getTypeFromMethodCall( // Return return match (true) { - $argType->isClassStringType()->yes() => $argType->getClassStringObjectType(), - $argType->getConstantStrings() !== [] => $this->getFromContainer($argType->getConstantStrings()), - default => null, + $argType->isClassStringType()->yes() => $argType->getClassStringObjectType(), + default => null, }; } - - /** - * @param list $constants - */ - protected function getFromContainer(array $constants): ?ObjectType { - // Unions are not supported - if (count($constants) !== 1) { - return null; - } - - // In the most cases, `$abstract` is the class/interface, but there are - // few of them which are not. - $abstract = $constants[0]->getValue(); - $strings = [ - 'migration.repository', - 'migrator', - ]; - $type = null; - - if (in_array($abstract, $strings, true)) { - try { - $concrete = Container::getInstance()->make($abstract); - - if (is_object($concrete)) { - $type = new ObjectType($concrete::class); - } - } catch (BindingResolutionException) { - // ignore - } - } - - return $type; - } } diff --git a/packages/documentator/UPGRADE.md b/packages/documentator/UPGRADE.md index e11f0898a..ab61c2fbc 100644 --- a/packages/documentator/UPGRADE.md +++ b/packages/documentator/UPGRADE.md @@ -27,6 +27,16 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases) [//]: # (end: c70a9a43c0a80bd2e7fa6010a9b2c0fbcab4cb4d536d7a498216d9df7431f7e2) +# Upgrade from v6 + +[include:file]: ../../docs/Shared/Upgrade/FromV6.md +[//]: # (start: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) +[//]: # (warning: Generated automatically. Do not edit.) + +* [ ] Direct usages of `Container::getInstances()` were replaced by explicit constructor parameters. You may need to update your code accordingly (#151). + +[//]: # (end: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) + # Upgrade from v5 [include:file]: ../../docs/Shared/Upgrade/FromV5.md diff --git a/packages/documentator/composer.json b/packages/documentator/composer.json index 6c3c51cee..d8349e216 100644 --- a/packages/documentator/composer.json +++ b/packages/documentator/composer.json @@ -22,8 +22,6 @@ "ext-mbstring": "*", "composer/semver": "^3.2", "illuminate/console": "^10.34.0|^11.0.0", - "illuminate/container": "^10.34.0|^11.0.0", - "illuminate/contracts": "^10.34.0|^11.0.0", "illuminate/process": "^10.34.0|^11.0.0", "illuminate/support": "^10.34.0|^11.0.0", "league/commonmark": "^2.4", diff --git a/packages/documentator/src/Commands/Preprocess.php b/packages/documentator/src/Commands/Preprocess.php index 790da022c..46b7a7d87 100644 --- a/packages/documentator/src/Commands/Preprocess.php +++ b/packages/documentator/src/Commands/Preprocess.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Commands; use Illuminate\Console\Command; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\Core\Utils\Cast; use LastDragon_ru\LaraASP\Documentator\Package; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Contracts\ParameterizableInstruction; @@ -82,7 +81,13 @@ class Preprocess extends Command { * Nested `` doesn't support. HELP; - public function __invoke(Filesystem $filesystem, Preprocessor $preprocessor): void { + public function __construct( + protected readonly Preprocessor $preprocessor, + ) { + parent::__construct(); + } + + public function __invoke(Filesystem $filesystem): void { $cwd = getcwd(); $path = Cast::toString($this->argument('path') ?? $cwd); $finder = Finder::create() @@ -96,10 +101,10 @@ public function __invoke(Filesystem $filesystem, Preprocessor $preprocessor): vo foreach ($finder as $file) { $this->components->task( $file->getPathname(), - static function () use ($filesystem, $preprocessor, $file): void { + function () use ($filesystem, $file): void { $path = $file->getPathname(); $content = $file->getContents(); - $result = $preprocessor->process($path, $content); + $result = $this->preprocessor->process($path, $content); if ($content !== $result) { $filesystem->dumpFile($path, $result); @@ -111,15 +116,13 @@ static function () use ($filesystem, $preprocessor, $file): void { #[Override] public function getProcessedHelp(): string { - $preprocessor = Container::getInstance()->make(Preprocessor::class); - return strtr(parent::getProcessedHelp(), [ - '%instructions%' => $this->getInstructionsHelp($preprocessor), + '%instructions%' => $this->getInstructionsHelp(), ]); } - protected function getInstructionsHelp(Preprocessor $preprocessor): string { - $instructions = $preprocessor->getInstructions(); + protected function getInstructionsHelp(): string { + $instructions = $this->preprocessor->getInstructions(); $help = []; foreach ($instructions as $instruction) { diff --git a/packages/documentator/src/Commands/PreprocessTest.php b/packages/documentator/src/Commands/PreprocessTest.php index 7a96b4dcb..7823879a2 100644 --- a/packages/documentator/src/Commands/PreprocessTest.php +++ b/packages/documentator/src/Commands/PreprocessTest.php @@ -3,8 +3,10 @@ namespace LastDragon_ru\LaraASP\Documentator\Commands; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Contracts\ParameterizableInstruction; +use LastDragon_ru\LaraASP\Documentator\Preprocessor\Preprocessor; use LastDragon_ru\LaraASP\Documentator\Testing\Package\TestCase; use LastDragon_ru\LaraASP\Serializer\Contracts\Serializable; +use Mockery; use Override; use PHPUnit\Framework\Attributes\CoversClass; @@ -14,7 +16,8 @@ #[CoversClass(Preprocess::class)] final class PreprocessTest extends TestCase { public function testGetInstructionParameters(): void { - $command = new class() extends Preprocess { + $preprocessor = Mockery::mock(Preprocessor::class); + $command = new class($preprocessor) extends Preprocess { /** * @inheritDoc */ diff --git a/packages/documentator/src/Commands/RequirementsTest.php b/packages/documentator/src/Commands/RequirementsTest.php index f47211338..0f95c72e3 100644 --- a/packages/documentator/src/Commands/RequirementsTest.php +++ b/packages/documentator/src/Commands/RequirementsTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Commands; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\Documentator\Metadata\Metadata; use LastDragon_ru\LaraASP\Documentator\Testing\Package\TestCase; use LastDragon_ru\LaraASP\Serializer\Contracts\Serializer; @@ -68,7 +67,7 @@ public function getMergedVersions(array $versions, array $merge): array { public function testGetRequirements(): void { $metadata = self::getTestData()->content('.json'); - $metadata = Container::getInstance()->make(Serializer::class)->deserialize(Metadata::class, $metadata); + $metadata = $this->app()->make(Serializer::class)->deserialize(Metadata::class, $metadata); $packages = [ 'laravel/framework' => 'Laravel', 'php' => 'PHP', diff --git a/packages/documentator/src/PackageTranslator.php b/packages/documentator/src/PackageTranslator.php index 6c0e4967a..da1fedcb1 100644 --- a/packages/documentator/src/PackageTranslator.php +++ b/packages/documentator/src/PackageTranslator.php @@ -2,11 +2,12 @@ namespace LastDragon_ru\LaraASP\Documentator; -use Illuminate\Contracts\Translation\Translator as TranslatorContract; use LastDragon_ru\LaraASP\Core\Helpers\Translator; +use Override; class PackageTranslator extends Translator { - public function __construct(TranslatorContract $translator) { - parent::__construct($translator, Package::Name); + #[Override] + protected function getName(): string { + return Package::Name; } } diff --git a/packages/documentator/src/PackageViewer.php b/packages/documentator/src/PackageViewer.php index ffef351c9..24a64fa61 100644 --- a/packages/documentator/src/PackageViewer.php +++ b/packages/documentator/src/PackageViewer.php @@ -2,11 +2,12 @@ namespace LastDragon_ru\LaraASP\Documentator; -use Illuminate\Contracts\View\Factory as ViewFactory; use LastDragon_ru\LaraASP\Core\Helpers\Viewer; +use Override; class PackageViewer extends Viewer { - public function __construct(PackageTranslator $translator, ViewFactory $factory) { - parent::__construct($translator, $factory, Package::Name); + #[Override] + protected function getName(): string { + return Package::Name; } } diff --git a/packages/documentator/src/Preprocessor/Instructions/IncludeDocBlock/InstructionTest.php b/packages/documentator/src/Preprocessor/Instructions/IncludeDocBlock/InstructionTest.php index a3c5c56a5..98342fc3c 100644 --- a/packages/documentator/src/Preprocessor/Instructions/IncludeDocBlock/InstructionTest.php +++ b/packages/documentator/src/Preprocessor/Instructions/IncludeDocBlock/InstructionTest.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Preprocessor\Instructions\IncludeDocBlock; use Exception; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Exceptions\TargetIsNotValidPhpFile; use LastDragon_ru\LaraASP\Documentator\Testing\Package\TestCase; use PHPUnit\Framework\Attributes\CoversClass; @@ -21,7 +20,7 @@ final class InstructionTest extends TestCase { #[DataProvider('dataProviderProcess')] public function testProcess(Exception|string $expected, string $file, Parameters $params): void { $file = self::getTestData()->file($file); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); if ($expected instanceof Exception) { self::expectExceptionObject($expected); @@ -36,7 +35,7 @@ public function testProcessAbsolute(): void { $path = 'invalid/directory'; $file = self::getTestData()->path('Valid.txt'); $params = new Parameters(); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); $expected = self::getTestData()->content('ValidExpected.txt'); self::assertEquals($expected, $instance->process($path, $file, $params)); diff --git a/packages/documentator/src/Preprocessor/Instructions/IncludeDocumentList/InstructionTest.php b/packages/documentator/src/Preprocessor/Instructions/IncludeDocumentList/InstructionTest.php index d409dc560..72f37990b 100644 --- a/packages/documentator/src/Preprocessor/Instructions/IncludeDocumentList/InstructionTest.php +++ b/packages/documentator/src/Preprocessor/Instructions/IncludeDocumentList/InstructionTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Preprocessor\Instructions\IncludeDocumentList; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Exceptions\DocumentTitleIsMissing; use LastDragon_ru\LaraASP\Documentator\Testing\Package\TestCase; use PHPUnit\Framework\Attributes\CoversClass; @@ -17,7 +16,7 @@ final class InstructionTest extends TestCase { public function testProcessSameDirectory(): void { $path = self::getTestData()->file('Document.md'); $params = new Parameters(); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); $actual = $instance->process($path->getPathname(), './', $params); self::assertEquals( @@ -33,7 +32,7 @@ public function testProcessSameDirectory(): void { public function testProcessAnotherDirectory(): void { $path = self::getTestData()->file('~AnotherDirectory.md'); $params = new Parameters(); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); $actual = $instance->process($path->getPathname(), basename(self::getTestData()->path('/')), $params); self::assertEquals( @@ -49,7 +48,7 @@ public function testProcessAnotherDirectory(): void { public function testProcessNestedDirectories(): void { $path = self::getTestData()->file('nested/Document.md'); $params = new Parameters(null); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); $actual = $instance->process($path->getPathname(), './', $params); self::assertEquals( @@ -66,7 +65,7 @@ public function testProcessWithoutTitle(): void { $path = self::getTestData()->file('invalid/Document.md'); $target = './'; $params = new Parameters(); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::expectExceptionObject( new DocumentTitleIsMissing( diff --git a/packages/documentator/src/Preprocessor/Instructions/IncludeExample/Instruction.php b/packages/documentator/src/Preprocessor/Instructions/IncludeExample/Instruction.php index 1c8b5e10e..baeb6dc66 100644 --- a/packages/documentator/src/Preprocessor/Instructions/IncludeExample/Instruction.php +++ b/packages/documentator/src/Preprocessor/Instructions/IncludeExample/Instruction.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Preprocessor\Instructions\IncludeExample; use Exception; -use Illuminate\Container\Container; use Illuminate\Process\Factory; use LastDragon_ru\LaraASP\Core\Utils\Path; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Contracts\ProcessableInstruction; @@ -26,10 +25,11 @@ class Instruction implements ProcessableInstruction { public const Limit = 50; protected const MarkdownRegexp = '/^\<(?Pmarkdown)\>(?P.*?)\<\/(?P=tag)\>$/msu'; - protected readonly Factory $factory; - public function __construct() { - $this->factory = Container::getInstance()->make(Factory::class); // next(documentator): Inject in constructor + public function __construct( + protected readonly Factory $factory, + ) { + // empty } #[Override] diff --git a/packages/documentator/src/Preprocessor/Instructions/IncludeExample/InstructionTest.php b/packages/documentator/src/Preprocessor/Instructions/IncludeExample/InstructionTest.php index 226d110fc..88594b80e 100644 --- a/packages/documentator/src/Preprocessor/Instructions/IncludeExample/InstructionTest.php +++ b/packages/documentator/src/Preprocessor/Instructions/IncludeExample/InstructionTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Preprocessor\Instructions\IncludeExample; -use Illuminate\Container\Container; use Illuminate\Process\Factory; use Illuminate\Process\PendingProcess; use LastDragon_ru\LaraASP\Documentator\Testing\Package\TestCase; @@ -23,12 +22,12 @@ public function testProcessNoRun(): void { $path = self::getTestData()->path('~example.md'); $file = basename(self::getTestData()->path('~example.md')); $expected = trim(self::getTestData()->content('~example.md')); - $factory = $this->override(Factory::class, static function (): Factory { - return Container::getInstance()->make(Factory::class) + $factory = $this->override(Factory::class, function (): Factory { + return $this->app()->make(Factory::class) ->preventStrayProcesses() ->fake(); }); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::assertEquals( <<path('~runnable.run'); $expected = trim(self::getTestData()->content('~runnable.md')); $output = 'command output'; - $factory = $this->override(Factory::class, static function () use ($command, $output): Factory { - $factory = Container::getInstance()->make(Factory::class); + $factory = $this->override(Factory::class, function () use ($command, $output): Factory { + $factory = $this->app()->make(Factory::class); $factory->preventStrayProcesses(); $factory->fake([ $command => $factory->result($output), @@ -57,7 +56,7 @@ public function testProcess(): void { return $factory; }); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::assertEquals( <<path('~runnable.run'); $expected = trim(self::getTestData()->content('~runnable.md')); $output = implode("\n", range(0, Instruction::Limit + 1)); - $factory = $this->override(Factory::class, static function () use ($command, $output): Factory { - $factory = Container::getInstance()->make(Factory::class); + $factory = $this->override(Factory::class, function () use ($command, $output): Factory { + $factory = $this->app()->make(Factory::class); $factory->preventStrayProcesses(); $factory->fake([ $command => $factory->result($output), @@ -95,7 +94,7 @@ public function testProcessLongOutput(): void { return $factory; }); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::assertEquals( <<path('~runnable.run'); $expected = trim(self::getTestData()->content('~runnable.md')); $output = 'command output'; - $factory = $this->override(Factory::class, static function () use ($command, $output): Factory { - $factory = Container::getInstance()->make(Factory::class); + $factory = $this->override(Factory::class, function () use ($command, $output): Factory { + $factory = $this->app()->make(Factory::class); $factory->preventStrayProcesses(); $factory->fake([ $command => $factory->result("{$output}"), @@ -135,7 +134,7 @@ public function testProcessMarkdown(): void { return $factory; }); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::assertEquals( <<path('~runnable.run'); $expected = trim(self::getTestData()->content('~runnable.md')); $output = implode("\n", range(0, Instruction::Limit + 1)); - $factory = $this->override(Factory::class, static function () use ($command, $output): Factory { - $factory = Container::getInstance()->make(Factory::class); + $factory = $this->override(Factory::class, function () use ($command, $output): Factory { + $factory = $this->app()->make(Factory::class); $factory->preventStrayProcesses(); $factory->fake([ $command => $factory->result("{$output}"), @@ -169,7 +168,7 @@ public function testProcessMarkdownLongOutput(): void { return $factory; }); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::assertEquals( <<factory = Container::getInstance()->make(Factory::class); // next(documentator): Inject in constructor + public function __construct( + protected readonly Factory $factory, + ) { + // empty } #[Override] diff --git a/packages/documentator/src/Preprocessor/Instructions/IncludeExec/InstructionTest.php b/packages/documentator/src/Preprocessor/Instructions/IncludeExec/InstructionTest.php index 41e85f3ae..ecacc3b0a 100644 --- a/packages/documentator/src/Preprocessor/Instructions/IncludeExec/InstructionTest.php +++ b/packages/documentator/src/Preprocessor/Instructions/IncludeExec/InstructionTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Preprocessor\Instructions\IncludeExec; -use Illuminate\Container\Container; use Illuminate\Process\Factory; use Illuminate\Process\PendingProcess; use LastDragon_ru\LaraASP\Documentator\Testing\Package\TestCase; @@ -19,8 +18,8 @@ public function testProcess(): void { $path = 'current/working/directory/file.md'; $expected = 'result'; $command = 'command to execute'; - $factory = $this->override(Factory::class, static function () use ($command, $expected): Factory { - $factory = Container::getInstance()->make(Factory::class); + $factory = $this->override(Factory::class, function () use ($command, $expected): Factory { + $factory = $this->app()->make(Factory::class); $factory->preventStrayProcesses(); $factory->fake([ $command => $factory->result($expected), @@ -28,7 +27,7 @@ public function testProcess(): void { return $factory; }); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::assertEquals($expected, $instance->process($path, $command)); diff --git a/packages/documentator/src/Preprocessor/Instructions/IncludeFile/InstructionTest.php b/packages/documentator/src/Preprocessor/Instructions/IncludeFile/InstructionTest.php index b20a418bd..0daa3b58c 100644 --- a/packages/documentator/src/Preprocessor/Instructions/IncludeFile/InstructionTest.php +++ b/packages/documentator/src/Preprocessor/Instructions/IncludeFile/InstructionTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Preprocessor\Instructions\IncludeFile; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\Documentator\Testing\Package\TestCase; use PHPUnit\Framework\Attributes\CoversClass; @@ -13,7 +12,7 @@ final class InstructionTest extends TestCase { public function testProcessRelative(): void { $file = self::getTestData()->file('.md'); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); $expected = self::getTestData()->content('.md'); self::assertEquals($expected, $instance->process($file->getPathname(), $file->getFilename())); @@ -22,7 +21,7 @@ public function testProcessRelative(): void { public function testProcessAbsolute(): void { $path = 'invalid/directory'; $file = self::getTestData()->path('.md'); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); $expected = self::getTestData()->content('.md'); self::assertEquals($expected, $instance->process($path, $file)); diff --git a/packages/documentator/src/Preprocessor/Instructions/IncludeGraphqlDirective/InstructionTest.php b/packages/documentator/src/Preprocessor/Instructions/IncludeGraphqlDirective/InstructionTest.php index b85c27669..859679709 100644 --- a/packages/documentator/src/Preprocessor/Instructions/IncludeGraphqlDirective/InstructionTest.php +++ b/packages/documentator/src/Preprocessor/Instructions/IncludeGraphqlDirective/InstructionTest.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Preprocessor\Instructions\IncludeGraphqlDirective; use GraphQL\Language\Parser; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Exceptions\DependencyIsMissing; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Exceptions\TargetIsNotDirective; use LastDragon_ru\LaraASP\Documentator\Testing\Package\TestCase; @@ -41,7 +40,7 @@ public function testProcess(): void { return (new Printer())->setDirectiveResolver($resolver); }); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); $actual = $instance->process('path/to/file.md', '@test'); self::assertEquals( @@ -55,11 +54,11 @@ public function testProcess(): void { } public function testProcessNoPrinter(): void { - unset(Container::getInstance()[PrinterContract::class]); + unset($this->app()[PrinterContract::class]); $path = 'path/to/file.md'; $target = '@test'; - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::expectExceptionObject( new DependencyIsMissing($path, $target, PrinterContract::class), @@ -84,7 +83,7 @@ public function testProcessNoDirective(): void { $path = 'path/to/file.md'; $target = '@test'; - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::expectExceptionObject( new TargetIsNotDirective($path, $target), @@ -100,7 +99,7 @@ public function testProcessNoDirectiveResolver(): void { $path = 'path/to/file.md'; $target = '@test'; - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::expectExceptionObject( new TargetIsNotDirective($path, $target), diff --git a/packages/documentator/src/Preprocessor/Instructions/IncludePackageList/InstructionTest.php b/packages/documentator/src/Preprocessor/Instructions/IncludePackageList/InstructionTest.php index ec2877b96..6ff66e21c 100644 --- a/packages/documentator/src/Preprocessor/Instructions/IncludePackageList/InstructionTest.php +++ b/packages/documentator/src/Preprocessor/Instructions/IncludePackageList/InstructionTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Preprocessor\Instructions\IncludePackageList; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Exceptions\DocumentTitleIsMissing; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Exceptions\PackageComposerJsonIsMissing; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Exceptions\PackageReadmeIsMissing; @@ -24,7 +23,7 @@ public function testProcess(string $expected, string $template): void { $path = self::getTestData()->file('Document.md')->getPathname(); $target = basename(self::getTestData()->path('/packages')); $params = new Parameters(template: $template); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); $actual = $instance->process($path, $target, $params); self::assertEquals( @@ -41,7 +40,7 @@ public function testProcessNotAPackage(): void { $path = self::getTestData()->file('Document.md')->getPathname(); $target = basename(self::getTestData()->path('/invalid')); $params = new Parameters(); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::expectExceptionObject( new PackageComposerJsonIsMissing( @@ -58,7 +57,7 @@ public function testProcessNoReadme(): void { $path = self::getTestData()->file('Document.md')->getPathname(); $target = basename(self::getTestData()->path('/no readme')); $params = new Parameters(); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::expectExceptionObject( new PackageReadmeIsMissing( @@ -75,7 +74,7 @@ public function testProcessNoTitle(): void { $path = self::getTestData()->file('Document.md')->getPathname(); $target = basename(self::getTestData()->path('/no title')); $params = new Parameters(); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::expectExceptionObject( new DocumentTitleIsMissing( diff --git a/packages/documentator/src/Preprocessor/Instructions/IncludeTemplate/InstructionTest.php b/packages/documentator/src/Preprocessor/Instructions/IncludeTemplate/InstructionTest.php index 8e42bb4b4..52b49a1dd 100644 --- a/packages/documentator/src/Preprocessor/Instructions/IncludeTemplate/InstructionTest.php +++ b/packages/documentator/src/Preprocessor/Instructions/IncludeTemplate/InstructionTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Preprocessor\Instructions\IncludeTemplate; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Exceptions\TemplateDataMissed; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Exceptions\TemplateVariablesMissed; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Exceptions\TemplateVariablesUnused; @@ -20,7 +19,7 @@ public function testProcessRelative(): void { 'a' => 'Relative', 'b' => 'Inner reference ${a}', ]); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::assertEquals( <<<'FILE' @@ -41,7 +40,7 @@ public function testProcessAbsolute(): void { 'a' => 'Absolute', 'b' => 'Inner reference ${a}', ]); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::assertEquals( <<<'FILE' @@ -58,7 +57,7 @@ public function testProcessAbsolute(): void { public function testProcessNoData(): void { $file = self::getTestData()->file('.md'); $params = new Parameters([]); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::expectExceptionObject( new TemplateDataMissed( @@ -78,7 +77,7 @@ public function testProcessVariablesUnused(): void { 'c' => 'C', 'd' => 'D', ]); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::expectExceptionObject( new TemplateVariablesUnused( @@ -96,7 +95,7 @@ public function testProcessVariablesMissed(): void { $params = new Parameters([ 'a' => 'A', ]); - $instance = Container::getInstance()->make(Instruction::class); + $instance = $this->app()->make(Instruction::class); self::expectExceptionObject( new TemplateVariablesMissed( diff --git a/packages/documentator/src/Preprocessor/Preprocessor.php b/packages/documentator/src/Preprocessor/Preprocessor.php index 008fc8919..d6915f850 100644 --- a/packages/documentator/src/Preprocessor/Preprocessor.php +++ b/packages/documentator/src/Preprocessor/Preprocessor.php @@ -5,7 +5,7 @@ // @phpcs:disable Generic.Files.LineLength.TooLong use Exception; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use LastDragon_ru\LaraASP\Core\Utils\Path; use LastDragon_ru\LaraASP\Documentator\Commands\Preprocess; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Contracts\Instruction; @@ -86,6 +86,7 @@ class Preprocessor { private array $instructions = []; public function __construct( + protected readonly ContainerResolver $container, protected readonly Serializer $serializer, ) { $this->addInstruction(IncludeFile::class); @@ -122,7 +123,7 @@ protected function getInstruction(string $name): ?Instruction { } if (!isset($this->instructions[$name][1])) { - $this->instructions[$name][1] = Container::getInstance()->make( + $this->instructions[$name][1] = $this->container->getInstance()->make( $this->instructions[$name][0], ); } diff --git a/packages/documentator/src/Preprocessor/PreprocessorTest.php b/packages/documentator/src/Preprocessor/PreprocessorTest.php index cf7799dcc..a764857fb 100644 --- a/packages/documentator/src/Preprocessor/PreprocessorTest.php +++ b/packages/documentator/src/Preprocessor/PreprocessorTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Preprocessor; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Contracts\Instruction; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Contracts\ParameterizableInstruction; use LastDragon_ru\LaraASP\Documentator\Preprocessor\Contracts\ProcessableInstruction; @@ -90,7 +89,7 @@ public function testProcess(): void { ->once() ->andReturn('empty'); - $preprocessor = Container::getInstance()->make(Preprocessor::class) + $preprocessor = $this->app()->make(Preprocessor::class) ->addInstruction($parameterizableInstruction) ->addInstruction($processableInstruction) ->addInstruction($emptyInstruction); diff --git a/packages/documentator/src/Testing/Package/TestCase.php b/packages/documentator/src/Testing/Package/TestCase.php index 29b298701..0fa765928 100644 --- a/packages/documentator/src/Testing/Package/TestCase.php +++ b/packages/documentator/src/Testing/Package/TestCase.php @@ -2,6 +2,7 @@ namespace LastDragon_ru\LaraASP\Documentator\Testing\Package; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\Documentator\Provider; use LastDragon_ru\LaraASP\Serializer\Provider as SerializerProvider; use LastDragon_ru\LaraASP\Testing\Package\TestCase as PackageTestCase; @@ -20,6 +21,7 @@ abstract class TestCase extends PackageTestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, SerializerProvider::class, ]); } diff --git a/packages/documentator/src/Utils/Git.php b/packages/documentator/src/Utils/Git.php index bb387ec45..a59c44991 100644 --- a/packages/documentator/src/Utils/Git.php +++ b/packages/documentator/src/Utils/Git.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Documentator\Utils; -use Illuminate\Container\Container; use Illuminate\Process\Factory; use function array_filter; @@ -11,10 +10,10 @@ use function trim; class Git { - protected readonly Factory $factory; - - public function __construct() { - $this->factory = Container::getInstance()->make(Factory::class); // next(documentator): Inject in constructor + public function __construct( + protected readonly Factory $factory, + ) { + // empty } /** diff --git a/packages/eloquent/UPGRADE.md b/packages/eloquent/UPGRADE.md index e0923624f..52e5ca98a 100644 --- a/packages/eloquent/UPGRADE.md +++ b/packages/eloquent/UPGRADE.md @@ -27,6 +27,16 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases) [//]: # (end: c70a9a43c0a80bd2e7fa6010a9b2c0fbcab4cb4d536d7a498216d9df7431f7e2) +# Upgrade from v6 + +[include:file]: ../../docs/Shared/Upgrade/FromV6.md +[//]: # (start: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) +[//]: # (warning: Generated automatically. Do not edit.) + +* [ ] Direct usages of `Container::getInstances()` were replaced by explicit constructor parameters. You may need to update your code accordingly (#151). + +[//]: # (end: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) + # Upgrade from v5 [include:file]: ../../docs/Shared/Upgrade/FromV5.md diff --git a/packages/eloquent/composer.json b/packages/eloquent/composer.json index f410fae45..9de965773 100644 --- a/packages/eloquent/composer.json +++ b/packages/eloquent/composer.json @@ -26,7 +26,6 @@ }, "require-dev": { "ext-pdo_sqlite": "*", - "illuminate/container": "^10.34.0|^11.0.0", "lastdragon-ru/lara-asp-testing": "self.version", "mockery/mockery": "^1.6.2", "orchestra/testbench": "^8.0.0|^9.0.0", diff --git a/packages/eloquent/src/Iterators/ChunkedChangeSafeIteratorTest.php b/packages/eloquent/src/Iterators/ChunkedChangeSafeIteratorTest.php index 6300b044d..8a3505def 100644 --- a/packages/eloquent/src/Iterators/ChunkedChangeSafeIteratorTest.php +++ b/packages/eloquent/src/Iterators/ChunkedChangeSafeIteratorTest.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\Eloquent\Iterators; use Closure; -use Illuminate\Container\Container; use Illuminate\Database\ConnectionResolverInterface; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; @@ -37,7 +36,7 @@ public function testGetIterator(): void { $spyBefore = Mockery::spy(static fn () => null); $spyAfter = Mockery::spy(static fn () => null); - $db = Container::getInstance()->make(ConnectionResolverInterface::class); + $db = $this->app()->make(ConnectionResolverInterface::class); $log = $this->getQueryLog($db); $query = TestObject::query()->orderByDesc('value'); $count = count($log); diff --git a/packages/eloquent/src/Iterators/ChunkedIteratorTest.php b/packages/eloquent/src/Iterators/ChunkedIteratorTest.php index 079e54dc7..97a16be41 100644 --- a/packages/eloquent/src/Iterators/ChunkedIteratorTest.php +++ b/packages/eloquent/src/Iterators/ChunkedIteratorTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Eloquent\Iterators; -use Illuminate\Container\Container; use Illuminate\Database\ConnectionResolverInterface; use LastDragon_ru\LaraASP\Eloquent\Testing\Package\Models\TestObject; use LastDragon_ru\LaraASP\Eloquent\Testing\Package\Models\WithTestObject; @@ -29,7 +28,7 @@ public function testGetIterator(): void { $spyBefore = Mockery::spy(static fn() => null); $spyAfter = Mockery::spy(static fn() => null); - $db = Container::getInstance()->make(ConnectionResolverInterface::class); + $db = $this->app()->make(ConnectionResolverInterface::class); $log = $this->getQueryLog($db); $query = TestObject::query()->orderByDesc('value'); $expected = (clone $query)->get()->all(); diff --git a/packages/eloquent/src/Testing/Package/Models/WithTestObject.php b/packages/eloquent/src/Testing/Package/Models/WithTestObject.php index d6af71a5d..049f62492 100644 --- a/packages/eloquent/src/Testing/Package/Models/WithTestObject.php +++ b/packages/eloquent/src/Testing/Package/Models/WithTestObject.php @@ -2,8 +2,6 @@ namespace LastDragon_ru\LaraASP\Eloquent\Testing\Package\Models; -use Illuminate\Container\Container; -use Illuminate\Database\Schema\Builder; use LastDragon_ru\LaraASP\Eloquent\Testing\Package\TestCase; use PHPUnit\Framework\Attributes\After; use PHPUnit\Framework\Attributes\Before; @@ -20,8 +18,9 @@ trait WithTestObject { #[Before] protected function withTestObjectBefore(): void { $this->afterApplicationCreated(static function (): void { - $schema = Container::getInstance()->make(Builder::class); - $table = (new TestObject())->getTable(); + $instance = new TestObject(); + $schema = $instance->getConnection()->getSchemaBuilder(); + $table = $instance->getTable(); if ($schema->hasTable($table)) { return; @@ -40,8 +39,9 @@ protected function withTestObjectBefore(): void { #[After] protected function withTestObjectAfter(): void { $this->beforeApplicationDestroyed(static function (): void { - $schema = Container::getInstance()->make(Builder::class); - $table = (new TestObject())->getTable(); + $instance = new TestObject(); + $schema = $instance->getConnection()->getSchemaBuilder(); + $table = $instance->getTable(); $schema->dropIfExists($table); }); diff --git a/packages/formatter/README.md b/packages/formatter/README.md index 289f41fb7..5057a94bb 100644 --- a/packages/formatter/README.md +++ b/packages/formatter/README.md @@ -50,12 +50,11 @@ Formatter is very simple to use: ```php make(Formatter::class); // For default app locale -$locale = $default->forLocale('ru_RU'); // For ru_RU locale +$default = app()->make(Formatter::class); // For default app locale +$locale = $default->forLocale('ru_RU'); // For ru_RU locale Example::dump($default->integer(123.454321)); Example::dump($default->decimal(123.454321)); @@ -99,7 +98,6 @@ php artisan vendor:publish --provider=LastDragon_ru\\LaraASP\\Formatter\\Provide ```php make(Formatter::class); +$default = app()->make(Formatter::class); $locale = $default->forLocale('ru_RU'); Example::dump($default->date($datetime)); @@ -192,12 +190,11 @@ The syntax is the same as [ICU Date/Time format syntax](https://unicode-org.gith ```php make(Formatter::class); // For default app locale -$locale = $default->forLocale('ru_RU'); // For ru_RU locale +$default = app()->make(Formatter::class); // For default app locale +$locale = $default->forLocale('ru_RU'); // For ru_RU locale Example::dump($default->duration(123.454321)); Example::dump($locale->duration(123.4543)); diff --git a/packages/formatter/UPGRADE.md b/packages/formatter/UPGRADE.md index 4faa68e20..5fca9d10b 100644 --- a/packages/formatter/UPGRADE.md +++ b/packages/formatter/UPGRADE.md @@ -27,6 +27,16 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases) [//]: # (end: c70a9a43c0a80bd2e7fa6010a9b2c0fbcab4cb4d536d7a498216d9df7431f7e2) +# Upgrade from v6 + +[include:file]: ../../docs/Shared/Upgrade/FromV6.md +[//]: # (start: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) +[//]: # (warning: Generated automatically. Do not edit.) + +* [ ] Direct usages of `Container::getInstances()` were replaced by explicit constructor parameters. You may need to update your code accordingly (#151). + +[//]: # (end: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) + # Upgrade from v5 [include:file]: ../../docs/Shared/Upgrade/FromV5.md diff --git a/packages/formatter/composer.json b/packages/formatter/composer.json index f3264646b..fe8d21e9c 100644 --- a/packages/formatter/composer.json +++ b/packages/formatter/composer.json @@ -22,8 +22,6 @@ "ext-bcmath": "*", "ext-intl": "*", "ext-mbstring": "*", - "illuminate/container": "^10.34.0|^11.0.0", - "illuminate/contracts": "^10.34.0|^11.0.0", "illuminate/macroable": "^10.34.0|^11.0.0", "illuminate/support": "^10.34.0|^11.0.0", "lastdragon-ru/lara-asp-core": "self.version", diff --git a/packages/formatter/docs/Examples/Config.php b/packages/formatter/docs/Examples/Config.php index de27ed829..c98299cf3 100644 --- a/packages/formatter/docs/Examples/Config.php +++ b/packages/formatter/docs/Examples/Config.php @@ -1,6 +1,5 @@ make(Formatter::class); +$default = app()->make(Formatter::class); $locale = $default->forLocale('ru_RU'); Example::dump($default->date($datetime)); diff --git a/packages/formatter/docs/Examples/Duration.php b/packages/formatter/docs/Examples/Duration.php index 83d186dd3..2832f3c45 100644 --- a/packages/formatter/docs/Examples/Duration.php +++ b/packages/formatter/docs/Examples/Duration.php @@ -1,11 +1,10 @@ make(Formatter::class); // For default app locale -$locale = $default->forLocale('ru_RU'); // For ru_RU locale +$default = app()->make(Formatter::class); // For default app locale +$locale = $default->forLocale('ru_RU'); // For ru_RU locale Example::dump($default->duration(123.454321)); Example::dump($locale->duration(123.4543)); diff --git a/packages/formatter/docs/Examples/Usage.php b/packages/formatter/docs/Examples/Usage.php index 11c92afe3..44fbb42c3 100644 --- a/packages/formatter/docs/Examples/Usage.php +++ b/packages/formatter/docs/Examples/Usage.php @@ -1,11 +1,10 @@ make(Formatter::class); // For default app locale -$locale = $default->forLocale('ru_RU'); // For ru_RU locale +$default = app()->make(Formatter::class); // For default app locale +$locale = $default->forLocale('ru_RU'); // For ru_RU locale Example::dump($default->integer(123.454321)); Example::dump($default->decimal(123.454321)); diff --git a/packages/formatter/src/Formatter.php b/packages/formatter/src/Formatter.php index b7ec2ed0f..84fe9c7e8 100644 --- a/packages/formatter/src/Formatter.php +++ b/packages/formatter/src/Formatter.php @@ -6,13 +6,12 @@ use DateInterval; use DateTimeInterface; use DateTimeZone; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; -use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\Str; use Illuminate\Support\Traits\Macroable; use IntlDateFormatter; use IntlTimeZone; +use LastDragon_ru\LaraASP\Core\Application\ApplicationResolver; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; use LastDragon_ru\LaraASP\Core\Utils\Cast; use LastDragon_ru\LaraASP\Formatter\Exceptions\FailedToCreateDateFormatter; use LastDragon_ru\LaraASP\Formatter\Exceptions\FailedToCreateNumberFormatter; @@ -214,6 +213,8 @@ class Formatter { private array $numbersFormatters = []; public function __construct( + protected readonly ApplicationResolver $application, + protected readonly ConfigResolver $config, private PackageTranslator $translator, ) { // empty @@ -446,16 +447,16 @@ public function secret(?string $value, int $show = null): string { // // ========================================================================= protected function getDefaultLocale(): string { - return Container::getInstance()->make(Application::class)->getLocale() + return $this->application->getInstance()->getLocale() ?: Locale::getDefault(); } protected function getDefaultTimezone(): IntlTimeZone|DateTimeZone|string|null { - return Container::getInstance()->make(Repository::class)->get('app.timezone') ?: null; + return $this->config->getInstance()->get('app.timezone') ?: null; } protected function getOptions(string $type, mixed $default = null): mixed { - $repository = Container::getInstance()->make(Repository::class); + $repository = $this->config->getInstance(); $package = Package::Name; $key = "{$package}.options.{$type}"; @@ -463,7 +464,7 @@ protected function getOptions(string $type, mixed $default = null): mixed { } protected function getLocaleOptions(string $type, string $option): mixed { - $repository = Container::getInstance()->make(Repository::class); + $repository = $this->config->getInstance(); $package = Package::Name; $locale = $this->getLocale(); $pattern = $repository->get("{$package}.locales.{$locale}.{$type}.{$option}") diff --git a/packages/formatter/src/FormatterTest.php b/packages/formatter/src/FormatterTest.php index 56d00df60..ed4a0fa0d 100644 --- a/packages/formatter/src/FormatterTest.php +++ b/packages/formatter/src/FormatterTest.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\Formatter; use DateTime; -use Illuminate\Container\Container; use IntlDateFormatter; use LastDragon_ru\LaraASP\Formatter\Testing\Package\TestCase; use NumberFormatter; @@ -28,7 +27,7 @@ final class FormatterTest extends TestCase { public function setUp(): void { parent::setUp(); - $this->formatter = Container::getInstance()->make(Formatter::class); + $this->formatter = $this->app()->make(Formatter::class); } #[Override] diff --git a/packages/formatter/src/PackageTranslator.php b/packages/formatter/src/PackageTranslator.php index cb8c102b5..5aca2d5c8 100644 --- a/packages/formatter/src/PackageTranslator.php +++ b/packages/formatter/src/PackageTranslator.php @@ -2,11 +2,12 @@ namespace LastDragon_ru\LaraASP\Formatter; -use Illuminate\Contracts\Translation\Translator as TranslatorContract; use LastDragon_ru\LaraASP\Core\Helpers\Translator; +use Override; class PackageTranslator extends Translator { - public function __construct(TranslatorContract $translator) { - parent::__construct($translator, Package::Name); + #[Override] + protected function getName(): string { + return Package::Name; } } diff --git a/packages/formatter/src/ProviderTest.php b/packages/formatter/src/ProviderTest.php index cf2cc9016..dc06cf5c6 100644 --- a/packages/formatter/src/ProviderTest.php +++ b/packages/formatter/src/ProviderTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Formatter; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\Formatter\Testing\Package\TestCase; use PHPUnit\Framework\Attributes\CoversClass; @@ -13,8 +12,8 @@ final class ProviderTest extends TestCase { public function testRegister(): void { self::assertSame( - Container::getInstance()->make(Formatter::class), - Container::getInstance()->make(Formatter::class), + $this->app()->make(Formatter::class), + $this->app()->make(Formatter::class), ); } } diff --git a/packages/formatter/src/Testing/Package/TestCase.php b/packages/formatter/src/Testing/Package/TestCase.php index 11713c7b5..a7e6122e9 100644 --- a/packages/formatter/src/Testing/Package/TestCase.php +++ b/packages/formatter/src/Testing/Package/TestCase.php @@ -2,6 +2,7 @@ namespace LastDragon_ru\LaraASP\Formatter\Testing\Package; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\Formatter\Provider; use LastDragon_ru\LaraASP\Testing\Package\TestCase as PackageTestCase; use Override; @@ -18,6 +19,7 @@ abstract class TestCase extends PackageTestCase { #[Override] protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ + CoreProvider::class, Provider::class, ]); } diff --git a/packages/graphql-printer/src/Blocks/ListBlockTest.php b/packages/graphql-printer/src/Blocks/ListBlockTest.php index 335dbd82d..635050b18 100644 --- a/packages/graphql-printer/src/Blocks/ListBlockTest.php +++ b/packages/graphql-printer/src/Blocks/ListBlockTest.php @@ -800,7 +800,6 @@ protected function content(Collector $collector, int $level, int $used): string * @extends PropertyBlock */ class ListBlockTest__NamedBlock extends PropertyBlock { - /** @noinspection PhpMissingParentConstructorInspection */ public function __construct( protected string $name, protected string $serialized, diff --git a/packages/graphql/README.md b/packages/graphql/README.md index 7986a2f7a..b146fab2e 100644 --- a/packages/graphql/README.md +++ b/packages/graphql/README.md @@ -227,15 +227,14 @@ The package provides bindings for [`Printer`][pkg:graphql-printer] so you can si ```php make(SchemaBuilder::class)->schema(); -$printer = Container::getInstance()->make(Printer::class); +$schema = app()->make(SchemaBuilder::class)->schema(); +$printer = app()->make(Printer::class); $settings = new DefaultSettings(); $printer->setSettings( diff --git a/packages/graphql/UPGRADE.md b/packages/graphql/UPGRADE.md index 6af134c1a..b9e8dc499 100644 --- a/packages/graphql/UPGRADE.md +++ b/packages/graphql/UPGRADE.md @@ -35,10 +35,37 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases) # Upgrade from v6 +## General + +[include:file]: ../../docs/Shared/Upgrade/FromV6.md +[//]: # (start: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) +[//]: # (warning: Generated automatically. Do not edit.) + +* [ ] Direct usages of `Container::getInstances()` were replaced by explicit constructor parameters. You may need to update your code accordingly (#151). + +[//]: # (end: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) + * [ ] The `\LastDragon_ru\LaraASP\GraphQL\Scalars\JsonStringType` is not implement `\LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition` anymore. To add the scalar into the Schema, you can use `@type`/`@scalar` directive, or create a custom implementation of `TypeDefinition` contract to use with `Builder`/`Manipulator`. +## Tests + +* [ ] Following traits required `app()` method to get access to the Container (#151) + * `\LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions` + + ```php + protected function app(): Application { + return $this->app; + } + ``` + +## API + +This section is actual only if you are extending the package. Please review and update (listed the most significant changes only): + * [ ] `\LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition::getTypeDefinition()` return type changed. +* [ ] `\LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithManipulator` removed, create instance by hand instead (reason #151). + # Upgrade from v5 ## General diff --git a/packages/graphql/docs/Assertions/AssertGraphQLIntrospectionEquals.md b/packages/graphql/docs/Assertions/AssertGraphQLIntrospectionEquals.md index bb188a089..b96491b50 100644 --- a/packages/graphql/docs/Assertions/AssertGraphQLIntrospectionEquals.md +++ b/packages/graphql/docs/Assertions/AssertGraphQLIntrospectionEquals.md @@ -14,7 +14,7 @@ Compares default public schema (as the client sees it through introspection). namespace LastDragon_ru\LaraASP\GraphQL\Docs\Assertions; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\GraphQL\Provider; use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\TestDirective; @@ -48,6 +48,7 @@ final class AssertGraphQLIntrospectionEqualsTest extends TestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, TestProvider::class, LighthouseServiceProvider::class, ]); @@ -58,7 +59,7 @@ final class AssertGraphQLIntrospectionEqualsTest extends TestCase { */ public function testAssertion(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('a', TestDirective::class) ->setResolved('test', TestDirective::class); diff --git a/packages/graphql/docs/Assertions/AssertGraphQLIntrospectionEqualsTest.php b/packages/graphql/docs/Assertions/AssertGraphQLIntrospectionEqualsTest.php index 28c3007de..b2608e992 100644 --- a/packages/graphql/docs/Assertions/AssertGraphQLIntrospectionEqualsTest.php +++ b/packages/graphql/docs/Assertions/AssertGraphQLIntrospectionEqualsTest.php @@ -2,7 +2,7 @@ namespace LastDragon_ru\LaraASP\GraphQL\Docs\Assertions; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\GraphQL\Provider; use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\TestDirective; @@ -36,6 +36,7 @@ final class AssertGraphQLIntrospectionEqualsTest extends TestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, TestProvider::class, LighthouseServiceProvider::class, ]); @@ -46,7 +47,7 @@ protected function getPackageProviders(mixed $app): array { */ public function testAssertion(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('a', TestDirective::class) ->setResolved('test', TestDirective::class); diff --git a/packages/graphql/docs/Assertions/AssertGraphQLSchemaEquals.md b/packages/graphql/docs/Assertions/AssertGraphQLSchemaEquals.md index e40519db9..f41534b0c 100644 --- a/packages/graphql/docs/Assertions/AssertGraphQLSchemaEquals.md +++ b/packages/graphql/docs/Assertions/AssertGraphQLSchemaEquals.md @@ -11,7 +11,7 @@ Compares default internal schema (with all directives). namespace LastDragon_ru\LaraASP\GraphQL\Docs\Assertions; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\GraphQL\Provider; use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\TestDirective; @@ -43,6 +43,7 @@ final class AssertGraphQLSchemaEqualsTest extends TestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, TestProvider::class, LighthouseServiceProvider::class, ]); @@ -53,7 +54,7 @@ final class AssertGraphQLSchemaEqualsTest extends TestCase { */ public function testAssertion(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('a', TestDirective::class) ->setResolved('test', TestDirective::class); diff --git a/packages/graphql/docs/Assertions/AssertGraphQLSchemaEqualsTest.php b/packages/graphql/docs/Assertions/AssertGraphQLSchemaEqualsTest.php index cd78b5ec1..7b7ca678f 100644 --- a/packages/graphql/docs/Assertions/AssertGraphQLSchemaEqualsTest.php +++ b/packages/graphql/docs/Assertions/AssertGraphQLSchemaEqualsTest.php @@ -2,7 +2,7 @@ namespace LastDragon_ru\LaraASP\GraphQL\Docs\Assertions; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\GraphQL\Provider; use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\TestDirective; @@ -34,6 +34,7 @@ final class AssertGraphQLSchemaEqualsTest extends TestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, TestProvider::class, LighthouseServiceProvider::class, ]); @@ -44,7 +45,7 @@ protected function getPackageProviders(mixed $app): array { */ public function testAssertion(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('a', TestDirective::class) ->setResolved('test', TestDirective::class); diff --git a/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoBreakingChanges.md b/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoBreakingChanges.md index c818a110a..07add5ee0 100644 --- a/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoBreakingChanges.md +++ b/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoBreakingChanges.md @@ -11,7 +11,7 @@ Checks that no breaking changes in the default internal schema (with all directi namespace LastDragon_ru\LaraASP\GraphQL\Docs\Assertions; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\GraphQL\Provider; use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\TestDirective; @@ -43,6 +43,7 @@ final class AssertGraphQLSchemaNoBreakingChangesTest extends TestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, TestProvider::class, LighthouseServiceProvider::class, ]); @@ -53,7 +54,7 @@ final class AssertGraphQLSchemaNoBreakingChangesTest extends TestCase { */ public function testAssertion(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('test', TestDirective::class); $this->useGraphQLSchema( diff --git a/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoBreakingChangesTest.php b/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoBreakingChangesTest.php index 4b2cda1b9..7dd044277 100644 --- a/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoBreakingChangesTest.php +++ b/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoBreakingChangesTest.php @@ -2,7 +2,7 @@ namespace LastDragon_ru\LaraASP\GraphQL\Docs\Assertions; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\GraphQL\Provider; use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\TestDirective; @@ -34,6 +34,7 @@ final class AssertGraphQLSchemaNoBreakingChangesTest extends TestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, TestProvider::class, LighthouseServiceProvider::class, ]); @@ -44,7 +45,7 @@ protected function getPackageProviders(mixed $app): array { */ public function testAssertion(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('test', TestDirective::class); $this->useGraphQLSchema( diff --git a/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoDangerousChanges.md b/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoDangerousChanges.md index 3b6a1fd27..7060b11b5 100644 --- a/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoDangerousChanges.md +++ b/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoDangerousChanges.md @@ -11,7 +11,7 @@ Checks that no dangerous changes in the default internal schema (with all direct namespace LastDragon_ru\LaraASP\GraphQL\Docs\Assertions; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\GraphQL\Provider; use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\TestDirective; @@ -43,6 +43,7 @@ final class AssertGraphQLSchemaNoDangerousChangesTest extends TestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, TestProvider::class, LighthouseServiceProvider::class, ]); @@ -53,7 +54,7 @@ final class AssertGraphQLSchemaNoDangerousChangesTest extends TestCase { */ public function testAssertion(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('test', TestDirective::class); $this->useGraphQLSchema( diff --git a/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoDangerousChangesTest.php b/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoDangerousChangesTest.php index 6494b30c9..5bc7471af 100644 --- a/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoDangerousChangesTest.php +++ b/packages/graphql/docs/Assertions/AssertGraphQLSchemaNoDangerousChangesTest.php @@ -2,7 +2,7 @@ namespace LastDragon_ru\LaraASP\GraphQL\Docs\Assertions; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\GraphQL\Provider; use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\TestDirective; @@ -34,6 +34,7 @@ final class AssertGraphQLSchemaNoDangerousChangesTest extends TestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, TestProvider::class, LighthouseServiceProvider::class, ]); @@ -44,7 +45,7 @@ protected function getPackageProviders(mixed $app): array { */ public function testAssertion(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('test', TestDirective::class); $this->useGraphQLSchema( diff --git a/packages/graphql/docs/Assertions/AssertGraphQLSchemaValid.md b/packages/graphql/docs/Assertions/AssertGraphQLSchemaValid.md index fcb9d8f54..f1b59db70 100644 --- a/packages/graphql/docs/Assertions/AssertGraphQLSchemaValid.md +++ b/packages/graphql/docs/Assertions/AssertGraphQLSchemaValid.md @@ -11,7 +11,7 @@ Validates default internal schema (with all directives). Faster than `lighthouse namespace LastDragon_ru\LaraASP\GraphQL\Docs\Assertions; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\GraphQL\Provider; use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\TestDirective; @@ -43,6 +43,7 @@ final class AssertGraphQLSchemaValidTest extends TestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, TestProvider::class, LighthouseServiceProvider::class, ]); @@ -53,7 +54,7 @@ final class AssertGraphQLSchemaValidTest extends TestCase { */ public function testAssertion(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('a', TestDirective::class) ->setResolved('test', TestDirective::class); diff --git a/packages/graphql/docs/Assertions/AssertGraphQLSchemaValidTest.php b/packages/graphql/docs/Assertions/AssertGraphQLSchemaValidTest.php index a3e6124d5..f2516bb49 100644 --- a/packages/graphql/docs/Assertions/AssertGraphQLSchemaValidTest.php +++ b/packages/graphql/docs/Assertions/AssertGraphQLSchemaValidTest.php @@ -2,7 +2,7 @@ namespace LastDragon_ru\LaraASP\GraphQL\Docs\Assertions; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\GraphQL\Provider; use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\TestDirective; @@ -34,6 +34,7 @@ final class AssertGraphQLSchemaValidTest extends TestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, TestProvider::class, LighthouseServiceProvider::class, ]); @@ -44,7 +45,7 @@ protected function getPackageProviders(mixed $app): array { */ public function testAssertion(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('a', TestDirective::class) ->setResolved('test', TestDirective::class); diff --git a/packages/graphql/docs/Examples/Printer.php b/packages/graphql/docs/Examples/Printer.php index 3e94711b0..4ad033c2c 100644 --- a/packages/graphql/docs/Examples/Printer.php +++ b/packages/graphql/docs/Examples/Printer.php @@ -1,14 +1,13 @@ make(SchemaBuilder::class)->schema(); -$printer = Container::getInstance()->make(Printer::class); +$schema = app()->make(SchemaBuilder::class)->schema(); +$printer = app()->make(Printer::class); $settings = new DefaultSettings(); $printer->setSettings( diff --git a/packages/graphql/src/Builder/BuilderInfoDetector.php b/packages/graphql/src/Builder/BuilderInfoDetector.php index f22c7da79..4e9fd1d5f 100644 --- a/packages/graphql/src/Builder/BuilderInfoDetector.php +++ b/packages/graphql/src/Builder/BuilderInfoDetector.php @@ -16,7 +16,6 @@ use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceFieldSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldSource; -use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithManipulator; use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithSource; use LastDragon_ru\LaraASP\GraphQL\Utils\AstManipulator; use Nuwave\Lighthouse\Pagination\PaginateDirective; @@ -40,10 +39,11 @@ use function reset; class BuilderInfoDetector { - use WithManipulator; use WithSource; - public function __construct() { + public function __construct( + private readonly ManipulatorFactory $manipulatorFactory, + ) { // empty } @@ -52,7 +52,7 @@ public function getFieldBuilderInfo( ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode $type, FieldDefinitionNode $field, ): BuilderInfo { - $manipulator = $this->getAstManipulator($document); + $manipulator = $this->manipulatorFactory->create($document); $fieldSource = $this->getFieldSource($manipulator, $type, $field); $builder = $this->getSourceBuilderInfo($manipulator, $fieldSource); @@ -65,7 +65,7 @@ public function getFieldArgumentBuilderInfo( FieldDefinitionNode $field, InputValueDefinitionNode $argument, ): BuilderInfo { - $manipulator = $this->getAstManipulator($document); + $manipulator = $this->manipulatorFactory->create($document); $argSource = $this->getFieldArgumentSource($manipulator, $type, $field, $argument); $builder = $this->getSourceBuilderInfo($manipulator, $argSource); diff --git a/packages/graphql/src/Builder/BuilderInfoDetectorTest.php b/packages/graphql/src/Builder/BuilderInfoDetectorTest.php index 260aba5d9..e0c1d7928 100644 --- a/packages/graphql/src/Builder/BuilderInfoDetectorTest.php +++ b/packages/graphql/src/Builder/BuilderInfoDetectorTest.php @@ -6,7 +6,6 @@ use Exception; use GraphQL\Language\Parser; use GraphQL\Type\Definition\ObjectType; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Query\Builder as QueryBuilder; use Laravel\Scout\Builder as ScoutBuilder; @@ -17,7 +16,6 @@ use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectSource; -use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithManipulator; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Requirements\RequiresLaravelScout; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\TestCase; use LastDragon_ru\LaraASP\GraphQL\Utils\AstManipulator; @@ -48,8 +46,6 @@ */ #[CoversClass(BuilderInfoDetector::class)] final class BuilderInfoDetectorTest extends TestCase { - use WithManipulator; - // // ========================================================================= /** @@ -59,11 +55,12 @@ final class BuilderInfoDetectorTest extends TestCase { */ #[DataProvider('dataProviderGetNodeBuilderInfo')] public function testGetNodeBuilderInfo(array $expected, Closure $sourceFactory): void { - $manipulator = $this->getAstManipulator(Mockery::mock(DocumentAST::class)); - $locator = Container::getInstance()->make(DirectiveLocator::class); - $source = $sourceFactory($locator, $manipulator); - $directive = new BuilderInfoDetectorTest__BuilderInfoDetector(); - $actual = $directive->getBuilderInfo($manipulator, $source); + $manipulatorFactory = $this->app()->make(ManipulatorFactory::class); + $manipulator = $manipulatorFactory->create(Mockery::mock(DocumentAST::class)); + $locator = $this->app()->make(DirectiveLocator::class); + $source = $sourceFactory($locator, $manipulator); + $directive = new BuilderInfoDetectorTest__BuilderInfoDetector($manipulatorFactory); + $actual = $directive->getBuilderInfo($manipulator, $source); self::assertEquals( $expected, @@ -81,11 +78,12 @@ public function testGetNodeBuilderInfo(array $expected, Closure $sourceFactory): #[DataProvider('dataProviderGetNodeBuilderInfoScoutBuilder')] #[RequiresLaravelScout] public function testGetNodeBuilderInfoScoutBuilder(array $expected, Closure $sourceFactory): void { - $manipulator = $this->getAstManipulator(Mockery::mock(DocumentAST::class)); - $locator = Container::getInstance()->make(DirectiveLocator::class); - $source = $sourceFactory($locator, $manipulator); - $directive = new BuilderInfoDetectorTest__BuilderInfoDetector(); - $actual = $directive->getBuilderInfo($manipulator, $source); + $manipulatorFactory = $this->app()->make(ManipulatorFactory::class); + $manipulator = $manipulatorFactory->create(Mockery::mock(DocumentAST::class)); + $locator = $this->app()->make(DirectiveLocator::class); + $source = $sourceFactory($locator, $manipulator); + $directive = new BuilderInfoDetectorTest__BuilderInfoDetector($manipulatorFactory); + $actual = $directive->getBuilderInfo($manipulator, $source); self::assertEquals( $expected, diff --git a/packages/graphql/src/Builder/Directives/HandlerDirective.php b/packages/graphql/src/Builder/Directives/HandlerDirective.php index 70a98c0f7..b6096a422 100644 --- a/packages/graphql/src/Builder/Directives/HandlerDirective.php +++ b/packages/graphql/src/Builder/Directives/HandlerDirective.php @@ -10,7 +10,6 @@ use GraphQL\Language\AST\NonNullTypeNode; use GraphQL\Language\AST\ObjectTypeDefinitionNode; use GraphQL\Language\Parser; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Query\Builder as QueryBuilder; @@ -30,9 +29,10 @@ use LastDragon_ru\LaraASP\GraphQL\Builder\Exceptions\HandlerInvalidConditions; use LastDragon_ru\LaraASP\GraphQL\Builder\Field; use LastDragon_ru\LaraASP\GraphQL\Builder\Manipulator; +use LastDragon_ru\LaraASP\GraphQL\Builder\ManipulatorFactory; +use LastDragon_ru\LaraASP\GraphQL\Builder\Operators; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldArgumentSource; -use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithManipulator; use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithSource; use LastDragon_ru\LaraASP\GraphQL\Utils\ArgumentFactory; use Nuwave\Lighthouse\Execution\Arguments\Argument; @@ -48,14 +48,17 @@ /** * @see HandlerContextBuilderInfo + * @see HandlerContextOperators * @see HandlerContextImplicit */ abstract class HandlerDirective extends BaseDirective implements Handler, Enhancer { - use WithManipulator; use WithSource; public function __construct( - protected readonly ArgumentFactory $argumentFactory, + private readonly ManipulatorFactory $manipulatorFactory, + private readonly ArgumentFactory $argumentFactory, + private readonly BuilderInfoDetector $detector, + private readonly Operators $operators, ) { // empty } @@ -226,9 +229,9 @@ public function manipulateArgDefinition( ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode &$parentType, ): void { // Converted? - $detector = Container::getInstance()->make(BuilderInfoDetector::class); + $detector = $this->detector; $builder = $detector->getFieldArgumentBuilderInfo($documentAST, $parentType, $parentField, $argDefinition); - $manipulator = $this->getAstManipulator($documentAST); + $manipulator = $this->manipulatorFactory->create($documentAST); if ($this->isTypeName($manipulator->getTypeName($argDefinition))) { return; @@ -237,6 +240,7 @@ public function manipulateArgDefinition( // Argument $context = (new Context())->override([ HandlerContextBuilderInfo::class => new HandlerContextBuilderInfo($builder), + HandlerContextOperators::class => new HandlerContextOperators($this->operators), HandlerContextImplicit::class => new HandlerContextImplicit( $manipulator->isPlaceholder($argDefinition), ), diff --git a/packages/graphql/src/Builder/Directives/SchemaDirective.php b/packages/graphql/src/Builder/Directives/SchemaDirective.php index cb2501522..531da71ab 100644 --- a/packages/graphql/src/Builder/Directives/SchemaDirective.php +++ b/packages/graphql/src/Builder/Directives/SchemaDirective.php @@ -20,8 +20,8 @@ use Illuminate\Support\Str; use LastDragon_ru\LaraASP\Core\Utils\Cast; use LastDragon_ru\LaraASP\GraphQL\Builder\Exceptions\TypeDefinitionIsNotScalarExtension; +use LastDragon_ru\LaraASP\GraphQL\Builder\ManipulatorFactory; use LastDragon_ru\LaraASP\GraphQL\Builder\Scalars\Internal; -use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithManipulator; use Nuwave\Lighthouse\Events\BuildSchemaString; use Nuwave\Lighthouse\Schema\AST\DocumentAST; use Nuwave\Lighthouse\Schema\DirectiveLocator; @@ -47,7 +47,11 @@ * @internal */ abstract class SchemaDirective extends BaseDirective implements TypeManipulator { - use WithManipulator; + public function __construct( + private readonly ManipulatorFactory $manipulatorFactory, + ) { + // empty + } #[Override] public static function definition(): string { @@ -77,7 +81,7 @@ public function manipulateTypeDefinition(DocumentAST &$documentAST, TypeDefiniti // be simplified. // Apply `extend scalar`. - $manipulator = $this->getAstManipulator($documentAST); + $manipulator = $this->manipulatorFactory->create($documentAST); foreach ($documentAST->typeExtensions as $type => $extensions) { // Supported? diff --git a/packages/graphql/src/Builder/Directives/SchemaDirectiveTest.php b/packages/graphql/src/Builder/Directives/SchemaDirectiveTest.php index 6f603530f..3b9cc2462 100644 --- a/packages/graphql/src/Builder/Directives/SchemaDirectiveTest.php +++ b/packages/graphql/src/Builder/Directives/SchemaDirectiveTest.php @@ -11,9 +11,11 @@ use GraphQL\Utils\AST; use LastDragon_ru\LaraASP\Core\Utils\Cast; use LastDragon_ru\LaraASP\GraphQL\Builder\Exceptions\TypeDefinitionIsNotScalarExtension; +use LastDragon_ru\LaraASP\GraphQL\Builder\ManipulatorFactory; use LastDragon_ru\LaraASP\GraphQL\Builder\Scalars\Internal; use LastDragon_ru\LaraASP\GraphQL\Exceptions\TypeDefinitionAlreadyDefined; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\TestCase; +use Mockery; use Nuwave\Lighthouse\Events\BuildSchemaString; use Nuwave\Lighthouse\Schema\AST\DocumentAST; use Override; @@ -30,10 +32,11 @@ final class SchemaDirectiveTest extends TestCase { // // ========================================================================= public function testInvoke(): void { - $directive = new SchemaDirective__Directive(); - $actual = $directive(new BuildSchemaString('')); - $class = self::getGraphQLStringValue(Internal::class); - $expected = <<app()->make(ManipulatorFactory::class); + $directive = new SchemaDirective__Directive($manipulatorFactory); $document = DocumentAST::fromSource($schema); $root = Parser::scalarTypeDefinition($directive(new BuildSchemaString($schema))); $document->types['SchemaDirective'] = $root; diff --git a/packages/graphql/src/Builder/Manipulator.php b/packages/graphql/src/Builder/Manipulator.php index b28e4d493..a46dad2cb 100644 --- a/packages/graphql/src/Builder/Manipulator.php +++ b/packages/graphql/src/Builder/Manipulator.php @@ -19,7 +19,7 @@ use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextOperators; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Operator; @@ -36,7 +36,9 @@ use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\Source; use LastDragon_ru\LaraASP\GraphQL\Utils\AstManipulator; use LastDragon_ru\LaraASP\GraphQL\Utils\TypeReference; +use Nuwave\Lighthouse\Schema\AST\DocumentAST; use Nuwave\Lighthouse\Schema\DirectiveLocator; +use Nuwave\Lighthouse\Schema\TypeRegistry; use Nuwave\Lighthouse\Support\Contracts\Directive; use Override; @@ -47,12 +49,21 @@ use function is_string; class Manipulator extends AstManipulator implements TypeProvider { + public function __construct( + protected readonly ContainerResolver $container, + DirectiveLocator $directiveLocator, + DocumentAST $document, + TypeRegistry $types, + ) { + parent::__construct($directiveLocator, $document, $types); + } + // // ========================================================================= #[Override] public function getType(string $definition, TypeSource $source, Context $context): string { // Exists? - $instance = Container::getInstance()->make($definition); + $instance = $this->container->getInstance()->make($definition); $name = $instance->getTypeName($source, $context); if ($this->isTypeDefinitionExists($name)) { diff --git a/packages/graphql/src/Builder/ManipulatorFactory.php b/packages/graphql/src/Builder/ManipulatorFactory.php new file mode 100644 index 000000000..e052b93c0 --- /dev/null +++ b/packages/graphql/src/Builder/ManipulatorFactory.php @@ -0,0 +1,23 @@ +containerResolver->getInstance()->make(Manipulator::class, [ + 'document' => $document, + ]); + } +} diff --git a/packages/graphql/src/Builder/Operators.php b/packages/graphql/src/Builder/Operators.php index 9eea1e045..877892773 100644 --- a/packages/graphql/src/Builder/Operators.php +++ b/packages/graphql/src/Builder/Operators.php @@ -2,7 +2,7 @@ namespace LastDragon_ru\LaraASP\GraphQL\Builder; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Ignored; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Operator; @@ -48,7 +48,10 @@ abstract class Operators { /** * @param array|string>> $operators */ - public function __construct(array $operators = []) { + public function __construct( + protected readonly ContainerResolver $container, + array $operators = [], + ) { $this->types = new WeakMap(); $this->enabled = new WeakMap(); @@ -80,7 +83,7 @@ public function getOperator( } if (is_string($operator)) { - $operator = Container::getInstance()->make($operator); + $operator = $this->container->getInstance()->make($operator); } if (!$this->isEnabled($manipulator, $operator)) { diff --git a/packages/graphql/src/Builder/OperatorsTest.php b/packages/graphql/src/Builder/OperatorsTest.php index 5acea6a5b..a9a01d4fd 100644 --- a/packages/graphql/src/Builder/OperatorsTest.php +++ b/packages/graphql/src/Builder/OperatorsTest.php @@ -3,7 +3,7 @@ namespace LastDragon_ru\LaraASP\GraphQL\Builder; use Exception; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Handler; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Ignored; @@ -32,7 +32,7 @@ final class OperatorsTest extends TestCase { // ========================================================================= public function testGetOperators(): void { // Directives - $directives = Container::getInstance()->make(DirectiveLocator::class); + $directives = $this->app()->make(DirectiveLocator::class); $directives->setResolved('ignored', OperatorsTest__Ignored::class); $directives->setResolved('operators', OperatorsTest__OperatorsDirective::class); @@ -143,9 +143,10 @@ public function testGetOperators(): void { ]; $source = Mockery::mock(TypeSource::class); $context = Mockery::mock(Context::class); - $operators = new OperatorsTest__Operators($config, $default); - $document = Container::getInstance()->make(ASTBuilder::class)->documentAST(); - $manipulator = Container::getInstance()->make(Manipulator::class, [ + $container = $this->app()->make(ContainerResolver::class); + $operators = new OperatorsTest__Operators($container, $config, $default); + $document = $this->app()->make(ASTBuilder::class)->documentAST(); + $manipulator = $this->app()->make(Manipulator::class, [ 'document' => $document, ]); @@ -275,8 +276,12 @@ class OperatorsTest__Operators extends Operators { * @param array|string>> $operators * @param array|string>> $default */ - public function __construct(array $operators = [], array $default = []) { - parent::__construct($operators); + public function __construct( + ContainerResolver $container, + array $operators = [], + array $default = [], + ) { + parent::__construct($container, $operators); $this->default = $default; } diff --git a/packages/graphql/src/Builder/Traits/BuilderHelperFactory.php b/packages/graphql/src/Builder/Traits/BuilderHelperFactory.php index f37dca416..baa2dc346 100644 --- a/packages/graphql/src/Builder/Traits/BuilderHelperFactory.php +++ b/packages/graphql/src/Builder/Traits/BuilderHelperFactory.php @@ -2,12 +2,14 @@ namespace LastDragon_ru\LaraASP\GraphQL\Builder\Traits; -use Illuminate\Container\Container; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use function array_key_exists; use function is_a; use function is_object; +// todo(graphql): Do we really need this? + /** * @internal */ @@ -48,7 +50,7 @@ private function getHelper(object|string $builder): ?object { if (!array_key_exists($builder, $this->instances)) { $class = $this->getHelperClass($builder); $this->instances[$builder] = $class - ? Container::getInstance()->make($class) + ? $this->getContainerResolver()->getInstance()->make($class) : null; } @@ -76,4 +78,6 @@ private function getHelperClass(object|string $builder): ?string { return $this->classes[$builder]; } + + abstract private function getContainerResolver(): ContainerResolver; } diff --git a/packages/graphql/src/Builder/Traits/WithManipulator.php b/packages/graphql/src/Builder/Traits/WithManipulator.php deleted file mode 100644 index 1318eae56..000000000 --- a/packages/graphql/src/Builder/Traits/WithManipulator.php +++ /dev/null @@ -1,15 +0,0 @@ -make(Manipulator::class, [ - 'document' => $document, - ]); - } -} diff --git a/packages/graphql/src/Builder/Types/InputObject.php b/packages/graphql/src/Builder/Types/InputObject.php index 8c4f324e0..74131e754 100644 --- a/packages/graphql/src/Builder/Types/InputObject.php +++ b/packages/graphql/src/Builder/Types/InputObject.php @@ -12,8 +12,7 @@ use GraphQL\Type\Definition\FieldDefinition; use GraphQL\Type\Definition\InputObjectField; use GraphQL\Type\Definition\Type; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextImplicit; use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextOperators; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; @@ -43,7 +42,9 @@ use function trim; abstract class InputObject implements TypeDefinition { - public function __construct() { + public function __construct( + protected readonly ConfigResolver $config, + ) { // empty } @@ -440,9 +441,8 @@ protected function isFieldDirectiveAllowed( } // Allowed? - $repository = Container::getInstance()->make(Repository::class); - $isAllowed = false; - $allowed = (array) $repository->get(Package::Name.'.builder.allowed_directives'); + $isAllowed = false; + $allowed = (array) $this->config->getInstance()->get(Package::Name.'.builder.allowed_directives'); foreach ($allowed as $class) { if (is_string($class) && $directive instanceof $class) { diff --git a/packages/graphql/src/Builder/Types/InputObjectTest.php b/packages/graphql/src/Builder/Types/InputObjectTest.php index 3b57d250a..78c7be4c9 100644 --- a/packages/graphql/src/Builder/Types/InputObjectTest.php +++ b/packages/graphql/src/Builder/Types/InputObjectTest.php @@ -3,6 +3,7 @@ namespace LastDragon_ru\LaraASP\GraphQL\Builder\Types; use Exception; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextImplicit; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context as ContextContract; @@ -54,7 +55,9 @@ public function testIsFieldDirectiveAllowed( $manipulator = Mockery::mock(Manipulator::class); $field = Mockery::mock(ObjectFieldSource::class); - $input = new InputObjectTest__InputObject(); + $input = new InputObjectTest__InputObject( + $this->app()->make(ConfigResolver::class), + ); self::assertEquals($expected, $input->isFieldDirectiveAllowed($manipulator, $field, $context, $directive)); } diff --git a/packages/graphql/src/Directives/TypeTest.php b/packages/graphql/src/Directives/TypeTest.php index e70c3d9f8..071fa52f7 100644 --- a/packages/graphql/src/Directives/TypeTest.php +++ b/packages/graphql/src/Directives/TypeTest.php @@ -5,7 +5,6 @@ use GraphQL\Language\AST\ScalarTypeDefinitionNode; use GraphQL\Type\Definition\PhpEnumType; use GraphQL\Type\Definition\StringType; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\TestCase; use LastDragon_ru\LaraASP\GraphQL\Utils\PhpEnumTypeHelper; use Nuwave\Lighthouse\Exceptions\DefinitionException; @@ -33,7 +32,7 @@ public function testResolveNodeEnum(): void { GRAPHQL, ); - $registry = Container::getInstance()->make(TypeRegistry::class); + $registry = $this->app()->make(TypeRegistry::class); $type = $registry->get($name); self::assertInstanceOf(PhpEnumType::class, $type); @@ -52,7 +51,7 @@ public function testResolveNodeType(): void { GRAPHQL, ); - $registry = Container::getInstance()->make(TypeRegistry::class); + $registry = $this->app()->make(TypeRegistry::class); $type = $registry->get($name); self::assertInstanceOf($class, $type); @@ -75,7 +74,7 @@ public function testResolveNodeScalar(): void { GRAPHQL, ); - $registry = Container::getInstance()->make(TypeRegistry::class); + $registry = $this->app()->make(TypeRegistry::class); $type = $registry->get($name); self::assertInstanceOf($class, $type); @@ -100,7 +99,7 @@ public function testResolveNodeInvalidName(): void { "The type name must be `{$name}`, `{$name}-changed` given (`scalar {$name}`).", ); - $registry = Container::getInstance()->make(TypeRegistry::class); + $registry = $this->app()->make(TypeRegistry::class); $registry->get($name); } @@ -120,7 +119,7 @@ public function testResolveNodeNotGraphQLType(): void { "The `{$class}` is not a GraphQL type (`scalar {$name}`).", ); - $registry = Container::getInstance()->make(TypeRegistry::class); + $registry = $this->app()->make(TypeRegistry::class); $registry->get($name); } } diff --git a/packages/graphql/src/PackageTranslator.php b/packages/graphql/src/PackageTranslator.php index 00cccf0a9..8cfd2e58d 100644 --- a/packages/graphql/src/PackageTranslator.php +++ b/packages/graphql/src/PackageTranslator.php @@ -2,11 +2,12 @@ namespace LastDragon_ru\LaraASP\GraphQL; -use Illuminate\Contracts\Translation\Translator as TranslatorContract; use LastDragon_ru\LaraASP\Core\Helpers\Translator; +use Override; class PackageTranslator extends Translator { - public function __construct(TranslatorContract $translator) { - parent::__construct($translator, Package::Name); + #[Override] + protected function getName(): string { + return Package::Name; } } diff --git a/packages/graphql/src/Printer/PrinterTest.php b/packages/graphql/src/Printer/PrinterTest.php index 52ab03194..06f4e150a 100644 --- a/packages/graphql/src/Printer/PrinterTest.php +++ b/packages/graphql/src/Printer/PrinterTest.php @@ -20,7 +20,6 @@ use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\UnionType; use GraphQL\Type\Schema; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\TestCase; use LastDragon_ru\LaraASP\GraphQLPrinter\Contracts\Printer; use LastDragon_ru\LaraASP\GraphQLPrinter\Contracts\Settings; @@ -67,7 +66,7 @@ public function testPrint( ): void { $schema = $schemaFactory($this); $schema = $this->useGraphQLSchema($schema)->getGraphQLSchema(); - $printer = Container::getInstance()->make(Printer::class)->setSettings($settings); + $printer = $this->app()->make(Printer::class)->setSettings($settings); $type = $typeFactory ? $typeFactory($this, $schema) : null; $printable = $printableFactory($this, $schema); $actual = $printer->print($printable, $level, $used, $type); @@ -94,7 +93,7 @@ public function testExport( ): void { $schema = $schemaFactory($this); $schema = $this->useGraphQLSchema($schema)->getGraphQLSchema(); - $printer = Container::getInstance()->make(Printer::class)->setSettings($settings); + $printer = $this->app()->make(Printer::class)->setSettings($settings); $type = $typeFactory ? $typeFactory($this, $schema) : null; $exportable = $exportableFactory($this, $schema); $actual = $printer->export($exportable, $level, $used, $type); @@ -841,8 +840,8 @@ static function (): Node { private static function getSchemaFactory(): Closure { return static function (TestCase $test): SplFileInfo { // Types - $directives = Container::getInstance()->make(DirectiveLocator::class); - $registry = Container::getInstance()->make(TypeRegistry::class); + $directives = $test->app()->make(DirectiveLocator::class); + $registry = $test->app()->make(TypeRegistry::class); $directive = (new class() extends BaseDirective { #[Override] public static function definition(): string { diff --git a/packages/graphql/src/Provider.php b/packages/graphql/src/Provider.php index 676ae72ae..6e840d359 100644 --- a/packages/graphql/src/Provider.php +++ b/packages/graphql/src/Provider.php @@ -8,6 +8,7 @@ use LastDragon_ru\LaraASP\Core\Provider\WithConfig; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\BuilderFieldResolver as BuilderFieldResolverContract; use LastDragon_ru\LaraASP\GraphQL\Builder\Defaults\BuilderFieldResolver; +use LastDragon_ru\LaraASP\GraphQL\Builder\ManipulatorFactory; use LastDragon_ru\LaraASP\GraphQL\Directives\Definitions\TypeDirective; use LastDragon_ru\LaraASP\GraphQL\Printer\DirectiveResolver; use LastDragon_ru\LaraASP\GraphQL\SearchBy\Definitions\SearchByDirective; @@ -66,6 +67,7 @@ static function (): array { } protected function registerBindings(): void { + $this->app->scopedIf(ManipulatorFactory::class); $this->app->scopedIf(SorterFactoryContract::class, SorterFactory::class); $this->app->scopedIf(StreamFactoryContract::class, StreamFactory::class); $this->app->scopedIf(BuilderFieldResolverContract::class, BuilderFieldResolver::class); diff --git a/packages/graphql/src/SearchBy/Directives/Directive.php b/packages/graphql/src/SearchBy/Directives/Directive.php index 6fe72f60e..0edfcd2e5 100644 --- a/packages/graphql/src/SearchBy/Directives/Directive.php +++ b/packages/graphql/src/SearchBy/Directives/Directive.php @@ -6,16 +6,18 @@ use GraphQL\Language\AST\NamedTypeNode; use GraphQL\Language\AST\NonNullTypeNode; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; -use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextOperators; +use LastDragon_ru\LaraASP\GraphQL\Builder\BuilderInfoDetector; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Directives\HandlerDirective; use LastDragon_ru\LaraASP\GraphQL\Builder\Field; use LastDragon_ru\LaraASP\GraphQL\Builder\Manipulator; +use LastDragon_ru\LaraASP\GraphQL\Builder\ManipulatorFactory; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\SearchBy\Exceptions\FailedToCreateSearchCondition; use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators; use LastDragon_ru\LaraASP\GraphQL\SearchBy\Operators\Root; +use LastDragon_ru\LaraASP\GraphQL\Utils\ArgumentFactory; use Nuwave\Lighthouse\Execution\Arguments\ArgumentSet; use Nuwave\Lighthouse\Schema\AST\DocumentAST; use Nuwave\Lighthouse\Schema\DirectiveLocator; @@ -29,6 +31,15 @@ class Directive extends HandlerDirective implements ArgManipulator, ArgBuilderDirective, ScoutBuilderDirective { final public const Name = 'SearchBy'; + public function __construct( + ManipulatorFactory $manipulatorFactory, + BuilderInfoDetector $detector, + ArgumentFactory $argumentFactory, + Operators $operators, + ) { + parent::__construct($manipulatorFactory, $argumentFactory, $detector, $operators); + } + #[Override] public static function definition(): string { $name = DirectiveLocator::directiveName(static::class); @@ -55,8 +66,7 @@ protected function getArgDefinitionType( ObjectFieldArgumentSource|InterfaceFieldArgumentSource $argument, Context $context, ): ListTypeNode|NamedTypeNode|NonNullTypeNode { - $context = $context->override([HandlerContextOperators::class => new HandlerContextOperators(new Operators())]); - $type = $this->getArgumentTypeDefinitionNode($manipulator, $document, $argument, $context, Root::class); + $type = $this->getArgumentTypeDefinitionNode($manipulator, $document, $argument, $context, Root::class); if (!$type) { throw new FailedToCreateSearchCondition($argument); diff --git a/packages/graphql/src/SearchBy/Directives/DirectiveTest.php b/packages/graphql/src/SearchBy/Directives/DirectiveTest.php index 2fe05f42b..22733deb9 100644 --- a/packages/graphql/src/SearchBy/Directives/DirectiveTest.php +++ b/packages/graphql/src/SearchBy/Directives/DirectiveTest.php @@ -10,7 +10,6 @@ use GraphQL\Type\Definition\InputObjectType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Model as EloquentModel; use Illuminate\Database\Query\Builder as QueryBuilder; @@ -124,7 +123,7 @@ public function testManipulateArgDefinitionScoutBuilder(): void { ], ]); - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('search', SearchDirective::class); $this->useGraphQLSchema( @@ -147,8 +146,8 @@ public function testManipulateArgDefinitionScoutBuilder(): void { */ #[RequiresLaravelScout] public function testManipulateArgDefinitionScoutBuilderV5Compat(): void { - Container::getInstance()->bind(Root::class, V5::class); - Container::getInstance()->bind(Condition::class, V5::class); + $this->app()->bind(Root::class, V5::class); + $this->app()->bind(Condition::class, V5::class); $this->override(SearchByOperatorNotInDirective::class, static function (MockInterface $mock): void { $mock @@ -164,7 +163,7 @@ public function testManipulateArgDefinitionScoutBuilderV5Compat(): void { ], ]); - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('search', SearchDirective::class); $this->useGraphQLSchema( @@ -256,8 +255,8 @@ public function testDirectiveV5Compat( Closure $builderFactory, mixed $value, ): void { - Container::getInstance()->bind(Root::class, V5::class); - Container::getInstance()->bind(Condition::class, V5::class); + $this->app()->bind(Root::class, V5::class); + $this->app()->bind(Condition::class, V5::class); $path = is_array($expected) ? 'data.test' : 'errors.0.message'; $body = is_array($expected) ? [] : json_encode($expected->getMessage(), JSON_THROW_ON_ERROR); @@ -362,8 +361,8 @@ public function testHandleBuilderV5Compat( Closure $builderFactory, mixed $value, ): void { - Container::getInstance()->bind(Root::class, V5::class); - Container::getInstance()->bind(Condition::class, V5::class); + $this->app()->bind(Root::class, V5::class); + $this->app()->bind(Condition::class, V5::class); $builder = $builderFactory($this); $directive = $this->getExposeBuilderDirective($builder); @@ -424,7 +423,7 @@ public function testHandleScoutBuilder( $builder = $builderFactory($this); $directive = $this->getExposeBuilderDirective($builder); - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('search', SearchDirective::class); if ($resolver) { @@ -496,13 +495,13 @@ public function testHandleScoutBuilderV5Compat( ?Closure $resolver, ?Closure $fieldResolver, ): void { - Container::getInstance()->bind(Root::class, V5::class); - Container::getInstance()->bind(Condition::class, V5::class); + $this->app()->bind(Root::class, V5::class); + $this->app()->bind(Condition::class, V5::class); $builder = $builderFactory($this); $directive = $this->getExposeBuilderDirective($builder); - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('search', SearchDirective::class); if ($resolver) { @@ -588,7 +587,7 @@ public static function dataProviderManipulateArgDefinition(): array { 'TypeRegistry' => [ 'TypeRegistry.expected.graphql', 'TypeRegistry.schema.graphql', - static function (): void { + static function (TestCase $test): void { $enum = new EnumType([ 'name' => 'TestEnum', 'values' => [ @@ -644,7 +643,7 @@ static function (): void { ], ]); - $registry = Container::getInstance()->make(TypeRegistry::class); + $registry = $test->app()->make(TypeRegistry::class); $registry->register($enum); $registry->register($typeA); @@ -655,9 +654,9 @@ static function (): void { 'CustomComplexOperator' => [ 'CustomComplexOperator.expected.graphql', 'CustomComplexOperator.schema.graphql', - static function (): void { - $locator = Container::getInstance()->make(DirectiveLocator::class); - $resolver = Container::getInstance()->make(BuilderFieldResolver::class); + static function (TestCase $test): void { + $locator = $test->app()->make(DirectiveLocator::class); + $resolver = $test->app()->make(BuilderFieldResolver::class); $directive = new DirectiveTest__CustomComplexOperator($resolver); $locator->setResolved('customComplexOperator', $directive::class); @@ -667,7 +666,7 @@ static function (): void { 'AllowedDirectives.expected.graphql', 'AllowedDirectives.schema.graphql', static function (TestCase $test): void { - $locator = Container::getInstance()->make(DirectiveLocator::class); + $locator = $test->app()->make(DirectiveLocator::class); $allowed = new class () extends BaseDirective { #[Override] public static function definition(): string { @@ -715,7 +714,7 @@ static function (TestCase $test): void { ], ]); - Container::getInstance()->make(TypeRegistry::class)->register( + $test->app()->make(TypeRegistry::class)->register( new class([ 'name' => 'IgnoredType', 'fields' => [ @@ -758,9 +757,9 @@ static function (TestCase $test): void { 'V5Compat' => [ 'V5Compat.expected.graphql', 'V5Compat.schema.graphql', - static function (): void { - Container::getInstance()->bind(Root::class, V5::class); - Container::getInstance()->bind(Condition::class, V5::class); + static function (TestCase $test): void { + $test->app()->bind(Root::class, V5::class); + $test->app()->bind(Condition::class, V5::class); }, ], ]; diff --git a/packages/graphql/src/SearchBy/Operators.php b/packages/graphql/src/SearchBy/Operators.php index 0a6748ed9..f150274db 100644 --- a/packages/graphql/src/SearchBy/Operators.php +++ b/packages/graphql/src/SearchBy/Operators.php @@ -3,8 +3,8 @@ namespace LastDragon_ru\LaraASP\GraphQL\SearchBy; use GraphQL\Type\Definition\Type; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Operator as BuilderOperator; use LastDragon_ru\LaraASP\GraphQL\Builder\Operators as BuilderOperators; use LastDragon_ru\LaraASP\GraphQL\Package; @@ -167,12 +167,15 @@ class Operators extends BuilderOperators { ], ]; - public function __construct() { + public function __construct( + ContainerResolver $container, + protected readonly ConfigResolver $config, + ) { /** @var array|string>> $operators */ - $operators = (array) Container::getInstance()->make(Repository::class) + $operators = (array) $this->config->getInstance() ->get(Package::Name.'.search_by.operators'); - parent::__construct($operators); + parent::__construct($container, $operators); } #[Override] diff --git a/packages/graphql/src/SearchBy/Operators/Comparison/NotInTest.php b/packages/graphql/src/SearchBy/Operators/Comparison/NotInTest.php index 46bd0c017..a423288ca 100644 --- a/packages/graphql/src/SearchBy/Operators/Comparison/NotInTest.php +++ b/packages/graphql/src/SearchBy/Operators/Comparison/NotInTest.php @@ -4,7 +4,6 @@ use Closure; use Composer\InstalledVersions; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Builder as ScoutBuilder; use LastDragon_ru\LaraASP\GraphQL\Builder\Context; @@ -90,7 +89,7 @@ public function testCallScoutBuilder( } // Supported? - $operator = Container::getInstance()->make(NotInTest_Operator::class); + $operator = $this->app()->make(NotInTest_Operator::class); if (!$operator->isScoutSupported()) { self::markTestSkipped( diff --git a/packages/graphql/src/SearchBy/OperatorsTest.php b/packages/graphql/src/SearchBy/OperatorsTest.php index 784d2227f..30792cdb7 100644 --- a/packages/graphql/src/SearchBy/OperatorsTest.php +++ b/packages/graphql/src/SearchBy/OperatorsTest.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\GraphQL\SearchBy; use Exception; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Handler; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeProvider; @@ -40,8 +39,8 @@ public function testConstructor(): void { $source = Mockery::mock(TypeSource::class); $context = Mockery::mock(Context::class); - $operators = Container::getInstance()->make(Operators::class); - $manipulator = Container::getInstance()->make(Manipulator::class, [ + $operators = $this->app()->make(Operators::class); + $manipulator = $this->app()->make(Manipulator::class, [ 'document' => Mockery::mock(DocumentAST::class), ]); diff --git a/packages/graphql/src/SortBy/Directives/Directive.php b/packages/graphql/src/SortBy/Directives/Directive.php index 4d5c2c9e5..8678a73b6 100644 --- a/packages/graphql/src/SortBy/Directives/Directive.php +++ b/packages/graphql/src/SortBy/Directives/Directive.php @@ -5,15 +5,17 @@ use GraphQL\Language\AST\ListTypeNode; use GraphQL\Language\AST\NamedTypeNode; use GraphQL\Language\AST\NonNullTypeNode; -use LastDragon_ru\LaraASP\GraphQL\Builder\Context\HandlerContextOperators; +use LastDragon_ru\LaraASP\GraphQL\Builder\BuilderInfoDetector; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Directives\HandlerDirective; use LastDragon_ru\LaraASP\GraphQL\Builder\Manipulator; +use LastDragon_ru\LaraASP\GraphQL\Builder\ManipulatorFactory; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\SortBy\Exceptions\FailedToCreateSortClause; use LastDragon_ru\LaraASP\GraphQL\SortBy\Operators; use LastDragon_ru\LaraASP\GraphQL\SortBy\Operators\Root; +use LastDragon_ru\LaraASP\GraphQL\Utils\ArgumentFactory; use Nuwave\Lighthouse\Schema\AST\DocumentAST; use Nuwave\Lighthouse\Schema\DirectiveLocator; use Nuwave\Lighthouse\Scout\ScoutBuilderDirective; @@ -26,6 +28,15 @@ class Directive extends HandlerDirective implements ArgManipulator, ArgBuilderDirective, ScoutBuilderDirective { final public const Name = 'SortBy'; + public function __construct( + ManipulatorFactory $manipulatorFactory, + BuilderInfoDetector $detector, + ArgumentFactory $argumentFactory, + Operators $operators, + ) { + parent::__construct($manipulatorFactory, $argumentFactory, $detector, $operators); + } + #[Override] public static function definition(): string { $name = DirectiveLocator::directiveName(static::class); @@ -52,8 +63,7 @@ protected function getArgDefinitionType( ObjectFieldArgumentSource|InterfaceFieldArgumentSource $argument, Context $context, ): ListTypeNode|NamedTypeNode|NonNullTypeNode { - $context = $context->override([HandlerContextOperators::class => new HandlerContextOperators(new Operators())]); - $type = $this->getArgumentTypeDefinitionNode($manipulator, $document, $argument, $context, Root::class); + $type = $this->getArgumentTypeDefinitionNode($manipulator, $document, $argument, $context, Root::class); if (!$type) { throw new FailedToCreateSortClause($argument); diff --git a/packages/graphql/src/SortBy/Directives/DirectiveTest.php b/packages/graphql/src/SortBy/Directives/DirectiveTest.php index 5cccc4e74..06752a7e7 100644 --- a/packages/graphql/src/SortBy/Directives/DirectiveTest.php +++ b/packages/graphql/src/SortBy/Directives/DirectiveTest.php @@ -8,7 +8,6 @@ use GraphQL\Type\Definition\InputObjectType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Model as EloquentModel; use Illuminate\Database\Query\Builder as QueryBuilder; @@ -113,7 +112,7 @@ public function testManipulateArgDefinitionScoutBuilder(): void { ], ]); - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('search', SearchDirective::class); $this->useGraphQLSchema( @@ -134,7 +133,7 @@ public function testManipulateArgDefinitionScoutBuilderV5Compat(): void { $this->override(Root::class, V5::class); $this->override(Clause::class, V5::class); - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('search', SearchDirective::class); $this->useGraphQLSchema( @@ -169,7 +168,7 @@ public function testManipulateArgDefinitionTypeRegistryEmpty(): void { new TypeDefinitionImpossibleToCreateType(Clause::class, 'type TestType', new Context()), ); - $registry = Container::getInstance()->make(TypeRegistry::class); + $registry = $this->app()->make(TypeRegistry::class); $registry->register($type); $this->useGraphQLSchema( @@ -251,8 +250,8 @@ public function testDirectiveV5Compat( mixed $value, ?Closure $prepare = null, ): void { - Container::getInstance()->bind(Root::class, V5::class); - Container::getInstance()->bind(Clause::class, V5::class); + $this->app()->bind(Root::class, V5::class); + $this->app()->bind(Clause::class, V5::class); if ($prepare) { $prepare($this); @@ -369,8 +368,8 @@ public function testHandleBuilderV5Compat( mixed $value, ?Closure $prepare = null, ): void { - Container::getInstance()->bind(Root::class, V5::class); - Container::getInstance()->bind(Clause::class, V5::class); + $this->app()->bind(Root::class, V5::class); + $this->app()->bind(Clause::class, V5::class); if ($prepare) { $prepare($this); @@ -435,7 +434,7 @@ public function testHandleScoutBuilder( $builder = $builderFactory($this); $directive = $this->getExposeBuilderDirective($builder); - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('search', SearchDirective::class); if ($resolver) { @@ -507,13 +506,13 @@ public function testHandleScoutBuilderV5Compat( ?Closure $resolver, ?Closure $fieldResolver, ): void { - Container::getInstance()->bind(Root::class, V5::class); - Container::getInstance()->bind(Clause::class, V5::class); + $this->app()->bind(Root::class, V5::class); + $this->app()->bind(Clause::class, V5::class); $builder = $builderFactory($this); $directive = $this->getExposeBuilderDirective($builder); - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('search', SearchDirective::class); if ($resolver) { @@ -584,8 +583,8 @@ public static function dataProviderManipulateArgDefinition(): array { 'Implicit' => [ 'Implicit.expected.graphql', 'Implicit.schema.graphql', - static function (): void { - Container::getInstance()->make(DirectiveLocator::class) + static function (TestCase $test): void { + $test->app()->make(DirectiveLocator::class) ->setResolved( DirectiveLocator::directiveName(DirectiveTest__CustomOperatorDirective::class), DirectiveTest__CustomOperatorDirective::class, @@ -606,7 +605,7 @@ static function (): void { 'AllowedDirectives.expected.graphql', 'AllowedDirectives.schema.graphql', static function (TestCase $test): void { - $locator = Container::getInstance()->make(DirectiveLocator::class); + $locator = $test->app()->make(DirectiveLocator::class); $allowed = new class () extends BaseDirective { #[Override] public static function definition(): string { @@ -648,7 +647,7 @@ static function (TestCase $test): void { ], ]); - Container::getInstance()->make(TypeRegistry::class)->register( + $test->app()->make(TypeRegistry::class)->register( new class([ 'name' => 'IgnoredType', 'fields' => [ @@ -677,7 +676,7 @@ static function (TestCase $test): void { 'TypeRegistry' => [ 'Example.expected.graphql', 'Example.schema.graphql', - static function (): void { + static function (TestCase $test): void { $i = new class([ 'name' => 'I', 'fields' => [ @@ -746,7 +745,7 @@ static function (): void { ], ]); - $registry = Container::getInstance()->make(TypeRegistry::class); + $registry = $test->app()->make(TypeRegistry::class); $registry->register($a); $registry->register($b); $registry->register($c); diff --git a/packages/graphql/src/SortBy/Operators.php b/packages/graphql/src/SortBy/Operators.php index d349fd0bc..14ca53498 100644 --- a/packages/graphql/src/SortBy/Operators.php +++ b/packages/graphql/src/SortBy/Operators.php @@ -2,8 +2,8 @@ namespace LastDragon_ru\LaraASP\GraphQL\SortBy; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Operator as BuilderOperator; use LastDragon_ru\LaraASP\GraphQL\Builder\Operators as BuilderOperators; use LastDragon_ru\LaraASP\GraphQL\Package; @@ -38,12 +38,15 @@ class Operators extends BuilderOperators { ], ]; - public function __construct() { + public function __construct( + ContainerResolver $container, + protected readonly ConfigResolver $config, + ) { /** @var array|string>> $operators */ - $operators = (array) Container::getInstance()->make(Repository::class) + $operators = (array) $this->config->getInstance() ->get(Package::Name.'.sort_by.operators'); - parent::__construct($operators); + parent::__construct($container, $operators); } #[Override] diff --git a/packages/graphql/src/SortBy/Operators/Sort.php b/packages/graphql/src/SortBy/Operators/Sort.php index a83d106e3..21b59798e 100644 --- a/packages/graphql/src/SortBy/Operators/Sort.php +++ b/packages/graphql/src/SortBy/Operators/Sort.php @@ -2,8 +2,7 @@ namespace LastDragon_ru\LaraASP\GraphQL\SortBy\Operators; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\BuilderFieldResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Handler; @@ -27,6 +26,7 @@ class Sort extends Operator { * @param SorterFactory $factory */ public function __construct( + protected readonly ConfigResolver $config, protected readonly SorterFactory $factory, BuilderFieldResolver $resolver, ) { @@ -107,7 +107,7 @@ protected function getNulls(Sorter $sorter, Context $context, Direction $directi // Default $nulls = null; - $config = Container::getInstance()->make(Repository::class)->get(Package::Name.'.sort_by.nulls'); + $config = $this->config->getInstance()->get(Package::Name.'.sort_by.nulls'); $direction = match ($direction) { Direction::asc => Direction::Asc, Direction::desc => Direction::Desc, diff --git a/packages/graphql/src/SortBy/Operators/SortTest.php b/packages/graphql/src/SortBy/Operators/SortTest.php index 74129a698..105f74c0f 100644 --- a/packages/graphql/src/SortBy/Operators/SortTest.php +++ b/packages/graphql/src/SortBy/Operators/SortTest.php @@ -4,14 +4,16 @@ use Closure; use Exception; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Query\Builder as QueryBuilder; use Laravel\Scout\Builder as ScoutBuilder; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Context; +use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\BuilderFieldResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Field; use LastDragon_ru\LaraASP\GraphQL\Package; use LastDragon_ru\LaraASP\GraphQL\SortBy\Contracts\Sorter; +use LastDragon_ru\LaraASP\GraphQL\SortBy\Contracts\SorterFactory; use LastDragon_ru\LaraASP\GraphQL\SortBy\Directives\Directive; use LastDragon_ru\LaraASP\GraphQL\SortBy\Enums\Direction; use LastDragon_ru\LaraASP\GraphQL\SortBy\Enums\Nulls; @@ -85,9 +87,9 @@ public function testCallEloquentBuilder(): void { ->andReturns(); }); - $directive = Container::getInstance()->make(Directive::class); + $directive = $this->app()->make(Directive::class); $field = new Field(); - $operator = Container::getInstance()->make(Sort::class); + $operator = $this->app()->make(Sort::class); $argument = $this->getGraphQLArgument( 'Test', Direction::Asc, @@ -112,9 +114,9 @@ public function testCallQueryBuilder(): void { ->once(); }); - $directive = Container::getInstance()->make(Directive::class); + $directive = $this->app()->make(Directive::class); $field = new Field(); - $operator = Container::getInstance()->make(Sort::class); + $operator = $this->app()->make(Sort::class); $argument = $this->getGraphQLArgument( 'Test', Direction::Asc, @@ -139,9 +141,9 @@ public function testCallScoutBuilder(): void { ->once(); }); - $directive = Container::getInstance()->make(Directive::class); + $directive = $this->app()->make(Directive::class); $field = new Field(); - $operator = Container::getInstance()->make(Sort::class); + $operator = $this->app()->make(Sort::class); $argument = $this->getGraphQLArgument( 'Test', Direction::Asc, @@ -170,7 +172,10 @@ public function testGetNulls( $sorter = $sorterFactory($this); $context = $contextFactory($this); - $operator = Mockery::mock(Sort::class); + $config = $this->app()->make(ConfigResolver::class); + $factory = Mockery::mock(SorterFactory::class); + $resolver = Mockery::mock(BuilderFieldResolver::class); + $operator = Mockery::mock(Sort::class, [$config, $factory, $resolver]); $operator->shouldAllowMockingProtectedMethods(); $operator->makePartial(); diff --git a/packages/graphql/src/SortBy/OperatorsTest.php b/packages/graphql/src/SortBy/OperatorsTest.php index 11ed1b6e5..4669ef625 100644 --- a/packages/graphql/src/SortBy/OperatorsTest.php +++ b/packages/graphql/src/SortBy/OperatorsTest.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\GraphQL\SortBy; use Exception; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Handler; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeProvider; @@ -37,8 +36,8 @@ public function testConstructor(): void { $source = Mockery::mock(TypeSource::class); $context = Mockery::mock(Context::class); - $operators = Container::getInstance()->make(Operators::class); - $manipulator = Container::getInstance()->make(Manipulator::class, [ + $operators = $this->app()->make(Operators::class); + $manipulator = $this->app()->make(Manipulator::class, [ 'document' => Mockery::mock(DocumentAST::class), ]); diff --git a/packages/graphql/src/SortBy/SorterFactory.php b/packages/graphql/src/SortBy/SorterFactory.php index 02f4d13de..9cf009b78 100644 --- a/packages/graphql/src/SortBy/SorterFactory.php +++ b/packages/graphql/src/SortBy/SorterFactory.php @@ -5,6 +5,7 @@ use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Query\Builder as QueryBuilder; use Laravel\Scout\Builder as ScoutBuilder; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\BuilderHelperFactory; use LastDragon_ru\LaraASP\GraphQL\SortBy\Contracts\Sorter as SorterContract; use LastDragon_ru\LaraASP\GraphQL\SortBy\Contracts\SorterFactory as SorterFactoryContract; @@ -23,7 +24,9 @@ class SorterFactory implements SorterFactoryContract { use BuilderHelperFactory; - public function __construct() { + public function __construct( + protected readonly ContainerResolver $container, + ) { $this->addHelper(EloquentBuilder::class, EloquentSorter::class); $this->addHelper(QueryBuilder::class, QuerySorter::class); $this->addHelper(ScoutBuilder::class, ScoutSorter::class); @@ -42,4 +45,9 @@ public function create(object|string $builder): ?SorterContract { return $helper; } + + #[Override] + private function getContainerResolver(): ContainerResolver { + return $this->container; + } } diff --git a/packages/graphql/src/SortBy/Sorters/EloquentSorterTest.php b/packages/graphql/src/SortBy/Sorters/EloquentSorterTest.php index 6cd510190..f5677fc62 100644 --- a/packages/graphql/src/SortBy/Sorters/EloquentSorterTest.php +++ b/packages/graphql/src/SortBy/Sorters/EloquentSorterTest.php @@ -4,7 +4,6 @@ use Closure; use Exception; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Model as EloquentModel; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -74,7 +73,7 @@ static function (MockInterface $mock) use ($resolver): void { ); } - $sorter = Container::getInstance()->make(EloquentSorter::class); + $sorter = $this->app()->make(EloquentSorter::class); $builder = $builder($this); $builder = $sorter->sort($builder, $field, $direction, $nulls); diff --git a/packages/graphql/src/SortBy/Sorters/QuerySorterTest.php b/packages/graphql/src/SortBy/Sorters/QuerySorterTest.php index 316e1e1cc..493697fbe 100644 --- a/packages/graphql/src/SortBy/Sorters/QuerySorterTest.php +++ b/packages/graphql/src/SortBy/Sorters/QuerySorterTest.php @@ -4,7 +4,6 @@ use Closure; use Exception; -use Illuminate\Container\Container; use Illuminate\Database\Query\Builder as QueryBuilder; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\BuilderFieldResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\Field; @@ -56,7 +55,7 @@ static function (MockInterface $mock) use ($resolver): void { ); } - $sorter = Container::getInstance()->make(QuerySorter::class); + $sorter = $this->app()->make(QuerySorter::class); $builder = $builder($this); $builder = $sorter->sort($builder, $field, $direction, null); diff --git a/packages/graphql/src/SortBy/Sorters/ScoutSorterTest.php b/packages/graphql/src/SortBy/Sorters/ScoutSorterTest.php index c76a880da..744103ddc 100644 --- a/packages/graphql/src/SortBy/Sorters/ScoutSorterTest.php +++ b/packages/graphql/src/SortBy/Sorters/ScoutSorterTest.php @@ -4,7 +4,6 @@ use Closure; use Exception; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Builder as ScoutBuilder; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\BuilderFieldResolver; @@ -63,8 +62,8 @@ static function (MockInterface $mock) use ($resolver): void { $this->override(FieldResolver::class, $fieldResolver); } - $sorter = Container::getInstance()->make(ScoutSorter::class); - $builder = Container::getInstance()->make(ScoutBuilder::class, [ + $sorter = $this->app()->make(ScoutSorter::class); + $builder = $this->app()->make(ScoutBuilder::class, [ 'query' => '', 'model' => new class() extends Model { // empty diff --git a/packages/graphql/src/Stream/Directives/Directive.php b/packages/graphql/src/Stream/Directives/Directive.php index 90d7c9600..3505c6757 100644 --- a/packages/graphql/src/Stream/Directives/Directive.php +++ b/packages/graphql/src/Stream/Directives/Directive.php @@ -9,13 +9,13 @@ use GraphQL\Language\Parser; use GraphQL\Type\Definition\HasFieldsType; use GraphQL\Type\Definition\Type; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Model as EloquentModel; use Illuminate\Database\Eloquent\Relations\Relation as EloquentRelation; use Illuminate\Database\Query\Builder as QueryBuilder; use Laravel\Scout\Builder as ScoutBuilder; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use LastDragon_ru\LaraASP\Core\Utils\Cast; use LastDragon_ru\LaraASP\Eloquent\ModelHelper; use LastDragon_ru\LaraASP\GraphQL\Builder\BuilderInfo; @@ -24,12 +24,12 @@ use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\BuilderInfoProvider; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Enhancer; use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeSource; +use LastDragon_ru\LaraASP\GraphQL\Builder\ManipulatorFactory; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceFieldSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldArgumentSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectSource; -use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithManipulator; use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithSource; use LastDragon_ru\LaraASP\GraphQL\Package; use LastDragon_ru\LaraASP\GraphQL\SearchBy\Definitions\SearchByDirective; @@ -89,7 +89,6 @@ use const JSON_THROW_ON_ERROR; class Directive extends BaseDirective implements FieldResolver, FieldManipulator, BuilderInfoProvider { - use WithManipulator; use WithSource; final public const Name = 'Stream'; @@ -101,10 +100,16 @@ class Directive extends BaseDirective implements FieldResolver, FieldManipulator final public const ArgKey = 'key'; /** - * @param StreamFactory $factory + * @param StreamFactory $streamFactory */ public function __construct( - protected readonly StreamFactory $factory, + protected readonly ContainerResolver $container, + protected readonly ConfigResolver $config, + protected readonly BuilderInfoDetector $detector, + protected readonly StreamFactory $streamFactory, + protected readonly StreamType $streamType, + protected readonly ProvidesResolver $provider, + protected readonly ManipulatorFactory $manipulatorFactory, ) { // empty } @@ -189,13 +194,13 @@ public function manipulateFieldDefinition( ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode &$parentType, ): void { // Prepare - $repository = Container::getInstance()->make(Repository::class); - $manipulator = $this->getAstManipulator($documentAST); + $repository = $this->config->getInstance(); + $manipulator = $this->manipulatorFactory->create($documentAST); $source = $this->getFieldSource($manipulator, $parentType, $fieldDefinition); $prefix = self::Settings; // Updated? - if (Container::getInstance()->make(StreamType::class)->is($source->getTypeName())) { + if ($this->streamType->is($source->getTypeName())) { return; } @@ -215,8 +220,7 @@ public function manipulateFieldDefinition( } // Builder? - Container::getInstance()->make(BuilderInfoDetector::class) - ->getFieldBuilderInfo($documentAST, $parentType, $fieldDefinition); + $this->detector->getFieldBuilderInfo($documentAST, $parentType, $fieldDefinition); // Searchable? $searchable = Cast::toBool( @@ -281,7 +285,7 @@ public function manipulateFieldDefinition( ); // Update type - $type = $this->getAstManipulator($documentAST)->getType(StreamType::class, $source, new Context()); + $type = $manipulator->getType(StreamType::class, $source, new Context()); $type = Parser::typeReference("{$type}!"); $manipulator->setFieldType( @@ -406,7 +410,7 @@ static function (mixed $argument, AstManipulator $manipulator): bool { } // Not supported? - if ($type !== null && !$this->factory->isSupported($type)) { + if ($type !== null && !$this->streamFactory->isSupported($type)) { throw new BuilderUnsupported($source, $type); } } catch (ReflectionException) { @@ -430,7 +434,7 @@ static function (mixed $argument, AstManipulator $manipulator): bool { public function resolveField(FieldValue $fieldValue): callable { return function (mixed $root, array $args, GraphQLContext $context, ResolveInfo $info): StreamValue { // Offset - $manipulator = $this->getAstManipulator(new DocumentAST()); + $manipulator = $this->manipulatorFactory->create(new DocumentAST()); $source = (new ObjectSource($manipulator, $info->parentType))->getField($info->fieldDefinition); $offset = $this->getFieldValue(StreamOffsetDirective::class, $manipulator, $source, $info, $args); @@ -445,7 +449,7 @@ public function resolveField(FieldValue $fieldValue): callable { if (!is_object($builder)) { throw new BuilderInvalid($source, gettype($builder)); - } elseif (!$this->factory->isSupported($builder)) { + } elseif (!$this->streamFactory->isSupported($builder)) { throw new BuilderUnsupported($source, $builder::class); } else { // ok @@ -454,7 +458,7 @@ public function resolveField(FieldValue $fieldValue): callable { // Stream $key = $this->getArgKey($manipulator, $source); $limit = $this->getFieldValue(StreamLimitDirective::class, $manipulator, $source, $info, $args); - $stream = $this->factory->create($builder, $key, $limit, $offset); + $stream = $this->streamFactory->create($builder, $key, $limit, $offset); $stream = new StreamValue($stream); return $stream; @@ -557,7 +561,7 @@ protected function getResolver(ObjectFieldSource|InterfaceFieldSource $source): if (!$resolver) { $resolver = RootType::isRootType($parent) ? $this->getResolverModel( - Container::getInstance()->make(StreamType::class)->getOriginalTypeName($source->getTypeName()), + $this->streamType->getOriginalTypeName($source->getTypeName()), ) : $this->getResolverRelation($parent, $source->getName()); } @@ -593,9 +597,7 @@ protected function getResolverRelation(string $model, string $relation): ?Closur protected function getResolverQuery(string $type, string $field): ?array { // We are mimicking to default Lighthouse resolver resolution, thus // custom implementations may not work. - $provider = Container::getInstance()->get(ProvidesResolver::class); - - if (!($provider instanceof ResolverProvider)) { + if (!($this->provider instanceof ResolverProvider)) { return null; } @@ -631,7 +633,7 @@ public function getResolverClass(ResolverProvider $provider, FieldValue $value, return $provider->findResolverClass($value, $method); } }; - $class = $helper->getResolverClass($provider, $value, $method); + $class = $helper->getResolverClass($this->provider, $value, $method); $resolver = $class ? [$class, $method] : null; return $resolver; @@ -679,7 +681,7 @@ protected function getArgKey( } // Search for field with `ID!` type - $type = Container::getInstance()->make(StreamType::class)->getOriginalTypeName($source->getTypeName()); + $type = $this->streamType->getOriginalTypeName($source->getTypeName()); $type = $manipulator->getTypeDefinition($type); $field = null; diff --git a/packages/graphql/src/Stream/Directives/DirectiveTest.php b/packages/graphql/src/Stream/Directives/DirectiveTest.php index 07d0538ce..6f0b7680f 100644 --- a/packages/graphql/src/Stream/Directives/DirectiveTest.php +++ b/packages/graphql/src/Stream/Directives/DirectiveTest.php @@ -10,19 +10,19 @@ use GraphQL\Type\Definition\FieldDefinition; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; -use Illuminate\Container\Container; use Illuminate\Contracts\Encryption\StringEncrypter; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Model as EloquentModel; use Illuminate\Database\Query\Builder as QueryBuilder; use Laravel\Scout\Builder as ScoutBuilder; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; use LastDragon_ru\LaraASP\GraphQL\Builder\BuilderInfo; -use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeSource; +use LastDragon_ru\LaraASP\GraphQL\Builder\BuilderInfoDetector; use LastDragon_ru\LaraASP\GraphQL\Builder\Exceptions\BuilderUnknown; +use LastDragon_ru\LaraASP\GraphQL\Builder\ManipulatorFactory; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\InterfaceFieldSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectFieldSource; use LastDragon_ru\LaraASP\GraphQL\Builder\Sources\ObjectSource; -use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithManipulator; use LastDragon_ru\LaraASP\GraphQL\Exceptions\ArgumentAlreadyDefined; use LastDragon_ru\LaraASP\GraphQL\Package; use LastDragon_ru\LaraASP\GraphQL\SearchBy\Definitions\SearchByDirective; @@ -42,6 +42,7 @@ use LastDragon_ru\LaraASP\GraphQL\Stream\Exceptions\KeyUnknown; use LastDragon_ru\LaraASP\GraphQL\Stream\Offset as StreamOffset; use LastDragon_ru\LaraASP\GraphQL\Stream\Streams\Stream; +use LastDragon_ru\LaraASP\GraphQL\Stream\Types\Stream as StreamType; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Data\Models\TestObject; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Data\Models\TestObjectSearchable; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Data\Models\WithTestObject; @@ -58,6 +59,7 @@ use LastDragon_ru\LaraASP\Testing\Constraints\Response\ContentTypes\JsonContentType; use LastDragon_ru\LaraASP\Testing\Constraints\Response\Response; use LastDragon_ru\LaraASP\Testing\Constraints\Response\StatusCodes\Ok; +use LastDragon_ru\LaraASP\Testing\Mockery\MockProperties; use Mockery; use Mockery\MockInterface; use Nuwave\Lighthouse\Execution\Arguments\ArgumentSetFactory; @@ -69,6 +71,7 @@ use Nuwave\Lighthouse\Scout\ScoutServiceProvider; use Nuwave\Lighthouse\Support\Contracts\Directive as DirectiveContract; use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; +use Nuwave\Lighthouse\Support\Contracts\ProvidesResolver; use Nuwave\Lighthouse\Testing\MakesGraphQLRequests; use Override; use PHPUnit\Framework\Attributes\CoversClass; @@ -77,6 +80,7 @@ use stdClass; use function array_merge; +use function count; use function is_string; use function json_encode; @@ -88,7 +92,6 @@ #[CoversClass(Directive::class)] final class DirectiveTest extends TestCase { use WithTestObject; - use WithManipulator; use MakesGraphQLRequests; // @@ -310,7 +313,7 @@ public function testManipulateFieldDefinitionScoutBuilder(): void { ], ]); - $directives = Container::getInstance()->make(DirectiveLocator::class); + $directives = $this->app()->make(DirectiveLocator::class); $directives->setResolved('stream', StreamDirective::class); @@ -325,16 +328,37 @@ public function testManipulateFieldDefinitionBuilderUnknown(): void { self::expectException(BuilderUnknown::class); self::expectExceptionMessage('Impossible to determine builder type for `type Query { field }`.'); - $directives = Container::getInstance()->make(DirectiveLocator::class); - $factory = Mockery::mock(StreamFactory::class); - $directive = new class($factory) extends StreamDirective { - #[Override] - public function getBuilderInfo(TypeSource $source): ?BuilderInfo { - return null; - } - }; + $directive = Mockery::mock(Directive::class, MockProperties::class); + $directive->makePartial(); + $directive + ->shouldUseProperty('config') + ->value( + $this->app()->make(ConfigResolver::class), + ); + $directive + ->shouldUseProperty('detector') + ->value( + $this->app()->make(BuilderInfoDetector::class), + ); + $directive + ->shouldUseProperty('streamType') + ->value( + $this->app()->make(StreamType::class), + ); + $directive + ->shouldUseProperty('manipulatorFactory') + ->value( + $this->app()->make(ManipulatorFactory::class), + ); + $directive + ->shouldReceive('getBuilderInfo') + ->once() + ->andReturn(null); + + $this->override(Directive::class, $directive); - $directives->setResolved('stream', $directive::class); + $directives = $this->app()->make(DirectiveLocator::class); + $directives->setResolved('stream', Directive::class); $this->useGraphQLSchema( <<<'GRAPHQL' @@ -355,7 +379,7 @@ public function testManipulateFieldDefinitionFieldIsNotList(): void { 'The `type Test { field }` is not a list.', ); - $directives = Container::getInstance()->make(DirectiveLocator::class); + $directives = $this->app()->make(DirectiveLocator::class); $directives->setResolved('stream', StreamDirective::class); @@ -376,7 +400,7 @@ public function testManipulateFieldDefinitionArgumentAlreadyDefined(): void { self::expectException(ArgumentAlreadyDefined::class); self::expectExceptionMessage('Argument `type Query { field(where) }` already defined.'); - $directives = Container::getInstance()->make(DirectiveLocator::class); + $directives = $this->app()->make(DirectiveLocator::class); $directives->setResolved('stream', StreamDirective::class); @@ -399,7 +423,7 @@ public function testManipulateFieldDefinitionFieldIsSubscription(): void { 'The `type Subscription { field }` is a Subscription. Subscriptions are not supported.', ); - $directives = Container::getInstance()->make(DirectiveLocator::class); + $directives = $this->app()->make(DirectiveLocator::class); $directives->setResolved('stream', StreamDirective::class); @@ -418,7 +442,7 @@ public function testManipulateFieldDefinitionFieldIsUnion(): void { 'The `type Query { field }` us a union. Unions are not supported.', ); - $directives = Container::getInstance()->make(DirectiveLocator::class); + $directives = $this->app()->make(DirectiveLocator::class); $directives->setResolved('stream', StreamDirective::class); @@ -450,15 +474,16 @@ public function testGetBuilderInfo( Exception|BuilderInfo|null $expected, Closure $sourceFactory, Closure|array|null $resolver, + ?string $builder, ): void { if ($expected instanceof Exception) { self::expectExceptionObject($expected); } - $manipulator = $this->getAstManipulator(Mockery::mock(DocumentAST::class)); - $source = $sourceFactory($manipulator); - $factory = Container::getInstance()->make(StreamFactory::class); - $directive = Mockery::mock(Directive::class, [$factory]); + $manipulatorFactory = $this->app()->make(ManipulatorFactory::class); + $manipulator = $manipulatorFactory->create(Mockery::mock(DocumentAST::class)); + $source = $sourceFactory($manipulator); + $directive = Mockery::mock(Directive::class, MockProperties::class); $directive->shouldAllowMockingProtectedMethods(); $directive->makePartial(); $directive @@ -467,6 +492,19 @@ public function testGetBuilderInfo( ->once() ->andReturn($resolver); + if ($builder !== null) { + $directive + ->shouldUseProperty('streamFactory') + ->value( + Mockery::mock(StreamFactory::class) + ->shouldReceive('isSupported') + ->with($builder) + ->once() + ->andReturn(true) + ->getMock(), + ); + } + self::assertEquals($expected, $directive->getBuilderInfo($source)); } @@ -513,7 +551,7 @@ public function testGetBuilder(): void { $info->path = ['field']; $info->parentType = $type; $info->fieldDefinition = $field; - $info->argumentSet = Container::getInstance()->make(ArgumentSetFactory::class)->fromResolveInfo( + $info->argumentSet = $this->app()->make(ArgumentSetFactory::class)->fromResolveInfo( [ 'limit' => 10, 'where' => [ @@ -587,7 +625,7 @@ public function testGetBuilderScoutBuilder(): void { $info->path = ['field']; $info->parentType = $type; $info->fieldDefinition = $field; - $info->argumentSet = Container::getInstance()->make(ArgumentSetFactory::class)->fromResolveInfo( + $info->argumentSet = $this->app()->make(ArgumentSetFactory::class)->fromResolveInfo( [ 'search' => '*', ], @@ -656,7 +694,7 @@ public function testGetBuilderLighthouseEnhancer(): void { $info->path = ['field']; $info->parentType = $type; $info->fieldDefinition = $field; - $info->argumentSet = Container::getInstance()->make(ArgumentSetFactory::class)->fromResolveInfo( + $info->argumentSet = $this->app()->make(ArgumentSetFactory::class)->fromResolveInfo( [ 'id' => 123, 'where' => [ @@ -702,15 +740,15 @@ public function testGetBuilderInfoScoutBuilder( Exception|BuilderInfo|null $expected, Closure $sourceFactory, Closure|array|null $resolver, + ?string $builder, ): void { if ($expected instanceof Exception) { self::expectExceptionObject($expected); } - $manipulator = $this->getAstManipulator(Mockery::mock(DocumentAST::class)); + $manipulator = $this->app()->make(ManipulatorFactory::class)->create(Mockery::mock(DocumentAST::class)); $source = $sourceFactory($manipulator); - $factory = Container::getInstance()->make(StreamFactory::class); - $directive = Mockery::mock(Directive::class, [$factory]); + $directive = Mockery::mock(Directive::class, MockProperties::class); $directive->shouldAllowMockingProtectedMethods(); $directive->makePartial(); $directive @@ -719,6 +757,19 @@ public function testGetBuilderInfoScoutBuilder( ->once() ->andReturn($resolver); + if ($builder !== null) { + $directive + ->shouldUseProperty('streamFactory') + ->value( + Mockery::mock(StreamFactory::class) + ->shouldReceive('isSupported') + ->with($builder) + ->once() + ->andReturn(true) + ->getMock(), + ); + } + self::assertEquals($expected, $directive->getBuilderInfo($source)); } @@ -728,9 +779,14 @@ public function testGetResolver(): void { Mockery::mock(AstManipulator::class)->makePartial(), new ObjectType(['name' => 'Car', 'fields' => []]), ); - $directive = Mockery::mock(Directive::class); + $directive = Mockery::mock(Directive::class, MockProperties::class); $directive->shouldAllowMockingProtectedMethods(); $directive->makePartial(); + $directive + ->shouldUseProperty('streamType') + ->value( + $this->app()->make(StreamType::class), + ); // Query $source = $parent->getField(Parser::fieldDefinition('query: String')); @@ -805,7 +861,7 @@ public function testGetResolverExplicit(array|null $expected, string $arguments) new ObjectType(['name' => 'Car', 'fields' => []]), ); $source = $object->getField($field); - $directive = Mockery::mock(Directive::class); + $directive = Mockery::mock(Directive::class, MockProperties::class); $directive->shouldAllowMockingProtectedMethods(); $directive->makePartial(); $directive->hydrate( @@ -813,7 +869,7 @@ public function testGetResolverExplicit(array|null $expected, string $arguments) $field, ); - if ($expected !== null) { + if ($expected) { $directive ->shouldReceive($expected['method']) ->withArgs($expected['args']) @@ -839,19 +895,13 @@ public function testGetResolverRelation(): void { $args = []; $info = Mockery::mock(ResolveInfo::class); $context = Mockery::mock(GraphQLContext::class); - $factory = Mockery::mock(StreamFactory::class); - $namespace = json_encode((new ReflectionClass(TestObject::class))->getNamespaceName(), JSON_THROW_ON_ERROR); - $directive = new class($factory) extends Directive { - #[Override] - public function name(): string { - return 'stream'; - } - - #[Override] - public function getResolverRelation(string $model, string $relation): ?Closure { - return parent::getResolverRelation($model, $relation); - } - }; + $namespace = json_encode( + (new ReflectionClass(TestObject::class))->getNamespaceName(), + JSON_THROW_ON_ERROR, + ); + $directive = Mockery::mock(Directive::class); + $directive->shouldAllowMockingProtectedMethods(); + $directive->makePartial(); $directive->hydrate( Parser::directive('@stream'), @@ -935,21 +985,14 @@ public function testGetResolverQuery(): void { ], ]); - $factory = Mockery::mock(StreamFactory::class); - $directive = new class($factory) extends Directive { - #[Override] - public function name(): string { - return 'stream'; - } - - /** - * @inheritDoc - */ - #[Override] - public function getResolverQuery(string $type, string $field): ?array { - return parent::getResolverQuery($type, $field); - } - }; + $directive = Mockery::mock(Directive::class, MockProperties::class); + $directive->shouldAllowMockingProtectedMethods(); + $directive->makePartial(); + $directive + ->shouldUseProperty('provider') + ->value( + $this->app()->make(ProvidesResolver::class), + ); $directive->hydrate( Parser::directive('@stream'), @@ -979,19 +1022,18 @@ public function testGetResolverModel(): void { $args = []; $info = Mockery::mock(ResolveInfo::class); $context = Mockery::mock(GraphQLContext::class); - $factory = Mockery::mock(StreamFactory::class); - $namespace = json_encode((new ReflectionClass(TestObject::class))->getNamespaceName(), JSON_THROW_ON_ERROR); - $directive = new class($factory) extends Directive { - #[Override] - public function name(): string { - return 'stream'; - } - - #[Override] - public function getResolverModel(string $model): Closure { - return parent::getResolverModel($model); - } - }; + $namespace = json_encode( + (new ReflectionClass(TestObject::class))->getNamespaceName(), + JSON_THROW_ON_ERROR, + ); + $directive = Mockery::mock(Directive::class); + $directive->shouldAllowMockingProtectedMethods(); + $directive->makePartial(); + $directive + ->shouldReceive('name') + ->atLeast() + ->once() + ->andReturn('stream'); $directive->hydrate( Parser::directive('@stream'), @@ -1019,22 +1061,15 @@ public function getResolverModel(string $model): Closure { public function testGetResolverClass(): void { // Prepare - $factory = Mockery::mock(StreamFactory::class); $namespace = json_encode(__NAMESPACE__, JSON_THROW_ON_ERROR); - $directive = new class($factory) extends Directive { - #[Override] - public function name(): string { - return 'stream'; - } - - /** - * @inheritDoc - */ - #[Override] - public function getResolverClass(string $class): array { - return parent::getResolverClass($class); - } - }; + $directive = Mockery::mock(Directive::class); + $directive->shouldAllowMockingProtectedMethods(); + $directive->makePartial(); + $directive + ->shouldReceive('name') + ->atLeast() + ->once() + ->andReturn('stream'); $directive->hydrate( Parser::directive('@stream'), @@ -1066,24 +1101,25 @@ public function testGetArgKey( DirectiveNode $directiveNode, Closure $sourceFactory, ): void { - $manipulator = $this->getAstManipulator(Mockery::mock(DocumentAST::class)); + $manipulator = $this->app()->make(ManipulatorFactory::class)->create(Mockery::mock(DocumentAST::class)); $source = $sourceFactory($manipulator); $field = $source->getField(); - $factory = Mockery::mock(StreamFactory::class); - $directive = new class($factory) extends Directive { - #[Override] - public function getArgKey( - AstManipulator $manipulator, - ObjectFieldSource|InterfaceFieldSource $source, - ): string { - return parent::getArgKey($manipulator, $source); - } - }; + $directive = Mockery::mock(Directive::class, MockProperties::class); + $directive->shouldAllowMockingProtectedMethods(); + $directive->makePartial(); self::assertInstanceOf(FieldDefinitionNode::class, $field); $directive->hydrate($directiveNode, $field); + if (count($directiveNode->arguments) === 0) { + $directive + ->shouldUseProperty('streamType') + ->value( + $this->app()->make(StreamType::class), + ); + } + if ($expected instanceof Exception) { self::expectExceptionObject($expected); } @@ -1123,7 +1159,7 @@ public function testResolveField(): void { $info->path = ['field']; $info->parentType = $type; $info->fieldDefinition = $field; - $info->argumentSet = Container::getInstance()->make(ArgumentSetFactory::class)->fromResolveInfo([], $info); + $info->argumentSet = $this->app()->make(ArgumentSetFactory::class)->fromResolveInfo([], $info); $info ->shouldReceive('enhanceBuilder') ->never(); @@ -1133,16 +1169,24 @@ public function testResolveField(): void { $value = Mockery::mock(FieldValue::class); $context = Mockery::mock(GraphQLContext::class); $builder = Mockery::mock(EloquentBuilder::class); - $factory = Container::getInstance()->make(StreamFactory::class); - $directive = Mockery::mock(Directive::class, [$factory]); + $directive = Mockery::mock(Directive::class, MockProperties::class); $directive->shouldAllowMockingProtectedMethods(); $directive->makePartial(); - - $directive->hydrate( - Parser::directive('@stream'), - $field->astNode, - ); - + $directive + ->shouldUseProperty('manipulatorFactory') + ->value( + $this->app()->make(ManipulatorFactory::class), + ); + $directive + ->shouldUseProperty('streamFactory') + ->value( + $this->app()->make(StreamFactory::class), + ); + $directive + ->shouldUseProperty('streamType') + ->value( + $this->app()->make(StreamType::class), + ); $directive ->shouldReceive('getResolver') ->once() @@ -1150,6 +1194,11 @@ public function testResolveField(): void { static fn () => $builder, ); + $directive->hydrate( + Parser::directive('@stream'), + $field->astNode, + ); + $stream = $directive->resolveField($value)($root, $args, $context, $info)->stream; $helper = new class() extends Stream { /** @noinspection PhpMissingParentConstructorInspection */ @@ -1227,10 +1276,14 @@ public function testResolveFieldBuilderInvalid(): void { $info->fieldDefinition = new FieldDefinition(['name' => 'field', 'type' => Type::string()]); $value = Mockery::mock(FieldValue::class); $context = Mockery::mock(GraphQLContext::class); - $factory = Mockery::mock(StreamFactory::class); - $directive = Mockery::mock(Directive::class, [$factory]); + $directive = Mockery::mock(Directive::class, MockProperties::class); $directive->shouldAllowMockingProtectedMethods(); $directive->makePartial(); + $directive + ->shouldUseProperty('manipulatorFactory') + ->value( + $this->app()->make(ManipulatorFactory::class), + ); $directive->hydrate( Parser::directive('@stream'), @@ -1265,9 +1318,19 @@ public function testResolveFieldBuilderUnsupported(): void { $value = Mockery::mock(FieldValue::class); $context = Mockery::mock(GraphQLContext::class); $factory = Mockery::mock(StreamFactory::class)->makePartial(); - $directive = Mockery::mock(Directive::class, [$factory]); + $directive = Mockery::mock(Directive::class, MockProperties::class); $directive->shouldAllowMockingProtectedMethods(); $directive->makePartial(); + $directive + ->shouldUseProperty('manipulatorFactory') + ->value( + $this->app()->make(ManipulatorFactory::class), + ); + $directive + ->shouldUseProperty('streamFactory') + ->value( + $factory, + ); $directive->hydrate( Parser::directive('@stream'), @@ -1308,49 +1371,32 @@ public function testResolveFieldBuilderUnsupported(): void { public function testGetFieldValue(): void { // Prepare - $manipulator = $this->getAstManipulator(Mockery::mock(DocumentAST::class)); - $factory = Mockery::mock(StreamFactory::class); - $directive = new class($factory) extends Directive { - /** - * @inheritDoc - */ - #[Override] - public function getFieldValue( - string $directive, - AstManipulator $manipulator, - ObjectFieldSource $source, - ResolveInfo $info, - array $args, - ): mixed { - return parent::getFieldValue( - $directive, - $manipulator, - $source, - $info, - $args, - ); - } - }; - $markerA = new class() extends DirectiveTest_Directive { + $manipulatorFactory = $this->app()->make(ManipulatorFactory::class); + $manipulator = $manipulatorFactory->create(Mockery::mock(DocumentAST::class)); + $directive = Mockery::mock(Directive::class); + $directive->shouldAllowMockingProtectedMethods(); + $directive->makePartial(); + + $markerA = new class() extends DirectiveTest_Directive { // empty }; - $markerB = new class() extends DirectiveTest_Directive { + $markerB = new class() extends DirectiveTest_Directive { #[Override] public function getFieldArgumentValue(ResolveInfo $info, mixed $value): mixed { return parent::getFieldArgumentValue($info, $value) ?? 'default-b'; } }; - $object = new ObjectType(['name' => 'Object', 'fields' => []]); - $info = Mockery::mock(ResolveInfo::class); - $args = [ + $object = new ObjectType(['name' => 'Object', 'fields' => []]); + $info = Mockery::mock(ResolveInfo::class); + $args = [ 'a' => null, 'b' => 'b', ]; - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('markerA', $markerA::class) ->setResolved('markerB', $markerB::class); - Container::getInstance()->make(TypeRegistry::class) + $this->app()->make(TypeRegistry::class) ->register($object); // Arg @@ -1390,38 +1436,21 @@ public function testGetFieldValueNoAttribute(): void { '/The `type Object { test }` must have at least one argument marked by `[^`]+` directive./', ); - $manipulator = $this->getAstManipulator(Mockery::mock(DocumentAST::class)); - $factory = Mockery::mock(StreamFactory::class); - $directive = new class($factory) extends Directive { - /** - * @inheritDoc - */ - #[Override] - public function getFieldValue( - string $directive, - AstManipulator $manipulator, - ObjectFieldSource $source, - ResolveInfo $info, - array $args, - ): mixed { - return parent::getFieldValue( - $directive, - $manipulator, - $source, - $info, - $args, - ); - } - }; - $object = new ObjectType(['name' => 'Object', 'fields' => []]); - $info = Mockery::mock(ResolveInfo::class); - $args = [ + $manipulatorFactory = $this->app()->make(ManipulatorFactory::class); + $manipulator = $manipulatorFactory->create(Mockery::mock(DocumentAST::class)); + $directive = Mockery::mock(Directive::class); + $directive->shouldAllowMockingProtectedMethods(); + $directive->makePartial(); + + $object = new ObjectType(['name' => 'Object', 'fields' => []]); + $info = Mockery::mock(ResolveInfo::class); + $args = [ 'a' => null, 'b' => 'b', 'c' => 123, ]; - Container::getInstance()->make(TypeRegistry::class) + $this->app()->make(TypeRegistry::class) ->register($object); $directive->getFieldValue( @@ -1441,41 +1470,24 @@ public function testGetFieldValueMultipleAttributes(): void { self::expectException(ArgumentsMutuallyExclusive::class); self::expectExceptionMessage('The arguments `a`, `b` of `type Object { test }` are mutually exclusive.'); - $manipulator = $this->getAstManipulator(Mockery::mock(DocumentAST::class)); - $factory = Mockery::mock(StreamFactory::class); - $directive = new class($factory) extends Directive { - /** - * @inheritDoc - */ - #[Override] - public function getFieldValue( - string $directive, - AstManipulator $manipulator, - ObjectFieldSource $source, - ResolveInfo $info, - array $args, - ): mixed { - return parent::getFieldValue( - $directive, - $manipulator, - $source, - $info, - $args, - ); - } - }; - $marker = Mockery::mock(DirectiveContract::class, FieldArgumentDirective::class); - $object = new ObjectType(['name' => 'Object', 'fields' => []]); - $info = Mockery::mock(ResolveInfo::class); - $args = [ + $manipulatorFactory = $this->app()->make(ManipulatorFactory::class); + $manipulator = $manipulatorFactory->create(Mockery::mock(DocumentAST::class)); + $directive = Mockery::mock(Directive::class); + $directive->shouldAllowMockingProtectedMethods(); + $directive->makePartial(); + + $marker = Mockery::mock(DirectiveContract::class, FieldArgumentDirective::class); + $object = new ObjectType(['name' => 'Object', 'fields' => []]); + $info = Mockery::mock(ResolveInfo::class); + $args = [ 'a' => null, 'b' => 'b', 'c' => 123, ]; - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('marker', $marker::class); - Container::getInstance()->make(TypeRegistry::class) + $this->app()->make(TypeRegistry::class) ->register($object); $directive->getFieldValue( @@ -1741,7 +1753,8 @@ static function (): void { * @return array */ public static function dataProviderGetBuilderInfo(): array { @@ -1758,6 +1771,7 @@ public static function dataProviderGetBuilderInfo(): array { null, $factory, null, + null, ], 'Closure(): mixed' => [ null, @@ -1765,6 +1779,7 @@ public static function dataProviderGetBuilderInfo(): array { static function (): mixed { return null; }, + null, ], 'Closure(): class' => [ BuilderInfo::create(EloquentBuilder::class), @@ -1772,6 +1787,7 @@ static function (): mixed { static function (): EloquentBuilder { throw new Exception('Should not be called.'); }, + EloquentBuilder::class, ], 'Closure(): union' => [ null, @@ -1779,26 +1795,31 @@ static function (): EloquentBuilder { static function () use ($class): stdClass|self { return $class->union(); }, + null, ], 'array(Unknown, method)' => [ null, $factory, ['Unknown', 'method'], + null, ], 'array(Class, unknownMethod)' => [ null, $factory, [stdClass::class, 'unknownMethod'], + null, ], 'array(Class, method: union)' => [ null, $factory, [$class::class, 'union'], + null, ], 'array(Class, method)' => [ BuilderInfo::create(EloquentBuilder::class), $factory, [$class::class, 'method'], + EloquentBuilder::class, ], ]; } @@ -1807,7 +1828,8 @@ static function () use ($class): stdClass|self { * @return array */ public static function dataProviderGetBuilderInfoScoutBuilder(): array { @@ -1823,6 +1845,7 @@ public static function dataProviderGetBuilderInfoScoutBuilder(): array { BuilderInfo::create(ScoutBuilder::class), $factory, [DirectiveTest_Model::class, 'method'], + ScoutBuilder::class, ], '@search: Closure(): class' => [ null, @@ -1830,6 +1853,7 @@ public static function dataProviderGetBuilderInfoScoutBuilder(): array { static function (): QueryBuilder { throw new Exception('Should not be called.'); }, + null, ], ]; } @@ -1843,7 +1867,13 @@ static function (): QueryBuilder { public static function dataProviderGetResolverExplicit(): array { return [ 'empty' => [ - null, + [ + 'method' => 'getResolverQuery', + 'args' => [ + 'Car', + 'test', + ], + ], '{}', ], 'builder' => [ diff --git a/packages/graphql/src/Stream/Directives/Limit.php b/packages/graphql/src/Stream/Directives/Limit.php index 286ddb1b4..ed21144af 100644 --- a/packages/graphql/src/Stream/Directives/Limit.php +++ b/packages/graphql/src/Stream/Directives/Limit.php @@ -13,7 +13,7 @@ use Illuminate\Container\Container; use Illuminate\Contracts\Config\Repository; use LastDragon_ru\LaraASP\Core\Utils\Cast; -use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithManipulator; +use LastDragon_ru\LaraASP\GraphQL\Builder\ManipulatorFactory; use LastDragon_ru\LaraASP\GraphQL\Stream\Contracts\FieldArgumentDirective; use Nuwave\Lighthouse\Execution\ResolveInfo; use Nuwave\Lighthouse\Schema\AST\DocumentAST; @@ -31,11 +31,15 @@ * @implements FieldArgumentDirective> */ class Limit extends BaseDirective implements ArgManipulator, FieldArgumentDirective { - use WithManipulator; - final public const ArgDefault = 'default'; final public const ArgMax = 'max'; + public function __construct( + private readonly ManipulatorFactory $manipulatorFactory, + ) { + // empty + } + /** * @return array{name: string, default: int, max: int} */ @@ -73,7 +77,7 @@ public function manipulateArgDefinition( ): void { // Type $type = Type::nonNull(Type::int()); - $manipulator = $this->getAstManipulator($documentAST); + $manipulator = $this->manipulatorFactory->create($documentAST); $argDefinition = $manipulator->setArgumentType( $parentType, $parentField, diff --git a/packages/graphql/src/Stream/Directives/Offset.php b/packages/graphql/src/Stream/Directives/Offset.php index ac98d264b..de01ba8fb 100644 --- a/packages/graphql/src/Stream/Directives/Offset.php +++ b/packages/graphql/src/Stream/Directives/Offset.php @@ -11,7 +11,7 @@ use Illuminate\Contracts\Config\Repository; use LastDragon_ru\LaraASP\Core\Utils\Cast; use LastDragon_ru\LaraASP\GraphQL\Builder\Context; -use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithManipulator; +use LastDragon_ru\LaraASP\GraphQL\Builder\ManipulatorFactory; use LastDragon_ru\LaraASP\GraphQL\Builder\Traits\WithSource; use LastDragon_ru\LaraASP\GraphQL\Stream\Contracts\FieldArgumentDirective; use LastDragon_ru\LaraASP\GraphQL\Stream\Exceptions\Client\CursorInvalidPath; @@ -33,9 +33,14 @@ * @implements FieldArgumentDirective */ class Offset extends BaseDirective implements ArgManipulator, FieldArgumentDirective { - use WithManipulator; use WithSource; + public function __construct( + private readonly ManipulatorFactory $manipulatorFactory, + ) { + // empty + } + /** * @return array{name: string} */ @@ -64,7 +69,7 @@ public function manipulateArgDefinition( FieldDefinitionNode &$parentField, ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode &$parentType, ): void { - $manipulator = $this->getAstManipulator($documentAST); + $manipulator = $this->manipulatorFactory->create($documentAST); $context = new Context(); $source = $this->getFieldArgumentSource($manipulator, $parentType, $parentField, $argDefinition); $type = Parser::typeReference($manipulator->getType(OffsetType::class, $source, $context)); diff --git a/packages/graphql/src/Stream/Directives/OffsetTest.php b/packages/graphql/src/Stream/Directives/OffsetTest.php index 885d1e13e..25873e280 100644 --- a/packages/graphql/src/Stream/Directives/OffsetTest.php +++ b/packages/graphql/src/Stream/Directives/OffsetTest.php @@ -3,6 +3,7 @@ namespace LastDragon_ru\LaraASP\GraphQL\Stream\Directives; use Exception; +use LastDragon_ru\LaraASP\GraphQL\Builder\ManipulatorFactory; use LastDragon_ru\LaraASP\GraphQL\Stream\Exceptions\Client\CursorInvalidPath; use LastDragon_ru\LaraASP\GraphQL\Stream\Offset as StreamOffset; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\TestCase; @@ -24,8 +25,9 @@ public function testGetFieldArgumentValue(Exception|StreamOffset $expected, Reso self::expectExceptionObject($expected); } - $directive = new Offset(); - $actual = $directive->getFieldArgumentValue($info, $value); + $manipulatorFactory = $this->app()->make(ManipulatorFactory::class); + $directive = new Offset($manipulatorFactory); + $actual = $directive->getFieldArgumentValue($info, $value); self::assertEquals($expected, $actual); } diff --git a/packages/graphql/src/Stream/Scalars/Offset.php b/packages/graphql/src/Stream/Scalars/Offset.php index f57132d83..08a02e7ef 100644 --- a/packages/graphql/src/Stream/Scalars/Offset.php +++ b/packages/graphql/src/Stream/Scalars/Offset.php @@ -9,16 +9,10 @@ use GraphQL\Language\AST\Node; use GraphQL\Language\AST\NodeKind; use GraphQL\Language\AST\StringValueNode; -use GraphQL\Language\AST\TypeDefinitionNode; use GraphQL\Type\Definition\ScalarType; use GraphQL\Utils\Utils; -use Illuminate\Container\Container; use Illuminate\Contracts\Encryption\StringEncrypter; use LastDragon_ru\LaraASP\Core\Utils\Cast; -use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\Context; -use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeDefinition; -use LastDragon_ru\LaraASP\GraphQL\Builder\Contracts\TypeSource; -use LastDragon_ru\LaraASP\GraphQL\Builder\Manipulator; use LastDragon_ru\LaraASP\GraphQL\Stream\Directives\Directive; use LastDragon_ru\LaraASP\GraphQL\Stream\Offset as StreamOffset; use LastDragon_ru\LaraASP\Serializer\Contracts\Serializer; @@ -31,7 +25,10 @@ use const FILTER_VALIDATE_INT; -class Offset extends ScalarType implements TypeDefinition { +/** + * @phpstan-import-type ScalarConfig from ScalarType + */ +class Offset extends ScalarType { public string $name = Directive::Name.'Offset'; public ?string $description = <<<'DESCRIPTION' Represents a offset for the `@stream` directive. The value can be a @@ -42,16 +39,16 @@ class Offset extends ScalarType implements TypeDefinition { pagination). DESCRIPTION; - // - // ========================================================================= - protected function getEncrypter(): StringEncrypter { - return Container::getInstance()->make(StringEncrypter::class); - } - - protected function getSerializer(): Serializer { - return Container::getInstance()->make(Serializer::class); + /** + * @param ScalarConfig $config + */ + public function __construct( + protected readonly StringEncrypter $encrypter, + protected readonly Serializer $serializer, + array $config = [], + ) { + parent::__construct($config); } - // // // ========================================================================= @@ -63,8 +60,8 @@ public function serialize(mixed $value): string|int { $value = $this->validate($value, InvariantViolation::class); if ($value instanceof StreamOffset) { - $value = $this->getSerializer()->serialize($value, 'json'); - $value = $this->encrypt($value); + $value = $this->serializer->serialize($value, 'json'); + $value = $this->encrypter->encryptString($value); } return $value; @@ -77,8 +74,8 @@ public function serialize(mixed $value): string|int { public function parseValue(mixed $value): StreamOffset|int { if (is_string($value)) { try { - $value = $this->decrypt($value); - $value = $this->getSerializer()->deserialize(StreamOffset::class, $value, 'json'); + $value = Cast::toString($this->encrypter->decryptString($value)); + $value = $this->serializer->deserialize(StreamOffset::class, $value, 'json'); } catch (Exception) { throw new Error('The cursor is not valid.'); } @@ -139,31 +136,4 @@ protected function validate(mixed $value, string $error): StreamOffset|int { return $value; } - - protected function encrypt(string $value): string { - return $this->getEncrypter()->encryptString($value); - } - - protected function decrypt(string $value): string { - return Cast::toString($this->getEncrypter()->decryptString($value)); - } - // - - // - // ========================================================================= - #[Override] - public function getTypeName(TypeSource $source, Context $context): string { - return $this->name(); - } - - #[Override] - public function getTypeDefinition( - Manipulator $manipulator, - TypeSource $source, - Context $context, - string $name, - ): TypeDefinitionNode|string|null { - return self::class; - } - // } diff --git a/packages/graphql/src/Stream/Scalars/OffsetTest.php b/packages/graphql/src/Stream/Scalars/OffsetTest.php index d0e03f710..a8d122c9d 100644 --- a/packages/graphql/src/Stream/Scalars/OffsetTest.php +++ b/packages/graphql/src/Stream/Scalars/OffsetTest.php @@ -9,10 +9,12 @@ use GraphQL\Language\AST\Node; use GraphQL\Language\AST\StringValueNode; use GraphQL\Language\AST\ValueNode; -use Illuminate\Container\Container; use Illuminate\Contracts\Encryption\Encrypter; use LastDragon_ru\LaraASP\GraphQL\Stream\Offset as StreamOffset; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\TestCase; +use LastDragon_ru\LaraASP\Serializer\Contracts\Serializer; +use LastDragon_ru\LaraASP\Testing\Mockery\MockProperties; +use Mockery; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; @@ -31,10 +33,24 @@ public function testSerialize(Exception|string|int $expected, mixed $value): voi self::expectExceptionObject($expected); } - $scalar = new Offset(); + $encrypter = $this->app()->make(Encrypter::class); + $scalar = Mockery::mock(Offset::class, MockProperties::class); + $scalar->makePartial(); + + if (is_string($expected)) { + $scalar + ->shouldUseProperty('encrypter') + ->value($encrypter); + $scalar + ->shouldUseProperty('serializer') + ->value( + $this->app()->make(Serializer::class), + ); + } + $actual = $scalar->serialize($value); $actual = is_string($actual) - ? Container::getInstance()->make(Encrypter::class)->decrypt($actual, false) + ? $encrypter->decrypt($actual, false) : $actual; self::assertEquals($expected, $actual); @@ -46,10 +62,24 @@ public function testParseValue(Exception|StreamOffset|int $expected, mixed $valu self::expectExceptionObject($expected); } + $encrypter = $this->app()->make(Encrypter::class); + $scalar = Mockery::mock(Offset::class, MockProperties::class); + $scalar->makePartial(); + + if (is_string($value)) { + $scalar + ->shouldUseProperty('encrypter') + ->value($encrypter); + $scalar + ->shouldUseProperty('serializer') + ->value( + $this->app()->make(Serializer::class), + ); + } + $value = is_string($value) - ? Container::getInstance()->make(Encrypter::class)->encrypt($value, false) + ? $encrypter->encrypt($value, false) : $value; - $scalar = new Offset(); $actual = $scalar->parseValue($value); self::assertEquals($expected, $actual); @@ -61,11 +91,22 @@ public function testParseLiteral(Exception|StreamOffset|int $expected, Node&Valu self::expectExceptionObject($expected); } + $encrypter = $this->app()->make(Encrypter::class); + $scalar = Mockery::mock(Offset::class, MockProperties::class); + $scalar->makePartial(); + if ($value instanceof StringValueNode) { - $value->value = Container::getInstance()->make(Encrypter::class)->encrypt($value->value, false); + $value->value = $encrypter->encrypt($value->value, false); + $scalar + ->shouldUseProperty('encrypter') + ->value($encrypter); + $scalar + ->shouldUseProperty('serializer') + ->value( + $this->app()->make(Serializer::class), + ); } - $scalar = new Offset(); $actual = $scalar->parseLiteral($value); self::assertEquals($expected, $actual); diff --git a/packages/graphql/src/Stream/Streams/ScoutTest.php b/packages/graphql/src/Stream/Streams/ScoutTest.php index fc188d24c..1085451cb 100644 --- a/packages/graphql/src/Stream/Streams/ScoutTest.php +++ b/packages/graphql/src/Stream/Streams/ScoutTest.php @@ -2,6 +2,7 @@ namespace LastDragon_ru\LaraASP\GraphQL\Stream\Streams; +use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Pagination\LengthAwarePaginator; use LastDragon_ru\LaraASP\GraphQL\Stream\Offset; use LastDragon_ru\LaraASP\GraphQL\Stream\Utils\Page; @@ -33,12 +34,11 @@ final class ScoutTest extends TestCase { * @inheritDoc */ #[Override] - protected function getEnvironmentSetUp($app): void { - parent::getEnvironmentSetUp($app); + protected function defineEnvironment($app): void { + parent::defineEnvironment($app); - $this->setConfig([ - 'scout.driver' => 'database', - ]); + $app->make(Repository::class) + ->set('scout.driver', 'database'); } // diff --git a/packages/graphql/src/Testing/GraphQLAssertions.php b/packages/graphql/src/Testing/GraphQLAssertions.php index 8a77152f5..8f45030b5 100644 --- a/packages/graphql/src/Testing/GraphQLAssertions.php +++ b/packages/graphql/src/Testing/GraphQLAssertions.php @@ -18,7 +18,7 @@ use GraphQL\Utils\BreakingChangesFinder; use GraphQL\Utils\BuildClientSchema; use GraphQL\Utils\BuildSchema; -use Illuminate\Container\Container; +use Illuminate\Contracts\Foundation\Application; use LastDragon_ru\LaraASP\GraphQLPrinter\Contracts\Printer; use LastDragon_ru\LaraASP\GraphQLPrinter\Contracts\Result; use LastDragon_ru\LaraASP\GraphQLPrinter\Contracts\Settings; @@ -51,6 +51,11 @@ trait GraphQLAssertions { assertGraphQLResult as private printerAssertGraphQLResult; } + // + // ========================================================================= + abstract protected function app(): Application; + // + // // ========================================================================= /** @@ -192,7 +197,7 @@ protected function useGraphQLSchema(Schema|DocumentNode|DocumentAST|SplFileInfo| : Args::content($schema); $provider = new TestSchemaProvider($schema); - $this->getGraphQLSchemaBuilder()->setSchema($provider); + $this->getGraphQLSchemaBuilder()->setSchema($this->app(), $provider); return $this; } @@ -201,7 +206,7 @@ protected function useGraphQLSchema(Schema|DocumentNode|DocumentAST|SplFileInfo| * Resets the current (application) schema to the default schema. */ protected function resetGraphQLSchema(): static { - $this->getGraphQLSchemaBuilder()->setSchema(null); + $this->getGraphQLSchemaBuilder()->setSchema($this->app(), null); return $this; } @@ -211,12 +216,12 @@ protected function getGraphQLSchema(): Schema { } protected function getGraphQLPrinter(Settings $settings = null): Printer { - return Container::getInstance()->make(Printer::class)->setSettings($settings ?? new TestSettings()); + return $this->app()->make(Printer::class)->setSettings($settings ?? new TestSettings()); } protected function getGraphQLSchemaBuilder(): SchemaBuilderWrapper { // Wrap - $container = Container::getInstance(); + $container = $this->app(); $builder = $container->resolved(SchemaBuilder::class) ? $container->make(SchemaBuilder::class) : null; diff --git a/packages/graphql/src/Testing/GraphQLAssertionsTest.php b/packages/graphql/src/Testing/GraphQLAssertionsTest.php index 3eaee764c..3fcd8e776 100644 --- a/packages/graphql/src/Testing/GraphQLAssertionsTest.php +++ b/packages/graphql/src/Testing/GraphQLAssertionsTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\GraphQL\Testing; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\TestDirective; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\TestCase; use Nuwave\Lighthouse\Schema\DirectiveLocator; @@ -15,7 +14,7 @@ #[CoversClass(GraphQLAssertions::class)] final class GraphQLAssertionsTest extends TestCase { public function testAssertGraphQLExportableEquals(): void { - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('a', TestDirective::class); $this->useGraphQLSchema( @@ -65,7 +64,7 @@ public function testAssertGraphQLExportableEquals(): void { } public function testAssertGraphQLPrintableEquals(): void { - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('a', TestDirective::class); $this->useGraphQLSchema( @@ -105,7 +104,7 @@ public function testAssertGraphQLPrintableEquals(): void { public function testAssertGraphQLSchemaValid(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('a', TestDirective::class) ->setResolved('test', TestDirective::class); @@ -144,7 +143,7 @@ public function testAssertGraphQLSchemaValid(): void { public function testAssertGraphQLSchemaNoBreakingChanges(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('a', TestDirective::class) ->setResolved('test', TestDirective::class); @@ -209,7 +208,7 @@ public function testAssertGraphQLSchemaNoBreakingChanges(): void { public function testAssertGraphQLSchemaNoDangerousChanges(): void { // Prepare - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved('a', TestDirective::class) ->setResolved('test', TestDirective::class); diff --git a/packages/graphql/src/Testing/Package/Data/Models/WithTestObject.php b/packages/graphql/src/Testing/Package/Data/Models/WithTestObject.php index 65eb7fac2..4b31b7f9d 100644 --- a/packages/graphql/src/Testing/Package/Data/Models/WithTestObject.php +++ b/packages/graphql/src/Testing/Package/Data/Models/WithTestObject.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\GraphQL\Testing\Package\Data\Models; -use Illuminate\Container\Container; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Builder; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\TestCase; @@ -20,8 +19,8 @@ trait WithTestObject { */ #[Before] protected function initWithTestObject(): void { - $this->afterApplicationCreated(static function (): void { - $schema = Container::getInstance()->make(Builder::class); + $this->afterApplicationCreated(function (): void { + $schema = $this->app()->make(Builder::class); $table = (new TestObject())->getTable(); if ($schema->hasTable($table)) { @@ -40,8 +39,8 @@ protected function initWithTestObject(): void { */ #[After] protected function withTestObjectAfter(): void { - $this->beforeApplicationDestroyed(static function (): void { - $schema = Container::getInstance()->make(Builder::class); + $this->beforeApplicationDestroyed(function (): void { + $schema = $this->app()->make(Builder::class); $table = (new TestObject())->getTable(); $schema->dropIfExists($table); diff --git a/packages/graphql/src/Testing/Package/DataProviders/QueryBuilderDataProvider.php b/packages/graphql/src/Testing/Package/DataProviders/QueryBuilderDataProvider.php index c4690ab81..c65968965 100644 --- a/packages/graphql/src/Testing/Package/DataProviders/QueryBuilderDataProvider.php +++ b/packages/graphql/src/Testing/Package/DataProviders/QueryBuilderDataProvider.php @@ -2,9 +2,8 @@ namespace LastDragon_ru\LaraASP\GraphQL\Testing\Package\DataProviders; -use Illuminate\Container\Container; -use Illuminate\Database\DatabaseManager; use Illuminate\Database\Query\Builder as QueryBuilder; +use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Data\Models\TestObject; use LastDragon_ru\LaraASP\Testing\Providers\ArrayDataProvider; use LastDragon_ru\LaraASP\Testing\Providers\UnknownValue; @@ -17,7 +16,7 @@ public function __construct() { 'Builder' => [ new UnknownValue(), static function (): QueryBuilder { - return Container::getInstance()->make(DatabaseManager::class)->table('test_objects'); + return TestObject::query()->toBase(); }, ], ]); diff --git a/packages/graphql/src/Testing/Package/DataProviders/ScoutBuilderDataProvider.php b/packages/graphql/src/Testing/Package/DataProviders/ScoutBuilderDataProvider.php index 8d0d498e0..2336d507f 100644 --- a/packages/graphql/src/Testing/Package/DataProviders/ScoutBuilderDataProvider.php +++ b/packages/graphql/src/Testing/Package/DataProviders/ScoutBuilderDataProvider.php @@ -2,9 +2,8 @@ namespace LastDragon_ru\LaraASP\GraphQL\Testing\Package\DataProviders; -use Illuminate\Container\Container; -use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Builder as ScoutBuilder; +use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Data\Models\TestObjectSearchable; use LastDragon_ru\LaraASP\Testing\Providers\ArrayDataProvider; use LastDragon_ru\LaraASP\Testing\Providers\UnknownValue; @@ -17,12 +16,7 @@ public function __construct() { 'Builder' => [ new UnknownValue(), static function (): ScoutBuilder { - return Container::getInstance()->make(ScoutBuilder::class, [ - 'query' => '', - 'model' => new class() extends Model { - // empty - }, - ]); + return TestObjectSearchable::search(); }, ], ]); diff --git a/packages/graphql/src/Testing/Package/OperatorTests.php b/packages/graphql/src/Testing/Package/OperatorTests.php index 4e916b106..8042a9a28 100644 --- a/packages/graphql/src/Testing/Package/OperatorTests.php +++ b/packages/graphql/src/Testing/Package/OperatorTests.php @@ -4,7 +4,6 @@ use Closure; use Exception; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Query\Builder as QueryBuilder; use Laravel\Scout\Builder as ScoutBuilder; @@ -72,10 +71,10 @@ static function (MockInterface $mock) use ($resolver): void { ); } - $operator = Container::getInstance()->make($this->getOperator()); + $operator = $this->app()->make($this->getOperator()); $argument = $argumentFactory($this); $context = $contextFactory ? $contextFactory($this) : new Context(); - $handler = Container::getInstance()->make($directive); + $handler = $this->app()->make($directive); $builder = $builderFactory($this); $actual = $operator->call($handler, $builder, $field, $argument, $context); diff --git a/packages/graphql/src/Testing/Package/Provider.php b/packages/graphql/src/Testing/Package/Provider.php index b5b7e449c..e6046b137 100644 --- a/packages/graphql/src/Testing/Package/Provider.php +++ b/packages/graphql/src/Testing/Package/Provider.php @@ -4,7 +4,9 @@ use Illuminate\Contracts\Config\Repository; use Illuminate\Support\ServiceProvider; +use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Data\Models\TestObject; use Override; +use ReflectionClass; /** * @internal @@ -19,6 +21,9 @@ public function register(): void { static function (Repository $config): void { $config->set('lighthouse.schema_path', __DIR__.'/schema.graphql'); $config->set('lighthouse.guards', null); + $config->set('lighthouse.namespaces.models', [ + (new ReflectionClass(TestObject::class))->getNamespaceName(), + ]); }, ); } diff --git a/packages/graphql/src/Testing/Package/TestCase.php b/packages/graphql/src/Testing/Package/TestCase.php index de0dd118f..78e2ff9b5 100644 --- a/packages/graphql/src/Testing/Package/TestCase.php +++ b/packages/graphql/src/Testing/Package/TestCase.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\GraphQL\Testing\Package; use GraphQL\Type\Schema; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Model as EloquentModel; use Illuminate\Database\Query\Builder as QueryBuilder; @@ -11,7 +10,6 @@ use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\GraphQL\Provider; use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions; -use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Data\Models\TestObject; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Directives\ExposeBuilderDirective; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Provider as TestProvider; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\SchemaPrinter\LighthouseDirectiveFilter; @@ -27,7 +25,6 @@ use Nuwave\Lighthouse\Testing\TestingServiceProvider as LighthouseTestingServiceProvider; use Nuwave\Lighthouse\Validation\ValidationServiceProvider as LighthouseValidationServiceProvider; use Override; -use ReflectionClass; use SplFileInfo; use function array_merge; @@ -50,6 +47,7 @@ protected function getPackageProviders(mixed $app): array { Provider::class, CoreProvider::class, TestProvider::class, + CoreProvider::class, SerializerProvider::class, LighthouseServiceProvider::class, LighthouseTestingServiceProvider::class, @@ -57,23 +55,9 @@ protected function getPackageProviders(mixed $app): array { ]); } - /** - * @inheritDoc - */ - #[Override] - protected function getEnvironmentSetUp($app): void { - parent::getEnvironmentSetUp($app); - - $this->setConfig([ - 'lighthouse.namespaces.models' => [ - (new ReflectionClass(TestObject::class))->getNamespaceName(), - ], - ]); - } - protected function getGraphQLPrinter(Settings $settings = null): Printer { $settings ??= (new TestSettings()) - ->setDirectiveDefinitionFilter(Container::getInstance()->make(LighthouseDirectiveFilter::class)); + ->setDirectiveDefinitionFilter($this->app()->make(LighthouseDirectiveFilter::class)); $printer = $this->getDefaultGraphQLPrinter($settings); return $printer; @@ -89,7 +73,7 @@ protected function getGraphQLArgument( $this->useGraphQLSchema($schema); } - $factory = Container::getInstance()->make(ArgumentFactory::class); + $factory = $this->app()->make(ArgumentFactory::class); $argument = $factory->getArgument($type, $value); return $argument; @@ -113,7 +97,7 @@ protected function getExposeBuilderDirective( $directive::$builder = $builder; $directive::$result = $builder; - Container::getInstance()->make(DirectiveLocator::class) + $this->app()->make(DirectiveLocator::class) ->setResolved(mb_substr($directive::getName(), 1), $directive::class); return $directive; diff --git a/packages/graphql/src/Testing/SchemaBuilderWrapper.php b/packages/graphql/src/Testing/SchemaBuilderWrapper.php index eba33c0bb..d9a4acdfb 100644 --- a/packages/graphql/src/Testing/SchemaBuilderWrapper.php +++ b/packages/graphql/src/Testing/SchemaBuilderWrapper.php @@ -3,8 +3,8 @@ namespace LastDragon_ru\LaraASP\GraphQL\Testing; use GraphQL\Type\Schema; -use Illuminate\Container\Container; -use Illuminate\Contracts\Events\Dispatcher as EventsDispatcher; +use Illuminate\Contracts\Container\Container; +use Illuminate\Contracts\Events\Dispatcher; use Nuwave\Lighthouse\Schema\AST\ASTBuilder; use Nuwave\Lighthouse\Schema\AST\ASTCache; use Nuwave\Lighthouse\Schema\DirectiveLocator; @@ -42,10 +42,8 @@ public function schema(): Schema { return $this->getSchemaBuilder()->schema(); } - public function setSchema(?SchemaSourceProvider $provider): void { + public function setSchema(Container $container, ?SchemaSourceProvider $provider): void { // Origins - $container = Container::getInstance(); - if (!$this->singletons) { $this->singletons = [ ASTCache::class => $container->make(ASTCache::class), @@ -58,7 +56,7 @@ public function setSchema(?SchemaSourceProvider $provider): void { if ($provider) { $types = $container->make(TypeRegistry::class); - $dispatcher = $container->make(EventsDispatcher::class); + $dispatcher = $container->make(Dispatcher::class); $directives = $container->make(DirectiveLocator::class); $astCache = $container->make(SchemaCache::class, ['key' => spl_object_hash($provider)]); $astBuilder = new ASTBuilder($directives, $provider, $dispatcher, $astCache); diff --git a/packages/graphql/src/Utils/AstManipulatorTest.php b/packages/graphql/src/Utils/AstManipulatorTest.php index bcad81287..6c7205455 100644 --- a/packages/graphql/src/Utils/AstManipulatorTest.php +++ b/packages/graphql/src/Utils/AstManipulatorTest.php @@ -24,7 +24,6 @@ use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\GraphQL\Exceptions\ArgumentAlreadyDefined; use LastDragon_ru\LaraASP\GraphQL\Exceptions\NotImplemented; use LastDragon_ru\LaraASP\GraphQL\Testing\Package\TestCase; @@ -87,7 +86,7 @@ interface A { public function testGetInterfaces(): void { // Object - $types = Container::getInstance()->make(TypeRegistry::class); + $types = $this->app()->make(TypeRegistry::class); $manipulator = $this->getManipulator( <<<'GRAPHQL' interface InterfaceA { @@ -198,7 +197,7 @@ static function (): InterfaceType { public function testGetDirectives(): void { // Types - $types = Container::getInstance()->make(TypeRegistry::class); + $types = $this->app()->make(TypeRegistry::class); $types->register( new CustomScalarType([ @@ -207,7 +206,7 @@ public function testGetDirectives(): void { ); // Directives - $locator = Container::getInstance()->make(DirectiveLocator::class); + $locator = $this->app()->make(DirectiveLocator::class); $locator->setResolved('aDirective', AstManipulatorTest_ADirective::class); $locator->setResolved('bDirective', AstManipulatorTest_BDirective::class); @@ -279,7 +278,7 @@ public function testGetDirectives(): void { ); // Field - $schema = Container::getInstance()->make(SchemaBuilder::class)->schema(); + $schema = $this->app()->make(SchemaBuilder::class)->schema(); $query = $schema->getQueryType(); $field = $query ? $manipulator->getField($query, 'test') : null; $expected = [ @@ -374,7 +373,7 @@ public function testAddArgument( public function testFindArgument(): void { // Directives - $locator = Container::getInstance()->make(DirectiveLocator::class); + $locator = $this->app()->make(DirectiveLocator::class); $locator->setResolved('aDirective', AstManipulatorTest_ADirective::class); @@ -444,7 +443,7 @@ public function testAddDirective( self::expectExceptionObject($expected); } - $locator = Container::getInstance()->make(DirectiveLocator::class); + $locator = $this->app()->make(DirectiveLocator::class); $locator->setResolved( DirectiveLocator::directiveName($directive), @@ -585,8 +584,8 @@ static function (mixed $field) use ($manipulator): bool { #[DataProvider('dataProviderGetOriginType')] public function testGetOriginType(string $expected, string $graphql): void { $ast = Mockery::mock(DocumentAST::class); - $types = Container::getInstance()->make(TypeRegistry::class); - $directives = Container::getInstance()->make(DirectiveLocator::class); + $types = $this->app()->make(TypeRegistry::class); + $directives = $this->app()->make(DirectiveLocator::class); $manipulator = new AstManipulator($directives, $ast, $types); $schema = $this->useGraphQLSchema($graphql)->getGraphQLSchema(); @@ -608,8 +607,8 @@ public function testGetOriginType(string $expected, string $graphql): void { protected function getManipulator(string $schema = null): AstManipulator { $document = $schema ? DocumentAST::fromSource($schema) - : Container::getInstance()->make(ASTBuilder::class)->documentAST(); - $manipulator = Container::getInstance()->make(AstManipulator::class, [ + : $this->app()->make(ASTBuilder::class)->documentAST(); + $manipulator = $this->app()->make(AstManipulator::class, [ 'document' => $document, ]); diff --git a/packages/migrator/UPGRADE.md b/packages/migrator/UPGRADE.md index e0923624f..52e5ca98a 100644 --- a/packages/migrator/UPGRADE.md +++ b/packages/migrator/UPGRADE.md @@ -27,6 +27,16 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases) [//]: # (end: c70a9a43c0a80bd2e7fa6010a9b2c0fbcab4cb4d536d7a498216d9df7431f7e2) +# Upgrade from v6 + +[include:file]: ../../docs/Shared/Upgrade/FromV6.md +[//]: # (start: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) +[//]: # (warning: Generated automatically. Do not edit.) + +* [ ] Direct usages of `Container::getInstances()` were replaced by explicit constructor parameters. You may need to update your code accordingly (#151). + +[//]: # (end: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) + # Upgrade from v5 [include:file]: ../../docs/Shared/Upgrade/FromV5.md diff --git a/packages/migrator/composer.json b/packages/migrator/composer.json index 06f51c277..367994b1a 100644 --- a/packages/migrator/composer.json +++ b/packages/migrator/composer.json @@ -22,6 +22,7 @@ "require": { "php": "^8.1|^8.2|^8.3", "ext-json": "*", + "ext-mbstring": "*", "illuminate/container": "^10.34.0|^11.0.0", "illuminate/contracts": "^10.34.0|^11.0.0", "illuminate/database": "^10.34.0|^11.0.0", diff --git a/packages/migrator/src/Concerns/RawSqlHelper.php b/packages/migrator/src/Concerns/RawSqlHelper.php index 002352738..5c796b5b7 100644 --- a/packages/migrator/src/Concerns/RawSqlHelper.php +++ b/packages/migrator/src/Concerns/RawSqlHelper.php @@ -2,17 +2,15 @@ namespace LastDragon_ru\LaraASP\Migrator\Concerns; -use Illuminate\Container\Container; use Illuminate\Database\Connection; -use Illuminate\Database\DatabaseManager; -use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\SchemaState; -use Illuminate\Filesystem\Filesystem; use ReflectionClass; use RuntimeException; use function basename; use function dirname; +use function file_get_contents; +use function is_file; use function method_exists; /** @@ -23,14 +21,13 @@ protected function runRaw(string $type = null): void { $connection = $this->getConnectionInstance(); $state = $this->getSchemaState($connection); $path = $this->getRawPath($type); - $fs = Container::getInstance()->make(Filesystem::class); - if ($fs->isFile($path)) { + if (is_file($path)) { if (!$connection->pretending()) { $state->load($path); } - $connection->logQuery($fs->get($path), [], 0); + $connection->logQuery((string) file_get_contents($path), [], 0); } } @@ -44,14 +41,7 @@ protected function getRawPath(string $type = null): string { : "{$dir}/{$file}.sql"; } - private function getConnectionInstance(): Connection { - $connection = $this instanceof Migration - ? $this->getConnection() - : null; - $connection = Container::getInstance()->make(DatabaseManager::class)->connection($connection); - - return $connection; - } + abstract private function getConnectionInstance(): Connection; private function getSchemaState(Connection $connection): SchemaState { if (!method_exists($connection, 'getSchemaState')) { diff --git a/packages/migrator/src/Extenders/SmartMigratorTest.php b/packages/migrator/src/Extenders/SmartMigratorTest.php index 92f1f4802..30e058b5b 100644 --- a/packages/migrator/src/Extenders/SmartMigratorTest.php +++ b/packages/migrator/src/Extenders/SmartMigratorTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Migrator\Extenders; -use Illuminate\Container\Container; use Illuminate\Database\ConnectionResolverInterface; use Illuminate\Database\Migrations\MigrationRepositoryInterface; use Illuminate\Filesystem\Filesystem; @@ -14,7 +13,6 @@ use function array_map; use function explode; -use function get_class; use function implode; use function json_decode; use function json_encode; @@ -29,7 +27,7 @@ #[CoversClass(Provider::class)] final class SmartMigratorTest extends TestCase { public function testProvider(): void { - self::assertEquals(SmartMigrator::class, get_class(Container::getInstance()->make('migrator'))); + self::assertInstanceOf(SmartMigrator::class, $this->app()->make('migrator')); } public function testMigrate(): void { @@ -62,8 +60,8 @@ public function testMigrate(): void { // Vars $migrator = new SmartMigrator( $repository, - Container::getInstance()->make(ConnectionResolverInterface::class), - Container::getInstance()->make(Filesystem::class), + $this->app()->make(ConnectionResolverInterface::class), + $this->app()->make(Filesystem::class), ); $output = new BufferedOutput(); diff --git a/packages/migrator/src/Migrations/RawMigration.php b/packages/migrator/src/Migrations/RawMigration.php index 45671f1ec..271e0acf1 100644 --- a/packages/migrator/src/Migrations/RawMigration.php +++ b/packages/migrator/src/Migrations/RawMigration.php @@ -2,8 +2,12 @@ namespace LastDragon_ru\LaraASP\Migrator\Migrations; +use Illuminate\Container\Container; +use Illuminate\Database\Connection; +use Illuminate\Database\DatabaseManager; use Illuminate\Database\Migrations\Migration; use LastDragon_ru\LaraASP\Migrator\Concerns\RawSqlHelper; +use Override; abstract class RawMigration extends Migration { use RawSqlHelper; @@ -35,4 +39,12 @@ protected function runRawDown(): void { $this->runRaw('down'); } // + + // + // ========================================================================= + #[Override] + private function getConnectionInstance(): Connection { + return Container::getInstance()->make(DatabaseManager::class)->connection($this->getConnection()); + } + // } diff --git a/packages/migrator/src/Provider.php b/packages/migrator/src/Provider.php index a849eb01a..ddb02146e 100644 --- a/packages/migrator/src/Provider.php +++ b/packages/migrator/src/Provider.php @@ -11,6 +11,7 @@ use LastDragon_ru\LaraASP\Migrator\Commands\RawSeeder; use LastDragon_ru\LaraASP\Migrator\Extenders\RawMigrationCreator; use LastDragon_ru\LaraASP\Migrator\Extenders\SmartMigrator; +use LastDragon_ru\LaraASP\Migrator\Seeders\SeederService; use Override; class Provider extends ServiceProvider { @@ -23,6 +24,7 @@ class Provider extends ServiceProvider { public function register() { parent::register(); + $this->registerSeeder(); $this->registerMigrator(); $this->registerMigrationCreator(); } @@ -37,6 +39,10 @@ public function boot(): void { // // ========================================================================= + protected function registerSeeder(): void { + $this->app->scopedIf(SeederService::class); + } + protected function registerMigrator(): void { $this->app->extend('migrator', static function (Migrator $migrator): Migrator { return SmartMigrator::create($migrator); diff --git a/packages/migrator/src/Seeders/RawSeeder.php b/packages/migrator/src/Seeders/RawSeeder.php index 6c88627fc..2788b1955 100644 --- a/packages/migrator/src/Seeders/RawSeeder.php +++ b/packages/migrator/src/Seeders/RawSeeder.php @@ -2,6 +2,7 @@ namespace LastDragon_ru\LaraASP\Migrator\Seeders; +use Illuminate\Database\Connection; use LastDragon_ru\LaraASP\Migrator\Concerns\RawSqlHelper; use Override; @@ -18,4 +19,12 @@ public function seed(): void { $this->runRaw(); } // + + // + // ========================================================================= + #[Override] + private function getConnectionInstance(): Connection { + return $this->service->getConnection(); + } + // } diff --git a/packages/migrator/src/Seeders/SeederService.php b/packages/migrator/src/Seeders/SeederService.php index 264ffdd36..bcf61e888 100644 --- a/packages/migrator/src/Seeders/SeederService.php +++ b/packages/migrator/src/Seeders/SeederService.php @@ -2,18 +2,22 @@ namespace LastDragon_ru\LaraASP\Migrator\Seeders; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; use Illuminate\Database\Connection; use Illuminate\Database\DatabaseManager; use Illuminate\Database\Eloquent\Model; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; +use LastDragon_ru\LaraASP\Core\Utils\Cast; use function array_column; -use function in_array; +use function is_array; use function is_string; +use function mb_strtolower; class SeederService { - public function __construct() { + public function __construct( + protected readonly ConfigResolver $config, + protected readonly DatabaseManager $manager, + ) { // empty } @@ -22,12 +26,13 @@ public function __construct() { public function isSeeded(): bool { $seeded = false; $tables = array_column($this->getConnection()->getSchemaBuilder()->getTables(), 'name'); - $skipped = [ - Container::getInstance()->make(Repository::class)->get('database.migrations'), - ]; + $default = 'migrations'; + $skipped = $this->config->getInstance()->get('database.migrations', $default); + $skipped = is_array($skipped) ? ($skipped['table'] ?: $default) : $skipped; + $skipped = mb_strtolower(Cast::toString($skipped)); foreach ($tables as $table) { - if (in_array($table, $skipped, true)) { + if ($skipped === mb_strtolower($table)) { continue; } @@ -58,8 +63,8 @@ public function isTableSeeded(string $table): bool { // // ========================================================================= - protected function getConnection(): Connection { - return Container::getInstance()->make(DatabaseManager::class)->connection(); + public function getConnection(): Connection { + return $this->manager->connection(); } // } diff --git a/packages/migrator/src/Seeders/SmartSeeder.php b/packages/migrator/src/Seeders/SmartSeeder.php index 08774f739..dd65f0b6c 100644 --- a/packages/migrator/src/Seeders/SmartSeeder.php +++ b/packages/migrator/src/Seeders/SmartSeeder.php @@ -13,10 +13,10 @@ * database already seeded. */ abstract class SmartSeeder extends Seeder { - protected SeederService $service; - - public function __construct(SeederService $service) { - $this->service = $service; + public function __construct( + protected readonly SeederService $service, + ) { + // empty } // diff --git a/packages/migrator/src/Testing/Package/TestCase.php b/packages/migrator/src/Testing/Package/TestCase.php index 82196f904..e2d19ede0 100644 --- a/packages/migrator/src/Testing/Package/TestCase.php +++ b/packages/migrator/src/Testing/Package/TestCase.php @@ -2,6 +2,7 @@ namespace LastDragon_ru\LaraASP\Migrator\Testing\Package; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\Migrator\Provider; use LastDragon_ru\LaraASP\Testing\Package\TestCase as PackageTestCase; use Override; @@ -18,6 +19,7 @@ abstract class TestCase extends PackageTestCase { #[Override] protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ + CoreProvider::class, Provider::class, ]); } diff --git a/packages/serializer/README.md b/packages/serializer/README.md index 7cc2dfdbe..0961234d3 100644 --- a/packages/serializer/README.md +++ b/packages/serializer/README.md @@ -48,7 +48,6 @@ composer require lastdragon-ru/lara-asp-serializer namespace LastDragon_ru\LaraASP\Serializer\Docs\Examples\Usage; use DateTimeInterface; -use Illuminate\Container\Container; use Illuminate\Support\Facades\Date; use LastDragon_ru\LaraASP\Dev\App\Example; use LastDragon_ru\LaraASP\Serializer\Contracts\Serializable; @@ -65,7 +64,7 @@ class User implements Serializable { } $user = new User(1, 'User', Date::parse('2023-08-27T08:30:44.473+00:00')); -$serializer = Container::getInstance()->make(Serializer::class); +$serializer = app()->make(Serializer::class); $serialized = $serializer->serialize($user); $deserialized = $serializer->deserialize(User::class, $serialized); diff --git a/packages/serializer/UPGRADE.md b/packages/serializer/UPGRADE.md index e0923624f..52e5ca98a 100644 --- a/packages/serializer/UPGRADE.md +++ b/packages/serializer/UPGRADE.md @@ -27,6 +27,16 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases) [//]: # (end: c70a9a43c0a80bd2e7fa6010a9b2c0fbcab4cb4d536d7a498216d9df7431f7e2) +# Upgrade from v6 + +[include:file]: ../../docs/Shared/Upgrade/FromV6.md +[//]: # (start: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) +[//]: # (warning: Generated automatically. Do not edit.) + +* [ ] Direct usages of `Container::getInstances()` were replaced by explicit constructor parameters. You may need to update your code accordingly (#151). + +[//]: # (end: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) + # Upgrade from v5 [include:file]: ../../docs/Shared/Upgrade/FromV5.md diff --git a/packages/serializer/docs/Examples/Usage.php b/packages/serializer/docs/Examples/Usage.php index 9c5e58a8d..a780ee853 100644 --- a/packages/serializer/docs/Examples/Usage.php +++ b/packages/serializer/docs/Examples/Usage.php @@ -6,7 +6,6 @@ namespace LastDragon_ru\LaraASP\Serializer\Docs\Examples\Usage; use DateTimeInterface; -use Illuminate\Container\Container; use Illuminate\Support\Facades\Date; use LastDragon_ru\LaraASP\Dev\App\Example; use LastDragon_ru\LaraASP\Serializer\Contracts\Serializable; @@ -23,7 +22,7 @@ public function __construct( } $user = new User(1, 'User', Date::parse('2023-08-27T08:30:44.473+00:00')); -$serializer = Container::getInstance()->make(Serializer::class); +$serializer = app()->make(Serializer::class); $serialized = $serializer->serialize($user); $deserialized = $serializer->deserialize(User::class, $serialized); diff --git a/packages/serializer/src/Factory.php b/packages/serializer/src/Factory.php index 283fdbe1c..35532381c 100644 --- a/packages/serializer/src/Factory.php +++ b/packages/serializer/src/Factory.php @@ -2,8 +2,8 @@ namespace LastDragon_ru\LaraASP\Serializer; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use LastDragon_ru\LaraASP\Serializer\Contracts\Serializer as SerializerContract; use LastDragon_ru\LaraASP\Serializer\Normalizers\DateTimeNormalizer; use LastDragon_ru\LaraASP\Serializer\Normalizers\DateTimeNormalizerContextBuilder; @@ -36,6 +36,13 @@ use const JSON_UNESCAPED_UNICODE; class Factory { + public function __construct( + protected readonly ContainerResolver $container, + protected readonly ConfigResolver $config, + ) { + // empty + } + /** * @param array, array> $encoders * @param array, array|null> $normalizers @@ -71,7 +78,7 @@ protected function make( array $context, string $format, ): SerializerContract { - $container = Container::getInstance(); + $container = $this->container->getInstance(); $encoderInstances = []; $normalizerInstances = []; @@ -93,7 +100,7 @@ protected function make( protected function getConfigFormat(?string $config): ?string { /** @var ?string $format */ $format = $config - ? Container::getInstance()->make(Repository::class)->get("{$config}.default") + ? $this->config->getInstance()->get("{$config}.default") : null; return $format; @@ -105,7 +112,7 @@ protected function getConfigFormat(?string $config): ?string { protected function getConfigContext(?string $config): array { /** @var array $context */ $context = $config - ? (array) Container::getInstance()->make(Repository::class)->get("{$config}.context") + ? (array) $this->config->getInstance()->get("{$config}.context") : []; return $context; @@ -140,7 +147,7 @@ protected function getEncoders(array $encoders, array &$context, ?string $config protected function getConfigEncoders(?string $config): array { /** @var array, array> $encoders */ $encoders = $config - ? (array) Container::getInstance()->make(Repository::class)->get("{$config}.encoders") + ? (array) $this->config->getInstance()->get("{$config}.encoders") : []; return $encoders; @@ -202,7 +209,7 @@ protected function getNormalizers(array $normalizers, array &$context, ?string $ protected function getConfigNormalizers(?string $config): array { /** @var array, array|null> $normalizers */ $normalizers = $config - ? (array) Container::getInstance()->make(Repository::class)->get("{$config}.normalizers") + ? (array) $this->config->getInstance()->get("{$config}.normalizers") : $config; return $normalizers; diff --git a/packages/serializer/src/FactoryTest.php b/packages/serializer/src/FactoryTest.php index df67d5916..c51947264 100644 --- a/packages/serializer/src/FactoryTest.php +++ b/packages/serializer/src/FactoryTest.php @@ -2,6 +2,8 @@ namespace LastDragon_ru\LaraASP\Serializer; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; +use LastDragon_ru\LaraASP\Core\Application\ContainerResolver; use LastDragon_ru\LaraASP\Serializer\Contracts\Serializer; use LastDragon_ru\LaraASP\Serializer\Normalizers\DateTimeNormalizer; use LastDragon_ru\LaraASP\Serializer\Normalizers\SerializableNormalizer; @@ -51,7 +53,9 @@ public function testCreate(): void { ], ]); - $factory = Mockery::mock(Factory::class) + $config = $this->app()->make(ConfigResolver::class); + $container = $this->app()->make(ContainerResolver::class); + $factory = Mockery::mock(Factory::class, [$container, $config]) ->shouldAllowMockingProtectedMethods() ->makePartial(); diff --git a/packages/serializer/src/ProviderTest.php b/packages/serializer/src/ProviderTest.php index 4695f22e5..fa94c24d2 100644 --- a/packages/serializer/src/ProviderTest.php +++ b/packages/serializer/src/ProviderTest.php @@ -4,7 +4,6 @@ use DateTimeInterface; use Exception; -use Illuminate\Container\Container; use Illuminate\Support\Carbon; use JsonSerializable; use LastDragon_ru\LaraASP\Serializer\Contracts\Serializable; @@ -38,15 +37,15 @@ final class ProviderTest extends TestCase { // ========================================================================= public function testRegister(): void { self::assertSame( - Container::getInstance()->make(SerializerContract::class), - Container::getInstance()->make(SerializerContract::class), + $this->app()->make(SerializerContract::class), + $this->app()->make(SerializerContract::class), ); } #[DataProvider('dataProviderSerialization')] public function testSerialization(Exception|string $expected, Serializable $serializable): void { try { - $serializer = Container::getInstance()->make(SerializerContract::class); + $serializer = $this->app()->make(SerializerContract::class); $serialized = $serializer->serialize($serializable); if (is_string($expected)) { @@ -72,7 +71,7 @@ public function testSerialization(Exception|string $expected, Serializable $seri #[DataProvider('dataProviderDeserialization')] public function testDeserialization(Exception|Serializable $expected, string $class, string $serialized): void { try { - $serializer = Container::getInstance()->make(SerializerContract::class); + $serializer = $this->app()->make(SerializerContract::class); $deserialized = $serializer->deserialize($class, $serialized); if ($expected instanceof Serializable) { diff --git a/packages/serializer/src/Testing/Package/TestCase.php b/packages/serializer/src/Testing/Package/TestCase.php index b542d36ea..219173c32 100644 --- a/packages/serializer/src/Testing/Package/TestCase.php +++ b/packages/serializer/src/Testing/Package/TestCase.php @@ -2,6 +2,7 @@ namespace LastDragon_ru\LaraASP\Serializer\Testing\Package; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\Serializer\Provider; use LastDragon_ru\LaraASP\Testing\Package\TestCase as PackageTestCase; use Override; @@ -18,6 +19,7 @@ abstract class TestCase extends PackageTestCase { #[Override] protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ + CoreProvider::class, Provider::class, ]); } diff --git a/packages/spa/UPGRADE.md b/packages/spa/UPGRADE.md index e0923624f..52e5ca98a 100644 --- a/packages/spa/UPGRADE.md +++ b/packages/spa/UPGRADE.md @@ -27,6 +27,16 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases) [//]: # (end: c70a9a43c0a80bd2e7fa6010a9b2c0fbcab4cb4d536d7a498216d9df7431f7e2) +# Upgrade from v6 + +[include:file]: ../../docs/Shared/Upgrade/FromV6.md +[//]: # (start: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) +[//]: # (warning: Generated automatically. Do not edit.) + +* [ ] Direct usages of `Container::getInstances()` were replaced by explicit constructor parameters. You may need to update your code accordingly (#151). + +[//]: # (end: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) + # Upgrade from v5 [include:file]: ../../docs/Shared/Upgrade/FromV5.md diff --git a/packages/spa/composer.json b/packages/spa/composer.json index 445237efe..c5f8b8513 100644 --- a/packages/spa/composer.json +++ b/packages/spa/composer.json @@ -21,7 +21,6 @@ "php": "^8.1|^8.2|^8.3", "ext-mbstring": "*", "illuminate/collections": "^10.34.0|^11.0.0", - "illuminate/container": "^10.34.0|^11.0.0", "illuminate/contracts": "^10.34.0|^11.0.0", "illuminate/database": "^10.34.0|^11.0.0", "illuminate/http": "^10.34.0|^11.0.0", diff --git a/packages/spa/defaults/routes.php b/packages/spa/defaults/routes.php index 2800991bb..0e1692e29 100644 --- a/packages/spa/defaults/routes.php +++ b/packages/spa/defaults/routes.php @@ -1,29 +1,9 @@ make(Repository::class); -$package = Package::Name; -$prefix = $repository->get("{$package}.routes.prefix"); -$enabled = $repository->get("{$package}.routes.enabled"); -$middleware = $repository->get("{$package}.routes.middleware"); - -if (!$enabled || !Container::getInstance()->bound(Registrar::class)) { - return; -} - -// SPA Routes -Container::getInstance()->make(Registrar::class)->group( - [ - 'middleware' => $middleware, - 'prefix' => $prefix, - ], - static function (Registrar $router): void { - $router->get('settings', [SpaController::class, 'settings']); - $router->get('user', [SpaController::class, 'user']); - }, -); +return static function (Registrar $router): void { + $router->get('settings', [SpaController::class, 'settings']); + $router->get('user', [SpaController::class, 'user']); +}; diff --git a/packages/spa/src/Http/Controllers/SpaController.php b/packages/spa/src/Http/Controllers/SpaController.php index 90d05048b..ab6cba77f 100644 --- a/packages/spa/src/Http/Controllers/SpaController.php +++ b/packages/spa/src/Http/Controllers/SpaController.php @@ -2,14 +2,19 @@ namespace LastDragon_ru\LaraASP\Spa\Http\Controllers; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; use Illuminate\Http\UploadedFile; use Illuminate\Routing\Controller; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; use LastDragon_ru\LaraASP\Core\Utils\ConfigMerger; use LastDragon_ru\LaraASP\Spa\Package; class SpaController extends Controller { + public function __construct( + protected readonly ConfigResolver $config, + ) { + // empty + } + // // ========================================================================= /** @@ -28,7 +33,7 @@ public function settings(): array { * @return array */ protected function getSettings(): array { - $repository = Container::getInstance()->make(Repository::class); + $repository = $this->config->getInstance(); $package = Package::Name; $default = [ ConfigMerger::Strict => false, diff --git a/packages/spa/src/Http/Controllers/SpaControllerTest.php b/packages/spa/src/Http/Controllers/SpaControllerTest.php index 2dcf00947..25b7da6dd 100644 --- a/packages/spa/src/Http/Controllers/SpaControllerTest.php +++ b/packages/spa/src/Http/Controllers/SpaControllerTest.php @@ -2,8 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Http\Controllers; -use Illuminate\Container\Container; -use Illuminate\Contracts\Foundation\Application; use LastDragon_ru\LaraASP\Spa\Package; use LastDragon_ru\LaraASP\Spa\Provider; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; @@ -17,7 +15,6 @@ use LastDragon_ru\LaraASP\Testing\Providers\ExpectedFinal; use LastDragon_ru\LaraASP\Testing\Providers\UnknownValue; use LastDragon_ru\LaraASP\Testing\Responses\JsonResponse; -use Override; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; @@ -26,21 +23,6 @@ */ #[CoversClass(SpaController::class)] final class SpaControllerTest extends TestCase { - // - // ========================================================================= - /** - * @inheritDoc - */ - #[Override] - protected function getEnvironmentSetUp($app): void { - parent::getEnvironmentSetUp($app); - - $this->setConfig([ - Package::Name.'.routes.enabled' => false, - ]); - } - // - // // ========================================================================= /** @@ -61,7 +43,11 @@ public function testSettings( Package::Name.'.spa' => $settings, ]); - $this->loadRoutes(); + $provider = new class($this->app()) extends Provider { + // empty + }; + $provider->boot(); + $provider->callBootedCallbacks(); $this->get("{$prefix}/settings", $headers)->assertThat($expected); } @@ -141,16 +127,4 @@ protected static function getAcceptDataProvider(): DataProviderContract { ]); } // - - // - // ========================================================================= - protected function loadRoutes(): void { - (new class(Container::getInstance()->make(Application::class)) extends Provider { - #[Override] - public function bootRoutes(): void { - parent::bootRoutes(); - } - })->bootRoutes(); - } - // } diff --git a/packages/spa/src/Http/RequestTest.php b/packages/spa/src/Http/RequestTest.php index 64ce1bee6..acfe7f8a8 100644 --- a/packages/spa/src/Http/RequestTest.php +++ b/packages/spa/src/Http/RequestTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Http; -use Illuminate\Container\Container; use Illuminate\Contracts\Translation\Translator; use Illuminate\Contracts\Validation\Rule; use Illuminate\Routing\Redirector; @@ -20,8 +19,8 @@ #[CoversClass(Request::class)] final class RequestTest extends TestCase { public function testValidated(): void { - $router = Container::getInstance()->make(Router::class); - $translator = Container::getInstance()->make(Translator::class); + $router = $this->app()->make(Router::class); + $translator = $this->app()->make(Translator::class); $resolverRuleA = new ResolverRule( $translator, new class($router) extends Resolver { @@ -109,8 +108,8 @@ public function rules(): array { ], ]); - $request->setContainer(Container::getInstance()); - $request->setRedirector(Container::getInstance()->make(Redirector::class)); + $request->setContainer($this->app()); + $request->setRedirector($this->app()->make(Redirector::class)); self::assertEquals([ 'rule' => true, diff --git a/packages/spa/src/Http/Resources/Scalar/BoolResourceTest.php b/packages/spa/src/Http/Resources/Scalar/BoolResourceTest.php index ad2df3f06..b00b7c043 100644 --- a/packages/spa/src/Http/Resources/Scalar/BoolResourceTest.php +++ b/packages/spa/src/Http/Resources/Scalar/BoolResourceTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Http\Resources\Scalar; -use Illuminate\Container\Container; use Illuminate\Contracts\Routing\Registrar; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use LastDragon_ru\LaraASP\Testing\Responses\Laravel\Json\OkResponse; @@ -14,7 +13,7 @@ #[CoversClass(BoolResource::class)] final class BoolResourceTest extends TestCase { public function testToResponse(): void { - Container::getInstance()->make(Registrar::class) + $this->app()->make(Registrar::class) ->get(__METHOD__, static function (): mixed { return new BoolResource(true); }); diff --git a/packages/spa/src/Http/Resources/Scalar/FalseResourceTest.php b/packages/spa/src/Http/Resources/Scalar/FalseResourceTest.php index 8b8b1c274..bdca1d6a0 100644 --- a/packages/spa/src/Http/Resources/Scalar/FalseResourceTest.php +++ b/packages/spa/src/Http/Resources/Scalar/FalseResourceTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Http\Resources\Scalar; -use Illuminate\Container\Container; use Illuminate\Contracts\Routing\Registrar; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use LastDragon_ru\LaraASP\Testing\Responses\Laravel\Json\OkResponse; @@ -14,7 +13,7 @@ #[CoversClass(FalseResource::class)] final class FalseResourceTest extends TestCase { public function testToResponse(): void { - Container::getInstance()->make(Registrar::class) + $this->app()->make(Registrar::class) ->get(__METHOD__, static function (): mixed { return new FalseResource(); }); diff --git a/packages/spa/src/Http/Resources/Scalar/IntResourceTest.php b/packages/spa/src/Http/Resources/Scalar/IntResourceTest.php index 0eb059f1a..81b44ec15 100644 --- a/packages/spa/src/Http/Resources/Scalar/IntResourceTest.php +++ b/packages/spa/src/Http/Resources/Scalar/IntResourceTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Http\Resources\Scalar; -use Illuminate\Container\Container; use Illuminate\Contracts\Routing\Registrar; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use LastDragon_ru\LaraASP\Testing\Responses\Laravel\Json\OkResponse; @@ -14,7 +13,7 @@ #[CoversClass(IntResource::class)] final class IntResourceTest extends TestCase { public function testToResponse(): void { - Container::getInstance()->make(Registrar::class) + $this->app()->make(Registrar::class) ->get(__METHOD__, static function (): mixed { return new IntResource(123); }); diff --git a/packages/spa/src/Http/Resources/Scalar/NullResourceTest.php b/packages/spa/src/Http/Resources/Scalar/NullResourceTest.php index 63e2934a1..fe96d67f9 100644 --- a/packages/spa/src/Http/Resources/Scalar/NullResourceTest.php +++ b/packages/spa/src/Http/Resources/Scalar/NullResourceTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Http\Resources\Scalar; -use Illuminate\Container\Container; use Illuminate\Contracts\Routing\Registrar; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use LastDragon_ru\LaraASP\Testing\Responses\Laravel\Json\OkResponse; @@ -14,7 +13,7 @@ #[CoversClass(NullResource::class)] final class NullResourceTest extends TestCase { public function testToResponse(): void { - Container::getInstance()->make(Registrar::class) + $this->app()->make(Registrar::class) ->get(__METHOD__, static function (): mixed { return new NullResource(); }); diff --git a/packages/spa/src/Http/Resources/Scalar/NumberResourceTest.php b/packages/spa/src/Http/Resources/Scalar/NumberResourceTest.php index b550dc18f..342734824 100644 --- a/packages/spa/src/Http/Resources/Scalar/NumberResourceTest.php +++ b/packages/spa/src/Http/Resources/Scalar/NumberResourceTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Http\Resources\Scalar; -use Illuminate\Container\Container; use Illuminate\Contracts\Routing\Registrar; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use LastDragon_ru\LaraASP\Testing\Responses\Laravel\Json\OkResponse; @@ -14,7 +13,7 @@ #[CoversClass(NumberResource::class)] final class NumberResourceTest extends TestCase { public function testToResponse(): void { - Container::getInstance()->make(Registrar::class) + $this->app()->make(Registrar::class) ->get(__METHOD__, static function (): mixed { return new NumberResource(123); }); diff --git a/packages/spa/src/Http/Resources/Scalar/StringResourceTest.php b/packages/spa/src/Http/Resources/Scalar/StringResourceTest.php index c809e298e..2cea5a6c2 100644 --- a/packages/spa/src/Http/Resources/Scalar/StringResourceTest.php +++ b/packages/spa/src/Http/Resources/Scalar/StringResourceTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Http\Resources\Scalar; -use Illuminate\Container\Container; use Illuminate\Contracts\Routing\Registrar; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use LastDragon_ru\LaraASP\Testing\Responses\Laravel\Json\OkResponse; @@ -14,7 +13,7 @@ #[CoversClass(StringResource::class)] final class StringResourceTest extends TestCase { public function testToResponse(): void { - Container::getInstance()->make(Registrar::class) + $this->app()->make(Registrar::class) ->get(__METHOD__, static function (): mixed { return new StringResource('123'); }); diff --git a/packages/spa/src/Http/Resources/Scalar/TrueResourceTest.php b/packages/spa/src/Http/Resources/Scalar/TrueResourceTest.php index fdc600984..e72f6e24c 100644 --- a/packages/spa/src/Http/Resources/Scalar/TrueResourceTest.php +++ b/packages/spa/src/Http/Resources/Scalar/TrueResourceTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Http\Resources\Scalar; -use Illuminate\Container\Container; use Illuminate\Contracts\Routing\Registrar; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use LastDragon_ru\LaraASP\Testing\Responses\Laravel\Json\OkResponse; @@ -14,7 +13,7 @@ #[CoversClass(TrueResource::class)] final class TrueResourceTest extends TestCase { public function testToResponse(): void { - Container::getInstance()->make(Registrar::class) + $this->app()->make(Registrar::class) ->get(__METHOD__, static function (): mixed { return new TrueResource(); }); diff --git a/packages/spa/src/Http/WithValueProviderTest.php b/packages/spa/src/Http/WithValueProviderTest.php index 904710837..ae6255719 100644 --- a/packages/spa/src/Http/WithValueProviderTest.php +++ b/packages/spa/src/Http/WithValueProviderTest.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\Spa\Http; use Closure; -use Illuminate\Container\Container; use Illuminate\Contracts\Translation\Translator; use Illuminate\Contracts\Validation\Factory; use Illuminate\Contracts\Validation\ValidationRule; @@ -21,8 +20,8 @@ #[CoversClass(WithValueProvider::class)] final class WithValueProviderTest extends TestCase { public function testValidated(): void { - $router = Container::getInstance()->make(Router::class); - $translator = Container::getInstance()->make(Translator::class); + $router = $this->app()->make(Router::class); + $translator = $this->app()->make(Translator::class); $resolverRuleA = new ResolverRule( $translator, new class($router) extends Resolver { @@ -73,13 +72,15 @@ public function validate(string $attribute, mixed $value, Closure $fail): void { ], ]; - $request = new class($rule, $resolverRuleA, $resolverRuleB, $data) { + $factory = $this->app()->make(Factory::class); + $request = new class($factory, $rule, $resolverRuleA, $resolverRuleB, $data) { use WithValueProvider; /** * @param array $data */ public function __construct( + private readonly Factory $factory, private readonly ValidationRule $rule, private readonly ResolverRule $resolverRuleA, private readonly ResolverRule $resolverRuleB, @@ -95,8 +96,7 @@ public function __construct( */ #[Override] protected function getValidatorInstance() { - $factory = Container::getInstance()->make(Factory::class); - $validator = $factory->make($this->data, [ + return $this->factory->make($this->data, [ 'rule' => ['required', $this->rule], 'rule_nullable' => ['nullable', 'int'], 'resolver' => ['required', $this->resolverRuleA], @@ -106,8 +106,6 @@ protected function getValidatorInstance() { 'array.*.rule' => ['required', $this->rule], 'array.*.resolver' => ['required', $this->resolverRuleA], ]); - - return $validator; } }; diff --git a/packages/spa/src/Provider.php b/packages/spa/src/Provider.php index 3f3e77275..5123ef09e 100644 --- a/packages/spa/src/Provider.php +++ b/packages/spa/src/Provider.php @@ -2,10 +2,12 @@ namespace LastDragon_ru\LaraASP\Spa; +use Illuminate\Contracts\Config\Repository; use Illuminate\Support\ServiceProvider; use LastDragon_ru\LaraASP\Core\Provider\WithConfig; use LastDragon_ru\LaraASP\Core\Provider\WithRoutes; use LastDragon_ru\LaraASP\Core\Provider\WithTranslations; +use LastDragon_ru\LaraASP\Core\Utils\Cast; use Override; class Provider extends ServiceProvider { @@ -17,8 +19,20 @@ class Provider extends ServiceProvider { // ========================================================================= public function boot(): void { $this->bootConfig(); - $this->bootRoutes(); $this->bootTranslations(); + $this->bootRoutes(function (): array { + $package = Package::Name; + $config = (array) $this->app->make(Repository::class)->get("{$package}.routes"); + $settings = [ + 'enabled' => Cast::toBool($config['enabled'] ?? false), + 'attributes' => [ + 'prefix' => Cast::toString($config['prefix'] ?? ''), + 'middleware' => Cast::toString($config['middleware'] ?? ''), + ], + ]; + + return $settings; + }); } // diff --git a/packages/spa/src/Routing/ResolverTest.php b/packages/spa/src/Routing/ResolverTest.php index 4c6ee6de1..ed3bf40ef 100644 --- a/packages/spa/src/Routing/ResolverTest.php +++ b/packages/spa/src/Routing/ResolverTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Routing; -use Illuminate\Container\Container; use Illuminate\Http\Request; use Illuminate\Routing\Route; use Illuminate\Routing\Router; @@ -17,7 +16,7 @@ #[CoversClass(Resolver::class)] final class ResolverTest extends TestCase { public function testGet(): void { - $router = Container::getInstance()->make(Router::class); + $router = $this->app()->make(Router::class); $resolver = new class($router) extends Resolver { /** * @inheritDoc @@ -70,7 +69,7 @@ public function testGetCached(): void { public function testGetUnresolvedValue(): void { self::expectException(UnresolvedValueException::class); - $router = Container::getInstance()->make(Router::class); + $router = $this->app()->make(Router::class); $resolver = new class($router) extends Resolver { /** * @inheritDoc diff --git a/packages/spa/src/Routing/UnresolvedValueExceptionTest.php b/packages/spa/src/Routing/UnresolvedValueExceptionTest.php index 656b9ffef..76cb8eb9d 100644 --- a/packages/spa/src/Routing/UnresolvedValueExceptionTest.php +++ b/packages/spa/src/Routing/UnresolvedValueExceptionTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Routing; -use Illuminate\Container\Container; use Illuminate\Contracts\Routing\Registrar; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use LastDragon_ru\LaraASP\Testing\Constraints\Response\StatusCodes\NotFound; @@ -14,7 +13,7 @@ #[CoversClass(UnresolvedValueException::class)] final class UnresolvedValueExceptionTest extends TestCase { public function testHttpResponse(): void { - Container::getInstance()->make(Registrar::class) + $this->app()->make(Registrar::class) ->get(__FUNCTION__, static function (): void { throw new UnresolvedValueException(123); }); diff --git a/packages/spa/src/Testing/Package/TestCase.php b/packages/spa/src/Testing/Package/TestCase.php index 9f5a21046..de42dbf85 100644 --- a/packages/spa/src/Testing/Package/TestCase.php +++ b/packages/spa/src/Testing/Package/TestCase.php @@ -2,6 +2,7 @@ namespace LastDragon_ru\LaraASP\Spa\Testing\Package; +use LastDragon_ru\LaraASP\Core\Provider as CoreProvider; use LastDragon_ru\LaraASP\Spa\Provider; use LastDragon_ru\LaraASP\Testing\Package\TestCase as PackageTestCase; use Override; @@ -19,6 +20,7 @@ abstract class TestCase extends PackageTestCase { protected function getPackageProviders(mixed $app): array { return array_merge(parent::getPackageProviders($app), [ Provider::class, + CoreProvider::class, ]); } } diff --git a/packages/spa/src/Validation/Rules/BoolRuleTest.php b/packages/spa/src/Validation/Rules/BoolRuleTest.php index 29aacf243..07aa128d6 100644 --- a/packages/spa/src/Validation/Rules/BoolRuleTest.php +++ b/packages/spa/src/Validation/Rules/BoolRuleTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Validation\Rules; -use Illuminate\Container\Container; use Illuminate\Contracts\Validation\Factory; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use PHPUnit\Framework\Attributes\CoversClass; @@ -17,8 +16,8 @@ final class BoolRuleTest extends TestCase { // ========================================================================= #[DataProvider('dataProviderIsValid')] public function testRule(bool $expected, mixed $value): void { - $rule = Container::getInstance()->make(BoolRule::class); - $factory = Container::getInstance()->make(Factory::class); + $rule = $this->app()->make(BoolRule::class); + $factory = $this->app()->make(Factory::class); $validator = $factory->make(['value' => $value], ['value' => $rule]); self::assertEquals($expected, !$validator->fails()); @@ -37,7 +36,7 @@ public function testRule(bool $expected, mixed $value): void { #[DataProvider('dataProviderIsValid')] public function testIsValid(bool $expected, mixed $value): void { - $rule = Container::getInstance()->make(BoolRule::class); + $rule = $this->app()->make(BoolRule::class); $actual = $rule->isValid('attribute', $value); self::assertEquals($expected, $actual); diff --git a/packages/spa/src/Validation/Rules/DateRuleTest.php b/packages/spa/src/Validation/Rules/DateRuleTest.php index a71eaac0f..a116333d9 100644 --- a/packages/spa/src/Validation/Rules/DateRuleTest.php +++ b/packages/spa/src/Validation/Rules/DateRuleTest.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\Spa\Validation\Rules; use Exception; -use Illuminate\Container\Container; use Illuminate\Contracts\Translation\Translator; use Illuminate\Contracts\Validation\Factory; use InvalidArgumentException; @@ -20,8 +19,8 @@ final class DateRuleTest extends TestCase { // ========================================================================= #[DataProvider('dataProviderIsValid')] public function testRule(bool $expected, mixed $value): void { - $rule = Container::getInstance()->make(DateRule::class); - $factory = Container::getInstance()->make(Factory::class); + $rule = $this->app()->make(DateRule::class); + $factory = $this->app()->make(Factory::class); $validator = $factory->make(['value' => $value], ['value' => $rule]); self::assertEquals($expected, !$validator->fails()); @@ -40,7 +39,7 @@ public function testRule(bool $expected, mixed $value): void { #[DataProvider('dataProviderIsValid')] public function testIsValid(bool $expected, string $value): void { - $rule = Container::getInstance()->make(DateRule::class); + $rule = $this->app()->make(DateRule::class); $actual = $rule->isValid('attribute', $value); self::assertEquals($expected, $actual); @@ -52,7 +51,7 @@ public function testGetValue(Exception|string|null $expected, string $value): vo self::expectExceptionObject($expected); } - $translator = Container::getInstance()->make(Translator::class); + $translator = $this->app()->make(Translator::class); $rule = new DateRule($translator); $date = $rule->getValue($value); diff --git a/packages/spa/src/Validation/Rules/DateTimeRule.php b/packages/spa/src/Validation/Rules/DateTimeRule.php index 82c30146d..18231e842 100644 --- a/packages/spa/src/Validation/Rules/DateTimeRule.php +++ b/packages/spa/src/Validation/Rules/DateTimeRule.php @@ -5,8 +5,8 @@ use DateTime; use DateTimeImmutable; use DateTimeInterface; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; +use Illuminate\Contracts\Translation\Translator; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; use LastDragon_ru\LaraASP\Spa\Package; use Override; @@ -14,11 +14,17 @@ * ISO 8601 DateTime. */ class DateTimeRule extends DateRule { + public function __construct( + protected readonly ConfigResolver $config, + Translator $translator, + ) { + parent::__construct($translator); + } + #[Override] public function getValue(mixed $value): DateTimeInterface|null { - $repository = Container::getInstance()->make(Repository::class); - $value = parent::getValue($value); - $tz = $repository->get('app.timezone') ?: 'UTC'; + $value = parent::getValue($value); + $tz = $this->config->getInstance()->get('app.timezone') ?: 'UTC'; if ($value instanceof DateTime || $value instanceof DateTimeImmutable) { $value = $value->setTimezone($tz); diff --git a/packages/spa/src/Validation/Rules/DateTimeRuleTest.php b/packages/spa/src/Validation/Rules/DateTimeRuleTest.php index 0960dffae..a80a80e65 100644 --- a/packages/spa/src/Validation/Rules/DateTimeRuleTest.php +++ b/packages/spa/src/Validation/Rules/DateTimeRuleTest.php @@ -2,10 +2,10 @@ namespace LastDragon_ru\LaraASP\Spa\Validation\Rules; -use Illuminate\Container\Container; use Illuminate\Contracts\Translation\Translator; use Illuminate\Contracts\Validation\Factory; use InvalidArgumentException; +use LastDragon_ru\LaraASP\Core\Application\ConfigResolver; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; @@ -22,8 +22,8 @@ final class DateTimeRuleTest extends TestCase { // ========================================================================= #[DataProvider('dataProviderIsValid')] public function testRule(bool $expected, mixed $value): void { - $rule = Container::getInstance()->make(DateTimeRule::class); - $factory = Container::getInstance()->make(Factory::class); + $rule = $this->app()->make(DateTimeRule::class); + $factory = $this->app()->make(Factory::class); $validator = $factory->make(['value' => $value], ['value' => $rule]); self::assertEquals($expected, !$validator->fails()); @@ -42,7 +42,7 @@ public function testRule(bool $expected, mixed $value): void { #[DataProvider('dataProviderIsValid')] public function testIsValid(bool $expected, string $value): void { - $rule = Container::getInstance()->make(DateTimeRule::class); + $rule = $this->app()->make(DateTimeRule::class); $actual = $rule->isValid('attribute', $value); self::assertEquals($expected, $actual); @@ -58,8 +58,9 @@ public function testGetValue(string|array $expected, ?string $tz, string $value) self::expectExceptionMessageMatches($expected['message']); } - $translator = Container::getInstance()->make(Translator::class); - $rule = new DateTimeRule($translator); + $translator = $this->app()->make(Translator::class); + $config = $this->app()->make(ConfigResolver::class); + $rule = new DateTimeRule($config, $translator); $this->setConfig([ 'app.timezone' => $tz, diff --git a/packages/spa/src/Validation/Rules/IntRuleTest.php b/packages/spa/src/Validation/Rules/IntRuleTest.php index cc1377c83..466d55c93 100644 --- a/packages/spa/src/Validation/Rules/IntRuleTest.php +++ b/packages/spa/src/Validation/Rules/IntRuleTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Validation\Rules; -use Illuminate\Container\Container; use Illuminate\Contracts\Validation\Factory; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use PHPUnit\Framework\Attributes\CoversClass; @@ -20,8 +19,8 @@ final class IntRuleTest extends TestCase { // ========================================================================= #[DataProvider('dataProviderIsValid')] public function testRule(bool $expected, mixed $value): void { - $rule = Container::getInstance()->make(IntRule::class); - $factory = Container::getInstance()->make(Factory::class); + $rule = $this->app()->make(IntRule::class); + $factory = $this->app()->make(Factory::class); $validator = $factory->make(['value' => $value], ['value' => $rule]); self::assertEquals($expected, !$validator->fails()); @@ -40,7 +39,7 @@ public function testRule(bool $expected, mixed $value): void { #[DataProvider('dataProviderIsValid')] public function testIsValid(bool $expected, mixed $value): void { - $rule = Container::getInstance()->make(IntRule::class); + $rule = $this->app()->make(IntRule::class); $actual = $rule->isValid('attribute', $value); self::assertEquals($expected, $actual); diff --git a/packages/spa/src/Validation/Rules/NumberRuleTest.php b/packages/spa/src/Validation/Rules/NumberRuleTest.php index 8eb7bd9cb..6df97736a 100644 --- a/packages/spa/src/Validation/Rules/NumberRuleTest.php +++ b/packages/spa/src/Validation/Rules/NumberRuleTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Validation\Rules; -use Illuminate\Container\Container; use Illuminate\Contracts\Validation\Factory; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use PHPUnit\Framework\Attributes\CoversClass; @@ -20,8 +19,8 @@ final class NumberRuleTest extends TestCase { // ========================================================================= #[DataProvider('dataProviderIsValid')] public function testRule(bool $expected, mixed $value): void { - $rule = Container::getInstance()->make(NumberRule::class); - $factory = Container::getInstance()->make(Factory::class); + $rule = $this->app()->make(NumberRule::class); + $factory = $this->app()->make(Factory::class); $validator = $factory->make(['value' => $value], ['value' => $rule]); self::assertEquals($expected, !$validator->fails()); @@ -40,7 +39,7 @@ public function testRule(bool $expected, mixed $value): void { #[DataProvider('dataProviderIsValid')] public function testIsValid(bool $expected, mixed $value): void { - $rule = Container::getInstance()->make(NumberRule::class); + $rule = $this->app()->make(NumberRule::class); $actual = $rule->isValid('attribute', $value); self::assertEquals($expected, $actual); diff --git a/packages/spa/src/Validation/Rules/ResolverRuleTest.php b/packages/spa/src/Validation/Rules/ResolverRuleTest.php index b7666a6c2..d0980df18 100644 --- a/packages/spa/src/Validation/Rules/ResolverRuleTest.php +++ b/packages/spa/src/Validation/Rules/ResolverRuleTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Validation\Rules; -use Illuminate\Container\Container; use Illuminate\Contracts\Translation\Translator; use Illuminate\Contracts\Validation\Factory; use Illuminate\Routing\Router; @@ -20,8 +19,8 @@ final class ResolverRuleTest extends TestCase { // // ========================================================================= public function testRule(): void { - $translator = Container::getInstance()->make(Translator::class); - $router = Container::getInstance()->make(Router::class); + $translator = $this->app()->make(Translator::class); + $router = $this->app()->make(Router::class); $resolver = new class($router) extends Resolver { /** * @inheritDoc @@ -32,7 +31,7 @@ protected function resolve(mixed $value, array $parameters): mixed { } }; $rule = new ResolverRule($translator, $resolver); - $factory = Container::getInstance()->make(Factory::class); + $factory = $this->app()->make(Factory::class); $validator = $factory->make( [ 'a' => true, @@ -56,8 +55,8 @@ protected function resolve(mixed $value, array $parameters): mixed { } public function testIsValid(): void { - $translator = Container::getInstance()->make(Translator::class); - $router = Container::getInstance()->make(Router::class); + $translator = $this->app()->make(Translator::class); + $router = $this->app()->make(Router::class); $resolver = new class($router) extends Resolver { /** * @inheritDoc @@ -73,8 +72,8 @@ protected function resolve(mixed $value, array $parameters): mixed { } public function testIsValidUnresolved(): void { - $translator = Container::getInstance()->make(Translator::class); - $router = Container::getInstance()->make(Router::class); + $translator = $this->app()->make(Translator::class); + $router = $this->app()->make(Router::class); $resolver = new class($router) extends Resolver { /** * @inheritDoc diff --git a/packages/spa/src/Validation/Rules/StringRuleTest.php b/packages/spa/src/Validation/Rules/StringRuleTest.php index f784e8494..d8c766183 100644 --- a/packages/spa/src/Validation/Rules/StringRuleTest.php +++ b/packages/spa/src/Validation/Rules/StringRuleTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Spa\Validation\Rules; -use Illuminate\Container\Container; use Illuminate\Contracts\Validation\Factory; use LastDragon_ru\LaraASP\Spa\Testing\Package\TestCase; use PHPUnit\Framework\Attributes\CoversClass; @@ -17,8 +16,8 @@ final class StringRuleTest extends TestCase { // ========================================================================= #[DataProvider('dataProviderIsValid')] public function testRule(bool $expected, mixed $value): void { - $rule = Container::getInstance()->make(StringRule::class); - $factory = Container::getInstance()->make(Factory::class); + $rule = $this->app()->make(StringRule::class); + $factory = $this->app()->make(Factory::class); $validator = $factory->make(['value' => $value], ['value' => $rule]); self::assertEquals($expected, !$validator->fails()); @@ -37,7 +36,7 @@ public function testRule(bool $expected, mixed $value): void { #[DataProvider('dataProviderIsValid')] public function testIsValid(bool $expected, mixed $value): void { - $rule = Container::getInstance()->make(StringRule::class); + $rule = $this->app()->make(StringRule::class); $actual = $rule->isValid('attribute', $value); self::assertEquals($expected, $actual); diff --git a/packages/testing/README.md b/packages/testing/README.md index 54661fc3b..1f6175912 100644 --- a/packages/testing/README.md +++ b/packages/testing/README.md @@ -62,14 +62,21 @@ In the general case, you just need to update `tests/TestCase.php` to include mos namespace Tests; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; use LastDragon_ru\LaraASP\Testing\Assertions\Assertions; use LastDragon_ru\LaraASP\Testing\Concerns\Concerns; +use Override; abstract class TestCase extends BaseTestCase { use Assertions; // Added use Concerns; // Added use CreatesApplication; + + #[Override] + protected function app(): Application { + return $this->app; + } } ``` @@ -197,7 +204,7 @@ associated with test) [//]: # (start: 0e8393713b25b89be1ee5c685bf900c5886a18a09f340b910b310e5026c4af1f) [//]: # (warning: Generated automatically. Do not edit.) -Allows to replace translation strings for Laravel. +Allows replacing translation strings for Laravel. [//]: # (end: 0e8393713b25b89be1ee5c685bf900c5886a18a09f340b910b310e5026c4af1f) diff --git a/packages/testing/UPGRADE.md b/packages/testing/UPGRADE.md index 24536b2f6..3d44e7634 100644 --- a/packages/testing/UPGRADE.md +++ b/packages/testing/UPGRADE.md @@ -27,6 +27,31 @@ Please also see [changelog](https://github.com/LastDragon-ru/lara-asp/releases) [//]: # (end: c70a9a43c0a80bd2e7fa6010a9b2c0fbcab4cb4d536d7a498216d9df7431f7e2) +# Upgrade from v6 + +[include:file]: ../../docs/Shared/Upgrade/FromV6.md +[//]: # (start: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) +[//]: # (warning: Generated automatically. Do not edit.) + +* [ ] Direct usages of `Container::getInstances()` were replaced by explicit constructor parameters. You may need to update your code accordingly (#151). + +[//]: # (end: 6b55bf5daea407a4590344596d41efd8368a783e2666bfe431a88a5eeaff3a95) + +* [ ] Following traits required `app()` method to get access to the Container (#151) + * `\LastDragon_ru\LaraASP\Testing\Assertions\Application\ScheduleAssertions` + * `\LastDragon_ru\LaraASP\Testing\Concerns\Override` + * `\LastDragon_ru\LaraASP\Testing\Database\QueryLog\WithQueryLog` + * `\LastDragon_ru\LaraASP\Testing\Database\RefreshDatabaseIfEmpty` + * `\LastDragon_ru\LaraASP\Testing\Utils\WithTranslations` + + ```php + protected function app(): Application { + return $this->app; + } + ``` + +* [ ] `\LastDragon_ru\LaraASP\Testing\Assertions\Application\ScheduleAssertions` methods became non-static (#151). + # Upgrade from v5 [include:file]: ../../docs/Shared/Upgrade/FromV5.md diff --git a/packages/testing/composer.json b/packages/testing/composer.json index ce7557712..544d0c83a 100644 --- a/packages/testing/composer.json +++ b/packages/testing/composer.json @@ -30,7 +30,6 @@ "http-interop/http-factory-guzzle": "^1.0.0", "illuminate/collections": "^10.34.0|^11.0.0", "illuminate/console": "^10.34.0|^11.0.0", - "illuminate/container": "^10.34.0|^11.0.0", "illuminate/contracts": "^10.34.0|^11.0.0", "illuminate/database": "^10.34.0|^11.0.0", "illuminate/testing": "^10.34.0|^11.0.0", diff --git a/packages/testing/docs/Assertions/AssertQueryLogEquals.md b/packages/testing/docs/Assertions/AssertQueryLogEquals.md index a1cc94c90..cbb4620e6 100644 --- a/packages/testing/docs/Assertions/AssertQueryLogEquals.md +++ b/packages/testing/docs/Assertions/AssertQueryLogEquals.md @@ -11,11 +11,14 @@ Asserts that `QueryLog` equals `QueryLog`. namespace LastDragon_ru\LaraASP\Testing\Docs\Assertions; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; use LastDragon_ru\LaraASP\Testing\Concerns\DatabaseQueryComparator; use LastDragon_ru\LaraASP\Testing\Database\QueryLog\WithQueryLog; +use LogicException; use Orchestra\Testbench\TestCase; +use Override; use PHPUnit\Framework\Attributes\CoversNothing; /** @@ -29,6 +32,11 @@ final class AssertQueryLogEqualsTest extends TestCase { use WithQueryLog; use DatabaseQueryComparator; + #[Override] + protected function app(): Application { + return $this->app ?? throw new LogicException('Application not yet initialized.'); + } + /** * Assertion test. */ diff --git a/packages/testing/docs/Assertions/AssertQueryLogEqualsTest.php b/packages/testing/docs/Assertions/AssertQueryLogEqualsTest.php index bdc0f3e0e..a2f1bbdcd 100644 --- a/packages/testing/docs/Assertions/AssertQueryLogEqualsTest.php +++ b/packages/testing/docs/Assertions/AssertQueryLogEqualsTest.php @@ -2,11 +2,14 @@ namespace LastDragon_ru\LaraASP\Testing\Docs\Assertions; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; use LastDragon_ru\LaraASP\Testing\Concerns\DatabaseQueryComparator; use LastDragon_ru\LaraASP\Testing\Database\QueryLog\WithQueryLog; +use LogicException; use Orchestra\Testbench\TestCase; +use Override; use PHPUnit\Framework\Attributes\CoversNothing; /** @@ -20,6 +23,11 @@ final class AssertQueryLogEqualsTest extends TestCase { use WithQueryLog; use DatabaseQueryComparator; + #[Override] + protected function app(): Application { + return $this->app ?? throw new LogicException('Application not yet initialized.'); + } + /** * Assertion test. */ diff --git a/packages/testing/docs/Assertions/AssertScheduled.md b/packages/testing/docs/Assertions/AssertScheduled.md index fd6e2101b..3c6f6c466 100644 --- a/packages/testing/docs/Assertions/AssertScheduled.md +++ b/packages/testing/docs/Assertions/AssertScheduled.md @@ -12,9 +12,11 @@ Asserts that Schedule contains task. namespace LastDragon_ru\LaraASP\Testing\Docs\Assertions; use Illuminate\Console\Scheduling\Schedule; -use Illuminate\Container\Container; +use Illuminate\Contracts\Foundation\Application; use LastDragon_ru\LaraASP\Testing\Assertions\Application\ScheduleAssertions; +use LogicException; use Orchestra\Testbench\TestCase; +use Override; use PHPUnit\Framework\Attributes\CoversNothing; /** @@ -27,13 +29,21 @@ final class AssertScheduledTest extends TestCase { */ use ScheduleAssertions; + #[Override] + protected function app(): Application { + return $this->app ?? throw new LogicException('Application not yet initialized.'); + } + /** * Assertion test. */ public function testAssertion(): void { // Prepare - /** @var Schedule $schedule */ - $schedule = Container::getInstance()->make(Schedule::class); + $schedule = $this->app?->make(Schedule::class); + + self::assertNotNull($schedule); + + // Schedule $schedule ->command('emails:send Example') ->daily(); @@ -42,8 +52,8 @@ final class AssertScheduledTest extends TestCase { ->daily(); // Test - self::assertScheduled('emails:send Example'); - self::assertScheduled('/path/to/command'); + $this->assertScheduled('emails:send Example'); + $this->assertScheduled('/path/to/command'); } } ``` diff --git a/packages/testing/docs/Assertions/AssertScheduledTest.php b/packages/testing/docs/Assertions/AssertScheduledTest.php index 4e120a2ed..0a1fc53d5 100644 --- a/packages/testing/docs/Assertions/AssertScheduledTest.php +++ b/packages/testing/docs/Assertions/AssertScheduledTest.php @@ -3,9 +3,11 @@ namespace LastDragon_ru\LaraASP\Testing\Docs\Assertions; use Illuminate\Console\Scheduling\Schedule; -use Illuminate\Container\Container; +use Illuminate\Contracts\Foundation\Application; use LastDragon_ru\LaraASP\Testing\Assertions\Application\ScheduleAssertions; +use LogicException; use Orchestra\Testbench\TestCase; +use Override; use PHPUnit\Framework\Attributes\CoversNothing; /** @@ -18,13 +20,21 @@ final class AssertScheduledTest extends TestCase { */ use ScheduleAssertions; + #[Override] + protected function app(): Application { + return $this->app ?? throw new LogicException('Application not yet initialized.'); + } + /** * Assertion test. */ public function testAssertion(): void { // Prepare - /** @var Schedule $schedule */ - $schedule = Container::getInstance()->make(Schedule::class); + $schedule = $this->app?->make(Schedule::class); + + self::assertNotNull($schedule); + + // Schedule $schedule ->command('emails:send Example') ->daily(); @@ -33,7 +43,7 @@ public function testAssertion(): void { ->daily(); // Test - self::assertScheduled('emails:send Example'); - self::assertScheduled('/path/to/command'); + $this->assertScheduled('emails:send Example'); + $this->assertScheduled('/path/to/command'); } } diff --git a/packages/testing/docs/Examples/TestCase.php b/packages/testing/docs/Examples/TestCase.php index e3e9219a5..c929a0288 100644 --- a/packages/testing/docs/Examples/TestCase.php +++ b/packages/testing/docs/Examples/TestCase.php @@ -2,12 +2,19 @@ namespace Tests; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; use LastDragon_ru\LaraASP\Testing\Assertions\Assertions; use LastDragon_ru\LaraASP\Testing\Concerns\Concerns; +use Override; abstract class TestCase extends BaseTestCase { use Assertions; // Added use Concerns; // Added use CreatesApplication; + + #[Override] + protected function app(): Application { + return $this->app; + } } diff --git a/packages/testing/src/Assertions/Application/ScheduleAssertions.php b/packages/testing/src/Assertions/Application/ScheduleAssertions.php index 391480e31..af4bdf4da 100644 --- a/packages/testing/src/Assertions/Application/ScheduleAssertions.php +++ b/packages/testing/src/Assertions/Application/ScheduleAssertions.php @@ -4,7 +4,7 @@ use Illuminate\Console\Scheduling\Event; use Illuminate\Console\Scheduling\Schedule; -use Illuminate\Container\Container; +use Illuminate\Contracts\Foundation\Application; use LastDragon_ru\LaraASP\Testing\Assertions\Application\ScheduleMatchers\CallbackEventMatcher; use LastDragon_ru\LaraASP\Testing\Assertions\Application\ScheduleMatchers\CommandMatcher; use LastDragon_ru\LaraASP\Testing\Assertions\Application\ScheduleMatchers\DescriptionMatcher; @@ -15,35 +15,46 @@ use function sprintf; trait ScheduleAssertions { + // + // ========================================================================= + abstract protected function app(): Application; + // + + // + // ========================================================================= /** * Asserts that Schedule contains task. */ - public static function assertScheduled(string $expected, string $message = ''): void { + public function assertScheduled(string $expected, string $message = ''): void { $message = $message ?: sprintf('The `%s` is not scheduled.', $expected); - $scheduled = self::isScheduledEvent($expected); + $scheduled = $this->isScheduledEvent($expected); Assert::assertTrue($scheduled, $message); } + // + // + // ========================================================================= /** * @internal */ - private static function isScheduledEvent(string $task): bool { - return count(self::getScheduledEvents($task)) === 1; + private function isScheduledEvent(string $task): bool { + return count($this->getScheduledEvents($task)) === 1; } /** * @internal * @return array */ - private static function getScheduledEvents(string $task): array { - $schedule = Container::getInstance()->make(Schedule::class); - $matchers = [ + private function getScheduledEvents(string $task): array { + $container = $this->app(); + $schedule = $container->make(Schedule::class); + $matchers = [ new DescriptionMatcher(), - new CommandMatcher(), + new CommandMatcher($container), new CallbackEventMatcher(), ]; - $events = array_filter($schedule->events(), static function (Event $event) use ($matchers, $task): bool { + $events = array_filter($schedule->events(), static function (Event $event) use ($matchers, $task): bool { $match = false; foreach ($matchers as $matcher) { @@ -58,4 +69,5 @@ private static function getScheduledEvents(string $task): array { return $events; } + // } diff --git a/packages/testing/src/Assertions/Application/ScheduleAssertionsTest.php b/packages/testing/src/Assertions/Application/ScheduleAssertionsTest.php index 41863e66b..c9ab9fc9a 100644 --- a/packages/testing/src/Assertions/Application/ScheduleAssertionsTest.php +++ b/packages/testing/src/Assertions/Application/ScheduleAssertionsTest.php @@ -4,9 +4,10 @@ use Illuminate\Console\Command; use Illuminate\Console\Scheduling\Schedule; -use Illuminate\Container\Container; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Queue\ShouldQueue; use LastDragon_ru\LaraASP\Testing\Package\TestCase; +use Override; use PHPUnit\Framework\Attributes\CoversClass; use Symfony\Component\Console\Attribute\AsCommand; @@ -16,11 +17,22 @@ #[CoversClass(ScheduleAssertions::class)] final class ScheduleAssertionsTest extends TestCase { public function testGetScheduleEvents(): void { - $schedule = Container::getInstance()->make(Schedule::class); - $assertions = new class() { + $schedule = $this->app()->make(Schedule::class); + $assertions = new class($this->app()) { use ScheduleAssertions { isScheduledEvent as public; } + + public function __construct( + private readonly Application $app, + ) { + // empty + } + + #[Override] + protected function app(): Application { + return $this->app; + } }; $taskExec = '/path/to/command'; $taskCommand = 'test:command abc'; @@ -40,11 +52,11 @@ public function __invoke(): void { $schedule->call($taskInvoke::class)->weekly(); $schedule->exec($taskExec)->weekly(); - self::assertTrue($assertions::isScheduledEvent("{$taskCommand} --a=123")); - self::assertTrue($assertions::isScheduledEvent($taskCommandClass)); - self::assertTrue($assertions::isScheduledEvent($taskInvoke::class)); - self::assertTrue($assertions::isScheduledEvent($taskShouldQueue::class)); - self::assertTrue($assertions::isScheduledEvent($taskExec)); + self::assertTrue($assertions->isScheduledEvent("{$taskCommand} --a=123")); + self::assertTrue($assertions->isScheduledEvent($taskCommandClass)); + self::assertTrue($assertions->isScheduledEvent($taskInvoke::class)); + self::assertTrue($assertions->isScheduledEvent($taskShouldQueue::class)); + self::assertTrue($assertions->isScheduledEvent($taskExec)); } } diff --git a/packages/testing/src/Assertions/Application/ScheduleMatchers/CommandMatcher.php b/packages/testing/src/Assertions/Application/ScheduleMatchers/CommandMatcher.php index 9a672648a..6538ffb3c 100644 --- a/packages/testing/src/Assertions/Application/ScheduleMatchers/CommandMatcher.php +++ b/packages/testing/src/Assertions/Application/ScheduleMatchers/CommandMatcher.php @@ -5,7 +5,7 @@ use Illuminate\Console\Application; use Illuminate\Console\Command; use Illuminate\Console\Scheduling\Event; -use Illuminate\Container\Container; +use Illuminate\Contracts\Container\Container; use LastDragon_ru\LaraASP\Testing\Assertions\Application\ScheduleMatcher; use Override; @@ -19,7 +19,9 @@ * @internal */ class CommandMatcher implements ScheduleMatcher { - public function __construct() { + public function __construct( + protected readonly Container $container, + ) { // empty } @@ -33,7 +35,7 @@ public function isMatch(Event $event, mixed $task): bool { // Check $variants = match (true) { is_string($task) && is_a($task, Command::class, true) => array_unique(array_filter([ - Application::formatCommandString(Container::getInstance()->make($task)->getName() ?? ''), + Application::formatCommandString($this->container->make($task)->getName() ?? ''), Application::formatCommandString($task::getDefaultName() ?? ''), ])), is_string($task) => [ diff --git a/packages/testing/src/Concerns/Override.php b/packages/testing/src/Concerns/Override.php index fc4895703..7bb866c64 100644 --- a/packages/testing/src/Concerns/Override.php +++ b/packages/testing/src/Concerns/Override.php @@ -2,7 +2,7 @@ namespace LastDragon_ru\LaraASP\Testing\Concerns; -use Illuminate\Container\Container; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Foundation\Testing\Concerns\InteractsWithContainer; use LogicException; use Mockery; @@ -34,6 +34,8 @@ trait Override { */ private array $overrides = []; + abstract protected function app(): Application; + /** * @internal */ @@ -92,7 +94,7 @@ protected function override(string $class, mixed $factory = null): mixed { /** @phpstan-ignore-next-line it may return `void` so it is fine here */ $mock = $factory($mock, $this) ?: $mock; } elseif (is_string($factory)) { - $mock = Container::getInstance()->make($factory); + $mock = $this->app()->make($factory); } else { // empty } @@ -104,7 +106,7 @@ protected function override(string $class, mixed $factory = null): mixed { assert(is_callable($this->overrides[$class])); - Container::getInstance()->bind( + $this->app()->bind( $class, ($this->overrides[$class])(...), ); diff --git a/packages/testing/src/Database/QueryLog/WithQueryLog.php b/packages/testing/src/Database/QueryLog/WithQueryLog.php index 05fdf7daa..9b928ee36 100644 --- a/packages/testing/src/Database/QueryLog/WithQueryLog.php +++ b/packages/testing/src/Database/QueryLog/WithQueryLog.php @@ -2,7 +2,7 @@ namespace LastDragon_ru\LaraASP\Testing\Database\QueryLog; -use Illuminate\Container\Container; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Database\Connection; use Illuminate\Database\ConnectionResolverInterface; use Illuminate\Database\Eloquent\Model; @@ -28,6 +28,8 @@ trait WithQueryLog { */ private ?WeakMap $withQueryLog = null; + abstract protected function app(): Application; + /** * @internal */ @@ -60,7 +62,7 @@ protected function getQueryLog(ConnectionResolverInterface|Connection|Model|stri } elseif ($connection instanceof ConnectionResolverInterface) { $connection = $connection->connection(); } else { - $connection = Container::getInstance()->make(ConnectionResolverInterface::class)->connection($connection); + $connection = $this->app()->make(ConnectionResolverInterface::class)->connection($connection); } // Valid? diff --git a/packages/testing/src/Database/RefreshDatabaseIfEmpty.php b/packages/testing/src/Database/RefreshDatabaseIfEmpty.php index d5b54d4e0..aa6694c40 100644 --- a/packages/testing/src/Database/RefreshDatabaseIfEmpty.php +++ b/packages/testing/src/Database/RefreshDatabaseIfEmpty.php @@ -2,7 +2,7 @@ namespace LastDragon_ru\LaraASP\Testing\Database; -use Illuminate\Container\Container; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Database\DatabaseManager; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabaseState; @@ -29,9 +29,11 @@ trait RefreshDatabaseIfEmpty { refreshTestDatabase as protected laravelRefreshTestDatabase; } + abstract protected function app(): Application; + protected function refreshTestDatabase(): void { if (!RefreshDatabaseState::$migrated) { - $connection = Container::getInstance()->make(DatabaseManager::class)->connection(); + $connection = $this->app()->make(DatabaseManager::class)->connection(); $tables = $connection->getSchemaBuilder()->getTables(); if ($tables) { diff --git a/packages/testing/src/Database/RefreshDatabaseIfEmptyTest.php b/packages/testing/src/Database/RefreshDatabaseIfEmptyTest.php index 6e644df6b..3a9be031c 100644 --- a/packages/testing/src/Database/RefreshDatabaseIfEmptyTest.php +++ b/packages/testing/src/Database/RefreshDatabaseIfEmptyTest.php @@ -3,7 +3,6 @@ namespace LastDragon_ru\LaraASP\Testing\Database; use Exception; -use Illuminate\Container\Container; use LastDragon_ru\LaraASP\Testing\Package\TestCase; use Override; use PHPUnit\Framework\Attributes\CoversClass; @@ -16,7 +15,7 @@ #[CoversClass(RefreshDatabaseIfEmpty::class)] final class RefreshDatabaseIfEmptyTest extends TestCase { public function testImpl(): void { - self::assertNotEmpty(Container::getInstance()->make(RefreshDatabaseIfEmptyTest_Impl::class, [ + self::assertNotEmpty($this->app()->make(RefreshDatabaseIfEmptyTest_Impl::class, [ 'name' => 'test', ])); } diff --git a/packages/testing/src/Package/TestCase.php b/packages/testing/src/Package/TestCase.php index aad9aa4d4..db6134166 100644 --- a/packages/testing/src/Package/TestCase.php +++ b/packages/testing/src/Package/TestCase.php @@ -2,13 +2,16 @@ namespace LastDragon_ru\LaraASP\Testing\Package; +use Illuminate\Contracts\Foundation\Application; use LastDragon_ru\LaraASP\Testing\Assertions\Assertions; use LastDragon_ru\LaraASP\Testing\Concerns\Concerns; use LastDragon_ru\LaraASP\Testing\Utils\WithTempDirectory; use LastDragon_ru\LaraASP\Testing\Utils\WithTempFile; use LastDragon_ru\LaraASP\Testing\Utils\WithTestData; use LastDragon_ru\LaraASP\Testing\Utils\WithTranslations; +use LogicException; use Orchestra\Testbench\TestCase as TestbenchTestCase; +use Override; /** * Special test case for packages with application. @@ -26,4 +29,9 @@ abstract class TestCase extends TestbenchTestCase { use WithTempFile; use WithTempDirectory; use WithTranslations; + + #[Override] + protected function app(): Application { + return $this->app ?? throw new LogicException('Application not yet initialized.'); + } } diff --git a/packages/testing/src/Package/WithConfig.php b/packages/testing/src/Package/WithConfig.php index 5dfce08e4..1f76af489 100644 --- a/packages/testing/src/Package/WithConfig.php +++ b/packages/testing/src/Package/WithConfig.php @@ -2,13 +2,13 @@ namespace LastDragon_ru\LaraASP\Testing\Package; -use Illuminate\Container\Container; use Illuminate\Contracts\Config\Repository; +use Illuminate\Contracts\Foundation\Application; use function is_callable; /** - * Allows to replace settings for Laravel. + * Allows replacing settings for Laravel. * * Required to avoid dependency from `Illuminate\Foundation\*` (`config()`). * @@ -19,11 +19,13 @@ * @phpstan-type SettingsFactory SettingsCallback|Settings|null */ trait WithConfig { + abstract protected function app(): Application; + /** * @param SettingsFactory $settings */ public function setConfig(callable|array|null $settings): void { - $repository = Container::getInstance()->make(Repository::class); + $repository = $this->app()->make(Repository::class); $settings = is_callable($settings) ? $settings($this, $repository) : $settings; if ($settings !== null) { diff --git a/packages/testing/src/Responses/Laravel/Json/ValidationErrorResponseTest.php b/packages/testing/src/Responses/Laravel/Json/ValidationErrorResponseTest.php index 84493c936..9a96a429e 100644 --- a/packages/testing/src/Responses/Laravel/Json/ValidationErrorResponseTest.php +++ b/packages/testing/src/Responses/Laravel/Json/ValidationErrorResponseTest.php @@ -2,7 +2,6 @@ namespace LastDragon_ru\LaraASP\Testing\Responses\Laravel\Json; -use Illuminate\Container\Container; use Illuminate\Contracts\Routing\Registrar; use Illuminate\Contracts\Validation\Factory as ValidatorFactory; use Illuminate\Http\Request; @@ -24,10 +23,9 @@ final class ValidationErrorResponseTest extends TestCase { */ #[DataProvider('dataProviderEvaluate')] public function testEvaluate(bool $expected, array $rules, ?array $errors): void { - Container::getInstance()->make(Registrar::class) - ->get(__FUNCTION__, static function (Request $request) use ($rules) { - return Container::getInstance() - ->make(ValidatorFactory::class) + $this->app()->make(Registrar::class) + ->get(__FUNCTION__, function (Request $request) use ($rules) { + return $this->app()->make(ValidatorFactory::class) ->validate($request->all(), $rules); }); diff --git a/packages/testing/src/TestCase.php b/packages/testing/src/TestCase.php index e9ddf3686..31cd56cb3 100644 --- a/packages/testing/src/TestCase.php +++ b/packages/testing/src/TestCase.php @@ -2,10 +2,12 @@ namespace LastDragon_ru\LaraASP\Testing; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; use LastDragon_ru\LaraASP\Testing\Assertions\Assertions; use LastDragon_ru\LaraASP\Testing\Concerns\Concerns; use LastDragon_ru\LaraASP\Testing\Utils\WithTestData; +use Override; use function trigger_deprecation; @@ -20,4 +22,9 @@ abstract class TestCase extends BaseTestCase { use Assertions; use Concerns; use WithTestData; + + #[Override] + protected function app(): Application { + return $this->app; + } } diff --git a/packages/testing/src/Utils/WithTranslations.php b/packages/testing/src/Utils/WithTranslations.php index 0c1cce762..6ea640000 100644 --- a/packages/testing/src/Utils/WithTranslations.php +++ b/packages/testing/src/Utils/WithTranslations.php @@ -2,7 +2,7 @@ namespace LastDragon_ru\LaraASP\Testing\Utils; -use Illuminate\Container\Container; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Translation\Translator; use Illuminate\Translation\Translator as TranslatorImpl; use LastDragon_ru\LaraASP\Testing\Exceptions\TranslatorUnsupported; @@ -10,19 +10,21 @@ use function is_callable; /** - * Allows to replace translation strings for Laravel. + * Allows replacing translation strings for Laravel. * * @phpstan-type Translations array> * @phpstan-type TranslationsCallback callable(static, string $currentLocale, string $fallbackLocale): Translations * @phpstan-type TranslationsFactory TranslationsCallback|Translations|null */ trait WithTranslations { + abstract protected function app(): Application; + /** * @param TranslationsFactory $translations */ public function setTranslations(callable|array|null $translations): void { // Translator - $translator = Container::getInstance()->make(Translator::class); + $translator = $this->app()->make(Translator::class); if (!($translator instanceof TranslatorImpl)) { throw new TranslatorUnsupported($translator::class); diff --git a/phpstan-baseline-well-known.neon b/phpstan-baseline-well-known.neon index 70f1df501..34f32b9a3 100644 --- a/phpstan-baseline-well-known.neon +++ b/phpstan-baseline-well-known.neon @@ -13,9 +13,9 @@ parameters: # Larastan doesn't support phpstan/phpstan-strict-rules # https://github.com/phpstan/phpstan-strict-rules/issues/140 - "#^Dynamic call to static method Illuminate\\\\Contracts\\\\Foundation\\\\CachesConfiguration\\:\\:(configurationIsCached|routesAreCached|langPath)\\(\\)\\.$#" + - "#^Dynamic call to static method Illuminate\\\\Contracts\\\\Foundation\\\\CachesRoutes\\:\\:routesAreCached\\(\\)\\.$#" - "#^Dynamic call to static method Illuminate\\\\Validation\\\\Factory\\:\\:(validate)\\(\\)\\.$#" - "#^Dynamic call to static method Illuminate\\\\Testing\\\\TestResponse\\:\\:assert[^(]+\\(\\)\\.$#" - - "#^Dynamic call to static method Illuminate\\\\Database\\\\Connection(\\<[^>]+\\>)?\\:\\:[^(]+\\(\\)\\.$#" - "#^Dynamic call to static method Illuminate\\\\Database\\\\Eloquent\\\\Model(\\<[^>]+\\>)?\\:\\:[^(]+\\(\\)\\.$#" - "#^Dynamic call to static method Illuminate\\\\Database\\\\Eloquent\\\\Builder(\\<[^>]+\\>)?\\:\\:[^(]+\\(\\)\\.$#" - "#^Dynamic call to static method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\[^\\\\]+(\\<[^>]+\\>)?\\:\\:[^(]+\\(\\)\\.$#" @@ -56,7 +56,7 @@ parameters: # False positive # https://github.com/phpstan/phpstan-mockery/issues/18 - - message: "#^Call to protected method getResolver\\(\\) of class LastDragon_ru\\\\LaraASP\\\\GraphQL\\\\Stream\\\\Directives\\\\Directive\\.$#" + message: "#^Call to protected method (getResolverRelation|getResolverModel|getResolverClass|getFieldValue)\\(\\) of class LastDragon_ru\\\\LaraASP\\\\GraphQL\\\\Stream\\\\Directives\\\\Directive\\.$#" paths: - packages/graphql/src/Stream/Directives/DirectiveTest.php -