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

orchestral / testbench-core / 13341495068

15 Feb 2025 03:47AM UTC coverage: 92.866% (-0.005%) from 92.871%
13341495068

push

github

crynobone
Release 8.33.0

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

1445 of 1556 relevant lines covered (92.87%)

68.06 hits per line

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

91.67
/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\LoadEnvironmentVariables;
10
use Illuminate\Foundation\Console\AboutCommand;
11
use Illuminate\Foundation\Console\ChannelListCommand;
12
use Illuminate\Foundation\Console\RouteListCommand;
13
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
14
use Illuminate\Foundation\Http\Middleware\TrimStrings;
15
use Illuminate\Http\Resources\Json\JsonResource;
16
use Illuminate\Queue\Queue;
17
use Illuminate\Support\Arr;
18
use Illuminate\Support\Sleep;
19
use Illuminate\View\Component;
20
use Orchestra\Testbench\Bootstrap\HandleExceptions;
21
use Orchestra\Testbench\Concerns\CreatesApplication;
22
use Orchestra\Testbench\Contracts\Config as ConfigContract;
23
use Orchestra\Testbench\Workbench\Workbench;
24

25
use function Orchestra\Testbench\join_paths;
26

27
/**
28
 * @api
29
 *
30
 * @phpstan-import-type TExtraConfig from \Orchestra\Testbench\Foundation\Config
31
 * @phpstan-import-type TOptionalExtraConfig from \Orchestra\Testbench\Foundation\Config
32
 *
33
 * @phpstan-type TConfig array{
34
 *   extra?: TOptionalExtraConfig,
35
 *   load_environment_variables?: bool,
36
 *   enabled_package_discoveries?: bool
37
 * }
38
 */
39
class Application
40
{
41
    use CreatesApplication {
42
        resolveApplicationResolvingCallback as protected resolveApplicationResolvingCallbackFromTrait;
43
        resolveApplicationConfiguration as protected resolveApplicationConfigurationFromTrait;
44
    }
45

46
    /**
47
     * The Illuminate application instance.
48
     *
49
     * @var \Illuminate\Foundation\Application|null
50
     */
51
    protected $app;
52

53
    /**
54
     * The application base path.
55
     *
56
     * @var string|null
57
     */
58
    protected $basePath;
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 $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(?string $basePath = null, ?callable $resolvingCallback = null)
95
    {
96
        $this->basePath = $basePath;
8✔
97
        $this->resolvingCallback = $resolvingCallback;
8✔
98
    }
99

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

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

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

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

148
        (new Actions\CreateVendorSymlink($workingVendorPath))->handle($app);
149

150
        return $app;
151
    }
152

153
    /**
154
     * Delete symlink to vendor path via new application instance.
155
     *
156
     * @param  string|null  $basePath
157
     * @return \Illuminate\Foundation\Application
158
     *
159
     * @codeCoverageIgnore
160
     */
161
    public static function deleteVendorSymlink(?string $basePath)
162
    {
163
        $app = static::create(basePath: $basePath, options: ['extra' => ['dont-discover' => ['*']]]);
164

165
        (new Actions\DeleteVendorSymlink)->handle($app);
166

167
        return $app;
168
    }
169

170
    /**
171
     * Create new application instance.
172
     *
173
     * @param  string|null  $basePath
174
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
175
     * @param  array<string, mixed>  $options
176
     * @return \Illuminate\Foundation\Application
177
     *
178
     * @phpstan-param TConfig  $options
179
     */
180
    public static function create(?string $basePath = null, ?callable $resolvingCallback = null, array $options = [])
181
    {
182
        return static::make($basePath, $resolvingCallback, $options)->createApplication();
3✔
183
    }
184

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

200
    /**
201
     * Flush the application states.
202
     *
203
     * @param  \Orchestra\Testbench\Console\Commander|\Orchestra\Testbench\PHPUnit\TestCase|null  $instance
204
     * @return void
205
     */
206
    public static function flushState(?object $instance = null): void
207
    {
208
        AboutCommand::flushState();
173✔
209
        Artisan::forgetBootstrappers();
173✔
210
        ChannelListCommand::resolveTerminalWidthUsing(null);
173✔
211
        Component::flushCache();
173✔
212
        Component::forgetComponentsResolver();
173✔
213
        Component::forgetFactory();
173✔
214
        ConvertEmptyStringsToNull::flushState();
173✔
215
        HandleExceptions::forgetApp();
173✔
216
        JsonResource::wrap('data');
173✔
217
        Queue::createPayloadUsing(null);
173✔
218
        RouteListCommand::resolveTerminalWidthUsing(null);
173✔
219
        ScheduleListCommand::resolveTerminalWidthUsing(null);
173✔
220
        SchemaBuilder::$defaultStringLength = 255;
173✔
221
        SchemaBuilder::$defaultMorphKeyType = 'int';
173✔
222
        Signals::resolveAvailabilityUsing(null);
173✔
223
        Sleep::fake(false);
173✔
224
        TrimStrings::flushState();
173✔
225
    }
