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

orchestral / testbench-core / 13171110673

06 Feb 2025 03:15AM UTC coverage: 88.252% (+0.02%) from 88.232%
13171110673

push

github

crynobone
Merge branch '9.x' into 10.x

3 of 3 new or added lines in 1 file covered. (100.0%)

7 existing lines in 1 file now uncovered.

1525 of 1728 relevant lines covered (88.25%)

71.0 hits per line

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

90.0
/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\Schema\Builder as SchemaBuilder;
9
use Illuminate\Foundation\Bootstrap\HandleExceptions;
10
use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables;
11
use Illuminate\Foundation\Bootstrap\RegisterProviders;
12
use Illuminate\Foundation\Console\AboutCommand;
13
use Illuminate\Foundation\Console\ChannelListCommand;
14
use Illuminate\Foundation\Console\RouteListCommand;
15
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
16
use Illuminate\Foundation\Http\Middleware\TrimStrings;
17
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
18
use Illuminate\Http\Middleware\TrustProxies;
19
use Illuminate\Http\Resources\Json\JsonResource;
20
use Illuminate\Queue\Console\WorkCommand;
21
use Illuminate\Queue\Queue;
22
use Illuminate\Routing\Middleware\ThrottleRequests;
23
use Illuminate\Support\Arr;
24
use Illuminate\Support\Once;
25
use Illuminate\Support\Sleep;
26
use Illuminate\View\Component;
27
use Orchestra\Testbench\Concerns\CreatesApplication;
28
use Orchestra\Testbench\Console\Commander;
29
use Orchestra\Testbench\Contracts\Config as ConfigContract;
30
use Orchestra\Testbench\Workbench\Workbench;
31

32
use function Orchestra\Testbench\join_paths;
33

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

53
    /**
54
     * The Illuminate application instance.
55
     *
56
     * @var \Illuminate\Foundation\Application|null
57
     */
58
    protected $app;
59

60
    /**
61
     * List of configurations.
62
     *
63
     * @var array<string, mixed>
64
     *
65
     * @phpstan-var TExtraConfig
66
     */
67
    protected array $config = [
68
        'env' => [],
69
        'providers' => [],
70
        'dont-discover' => [],
71
        'bootstrappers' => [],
72
    ];
73

74
    /**
75
     * The application resolving callback.
76
     *
77
     * @var (callable(\Illuminate\Foundation\Application):(void))|null
78
     */
79
    protected $resolvingCallback;
80

81
    /**
82
     * Load Environment variables.
83
     *
84
     * @var bool
85
     */
86
    protected bool $loadEnvironmentVariables = false;
87

88
    /**
89
     * Create new application resolver.
90
     *
91
     * @param  string|null  $basePath
92
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
93
     */
94
    public function __construct(
95
        protected readonly ?string $basePath = null,
96
        ?callable $resolvingCallback = null
97
    ) {
98
        $this->resolvingCallback = $resolvingCallback;
7✔
99
    }
100

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

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

130
        return (new static($config['laravel'], $resolvingCallback))->configure(array_merge($options, [
1✔
131
            'load_environment_variables' => is_file("{$basePath}/.env"),
1✔
132
            'extra' => $config->getExtraAttributes(),
1✔
133
        ]));
1✔
134
    }
135

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

149
        (new Bootstrap\CreateVendorSymlink($workingVendorPath))->bootstrap($app);
150

151
        return $app;
152
    }
153

154
    /**
155
     * Create new application instance.
156
     *
157
     * @param  string|null  $basePath
158
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
159
     * @param  array<string, mixed>  $options
160
     * @return \Illuminate\Foundation\Application
161
     *
162
     * @phpstan-param TConfig  $options
163
     */
164
    public static function create(?string $basePath = null, ?callable $resolvingCallback = null, array $options = [])
165
    {
166
        return static::make($basePath, $resolvingCallback, $options)->createApplication();
2✔
167
    }
168

