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

orchestral / testbench-core / 14039627707

24 Mar 2025 03:45PM UTC coverage: 91.878% (-0.9%) from 92.776%
14039627707

Pull #329

github

web-flow
Merge f2c8ddbc1 into ce7418771
Pull Request #329: [7.x] Add support for `workbench/bootstrap/providers.php`

28 of 45 new or added lines in 3 files covered. (62.22%)

5 existing lines in 1 file now uncovered.

1414 of 1539 relevant lines covered (91.88%)

63.24 hits per line

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

90.91
/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\Console\RouteListCommand;
12
use Illuminate\Http\Resources\Json\JsonResource;
13
use Illuminate\Queue\Queue;
14
use Illuminate\Support\Arr;
15
use Illuminate\View\Component;
16
use Orchestra\Testbench\Concerns\CreatesApplication;
17
use Orchestra\Testbench\Contracts\Config as ConfigContract;
18
use Orchestra\Testbench\Workbench\Workbench;
19

20
/**
21
 * @api
22
 *
23
 * @phpstan-import-type TExtraConfig from \Orchestra\Testbench\Foundation\Config
24
 * @phpstan-import-type TOptionalExtraConfig from \Orchestra\Testbench\Foundation\Config
25
 *
26
 * @phpstan-type TConfig array{
27
 *   extra?: TOptionalExtraConfig,
28
 *   load_environment_variables?: bool,
29
 *   enabled_package_discoveries?: bool
30
 * }
31
 */
32
class Application
33
{
34
    use CreatesApplication {
35
        resolveApplicationResolvingCallback as protected resolveApplicationResolvingCallbackFromTrait;
36
        resolveApplicationConfiguration as protected resolveApplicationConfigurationFromTrait;
37
    }
38

39
    /**
40
     * The Illuminate application instance.
41
     *
42
     * @var \Illuminate\Foundation\Application|null
43
     */
44
    protected $app;
45

46
    /**
47
     * The application base path.
48
     *
49
     * @var string|null
50
     */
51
    protected $basePath;
52

53
    /**
54
     * List of configurations.
55
     *
56
     * @var array<string, mixed>
57
     *
58
     * @phpstan-var TExtraConfig
59
     */
60
    protected array $config = [
61
        'env' => [],
62
        'providers' => [],
63
        'dont-discover' => [],
64
        'bootstrappers' => [],
65
    ];
66

67
    /**
68
     * The application resolving callback.
69
     *
70
     * @var (callable(\Illuminate\Foundation\Application):(void))|null
71
     */
72
    protected $resolvingCallback;
73

74
    /**
75
     * Load Environment variables.
76
     *
77
     * @var bool
78
     */
79
    protected $loadEnvironmentVariables = false;
80

81
    /**
82
     * Create new application resolver.
83
     *
84
     * @param  string|null  $basePath
85
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
86
     */
87
    public function __construct(?string $basePath = null, ?callable $resolvingCallback = null)
88
    {
89
        $this->basePath = $basePath;
12✔
90
        $this->resolvingCallback = $resolvingCallback;
12✔
91
    }
92

93
    /**
94
     * Create new application resolver.
95
     *
96
     * @param  string|null  $basePath
97
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
98
     * @param  array<string, mixed>  $options
99
     * @return static
100
     *
101
     * @phpstan-param TConfig  $options
102
     */
103
    public static function make(?string $basePath = null, ?callable $resolvingCallback = null, array $options = [])
104
    {
105
        return (new static($basePath, $resolvingCallback))->configure($options);
10✔
106
    }
107

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

122
        return (new static($config['laravel'], $resolvingCallback))->configure(array_merge($options, [
1✔
123
            'load_environment_variables' => is_file("{$basePath}/.env"),
1✔
124
            'extra' => $config->getExtraAttributes(),
1✔
125
        ]));
1✔
126
    }
127

128
    /**
129
     * Create symlink to vendor path via new application instance.
130
     *
131
     * @param  string|null  $basePath
132
     * @param  string  $workingVendorPath
133
     * @return \Illuminate\Foundation\Application
134
     *
135
     * @codeCoverageIgnore
136
     */
137
    public static function createVendorSymlink(?string $basePath, string $workingVendorPath)
138
    {
139
        $app = static::create(basePath: $basePath, options: ['extra' => ['dont-discover' => ['*']]]);
140

141
        (new Actions\CreateVendorSymlink($workingVendorPath))->handle($app);
142

143
        return $app;
144
    }
145

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

158
        (new Actions\DeleteVendorSymlink)->handle($app);
159

160
        return $app;
161
    }
162

163
    /**
164
     * Create new application instance.
165
     *
166
     * @param  string|null  $basePath
167
     * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
168
     * @param  array<string, mixed>  $options
169
     * @return \Illuminate\Foundation\Application
170
     *
171
     * @phpstan-param TConfig  $options
172
     */
173
    public static function create(?string $basePath = null, ?callable $resolvingCallback = null, array $options = [])
174
    {
175
        return static::make($basePath, $resolvingCallback, $options)->createApplication();
7✔
176
    }
177

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

193
    /**
194
     * Flush the application states.
195
     *
196
     * @param  \Orchestra\Testbench\Console\Commander|\Orchestra\Testbench\PHPUnit\TestCase|null  $instance
197
     * @return void
198
     */
199
    public static function flushState(?object $instance = null): void
