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

orchestral / testbench-core / 14643705094

24 Apr 2025 02:06PM UTC coverage: 92.397% (+0.02%) from 92.373%
14643705094

push

github

crynobone
Release 9.13.2

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

1519 of 1644 relevant lines covered (92.4%)

74.76 hits per line

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

90.79
/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\Migrations\Migrator;
10
use Illuminate\Database\Schema\Builder as SchemaBuilder;
11
use Illuminate\Foundation\Bootstrap\HandleExceptions;
12
use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables;
13
use Illuminate\Foundation\Bootstrap\RegisterProviders;
14
use Illuminate\Foundation\Console\AboutCommand;
15
use Illuminate\Foundation\Console\ChannelListCommand;
16
use Illuminate\Foundation\Console\RouteListCommand;
17
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
18
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance;
19
use Illuminate\Foundation\Http\Middleware\TrimStrings;
20
use Illuminate\Foundation\Http\Middleware\ValidateCsrfToken;
21
use Illuminate\Http\Middleware\TrustHosts;
22
use Illuminate\Http\Middleware\TrustProxies;
23
use Illuminate\Http\Resources\Json\JsonResource;
24
use Illuminate\Mail\Markdown;
25
use Illuminate\Queue\Console\WorkCommand;
26
use Illuminate\Queue\Queue;
27
use Illuminate\Routing\Middleware\ThrottleRequests;
28
use Illuminate\Support\Arr;
29
use Illuminate\Support\EncodedHtmlString;
30
use Illuminate\Support\Once;
31
use Illuminate\Support\Sleep;
32
use Illuminate\View\Component;
33
use Orchestra\Testbench\Concerns\CreatesApplication;
34
use Orchestra\Testbench\Console\Commander;
35
use Orchestra\Testbench\Contracts\Config as ConfigContract;
36
use Orchestra\Testbench\Workbench\Workbench;
37

38
use function Orchestra\Sidekick\join_paths;
39

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

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

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

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

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

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

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

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

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

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

155
        (new Actions\CreateVendorSymlink($workingVendorPath))->handle($app);
156

157
        return $app;
158
    }
159

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

172
        (new Actions\DeleteVendorSymlink)->handle($app);
173

174
        return $app;
175
    }
176

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

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

207
    /**
208
     * Flush the application states.
209
     *
210
     * @param  \Orchestra\Testbench\Console\Commander|\Orchestra\Testbench\PHPUnit\TestCase  $instance
211
     * @return void
212
     */
213
    public static function flushState(object $instance): void
214
    {
215
        AboutCommand::flushState();
193✔
216
        Artisan::forgetBootstrappers();
193✔
217
        ChannelListCommand::resolveTerminalWidthUsing(null);
193✔
218
        Component::flushCache();
193✔
219
        Component::forgetComponentsResolver();
193✔
220
        Component::forgetFactory();
193✔
221
        ConvertEmptyStringsToNull::flushState();
193✔
222
        Factory::flushState();
193✔
223
        EncodedHtmlString::flushState();
193✔
224

225
        if (! $instance instanceof Commander) {
193✔
226
            HandleExceptions::flushState();
193✔
227
        }
228

229
        JsonResource::wrap('data');
193✔
230
        Markdown::flushState();
193✔
231
        Migrator::withoutMigrations([]);
193✔
232
        Once::flush();
193✔
233
        PreventRequestsDuringMaintenance::flushState();
193✔
234
        Queue::createPayloadUsing(null);
193✔
235
        RegisterProviders::flushState();
193✔
236
        RouteListCommand::resolveTerminalWidthUsing(null);
193✔
237
        ScheduleListCommand::resolveTerminalWidthUsing(null);
193✔
238
        SchemaBuilder::$defaultStringLength = 255;
193✔
239
        SchemaBuilder::$defaultMorphKeyType = 'int';
193✔
240
        Signals::resolveAvailabilityUsing(null); // @phpstan-ignore argument.type
193✔
241
        Sleep::fake(false);
193✔
242
        ThrottleRequests::shouldHashKeys();
193✔
243
        TrimStrings::flushState();
193✔
244
        TrustProxies::flushState();
193✔
245
        TrustHosts::flushState();
193✔
246
        ValidateCsrfToken::flushState();
193✔
247
        WorkCommand::flushState();
193✔
248
    }
249

250
    /**
251
     * Configure the application options.
252
     *
253
     * @param  array<string, mixed>  $options
254
     * @return $this
255
     *
256
     * @phpstan-param TConfig  $options
257
     */
258
    public function configure(array $options)