169
    /**
170
     * Create new application instance from configuration file.
171
     *
172
     * @param  \Orchestra\Testbench\Contracts\Config  $config
173
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
174
     * @param  array<string, mixed>  $options
175
     * @return \Illuminate\Foundation\Application
176
     *
177
     * @phpstan-param TConfig  $options
178
     */
179
    public static function createFromConfig(ConfigContract $config, ?callable $resolvingCallback = null, array $options = [])
180
    {
181
        return static::makeFromConfig($config, $resolvingCallback, $options)->createApplication();
1✔
182
    }
183

184
    /**
185
     * Flush the application states.
186
     *
187
     * @param  \Orchestra\Testbench\Console\Commander|\Orchestra\Testbench\PHPUnit\TestCase  $instance
188
     * @return void
189
     */
190
    public static function flushState(object $instance): void
191
    {
192
        AboutCommand::flushState();
192✔
193
        Artisan::forgetBootstrappers();
192✔
194
        ChannelListCommand::resolveTerminalWidthUsing(null);
192✔
195
        Component::flushCache();
192✔
196
        Component::forgetComponentsResolver();
192✔
197
        Component::forgetFactory();
192✔
198
        ConvertEmptyStringsToNull::flushState();
192✔
199

200
        if (! $instance instanceof Commander) {
192✔
201
            HandleExceptions::flushState();
192✔
202
        }
203

204
        JsonResource::wrap('data');
192✔
205
        Once::flush();
192✔
206
        Queue::createPayloadUsing(null);
192✔
207
        RegisterProviders::flushState();
192✔
208
        RouteListCommand::resolveTerminalWidthUsing(null);
192✔
209
        ScheduleListCommand::resolveTerminalWidthUsing(null);
192✔
210
        SchemaBuilder::$defaultStringLength = 255;
192✔
211
        SchemaBuilder::$defaultMorphKeyType = 'int';
192✔
212
        Signals::resolveAvailabilityUsing(null); // @phpstan-ignore argument.type
192✔
213
        Sleep::fake(false);
192✔
214
        ThrottleRequests::shouldHashKeys();
192✔
215
        TrimStrings::flushState();
192✔
216
        TrustProxies::flushState();
192✔
217
        VerifyCsrfToken::flushState();
192✔
218
        WorkCommand::flushState();
192✔
219
    }
220

221
    /**
222
     * Configure the application options.
223
     *
224
     * @param  array<string, mixed>  $options
225
     * @return $this
226
     *
227
     * @phpstan-param TConfig  $options
228
     */
229
    public function configure(array $options)
230
    {
231
        if (isset($options['load_environment_variables']) && \is_bool($options['load_environment_variables'])) {
6✔
232
            $this->loadEnvironmentVariables = $options['load_environment_variables'];
1✔
233
        }
234

235
        if (isset($options['enables_package_discoveries']) && \is_bool($options['enables_package_discoveries'])) {
6✔
UNCOV
236
            Arr::set($options, 'extra.dont-discover', []);
×
237
        }
238

239
        /** @var TExtraConfig $config */
240
        $config = Arr::only($options['extra'] ?? [], array_keys($this->config));
6✔
241

242
        $this->config = $config;
6✔
243

244
        return $this;
6✔
245
    }
246

247
    /**
248
     * Ignore package discovery from.
249
     *
250
     * @api
251
     *
252
     * @return array<int, string>
253
     */
254
    public function ignorePackageDiscoveriesFrom()
255
    {
256
        return $this->config['dont-discover'] ?? [];
7✔
257
    }
258

259
    /**
260
     * Get package providers.
261
     *
262
     * @api
263
     *
264
     * @param  \Illuminate\Foundation\Application  $app
265
     * @return array<int, class-string>
266
     */
267
    protected function getPackageProviders($app)
268
    {
269
        return $this->config['providers'] ?? [];
7✔
270
    }
271

272
    /**
273
     * Get package bootstrapper.
274
     *
275
     * @api
276
     *
277
     * @param  \Illuminate\Foundation\Application  $app
278
     * @return array<int, class-string>
279
     */
280
    protected function getPackageBootstrappers($app)
