• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

orchestral / testbench-core / 17228981544

26 Aug 2025 05:36AM UTC coverage: 92.525% (-0.05%) from 92.577%
17228981544

push

github

crynobone
fix tests

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

1510 of 1632 relevant lines covered (92.52%)

75.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.8
/src/Foundation/Application.php
1
<?php
2

3
namespace Orchestra\Testbench\Foundation;
4

5
use Illuminate\Console\Application as Artisan;
6
use Illuminate\Console\Scheduling\ScheduleListCommand;
7
use Illuminate\Console\Signals;
8
use Illuminate\Database\Eloquent\Factories\Factory;
9
use Illuminate\Database\Eloquent\Model;
10
use Illuminate\Database\Migrations\Migrator;
11
use Illuminate\Database\Schema\Builder as SchemaBuilder;
12
use Illuminate\Foundation\Bootstrap\HandleExceptions;
13
use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables;
14
use Illuminate\Foundation\Bootstrap\RegisterProviders;
15
use Illuminate\Foundation\Console\AboutCommand;
16
use Illuminate\Foundation\Console\ChannelListCommand;
17
use Illuminate\Foundation\Console\RouteListCommand;
18
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
19
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance;
20
use Illuminate\Foundation\Http\Middleware\TrimStrings;
21
use Illuminate\Foundation\Http\Middleware\ValidateCsrfToken;
22
use Illuminate\Http\Middleware\TrustHosts;
23
use Illuminate\Http\Middleware\TrustProxies;
24
use Illuminate\Http\Resources\Json\JsonResource;
25
use Illuminate\Mail\Markdown;
26
use Illuminate\Queue\Console\WorkCommand;
27
use Illuminate\Queue\Queue;
28
use Illuminate\Routing\Middleware\ThrottleRequests;
29
use Illuminate\Support\Arr;
30
use Illuminate\Support\EncodedHtmlString;
31
use Illuminate\Support\Once;
32
use Illuminate\Support\Sleep;
33
use Illuminate\View\Component;
34
use Orchestra\Testbench\Concerns\CreatesApplication;
35
use Orchestra\Testbench\Console\Commander;
36
use Orchestra\Testbench\Contracts\Config as ConfigContract;
37
use Orchestra\Testbench\Workbench\Workbench;
38

39
use function Orchestra\Sidekick\join_paths;
40
use function Orchestra\Sidekick\laravel_version_compare;
41

42
/**
43
 * @api
44
 *
45
 * @phpstan-import-type TExtraConfig from \Orchestra\Testbench\Foundation\Config
46
 * @phpstan-import-type TOptionalExtraConfig from \Orchestra\Testbench\Foundation\Config
47
 *
48
 * @phpstan-type TConfig array{
49
 *   extra?: TOptionalExtraConfig,
50
 *   load_environment_variables?: bool,
51
 *   enabled_package_discoveries?: bool
52
 * }
53
 */