259
    {
260
        if (isset($options['load_environment_variables']) && \is_bool($options['load_environment_variables'])) {
14✔
261
            $this->loadEnvironmentVariables = $options['load_environment_variables'];
1✔
262
        }
263

264
        if (isset($options['enables_package_discoveries']) && \is_bool($options['enables_package_discoveries'])) {
14✔
265
            Arr::set($options, 'extra.dont-discover', []);
×
266
        }
267

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

271
        $this->config = $config;
14✔
272

273
        return $this;
14✔
274
    }
275

276
    /**
277
     * Ignore package discovery from.
278
     *
279
     * @api
280
     *
281
     * @return array<int, string>
282
     */
283
    public function ignorePackageDiscoveriesFrom()
284
    {
285
        return $this->config['dont-discover'] ?? [];
15✔
286
    }
287

288
    /**
289
     * Get package providers.
290
     *
291
     * @api
292
     *
293
     * @param  \Illuminate\Foundation\Application  $app
294
     * @return array<int, class-string>
295
     */
296
    protected function getPackageProviders($app)
297
    {
298
        return $this->config['providers'] ?? [];
15✔
299
    }
300

301
    /**
302
     * Get package bootstrapper.
303
     *
304
     * @api
305
     *
306
     * @param  \Illuminate\Foundation\Application  $app
307
     * @return array<int, class-string>
308
     */
309
    protected function getPackageBootstrappers($app)
310
    {
311
        if (\is_null($bootstrappers = ($this->config['bootstrappers'] ?? null))) {
15✔
312
            return [];
13✔
313
        }
314

315
        return Arr::wrap($bootstrappers);
2✔
316
    }
317

318
    /**
319
     * Resolve application resolving callback.
320
     *
321
     * @internal
322
     *
323
     * @param  \Illuminate\Foundation\Application  $app
324
     * @return void
325
     */
326
    protected function resolveApplicationResolvingCallback($app): void
327
    {
328
        $this->resolveApplicationResolvingCallbackFromTrait($app);
15✔
329

330
        if (\is_callable($this->resolvingCallback)) {
15✔
331
            \call_user_func($this->resolvingCallback, $app);
×
332
        }
333
    }
334

335
    /**
336
     * Resolve the application's base path.
337
     *
338
     * @api
339
     *
340
     * @internal
341
     *
342
     * @return string
343
     */
344
    protected function getApplicationBasePath()
345
    {
346
        return $this->basePath ?? static::applicationBasePath();
15✔
347
    }
348

349
    /**
350
     * Resolve application core environment variables implementation.
351
     *
352
     * @internal
353
     *
354
     * @param  \Illuminate\Foundation\Application  $app
355
     * @return void
356
     */
357
    protected function resolveApplicationEnvironmentVariables($app)
358
    {
359
        Env::disablePutenv();
15✔
360

361
        $app->terminating(static function () {
15✔
362
            Env::enablePutenv();
1✔
363
        });
15✔
364

365
        if ($this->loadEnvironmentVariables === true) {
15✔
366
            $app->make(LoadEnvironmentVariables::class)->bootstrap($app);
×
367
        }
368

369
        (new Bootstrap\LoadEnvironmentVariablesFromArray($this->config['env'] ?? []))->bootstrap($app);
15✔
370
    }
371

372
    /**
373
     * Resolve application core configuration implementation.
374
     *
375
     * @internal
376
     *
377
     * @param  \Illuminate\Foundation\Application  $app
378
     * @return void
379
     */
380
    protected function resolveApplicationConfiguration($app)
381
    {
382
        $this->resolveApplicationConfigurationFromTrait($app);
15✔
383

384
        (new Bootstrap\EnsuresDefaultConfiguration)->bootstrap($app);
15✔
385
    }
386

387
    /**
388
     * Resolve application Console Kernel implementation.
389
     *
390
     * @api
391
     *
392
     * @param  \Illuminate\Foundation\Application  $app
393
     * @return void
394
     */
395
    protected function resolveApplicationConsoleKernel($app)
396
    {
397
        if ($this->hasCustomApplicationKernels() === true) {
15✔
398
            return;
×
399
        }
400

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

403
        if (is_file($app->basePath(join_paths('app', 'Console', 'Kernel.php'))) && class_exists('App\Console\Kernel')) {
15✔
404
            $kernel = 'App\Console\Kernel';
×
405
        }
406

407
        $app->singleton('Illuminate\Contracts\Console\Kernel', $kernel);
15✔
408
    }
409

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

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

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

430
        $app->singleton('Illuminate\Contracts\Http\Kernel', $kernel);
15✔
431
    }
432
}
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