226

227
    /**
228
     * Configure the application options.
229
     *
230
     * @param  array<string, mixed>  $options
231
     * @return $this
232
     *
233
     * @phpstan-param TConfig  $options
234
     */
235
    public function configure(array $options)
236
    {
237
        if (isset($options['load_environment_variables']) && \is_bool($options['load_environment_variables'])) {
7✔
238
            $this->loadEnvironmentVariables = $options['load_environment_variables'];
1✔
239
        }
240

241
        if (isset($options['enables_package_discoveries']) && \is_bool($options['enables_package_discoveries'])) {
7✔
242
            Arr::set($options, 'extra.dont-discover', []);
×
243
        }
244

245
        /** @var TExtraConfig $config */
246
        $config = Arr::only($options['extra'] ?? [], array_keys($this->config));
7✔
247

248
        $this->config = $config;
7✔
249

250
        return $this;
7✔
251
    }
252

253
    /**
254
     * Ignore package discovery from.
255
     *
256
     * @return array<int, string>
257
     */
258
    public function ignorePackageDiscoveriesFrom()
259
    {
260
        return $this->config['dont-discover'] ?? [];
8✔
261
    }
262

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

274
    /**
275
     * Get package bootstrapper.
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))) {
8✔
283
            return [];
6✔
284
        }
285

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

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

299
        if (\is_callable($this->resolvingCallback)) {
8✔
300
            \call_user_func($this->resolvingCallback, $app);
×
301
        }
302
    }
303

304
    /**
305
     * Resolve the application's base path.
306
     *
307
     * @api
308
     *
309
     * @return string
310
     */
311
    protected function getApplicationBasePath()
312
    {
313
        return $this->basePath ?? static::applicationBasePath();
8✔
314
    }
315

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

326
        $app->terminating(static function () {
8✔
327
            Env::enablePutenv();
1✔
328
        });
8✔
329

330
        if ($this->loadEnvironmentVariables === true) {
8✔
331
            $app->make(LoadEnvironmentVariables::class)->bootstrap($app);
×
332
        }
333

334
        (new Bootstrap\LoadEnvironmentVariablesFromArray($this->config['env'] ?? []))->bootstrap($app);
8✔
335
    }
336

337
    /**
338
     * Resolve application core configuration implementation.
339
     *
340
     * @param  \Illuminate\Foundation\Application  $app
341
     * @return void
342
     */
343
    protected function resolveApplicationConfiguration($app)
344
    {
345
        $this->resolveApplicationConfigurationFromTrait($app);
8✔
346

347
        (new Bootstrap\EnsuresDefaultConfiguration)->bootstrap($app);
8✔
348
    }
349

350
    /**
351
     * Resolve application Console Kernel implementation.
352
     *
353
     * @param  \Illuminate\Foundation\Application  $app
354
     * @return void
355
     */
356
    protected function resolveApplicationConsoleKernel($app)
357
    {
358
        $kernel = Workbench::applicationConsoleKernel() ?? 'Orchestra\Testbench\Console\Kernel';
8✔
359

360
        if (is_file($app->basePath(join_paths('app', 'Console', 'Kernel.php'))) && class_exists('App\Console\Kernel')) {
8✔
361
            $kernel = 'App\Console\Kernel';
×
362
        }
363

364
        $app->singleton('Illuminate\Contracts\Console\Kernel', $kernel);
8✔
365
    }
366

367
    /**
368
     * Resolve application HTTP Kernel implementation.
369
     *
370
     * @param  \Illuminate\Foundation\Application  $app
371
     * @return void
372
     */
373
    protected function resolveApplicationHttpKernel($app)
374
    {
375
        $kernel = Workbench::applicationHttpKernel() ?? 'Orchestra\Testbench\Http\Kernel';
8✔
376

377
        if (is_file($app->basePath(join_paths('app', 'Http', 'Kernel.php'))) && class_exists('App\Http\Kernel')) {
8✔
378
            $kernel = 'App\Http\Kernel';
×
379
        }
380

381
        $app->singleton('Illuminate\Contracts\Http\Kernel', $kernel);
8✔
382
    }
383
}
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