281
    {
282
        if (\is_null($bootstrappers = ($this->config['bootstrappers'] ?? null))) {
7✔
283
            return [];
5✔
284
        }
285

286
        return Arr::wrap($bootstrappers);
2✔
287
    }
288

289
    /**
290
     * Resolve application resolving callback.
291
     *
292
     * @internal
293
     *
294
     * @param  \Illuminate\Foundation\Application  $app
295
     * @return void
296
     */
297
    protected function resolveApplicationResolvingCallback($app): void
298
    {
299
        $this->resolveApplicationResolvingCallbackFromTrait($app);
7✔
300

301
        if (\is_callable($this->resolvingCallback)) {
7✔
UNCOV
302
            \call_user_func($this->resolvingCallback, $app);
×
303
        }
304
    }
305

306
    /**
307
     * Get base path.
308
     *
309
     * @internal
310
     *
311
     * @return string
312
     */
313
    protected function getBasePath()
314
    {
315
        return $this->basePath ?? static::applicationBasePath();
7✔
316
    }
317

318
    /**
319
     * Resolve application core environment variables implementation.
320
     *
321
     * @internal
322
     *
323
     * @param  \Illuminate\Foundation\Application  $app
324
     * @return void
325
     */
326
    protected function resolveApplicationEnvironmentVariables($app)
327
    {
328
        Env::disablePutenv();
7✔
329

330
        $app->terminating(static function () {
7✔
331
            Env::enablePutenv();
1✔
332
        });
7✔
333

334
        if ($this->loadEnvironmentVariables === true) {
7✔
UNCOV
335
            $app->make(LoadEnvironmentVariables::class)->bootstrap($app);
×
336
        }
337

338
        (new Bootstrap\LoadEnvironmentVariablesFromArray($this->config['env'] ?? []))->bootstrap($app);
7✔
339
    }
340

341
    /**
342
     * Resolve application core configuration implementation.
343
     *
344
     * @internal
345
     *
346
     * @param  \Illuminate\Foundation\Application  $app
347
     * @return void
348
     */
349
    protected function resolveApplicationConfiguration($app)
350
    {
351
        $this->resolveApplicationConfigurationFromTrait($app);
7✔
352

353
        (new Bootstrap\EnsuresDefaultConfiguration)->bootstrap($app);
7✔
354
    }
355

356
    /**
357
     * Resolve application Console Kernel implementation.
358
     *
359
     * @api
360
     *
361
     * @param  \Illuminate\Foundation\Application  $app
362
     * @return void
363
     */
364
    protected function resolveApplicationConsoleKernel($app)
365
    {
366
        if ($this->hasCustomApplicationKernels() === true) {
7✔
UNCOV
367
            return;
×
368
        }
369

370
        $kernel = Workbench::applicationConsoleKernel() ?? 'Orchestra\Testbench\Console\Kernel';
7✔
371

372
        if (is_file($app->basePath(join_paths('app', 'Console', 'Kernel.php'))) && class_exists('App\Console\Kernel')) {
7✔
UNCOV
373
            $kernel = 'App\Console\Kernel';
×
374
        }
375

376
        $app->singleton('Illuminate\Contracts\Console\Kernel', $kernel);
7✔
377
    }
378

379
    /**
380
     * Resolve application HTTP Kernel implementation.
381
     *
382
     * @api
383
     *
384
     * @param  \Illuminate\Foundation\Application  $app
385
     * @return void
386
     */
387
    protected function resolveApplicationHttpKernel($app)
388
    {
389
        if ($this->hasCustomApplicationKernels() === true) {
7✔
UNCOV
390
            return;
×
391
        }
392

393
        $kernel = Workbench::applicationHttpKernel() ?? 'Orchestra\Testbench\Http\Kernel';
7✔
394

395
        if (is_file($app->basePath(join_paths('app', 'Http', 'Kernel.php'))) && class_exists('App\Http\Kernel')) {
7✔
UNCOV
396
            $kernel = 'App\Http\Kernel';
×
397
        }
398

399
        $app->singleton('Illuminate\Contracts\Http\Kernel', $kernel);
7✔
400
    }
401
}
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