200
    {
201
        Artisan::forgetBootstrappers();
164✔
202
        Component::flushCache();
164✔
203
        Component::forgetComponentsResolver();
164✔
204
        Component::forgetFactory();
164✔
205
        HandleExceptions::forgetApp();
164✔
206
        JsonResource::wrap('data');
164✔
207
        Queue::createPayloadUsing(null);
164✔
208
        RouteListCommand::resolveTerminalWidthUsing(null);
164✔
209
        ScheduleListCommand::resolveTerminalWidthUsing(null);
164✔
210
        SchemaBuilder::$defaultStringLength = 255;
164✔
211
        SchemaBuilder::$defaultMorphKeyType = 'int';
164✔
212
        Signals::resolveAvailabilityUsing(null);
164✔
213
    }
214

215
    /**
216
     * Configure the application options.
217
     *
218
     * @param  array<string, mixed>  $options
219
     * @return $this
220
     *
221
     * @phpstan-param TConfig  $options
222
     */
223
    public function configure(array $options)
224
    {
225
        if (isset($options['load_environment_variables']) && \is_bool($options['load_environment_variables'])) {
11✔
226
            $this->loadEnvironmentVariables = $options['load_environment_variables'];
1✔
227
        }
228

229
        if (isset($options['enables_package_discoveries']) && \is_bool($options['enables_package_discoveries'])) {
11✔
UNCOV
230
            Arr::set($options, 'extra.dont-discover', []);
×
231
        }
232

233
        /** @var TExtraConfig $config */
234
        $config = Arr::only($options['extra'] ?? [], array_keys($this->config));
11✔
235

236
        $this->config = $config;
11✔
237

238
        return $this;
11✔
239
    }
240

241
    /**
242
     * Ignore package discovery from.
243
     *
244
     * @return array
245
     */
246
    public function ignorePackageDiscoveriesFrom()
247
    {
248
        return $this->config['dont-discover'] ?? [];
12✔
249
    }
250

251
    /**
252
     * Get package providers.
253
     *
254
     * @param  \Illuminate\Foundation\Application  $app
255
     * @return array
256
     */
257
    protected function getPackageProviders($app)
258
    {
259
        return $this->config['providers'] ?? [];
12✔
260
    }
261

262
    /**
263
     * Get package bootstrapper.
264
     *
265
     * @param  \Illuminate\Foundation\Application  $app
266
     * @return array<int, class-string>
267
     */
268
    protected function getPackageBootstrappers($app)
269
    {
270
        if (\is_null($bootstrappers = ($this->config['bootstrappers'] ?? null))) {
12✔
271
            return [];
10✔
272
        }
273

274
        return Arr::wrap($bootstrappers);
2✔
275
    }
276

277
    /**
278
     * Resolve application resolving callback.
279
     *
280
     * @param  \Illuminate\Foundation\Application  $app
281
     * @return void
282
     */
283
    private function resolveApplicationResolvingCallback($app): void
284
    {
285
        $this->resolveApplicationResolvingCallbackFromTrait($app);
12✔
286

287
        if (\is_callable($this->resolvingCallback)) {
12✔
UNCOV
288
            \call_user_func($this->resolvingCallback, $app);
×
289
        }
290
    }
291

292
    /**
293
     * Resolve the application's base path.
294
     *
295
     * @api
296
     *
297
     * @return string
298
     */
299
    protected function getApplicationBasePath()
300
    {
301
        return $this->basePath ?? static::applicationBasePath();
12✔
302
    }
303

304
    /**
305
     * Resolve application core environment variables implementation.
306
     *
307
     * @param  \Illuminate\Foundation\Application  $app
308
     * @return void
309
     */
310
    protected function resolveApplicationEnvironmentVariables($app)
311
    {
312
        Env::disablePutenv();
12✔
313

314
        $app->terminating(static function () {
12✔
315
            Env::enablePutenv();
1✔
316
        });
12✔
317

318
        if ($this->loadEnvironmentVariables === true) {
12✔
UNCOV
319
            $app->make(LoadEnvironmentVariables::class)->bootstrap($app);
×
320
        }
321

322
        (new Bootstrap\LoadEnvironmentVariablesFromArray($this->config['env'] ?? []))->bootstrap($app);
12✔
323
    }
324

325
    /**
326
     * Resolve application core configuration implementation.
327
     *
328
     * @param  \Illuminate\Foundation\Application  $app
329
     * @return void
330
     */
331
    protected function resolveApplicationConfiguration($app)
332
    {
333
        $this->resolveApplicationConfigurationFromTrait($app);
12✔
334

335
        (new Bootstrap\EnsuresDefaultConfiguration)->bootstrap($app);
12✔
336
    }
337

338
    /**
339
     * Resolve application Console Kernel implementation.
340
     *
341
     * @param  \Illuminate\Foundation\Application  $app
342
     * @return void
343
     */
344
    protected function resolveApplicationConsoleKernel($app)
345
    {
346
        $kernel = Workbench::applicationConsoleKernel() ?? 'Orchestra\Testbench\Console\Kernel';
12✔
347

348
        if (is_file($app->basePath('app/Console/Kernel.php')) && class_exists('App\Console\Kernel')) {
12✔
UNCOV
349
            $kernel = 'App\Console\Kernel';
×
350
        }
351

352
        $app->singleton('Illuminate\Contracts\Console\Kernel', $kernel);
12✔
353
    }
354

355
    /**
356
     * Resolve application HTTP Kernel implementation.
357
     *
358
     * @param  \Illuminate\Foundation\Application  $app
359
     * @return void
360
     */
361
    protected function resolveApplicationHttpKernel($app)
362
    {
363
        $kernel = Workbench::applicationHttpKernel() ?? 'Orchestra\Testbench\Http\Kernel';
12✔
364

365
        if (is_file($app->basePath('app/Http/Kernel.php')) && class_exists('App\Http\Kernel')) {
12✔
UNCOV
366
            $kernel = 'App\Http\Kernel';
×
367
        }
368

369
        $app->singleton('Illuminate\Contracts\Http\Kernel', $kernel);
12✔
370
    }
371
}
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