54
class Application
55
{
56
    use CreatesApplication {
57
        resolveApplicationResolvingCallback as protected resolveApplicationResolvingCallbackFromTrait;
58
        resolveApplicationConfiguration as protected resolveApplicationConfigurationFromTrait;
59
    }
60

61
    /**
62
     * The Illuminate application instance.
63
     *
64
     * @var \Illuminate\Foundation\Application|null
65
     */
66
    protected $app;
67

68
    /**
69
     * List of configurations.
70
     *
71
     * @var array<string, mixed>
72
     *
73
     * @phpstan-var TExtraConfig
74
     */
75
    protected array $config = [
76
        'env' => [],
77
        'providers' => [],
78
        'dont-discover' => [],
79
        'bootstrappers' => [],
80
    ];
81

82
    /**
83
     * The application resolving callback.
84
     *
85
     * @var (callable(\Illuminate\Foundation\Application):(void))|null
86
     */
87
    protected $resolvingCallback;
88

89
    /**
90
     * Load Environment variables.
91
     *
92
     * @var bool
93
     */
94
    protected bool $loadEnvironmentVariables = false;
95

96
    /**
97
     * Create new application resolver.
98
     *
99
     * @param  string|null  $basePath
100
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
101
     */
102
    public function __construct(
103
        protected readonly ?string $basePath = null,
104
        ?callable $resolvingCallback = null
105
    ) {
106
        $this->resolvingCallback = $resolvingCallback;
15✔
107
    }
108

109
    /**
110
     * Create new application resolver.
111
     *
112
     * @param  string|null  $basePath
113
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
114
     * @param  array<string, mixed>  $options
115
     *
116
     * @phpstan-param TConfig  $options
117
     *
118
     * @return static
119
     */
120
    public static function make(?string $basePath = null, ?callable $resolvingCallback = null, array $options = [])
121
    {
122
        return (new static($basePath, $resolvingCallback))->configure($options);
13✔
123
    }
124

125
    /**
126
     * Create new application resolver from configuration file.
127
     *
128
     * @param  \Orchestra\Testbench\Contracts\Config  $config
129
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
130
     * @param  array<string, mixed>  $options
131
     *
132
     * @phpstan-param TConfig  $options
133
     *
134
     * @return static
135
     */
136
    public static function makeFromConfig(ConfigContract $config, ?callable $resolvingCallback = null, array $options = [])
137
    {
138
        $basePath = $config['laravel'] ?? static::applicationBasePath();
1✔
139

140
        return (new static($config['laravel'], $resolvingCallback))->configure(array_merge($options, [
1✔
141
            'load_environment_variables' => is_file("{$basePath}/.env"),
1✔
142
            'extra' => $config->getExtraAttributes(),
1✔
143
        ]));
1✔
144
    }
145

146
    /**
147
     * Create symlink to vendor path via new application instance.
148
     *
149
     * @param  string|null  $basePath
150
     * @param  string  $workingVendorPath
151
     * @return \Illuminate\Foundation\Application
152
     *
153
     * @codeCoverageIgnore
154
     */
155
    public static function createVendorSymlink(?string $basePath, string $workingVendorPath)
156
    {
157
        $app = static::create(basePath: $basePath, options: ['extra' => ['dont-discover' => ['*']]]);
158

159
        (new Actions\CreateVendorSymlink($workingVendorPath))->handle($app);
160

161
        return $app;
162
    }
163

164
    /**
165
     * Delete symlink to vendor path via new application instance.
166
     *
167
     * @param  string|null  $basePath
168
     * @return \Illuminate\Foundation\Application
169
     *
170
     * @codeCoverageIgnore
171
     */
172
    public static function deleteVendorSymlink(?string $basePath)
173
    {
174
        $app = static::create(basePath: $basePath, options: ['extra' => ['dont-discover' => ['*']]]);
175

176
        (new Actions\DeleteVendorSymlink)->handle($app);
177

178
        return $app;
179
    }
180

181
    /**
182
     * Create new application instance.
183
     *
184
     * @param  string|null  $basePath
185
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
186
     * @param  array<string, mixed>  $options
187
     *
188
     * @phpstan-param TConfig  $options
189
     *
190
     * @return \Illuminate\Foundation\Application
191
     */
192
    public static function create(?string $basePath = null, ?callable $resolvingCallback = null, array $options = [])
193
    {
194
        return static::make($basePath, $resolvingCallback, $options)->createApplication();
10✔
195
    }
196

197
    /**
198
     * Create new application instance from configuration file.
199
     *
200
     * @param  \Orchestra\Testbench\Contracts\Config  $config
201
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
202
     * @param  array<string, mixed>  $options
203
     *
204
     * @phpstan-param TConfig  $options
205
     *
206
     * @return \Illuminate\Foundation\Application
207
     */
208
    public static function createFromConfig(ConfigContract $config, ?callable $resolvingCallback = null, array $options = [])
209
    {
210
        return static::makeFromConfig($config, $resolvingCallback, $options)->createApplication();
1✔
211
    }
212

213
    /**
214
     * Flush the application states.
215
     *
216
     * @param  \Orchestra\Testbench\Console\Commander|\Orchestra\Testbench\PHPUnit\TestCase  $instance
217
     * @return void
218
     */
219
    public static function flushState(object $instance): void
220
    {
221
        AboutCommand::flushState();
192✔
222
        Artisan::forgetBootstrappers();
192✔
223
        ChannelListCommand::resolveTerminalWidthUsing(null);
192✔
224
        Component::flushCache();
192✔
225
        Component::forgetComponentsResolver();
192✔
226
        Component::forgetFactory();
192✔
227
        ConvertEmptyStringsToNull::flushState();
192✔
228

229
        if (class_exists(EncodedHtmlString::class)) {
192✔
230
            EncodedHtmlString::flushState();
192✔
231
        }
232

233
        Factory::flushState();
192✔
234

235
        if (! $instance instanceof Commander) {
192✔
236
            if (laravel_version_compare('12.24.0', '<')) {
192✔
237
                HandleExceptions::flushState();
×
238
            } else {
239
                HandleExceptions::flushState($instance);
192✔
240
            }
241
        }
242

243
        JsonResource::wrap('data');
192✔
244

245
        if (method_exists(Markdown::class, 'flushState')) {
192✔
246
            Markdown::flushState();
192✔
247
        }
248

249
        Migrator::withoutMigrations([]);
192✔
250
        Model::handleDiscardedAttributeViolationUsing(null);
192✔
251
        Model::handleLazyLoadingViolationUsing(null);
192✔
252
        Model::handleMissingAttributeViolationUsing(null);
192✔
253
        Model::automaticallyEagerLoadRelationships(false);
192✔
254
        Model::preventAccessingMissingAttributes(false);
192✔
255
        Model::preventLazyLoading(false);
192✔
256
        Model::preventSilentlyDiscardingAttributes(false);
192✔
257
        Once::flush();
192✔
258
        PreventRequestsDuringMaintenance::flushState();
192✔
259
        Queue::createPayloadUsing(null);
192✔
260
        RegisterProviders::flushState();
192✔
261
        RouteListCommand::resolveTerminalWidthUsing(null);
192✔
262
        ScheduleListCommand::resolveTerminalWidthUsing(null);
192✔
263
        SchemaBuilder::$defaultStringLength = 255;
192✔
264
        SchemaBuilder::$defaultMorphKeyType = 'int';
192✔
265
        Signals::resolveAvailabilityUsing(null); // @phpstan-ignore argument.type
192✔
266
        Sleep::fake(false);
192✔
267
        ThrottleRequests::shouldHashKeys();
192✔
268
        TrimStrings::flushState();
192✔
269
        TrustProxies::flushState();
192✔
270
        TrustHosts::flushState();
192✔
271
        ValidateCsrfToken::flushState();
192✔
272
        WorkCommand::flushState();
192✔
273
    }
274

275
    /**
276
     * Configure the application options.
277
     *
278
     * @param  array<string, mixed>  $options
279
     *
280
     * @phpstan-param TConfig  $options
281
     *
282
     * @return $this
283
     */
284
    public function configure(array $options)
285
    {
286
        if (isset($options['load_environment_variables']) && \is_bool($options['load_environment_variables'])) {
14✔
287
            $this->loadEnvironmentVariables = $options['load_environment_variables'];
1✔
288
        }
289

290
        if (isset($options['enables_package_discoveries']) && \is_bool($options['enables_package_discoveries'])) {
14✔
291
            Arr::set($options, 'extra.dont-discover', []);
×
292
        }
293

294
        /** @var TExtraConfig $config */
295
        $config = Arr::only($options['extra'] ?? [], array_keys($this->config));
14✔
296

297
        $this->config = $config;
14✔
298

299
        return $this;
14✔
300
    }
301

302
    /**
303
     * Ignore package discovery from.
304
     *
305
     * @api
306
     *
307
     * @return array<int, string>
308
     */
309
    public function ignorePackageDiscoveriesFrom()
310
    {
311
        return $this->config['dont-discover'] ?? [];
15✔
312
    }
313

314
    /**
315
     * Get package providers.
316
     *
317
     * @api
318
     *
319
     * @param  \Illuminate\Foundation\Application  $app
320
     * @return array<int, class-string>
321
     */
322
    protected function getPackageProviders($app)
323
    {
324
        return $this->config['providers'] ?? [];
15✔
325
    }
326

327
    /**
328
     * Get package bootstrapper.
329
     *
330
     * @api
331
     *
332
     * @param  \Illuminate\Foundation\Application  $app
333
     * @return array<int, class-string>
334
     */
335
    protected function getPackageBootstrappers($app)
336
    {
337
        if (\is_null($bootstrappers = ($this->config['bootstrappers'] ?? null))) {
15✔
338
            return [];
13✔
339
        }
340

341
        return Arr::wrap($bootstrappers);
2✔
342
    }
343

344
    /**
345
     * Resolve application resolving callback.
346
     *
347
     * @internal
348
     *
349
     * @param  \Illuminate\Foundation\Application  $app
350
     * @return void
351
     */
352
    protected function resolveApplicationResolvingCallback($app): void
353
    {
354
        $this->resolveApplicationResolvingCallbackFromTrait($app);
15✔
355

356
        if (\is_callable($this->resolvingCallback)) {
15✔
357
            \call_user_func($this->resolvingCallback, $app);
×
358
        }
359
    }
360

361
    /**
362
     * Resolve the application's base path.
363
     *
364
     * @api
365
     *
366
     * @return string
367
     */
368
    protected function getApplicationBasePath()
369
    {
370
        return $this->basePath ?? static::applicationBasePath();
15✔
371
    }
372

373
    /**
374
     * Resolve application core environment variables implementation.
375
     *
376
     * @internal
377
     *
378
     * @param  \Illuminate\Foundation\Application  $app
379
     * @return void
380
     */
381
    protected function resolveApplicationEnvironmentVariables($app)
382
    {
383
        Env::disablePutenv();
15✔
384

385
        $app->terminating(static function () {
15✔
386
            Env::enablePutenv();
1✔
387
        });
15✔
388

389
        if ($this->loadEnvironmentVariables === true) {
15✔
390
            $app->make(LoadEnvironmentVariables::class)->bootstrap($app);
×
391
        }
392

393
        (new Bootstrap\LoadEnvironmentVariablesFromArray($this->config['env'] ?? []))->bootstrap($app);
15✔
394
    }
395

396
    /**
397
     * Resolve application core configuration implementation.
398
     *
399
     * @internal
400
     *
401
     * @param  \Illuminate\Foundation\Application  $app
402
     * @return void
403
     */
404
    protected function resolveApplicationConfiguration($app)
405
    {
406
        $this->resolveApplicationConfigurationFromTrait($app);
15✔
407

408
        (new Bootstrap\EnsuresDefaultConfiguration)->bootstrap($app);
15✔
409
    }
410

411
    /**
412
     * Resolve application Console Kernel implementation.
413
     *
414
     * @api
415
     *
416
     * @param  \Illuminate\Foundation\Application  $app
417
     * @return void
418
     */
419
    protected function resolveApplicationConsoleKernel($app)
420
    {
421
        if ($this->hasCustomApplicationKernels() === true) {
15✔
422
            return;
×
423
        }
424

425
        $kernel = Workbench::applicationConsoleKernel() ?? 'Orchestra\Testbench\Console\Kernel';
15✔
426

427
        if (is_file($app->basePath(join_paths('app', 'Console', 'Kernel.php'))) && class_exists('App\Console\Kernel')) {
15✔
428
            $kernel = 'App\Console\Kernel';
×
429
        }
430

431
        $app->singleton('Illuminate\Contracts\Console\Kernel', $kernel);
15✔
432
    }
433

434
    /**
435
     * Resolve application HTTP Kernel implementation.
436
     *
437
     * @api
438
     *
439
     * @param  \Illuminate\Foundation\Application  $app
440
     * @return void
441
     */
442
    protected function resolveApplicationHttpKernel($app)
443
    {
444
        if ($this->hasCustomApplicationKernels() === true) {
15✔
445
            return;
×
446
        }
447

448
        $kernel = Workbench::applicationHttpKernel() ?? 'Orchestra\Testbench\Http\Kernel';
15✔
449

450
        if (is_file($app->basePath(join_paths('app', 'Http', 'Kernel.php'))) && class_exists('App\Http\Kernel')) {
15✔
451
            $kernel = 'App\Http\Kernel';
×
452
        }
453

454
        $app->singleton('Illuminate\Contracts\Http\Kernel', $kernel);
15✔
455
    }
456
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc