From 1f68f12824f0cf9f6cd56dfaa87123b7554de2d1 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Tue, 7 Dec 2021 12:55:30 +0000 Subject: [PATCH 1/3] Adds `WithoutEvents` trait for application seeders --- .../Database/Console/Seeds/WithoutEvents.php | 19 ++++++ src/Illuminate/Database/Seeder.php | 15 ++++- tests/Database/SeedCommandTest.php | 58 +++++++++++++++++++ 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 src/Illuminate/Database/Console/Seeds/WithoutEvents.php diff --git a/src/Illuminate/Database/Console/Seeds/WithoutEvents.php b/src/Illuminate/Database/Console/Seeds/WithoutEvents.php new file mode 100644 index 000000000000..001f3050bcf6 --- /dev/null +++ b/src/Illuminate/Database/Console/Seeds/WithoutEvents.php @@ -0,0 +1,19 @@ + Model::withoutEvents($callback); + } +} diff --git a/src/Illuminate/Database/Seeder.php b/src/Illuminate/Database/Seeder.php index 560e81c15211..a55482f8e03f 100755 --- a/src/Illuminate/Database/Seeder.php +++ b/src/Illuminate/Database/Seeder.php @@ -4,6 +4,7 @@ use Illuminate\Console\Command; use Illuminate\Container\Container; +use Illuminate\Database\Console\Seeds\WithoutEvents; use Illuminate\Support\Arr; use InvalidArgumentException; @@ -170,8 +171,16 @@ public function __invoke(array $parameters = []) throw new InvalidArgumentException('Method [run] missing from '.get_class($this)); } - return isset($this->container) - ? $this->container->call([$this, 'run'], $parameters) - : $this->run(...$parameters); + $callback = fn () => isset($this->container) + ? $this->container->call([$this, 'run'], $parameters) + : $this->run(...$parameters); + + $uses = array_flip(class_uses_recursive(static::class)); + + if (isset($uses[WithoutEvents::class])) { + $callback = $this->withoutEvents($callback); + } + + return $callback(); } } diff --git a/tests/Database/SeedCommandTest.php b/tests/Database/SeedCommandTest.php index 215990f30bd2..d530e4e8b6a8 100644 --- a/tests/Database/SeedCommandTest.php +++ b/tests/Database/SeedCommandTest.php @@ -4,9 +4,14 @@ use Illuminate\Console\OutputStyle; use Illuminate\Container\Container; +use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Database\ConnectionResolverInterface; use Illuminate\Database\Console\Seeds\SeedCommand; +use Illuminate\Database\Console\Seeds\WithoutEvents; +use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Seeder; +use Illuminate\Events\NullDispatcher; +use Illuminate\Testing\Assert; use Mockery as m; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Input\ArrayInput; @@ -46,8 +51,61 @@ public function testHandle() $container->shouldHaveReceived('call')->with([$command, 'handle']); } + public function testWithoutEvents() + { + $input = new ArrayInput([ + '--force' => true, + '--database' => 'sqlite', + '--class' => UserWithoutEventsSeeder::class, + ]); + $output = new NullOutput; + + $instance = new UserWithoutEventsSeeder(); + + $seeder = m::mock($instance); + $seeder->shouldReceive('setContainer')->once()->andReturnSelf(); + $seeder->shouldReceive('setCommand')->once()->andReturnSelf(); + + $resolver = m::mock(ConnectionResolverInterface::class); + $resolver->shouldReceive('getDefaultConnection')->once(); + $resolver->shouldReceive('setDefaultConnection')->once()->with('sqlite'); + + $container = m::mock(Container::class); + $container->shouldReceive('call'); + $container->shouldReceive('environment')->once()->andReturn('testing'); + $container->shouldReceive('make')->with(UserWithoutEventsSeeder::class)->andReturn($seeder); + $container->shouldReceive('make')->with(OutputStyle::class, m::any())->andReturn( + new OutputStyle($input, $output) + ); + + $command = new SeedCommand($resolver); + $command->setLaravel($container); + + Model::setEventDispatcher($dispatcher = m::mock(Dispatcher::class)); + + // call run to set up IO, then fire manually. + $command->run($input, $output); + $command->handle(); + + Assert::assertSame($dispatcher, Model::getEventDispatcher()); + + $container->shouldHaveReceived('call')->with([$command, 'handle']); + } + protected function tearDown(): void { + Model::unsetEventDispatcher(); + m::close(); } } + +class UserWithoutEventsSeeder extends Seeder +{ + use WithoutEvents; + + public function run() + { + Assert::assertInstanceOf(NullDispatcher::class, Model::getEventDispatcher()); + } +} From 41e8899b6f67d3a0feb1c5f3022600b62f0d1e01 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Tue, 7 Dec 2021 14:44:57 +0000 Subject: [PATCH 2/3] Renames `WithoutEvents` to `WithoutModelEvents` --- .../{WithoutEvents.php => WithoutModelEvents.php} | 6 +++--- src/Illuminate/Database/Seeder.php | 6 +++--- tests/Database/SeedCommandTest.php | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) rename src/Illuminate/Database/Console/Seeds/{WithoutEvents.php => WithoutModelEvents.php} (60%) diff --git a/src/Illuminate/Database/Console/Seeds/WithoutEvents.php b/src/Illuminate/Database/Console/Seeds/WithoutModelEvents.php similarity index 60% rename from src/Illuminate/Database/Console/Seeds/WithoutEvents.php rename to src/Illuminate/Database/Console/Seeds/WithoutModelEvents.php index 001f3050bcf6..81f12e10a11f 100644 --- a/src/Illuminate/Database/Console/Seeds/WithoutEvents.php +++ b/src/Illuminate/Database/Console/Seeds/WithoutModelEvents.php @@ -4,15 +4,15 @@ use Illuminate\Database\Eloquent\Model; -trait WithoutEvents +trait WithoutModelEvents { /** - * Prevent all event handles from being executed by the given callback. + * Prevent model event handles from being executed by the given callback. * * @param callable $callback * @return callable */ - public function withoutEvents(callable $callback) + public function withoutModelEvents(callable $callback) { return fn () => Model::withoutEvents($callback); } diff --git a/src/Illuminate/Database/Seeder.php b/src/Illuminate/Database/Seeder.php index a55482f8e03f..1a7a12e1914d 100755 --- a/src/Illuminate/Database/Seeder.php +++ b/src/Illuminate/Database/Seeder.php @@ -4,7 +4,7 @@ use Illuminate\Console\Command; use Illuminate\Container\Container; -use Illuminate\Database\Console\Seeds\WithoutEvents; +use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Support\Arr; use InvalidArgumentException; @@ -177,8 +177,8 @@ public function __invoke(array $parameters = []) $uses = array_flip(class_uses_recursive(static::class)); - if (isset($uses[WithoutEvents::class])) { - $callback = $this->withoutEvents($callback); + if (isset($uses[WithoutModelEvents::class])) { + $callback = $this->withoutModelEvents($callback); } return $callback(); diff --git a/tests/Database/SeedCommandTest.php b/tests/Database/SeedCommandTest.php index d530e4e8b6a8..9d6a1bedfd33 100644 --- a/tests/Database/SeedCommandTest.php +++ b/tests/Database/SeedCommandTest.php @@ -7,7 +7,7 @@ use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Database\ConnectionResolverInterface; use Illuminate\Database\Console\Seeds\SeedCommand; -use Illuminate\Database\Console\Seeds\WithoutEvents; +use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Seeder; use Illuminate\Events\NullDispatcher; @@ -51,16 +51,16 @@ public function testHandle() $container->shouldHaveReceived('call')->with([$command, 'handle']); } - public function testWithoutEvents() + public function testWithoutModelEvents() { $input = new ArrayInput([ '--force' => true, '--database' => 'sqlite', - '--class' => UserWithoutEventsSeeder::class, + '--class' => UserWithoutModelEventsSeeder::class, ]); $output = new NullOutput; - $instance = new UserWithoutEventsSeeder(); + $instance = new UserWithoutModelEventsSeeder(); $seeder = m::mock($instance); $seeder->shouldReceive('setContainer')->once()->andReturnSelf(); @@ -73,7 +73,7 @@ public function testWithoutEvents() $container = m::mock(Container::class); $container->shouldReceive('call'); $container->shouldReceive('environment')->once()->andReturn('testing'); - $container->shouldReceive('make')->with(UserWithoutEventsSeeder::class)->andReturn($seeder); + $container->shouldReceive('make')->with(UserWithoutModelEventsSeeder::class)->andReturn($seeder); $container->shouldReceive('make')->with(OutputStyle::class, m::any())->andReturn( new OutputStyle($input, $output) ); @@ -100,9 +100,9 @@ protected function tearDown(): void } } -class UserWithoutEventsSeeder extends Seeder +class UserWithoutModelEventsSeeder extends Seeder { - use WithoutEvents; + use WithoutModelEvents; public function run() { From f4fbf54db61d66bfd8012fc3b5a64e7a4761d10c Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Tue, 7 Dec 2021 17:07:58 +0000 Subject: [PATCH 3/3] Adjusts comment Co-authored-by: James Brooks --- src/Illuminate/Database/Console/Seeds/WithoutModelEvents.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Console/Seeds/WithoutModelEvents.php b/src/Illuminate/Database/Console/Seeds/WithoutModelEvents.php index 81f12e10a11f..acd9ec3f207b 100644 --- a/src/Illuminate/Database/Console/Seeds/WithoutModelEvents.php +++ b/src/Illuminate/Database/Console/Seeds/WithoutModelEvents.php @@ -7,7 +7,7 @@ trait WithoutModelEvents { /** - * Prevent model event handles from being executed by the given callback. + * Prevent model events from being dispatched by the given callback. * * @param callable $callback * @return callable