From 773ee897183b5a41fa32db1b759b5122e546fd58 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Fri, 31 Oct 2025 15:39:35 -0400 Subject: [PATCH 01/11] with cached routes --- src/Illuminate/Foundation/Application.php | 4 ++- .../Providers/RouteServiceProvider.php | 1 + .../Foundation/Testing/WithCachedRoutes.php | 31 +++++++++++++++++++ .../Foundation/FoundationApplicationTest.php | 25 +++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/Illuminate/Foundation/Testing/WithCachedRoutes.php diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index ef99215b2441..7be28d4424c1 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -1322,7 +1322,9 @@ public function getCachedConfigPath() */ public function routesAreCached() { - return $this['files']->exists($this->getCachedRoutesPath()); + return ($this->bound('routes.cached') && + $this->make('routes.cached') === true) || + $this['files']->exists($this->getCachedRoutesPath()); } /** diff --git a/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php b/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php index ad881b371193..d4d244ecab97 100644 --- a/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php +++ b/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php @@ -53,6 +53,7 @@ public function register() $this->booted(function () { $this->setRootControllerNamespace(); + // if ($this->routesAreCached()) { $this->loadCachedRoutes(); } else { diff --git a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php new file mode 100644 index 000000000000..3ef69b36dbca --- /dev/null +++ b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php @@ -0,0 +1,31 @@ +app->instance('routes.cached', true); + + if ((self::$cachedRoutes ?? null) === null) { + $routes = $this->app['router']->getRoutes(); + $routes->refreshNameLookups(); + $routes->refreshActionLookups(); + self::$cachedRoutes = $routes; + } + + RouteServiceProvider::loadCachedRoutesUsing( + static fn () => app('router')->setCompiledRoutes(self::$cachedRoutes) + ); + } + + protected function tearDownWithCachedRoutes(): void + { + RouteServiceProvider::loadCachedRoutesUsing(null); + } +} diff --git a/tests/Foundation/FoundationApplicationTest.php b/tests/Foundation/FoundationApplicationTest.php index d403e4a0702a..1c2983acf266 100755 --- a/tests/Foundation/FoundationApplicationTest.php +++ b/tests/Foundation/FoundationApplicationTest.php @@ -9,6 +9,7 @@ use Illuminate\Foundation\Events\LocaleUpdated; use Illuminate\Support\ServiceProvider; use Mockery as m; +use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; use stdClass; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -609,6 +610,30 @@ public function testAbortAcceptsHeaders() $this->assertSame(['X-FOO' => 'BAR'], $exception->getHeaders()); } } + + public function test_routes_are_cached() + { + $app = new Application(); + $app->instance('routes.cached', true); + $this->assertTrue($app->routesAreCached()); + } + + public function test_routes_are_not_cached_by_instance_falls_back_to_file() + { + $app = new Application(); + $files = new class { + public string $pathRequested; + public function exists(string $path): bool + { + $this->pathRequested = $path; + return false; + } + }; + $app->instance('files', $files); + + $this->assertFalse($app->routesAreCached()); + $this->assertStringContainsString('routes-v7.php', $files->pathRequested); + } } class ApplicationBasicServiceProviderStub extends ServiceProvider From cd4000c6c9ef52badce4e1167d5a7bb527ef825f Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Fri, 31 Oct 2025 15:54:54 -0400 Subject: [PATCH 02/11] clean up --- .../Foundation/Support/Providers/RouteServiceProvider.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php b/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php index d4d244ecab97..ad881b371193 100644 --- a/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php +++ b/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php @@ -53,7 +53,6 @@ public function register() $this->booted(function () { $this->setRootControllerNamespace(); - // if ($this->routesAreCached()) { $this->loadCachedRoutes(); } else { From e1ac69c0779bd2a1f81a8eebc11b43d94a1e2cb2 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Fri, 31 Oct 2025 15:57:19 -0400 Subject: [PATCH 03/11] clean up --- src/Illuminate/Foundation/Testing/WithCachedRoutes.php | 4 ++-- tests/Foundation/FoundationApplicationTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php index 3ef69b36dbca..bbd639863d34 100644 --- a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php +++ b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php @@ -10,8 +10,6 @@ trait WithCachedRoutes protected function setUpWithCachedRoutes(): void { - $this->app->instance('routes.cached', true); - if ((self::$cachedRoutes ?? null) === null) { $routes = $this->app['router']->getRoutes(); $routes->refreshNameLookups(); @@ -19,6 +17,8 @@ protected function setUpWithCachedRoutes(): void self::$cachedRoutes = $routes; } + $this->app->instance('routes.cached', true); + RouteServiceProvider::loadCachedRoutesUsing( static fn () => app('router')->setCompiledRoutes(self::$cachedRoutes) ); diff --git a/tests/Foundation/FoundationApplicationTest.php b/tests/Foundation/FoundationApplicationTest.php index 1c2983acf266..86c34b542f93 100755 --- a/tests/Foundation/FoundationApplicationTest.php +++ b/tests/Foundation/FoundationApplicationTest.php @@ -9,7 +9,6 @@ use Illuminate\Foundation\Events\LocaleUpdated; use Illuminate\Support\ServiceProvider; use Mockery as m; -use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; use stdClass; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -621,7 +620,8 @@ public function test_routes_are_cached() public function test_routes_are_not_cached_by_instance_falls_back_to_file() { $app = new Application(); - $files = new class { + $files = new class + { public string $pathRequested; public function exists(string $path): bool { From 0490096ecbde8bb6682c4ec7e7ce8e9343f9b71a Mon Sep 17 00:00:00 2001 From: Luke Kuzmish <42181698+cosmastech@users.noreply.github.com> Date: Sat, 1 Nov 2025 07:53:05 -0400 Subject: [PATCH 04/11] try to guess how Taylor would format it --- src/Illuminate/Foundation/Application.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index 7be28d4424c1..afc89a11cc00 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -1322,9 +1322,9 @@ public function getCachedConfigPath() */ public function routesAreCached() { - return ($this->bound('routes.cached') && - $this->make('routes.cached') === true) || - $this['files']->exists($this->getCachedRoutesPath()); + return ($this->bound('routes.cached') + && $this->make('routes.cached') === true) + || $this['files']->exists($this->getCachedRoutesPath()); } /** From f4735581646264ff97392617ec994c2d220d35a9 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish <42181698+cosmastech@users.noreply.github.com> Date: Sat, 1 Nov 2025 10:45:55 -0400 Subject: [PATCH 05/11] compile to array --- src/Illuminate/Foundation/Testing/WithCachedRoutes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php index bbd639863d34..08d101533478 100644 --- a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php +++ b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php @@ -14,7 +14,7 @@ protected function setUpWithCachedRoutes(): void $routes = $this->app['router']->getRoutes(); $routes->refreshNameLookups(); $routes->refreshActionLookups(); - self::$cachedRoutes = $routes; + self::$cachedRoutes = $routes->compile(); } $this->app->instance('routes.cached', true); From b606fdd1d2663612f4b4de42199405863d5ef918 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish <42181698+cosmastech@users.noreply.github.com> Date: Sat, 1 Nov 2025 10:46:55 -0400 Subject: [PATCH 06/11] Update WithCachedRoutes.php --- src/Illuminate/Foundation/Testing/WithCachedRoutes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php index 08d101533478..9e4cfee1ba04 100644 --- a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php +++ b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php @@ -6,7 +6,7 @@ trait WithCachedRoutes { - protected static array $cachedRoutes = []; + protected static array $cachedRoutes; protected function setUpWithCachedRoutes(): void { From 45bc684f1c917f1b3c1de18336e120ce01c9e96f Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sat, 1 Nov 2025 11:42:37 -0400 Subject: [PATCH 07/11] I think this is better --- .../Foundation/Testing/CachedState.php | 8 +++++ .../Foundation/Testing/TestCase.php | 4 +++ .../Foundation/Testing/WithCachedRoutes.php | 30 +++++++++++++------ 3 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 src/Illuminate/Foundation/Testing/CachedState.php diff --git a/src/Illuminate/Foundation/Testing/CachedState.php b/src/Illuminate/Foundation/Testing/CachedState.php new file mode 100644 index 000000000000..79cd3e0e906b --- /dev/null +++ b/src/Illuminate/Foundation/Testing/CachedState.php @@ -0,0 +1,8 @@ +booting(fn () => $this->markRoutesCached($app)); + } + $app->make(Kernel::class)->bootstrap(); return $app; diff --git a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php index 9e4cfee1ba04..4dcfad9f51c5 100644 --- a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php +++ b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php @@ -2,30 +2,42 @@ namespace Illuminate\Foundation\Testing; +use Illuminate\Foundation\Application; use Illuminate\Foundation\Support\Providers\RouteServiceProvider; trait WithCachedRoutes { - protected static array $cachedRoutes; - + /** + * After creating the routes once, we can cache them for the remaining tests. + * + * @return void + */ protected function setUpWithCachedRoutes(): void { - if ((self::$cachedRoutes ?? null) === null) { + // If we haven't stored the cached routes yet, then let's store them + // once so we can use them in the remaining tests. + if ((CachedState::$cachedRoutes ?? null) === null) { $routes = $this->app['router']->getRoutes(); $routes->refreshNameLookups(); $routes->refreshActionLookups(); - self::$cachedRoutes = $routes->compile(); + CachedState::$cachedRoutes = $routes->compile(); } - $this->app->instance('routes.cached', true); - - RouteServiceProvider::loadCachedRoutesUsing( - static fn () => app('router')->setCompiledRoutes(self::$cachedRoutes) - ); + $this->markRoutesCached($this->app); } protected function tearDownWithCachedRoutes(): void { RouteServiceProvider::loadCachedRoutesUsing(null); } + + protected function markRoutesCached(Application $app): void + { + $app->instance('routes.cached', true); + + RouteServiceProvider::loadCachedRoutesUsing( + static fn () => app('router')->setCompiledRoutes(CachedState::$cachedRoutes) + ); + } + } From 33a4800edf4964997b8b5c8faa8302f74062e509 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sat, 1 Nov 2025 11:47:19 -0400 Subject: [PATCH 08/11] comments --- src/Illuminate/Foundation/Testing/WithCachedRoutes.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php index 4dcfad9f51c5..dd0cfe6723af 100644 --- a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php +++ b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php @@ -26,11 +26,20 @@ protected function setUpWithCachedRoutes(): void $this->markRoutesCached($this->app); } + /** + * Reset the route service provider so it's not defaulting to loading cached routes. + * Helpful if some of the tests in the suite apply this trait while others do not. + * + * @return void + */ protected function tearDownWithCachedRoutes(): void { RouteServiceProvider::loadCachedRoutesUsing(null); } + /** + * Inform the container to treat routes as cached. + */ protected function markRoutesCached(Application $app): void { $app->instance('routes.cached', true); From 3c84de0f6bdb95d1d4e6368573d51155ae4e32cc Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sat, 1 Nov 2025 11:48:44 -0400 Subject: [PATCH 09/11] lighter check first --- src/Illuminate/Foundation/Testing/TestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Foundation/Testing/TestCase.php b/src/Illuminate/Foundation/Testing/TestCase.php index 54468e5296fe..f2f5f296db55 100644 --- a/src/Illuminate/Foundation/Testing/TestCase.php +++ b/src/Illuminate/Foundation/Testing/TestCase.php @@ -29,7 +29,7 @@ public function createApplication() { $app = require Application::inferBasePath().'/bootstrap/app.php'; - if (in_array(WithCachedRoutes::class, class_uses_recursive(self::class)) && isset(CachedState::$cachedRoutes)) { + if (isset(CachedState::$cachedRoutes) && in_array(WithCachedRoutes::class, class_uses_recursive(self::class))) { $app->booting(fn () => $this->markRoutesCached($app)); } From d5024c2bcf8513b25110df178c44a4bd7d7f2965 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish Date: Sat, 1 Nov 2025 11:57:59 -0400 Subject: [PATCH 10/11] static --- src/Illuminate/Foundation/Testing/TestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Foundation/Testing/TestCase.php b/src/Illuminate/Foundation/Testing/TestCase.php index f2f5f296db55..3394092581df 100644 --- a/src/Illuminate/Foundation/Testing/TestCase.php +++ b/src/Illuminate/Foundation/Testing/TestCase.php @@ -29,7 +29,7 @@ public function createApplication() { $app = require Application::inferBasePath().'/bootstrap/app.php'; - if (isset(CachedState::$cachedRoutes) && in_array(WithCachedRoutes::class, class_uses_recursive(self::class))) { + if (isset(CachedState::$cachedRoutes) && in_array(WithCachedRoutes::class, class_uses_recursive(static::class))) { $app->booting(fn () => $this->markRoutesCached($app)); } From ea9a089fc49a1415722ea2f2fdad03316a3b4ab0 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Mon, 3 Nov 2025 16:21:45 -0600 Subject: [PATCH 11/11] formatting --- src/Illuminate/Foundation/Application.php | 5 ++--- src/Illuminate/Foundation/Testing/TestCase.php | 3 ++- src/Illuminate/Foundation/Testing/WithCachedRoutes.php | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index afc89a11cc00..c8680628b45b 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -1322,9 +1322,8 @@ public function getCachedConfigPath() */ public function routesAreCached() { - return ($this->bound('routes.cached') - && $this->make('routes.cached') === true) - || $this['files']->exists($this->getCachedRoutesPath()); + return ($this->bound('routes.cached') && $this->make('routes.cached') === true) || + $this['files']->exists($this->getCachedRoutesPath()); } /** diff --git a/src/Illuminate/Foundation/Testing/TestCase.php b/src/Illuminate/Foundation/Testing/TestCase.php index 3394092581df..dbf8bbd1a4ac 100644 --- a/src/Illuminate/Foundation/Testing/TestCase.php +++ b/src/Illuminate/Foundation/Testing/TestCase.php @@ -29,7 +29,8 @@ public function createApplication() { $app = require Application::inferBasePath().'/bootstrap/app.php'; - if (isset(CachedState::$cachedRoutes) && in_array(WithCachedRoutes::class, class_uses_recursive(static::class))) { + if (isset(CachedState::$cachedRoutes) && + in_array(WithCachedRoutes::class, class_uses_recursive(static::class))) { $app->booting(fn () => $this->markRoutesCached($app)); } diff --git a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php index dd0cfe6723af..05b57052ef4d 100644 --- a/src/Illuminate/Foundation/Testing/WithCachedRoutes.php +++ b/src/Illuminate/Foundation/Testing/WithCachedRoutes.php @@ -14,12 +14,12 @@ trait WithCachedRoutes */ protected function setUpWithCachedRoutes(): void { - // If we haven't stored the cached routes yet, then let's store them - // once so we can use them in the remaining tests. if ((CachedState::$cachedRoutes ?? null) === null) { $routes = $this->app['router']->getRoutes(); + $routes->refreshNameLookups(); $routes->refreshActionLookups(); + CachedState::$cachedRoutes = $routes->compile(); } @@ -28,7 +28,8 @@ protected function setUpWithCachedRoutes(): void /** * Reset the route service provider so it's not defaulting to loading cached routes. - * Helpful if some of the tests in the suite apply this trait while others do not. + * + * This is helpful if some of the tests in the suite apply this trait while others do not. * * @return void */