Laravel 9.28 released with console signal traps, view data assertions for TestView, redirector getIntendedUrl method, prevent $fillable’s prevently silently discarding fills, added macroable trait, and more including the fixes. Let’s check these updates in detail here:
1. View data assertions to TestView:
Andrew Brown contributed these TestView assertion methods followings to assert view data, which helps to test the workings of the component, and not reliant on the data displayed on the view side of things.
- assertViewHas()
- assertViewHasAll()
- assertViewMissing()
View
$view = $this->view('welcome', [ 'name' => 'John', 'email' => 'john@email.com' ]);
i. assertViewHas() Method:
$view->assertViewHas('name'); // true $view->assertViewHas('name', 'John'); // false
ii. assertViewHasAll() Method:
$view->assertViewHasAll(['name', 'email']); // true $view->assertViewHasAll([ 'name' => 'John', 'email' => 'john@email.com', ]); // true
iii. assertViewMissing() Method:
$view->assertViewMissing('deo'); // true $view->assertViewMissing('name'); // false
Now, you can check these class codes in detail here.
Source File Edits: src/Illuminate/Testing/TestView.php
assertViewHas()
/** * Assert that the response view has a given piece of bound data. * * @param string|array $key * @param mixed $value * @return $this */ public function assertViewHas($key, $value = null) { if (is_array($key)) { return $this->assertViewHasAll($key); } if (is_null($value)) { PHPUnit::assertTrue(Arr::has($this->view->gatherData(), $key)); } elseif ($value instanceof Closure) { PHPUnit::assertTrue($value(Arr::get($this->view->gatherData(), $key))); } elseif ($value instanceof Model) { PHPUnit::assertTrue($value->is(Arr::get($this->view->gatherData(), $key))); } elseif ($value instanceof Collection) { $actual = Arr::get($this->view->gatherData(), $key); PHPUnit::assertInstanceOf(Collection::class, $actual); PHPUnit::assertSameSize($value, $actual); $value->each(fn ($item, $index) => PHPUnit::assertTrue($actual->get($index)->is($item))); } else { PHPUnit::assertEquals($value, Arr::get($this->view->gatherData(), $key)); } return $this; }
assertViewHasAll()
/** * Assert that the response view has a given list of bound data. * * @param array $bindings * @return $this */ public function assertViewHasAll(array $bindings) { foreach ($bindings as $key => $value) { if (is_int($key)) { $this->assertViewHas($value); } else { $this->assertViewHas($key, $value); } } return $this; }
assertViewMissing()
/** * Assert that the response view is missing a piece of bound data. * * @param string $key * @return $this */ public function assertViewMissing($key) { PHPUnit::assertFalse(Arr::has($this->view->gatherData(), $key)); return $this; }
2. Get Intended Url Session method from redirector:
D. Nagy Gergő contributed to adding the getIntendedUrl method to the Redirector class. It get and set the intended redirect URL from the session.
$redirect->setIntendedUrl('https://website.com/foo'); $redirect->getIntendedUrl(); // http://website.com/foo
Source File Edits: src/Illuminate/Testing/TestView.php
- setIntendedUrl()
/** * Set the "intended" URL in the session. * * @param string $url * @return $this */ public function setIntendedUrl($url) { $this->session->put('url.intended', $url); return $this; }
- getIntendedUrl()
/** * Get the "intended" URL from the session. * * @return string|null */ public function getIntendedUrl() { return $this->session->get('url.intended'); }
3. Eloquent mode to prevent silently discarding fills for attributes
Ralph J. Smit contributed to prevent non-fillable attributes from being silently discarded. It works more efficiently with the $fillable fields. This would be very useful to prevent bugs in local or non-production environments where sometimes we forget to add an attribute to $fillable. But you could also use the environment to only trigger an exception.
Model::preventSilentlyDiscardingAttributes(); // Only prevent in non-production environments Model::preventSilentlyDiscardingAttributes( ! app()->isProduction() );
Source File Edits: src/Illuminate/Database/Eloquent/Model.php
/** * Indicates if an exception should be thrown instead of silently discarding non-fillable attributes. * * @var bool */ protected static $modelsShouldPreventSilentlyDiscardingAttributes = false; .... /** * Prevent non-fillable attributes from being silently discarded. * * @param bool $value * @return void */ public static function preventSilentlyDiscardingAttributes($value = true) { static::$modelsShouldPreventSilentlyDiscardingAttributes = $value; }
4. assertOk Command for Testing:
Nuno Maduro contributed to adding assertOk() method as an alias of assertExitCode(0), which helps to write the php artisan test commands.
it('can run', function () { $this->artisan('inspire')->assertOk(); });
Note that, this combines well with the HTTP layer regarding testing, as we we already have an assertOk()
there:
$this->get('/')->assertOk();
Source File Edits: src/Illuminate/Testing/PendingCommand.php
/** * Assert that the command has the success exit code. * * @return $this */ public function assertOk() { return $this->assertSuccessful(); }
5. Make Application macroable:
Ralph J. Smit contributed to adding the macroable trait to the Application instance. This allows you to add handy macros (e.g. application environment) checks to the application instance.
App::macro('runningDuskTests', function () { return $this->environment('dusk'); });
6. Introducing Signal Traps:
Nuno Maduro contributed to introducing the signal traps that allow you to catch process signals and execute code when they occur. With this technique, you can perform any clean-up tasks / or potentially revert operations when an Artisan command is ended unexpectedly.
Artisan::command('export:sales', function () { $this->continue = true; $this->trap(SIGINT, function () { // End the command's job gracefully ... // E.g: clean created files, etc ... $this->continue = false; }); while($this->continue) { dump('Exporting batch of sales...'); } });
Multiple signal Traps:
// trap multiple signals $this->trap([SIGTERM, SIGQUIT], function ($signal) { $this->running = false; dump($signal); // SIGTERM or SIGQUIT });
7. Support Enumerable objects to Stringable methods:
Erik Gaal contributed the ability to pass enumerable objects such as Collection to Stringable helper functions that already accept array as a parameter.
Before:
/** @var Collection<array-key, string> $months */ $months = months(); Str::remove($months->toArray(), $someString);
After: we can skip the ->toArray
call.
/** @var Collection<array-key, string> $months */ $months = months(); Str::remove($months, $someString);
Now the list of the Laravel 9.28 Released updates:
Added
- Added view data assertions to TestView (#43923)
- Added
Illuminate/Routing/Redirector::getIntendedUrl()
(#43938) - Added Eloquent mode to prevent prevently silently discarding fills for attributes not in $fillable (#43893)
- Added
Illuminate/Testing/PendingCommand::assertOk()
(#43968) - Make Application macroable (#43966)
- Introducing Signal Traps (#43933)
- Allow registering instances of commands (#43986)
- Support Enumerable in Stringable (#44012)
Fixed
- Fixed RoueGroup::merge to format merged prefixes correctly. (#44011)
- Fixes providesTemporaryUrls on AwsS3V3Adapter (#44009)
- Fix ordering of stylesheets when using @Vite (#43962)
Changed
- Allow invokable rules to specify custom messsages (#43925)
- Support objects like GMP for custom Model casts (#43959)
- Default 404 message on denyAsNotFound (#43901)
- Changed
Illuminate/Container/Container::resolvePrimitive()
for isVariadic() (#43985) - Allow validator messages to use nested arrays (#43981)
- Ensure freezeUuids always resets UUID creation after exception in callback (#44018)
To get to know more about Laravel, you can check these articles too.
You can check the latest release tech articles like Laravel 9.28 Released here.