Skip to content

Commit cafe1ac

Browse files
[12.x] Introduce WithCachedConfig testing trait (#57663)
* with cached routes * clean up * clean up * try to guess how Taylor would format it * compile to array * Update WithCachedRoutes.php * I think this is better * comments * lighter check first * static * formatting * wip * WithCachedConfig * thanks static analysis * Update TestCase.php * Update WithCachedConfig.php * Update TestCase.php * formatting * Update WithCachedConfig.php --------- Co-authored-by: Taylor Otwell <taylor@laravel.com>
1 parent f1649db commit cafe1ac

File tree

5 files changed

+88
-5
lines changed

5 files changed

+88
-5
lines changed

src/Illuminate/Foundation/Bootstrap/LoadConfiguration.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Illuminate\Foundation\Bootstrap;
44

5+
use Closure;
56
use Illuminate\Config\Repository;
67
use Illuminate\Contracts\Config\Repository as RepositoryContract;
78
use Illuminate\Contracts\Foundation\Application;
@@ -11,6 +12,13 @@
1112

1213
class LoadConfiguration
1314
{
15+
/**
16+
* The closure that resolves the permanent, static configuration if applicable.
17+
*
18+
* @var (Closure(Application): array<array-key, mixed>)|null
19+
*/
20+
protected static ?Closure $alwaysUseConfig = null;
21+
1422
/**
1523
* Bootstrap the given application.
1624
*
@@ -24,18 +32,26 @@ public function bootstrap(Application $app)
2432
// First we will see if we have a cache configuration file. If we do, we'll load
2533
// the configuration items from that file so that it is very quick. Otherwise
2634
// we will need to spin through every configuration file and load them all.
27-
if (file_exists($cached = $app->getCachedConfigPath())) {
35+
$loadedFromCache = false;
36+
37+
if (self::$alwaysUseConfig !== null) {
38+
$items = $app->call(self::$alwaysUseConfig);
39+
40+
$loadedFromCache = true;
41+
} elseif (file_exists($cached = $app->getCachedConfigPath())) {
2842
$items = require $cached;
2943

30-
$app->instance('config_loaded_from_cache', $loadedFromCache = true);
44+
$loadedFromCache = true;
3145
}
3246

47+
$app->instance('config_loaded_from_cache', $loadedFromCache);
48+
3349
// Next we will spin through all of the configuration files in the configuration
3450
// directory and load each one into the repository. This will make all of the
3551
// options available to the developer for use in various parts of this app.
3652
$app->instance('config', $config = new Repository($items));
3753

38-
if (! isset($loadedFromCache)) {
54+
if (! $loadedFromCache) {
3955
$this->loadConfigurationFiles($app, $config);
4056
}
4157

@@ -195,4 +211,15 @@ protected function getBaseConfiguration()
195211

196212
return $config;
197213
}
214+
215+
/**
216+
* Set a callback to return the permanent, static configuration values.
217+
*
218+
* @param (Closure(Application): array<array-key, mixed>)|null $alwaysUseConfig
219+
* @return void
220+
*/
221+
public static function alwaysUse(?Closure $alwaysUseConfig): void
222+
{
223+
static::$alwaysUseConfig = $alwaysUseConfig;
224+
}
198225
}

src/Illuminate/Foundation/Testing/CachedState.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
class CachedState
66
{
77
public static array $cachedRoutes;
8+
public static array $cachedConfig;
89
}

src/Illuminate/Foundation/Testing/Concerns/InteractsWithTestCaseLifecycle.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ protected function tearDownTheTestEnvironment(): void
203203
*/
204204
protected function setUpTraits()
205205
{
206-
$uses = array_flip(class_uses_recursive(static::class));
206+
$uses = $this->traitsUsedByTest ?? array_flip(class_uses_recursive(static::class));
207207

208208
if (isset($uses[RefreshDatabase::class])) {
209209
$this->refreshDatabase();

src/Illuminate/Foundation/Testing/TestCase.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ abstract class TestCase extends BaseTestCase
2020
Concerns\InteractsWithTestCaseLifecycle,
2121
Concerns\InteractsWithViews;
2222

23+
/**
24+
* The list of trait that this test uses, fetched recursively.
25+
*
26+
* @var array<class-string, int>
27+
*/
28+
protected array $traitsUsedByTest;
29+
2330
/**
2431
* Creates the application.
2532
*
@@ -29,8 +36,15 @@ public function createApplication()
2936
{
3037
$app = require Application::inferBasePath().'/bootstrap/app.php';
3138

39+
$this->traitsUsedByTest = array_flip(class_uses_recursive(static::class));
40+
41+
if (isset(CachedState::$cachedConfig) &&
42+
isset($this->traitsUsedByTest[WithCachedConfig::class])) {
43+
$this->markConfigCached($app);
44+
}
45+
3246
if (isset(CachedState::$cachedRoutes) &&
33-
in_array(WithCachedRoutes::class, class_uses_recursive(static::class))) {
47+
isset($this->traitsUsedByTest[WithCachedRoutes::class])) {
3448
$app->booting(fn () => $this->markRoutesCached($app));
3549
}
3650

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Illuminate\Foundation\Testing;
4+
5+
use Illuminate\Foundation\Application;
6+
use Illuminate\Foundation\Bootstrap\LoadConfiguration;
7+
8+
trait WithCachedConfig
9+
{
10+
/**
11+
* After resolving the configuration once, we can cache it for the remaining tests.
12+
*/
13+
protected function setUpWithCachedConfig(): void
14+
{
15+
if ((CachedState::$cachedConfig ?? null) === null) {
16+
CachedState::$cachedConfig = $this->app->make('config')->all();
17+
}
18+
19+
$this->markConfigCached($this->app);
20+
}
21+
22+
/**
23+
* Reset the cached configuration.
24+
*
25+
* This is helpful if some of the tests in the suite apply this trait while others do not.
26+
*/
27+
protected function tearDownWithCachedConfig(): void
28+
{
29+
LoadConfiguration::setAlwaysUseConfig(null);
30+
}
31+
32+
/**
33+
* Inform the container that the configuration is cached.
34+
*/
35+
protected function markConfigCached(Application $app): void
36+
{
37+
$app->instance('config_loaded_from_cache', true); // I'm not sure this is actually needed
38+
39+
LoadConfiguration::alwaysUse(static fn () => CachedState::$cachedConfig);
40+
}
41+
}

0 commit comments

Comments
 (0)