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

orchestral / testbench-core / 10446738161

19 Aug 2024 03:39AM UTC coverage: 92.107% (-0.08%) from 92.189%
10446738161

push

github

crynobone
wip

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

1132 of 1229 relevant lines covered (92.11%)

60.72 hits per line

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

93.48
/src/functions.php
1
<?php
2

3
namespace Orchestra\Testbench;
4

5
use Closure;
6
use Illuminate\Contracts\Console\Kernel as ConsoleKernel;
7
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
8
use Illuminate\Foundation\Application;
9
use Illuminate\Routing\Router;
10
use Illuminate\Support\Arr;
11
use Illuminate\Support\Collection;
12
use Illuminate\Support\ProcessUtils;
13
use Illuminate\Support\Str;
14
use Illuminate\Testing\PendingCommand;
15
use InvalidArgumentException;
16
use Orchestra\Testbench\Foundation\Env;
17
use PHPUnit\Runner\Version;
18
use RuntimeException;
19
use Symfony\Component\Process\PhpExecutableFinder;
20
use Symfony\Component\Process\Process;
21

22
/**
23
 * Create Laravel application instance.
24
 *
25
 * @api
26
 *
27
 * @param  string|null  $basePath
28
 * @param  (callable(\Illuminate\Foundation\Application):(void))|null  $resolvingCallback
29
 * @param  array{extra?: array{providers?: array, dont-discover?: array, env?: array}, load_environment_variables?: bool, enabled_package_discoveries?: bool}  $options
30
 * @return \Orchestra\Testbench\Foundation\Application
31
 */
32
function container(?string $basePath = null, ?callable $resolvingCallback = null, array $options = []): Foundation\Application
33
{
34
    return Foundation\Application::make($basePath, $resolvingCallback, $options);
1✔
35
}
36

37
/**
38
 * Run artisan command.
39
 *
40
 * @api
41
 *
42
 * @param  \Orchestra\Testbench\Contracts\TestCase|\Illuminate\Contracts\Foundation\Application  $context
43
 * @param  string  $command
44
 * @param  array<string, mixed>  $parameters
45
 * @return int
46
 */
47
function artisan(Contracts\TestCase|ApplicationContract $context, string $command, array $parameters = []): int
48
{
49
    if ($context instanceof ApplicationContract) {
10✔
50
        return $context->make(ConsoleKernel::class)->call($command, $parameters);
1✔
51
    }
52

53
    $command = $context->artisan($command, $parameters);
10✔
54

55
    return $command instanceof PendingCommand ? $command->run() : $command;
10✔
56
}
57

58
/**
59
 * Run remote action using Testbench CLI.
60
 *
61
 * @api
62
 *
63
 * @param  array<int, string>|string  $command
64
 * @param  array<string, mixed>|string  $env
65
 * @return \Symfony\Component\Process\Process
66
 */
67
function remote(array|string $command, array|string $env = []): Process
68
{
69
    $phpBinary = transform(
9✔
70
        \defined('PHP_BINARY') ? PHP_BINARY : (new PhpExecutableFinder)->find(),
9✔
71
        static function ($phpBinary) {
9✔
72
            return ProcessUtils::escapeArgument((string) $phpBinary);
9✔
73
        }
9✔
74
    );
9✔
75

76
    $binary = \defined('TESTBENCH_DUSK') ? 'testbench-dusk' : 'testbench';
9✔
77

78
    $commander = is_file($vendorBin = package_path('vendor', 'bin', $binary))
9✔
79
        ? ProcessUtils::escapeArgument((string) $vendorBin)
×
80
        : $binary;
9✔
81

82
    if (\is_string($env)) {
9✔
83
        $env = ['APP_ENV' => $env];
×
84
    }
85

86
    Arr::add($env, 'TESTBENCH_PACKAGE_REMOTE', '(true)');
9✔
87

88
    return Process::fromShellCommandline(
9✔
89
        command: Arr::join([$phpBinary, $commander, ...Arr::wrap($command)], ' '),
9✔
90
        cwd: package_path(),
9✔
91
        env: array_merge(defined_environment_variables(), $env)
9✔
92
    );
9✔
93
}
94

95
/**
96
 * Run callback only once.
97
 *
98
 * @api
99
 *
100
 * @param  mixed  $callback
101
 * @return \Closure():mixed
102
 */
103
function once($callback): Closure
104
{
105
    $response = new Foundation\UndefinedValue;
146✔
106

107
    return function () use ($callback, &$response) {
146✔
108
        if ($response instanceof Foundation\UndefinedValue) {
146✔
109
            $response = value($callback) ?? null;
146✔
110
        }
111

112
        return $response;
146✔
113
    };
146✔
114
}
115

116
/**
117
 * Register after resolving callback.
118
 *
119
 * @api
120
 *
121
 * @param  \Illuminate\Contracts\Foundation\Application  $app
122
 * @param  string  $name
123
 * @param  (\Closure(object, \Illuminate\Contracts\Foundation\Application):(mixed))|null  $callback
124
 * @return void
125
 */
126
function after_resolving(ApplicationContract $app, string $name, ?Closure $callback = null): void
127
{
128
    $app->afterResolving($name, $callback);
146✔
129

130
    if ($app->resolved($name)) {
146✔
131
        value($callback, $app->make($name), $app);
5✔
132
    }
133
}
134

135
/**
136
 * Load migration paths.
137
 *
138
 * @api
139
 *
140
 * @param  \Illuminate\Contracts\Foundation\Application  $app
141
 * @param  array<int, string>|string  $paths
142
 * @return void
143
 */
144
function load_migration_paths(ApplicationContract $app, array|string $paths): void
145
{
146
    after_resolving($app, 'migrator', static function ($migrator) use ($paths) {
27✔
147
        foreach (Arr::wrap($paths) as $path) {
15✔
148
            /** @var \Illuminate\Database\Migrations\Migrator $migrator */
149
            $migrator->path($path);
15✔
150
        }
151
    });
27✔
152
}
153

154
/**
155
 * Get default environment variables.
156
 *
157
 * @return array<int, string>
158
 *
159
 * @deprecated
160
 *
161
 * @codeCoverageIgnore
162
 */
163
function default_environment_variables(): array
164
{
165
    return [];
166
}
167

168
/**
169
 * Get defined environment variables.
170
 *
171
 * @api
172
 *
173
 * @return array<string, mixed>
174
 */
175
function defined_environment_variables(): array
176
{
177
    return Collection::make(array_merge($_SERVER, $_ENV))
9✔
178
        ->keys()
9✔
179
        ->mapWithKeys(static function (string $key) {
9✔
180
            return [$key => Env::forward($key)];
9✔
181
        })->unless(
9✔
182
            Env::has('TESTBENCH_WORKING_PATH'), static fn ($env) => $env->put('TESTBENCH_WORKING_PATH', package_path())
9✔
183
        )->all();
9✔
184
}
185

186
/**
187
 * Get default environment variables.
188
 *
189
 * @api
190
 *
191
 * @param  iterable<string, mixed>  $variables
192
 * @return array<int, string>
193
 */
194
function parse_environment_variables($variables): array
195
{
196
    return Collection::make($variables)
4✔
197
        ->transform(static function ($value, $key) {
4✔
198
            if (\is_bool($value) || \in_array($value, ['true', 'false'])) {
4✔
199
                $value = \in_array($value, [true, 'true']) ? '(true)' : '(false)';
4✔
200
            } elseif (\is_null($value) || \in_array($value, ['null'])) {
1✔
201
                $value = '(null)';
1✔
202
            } else {
203
                $value = $key === 'APP_DEBUG' ? \sprintf('(%s)', Str::of($value)->ltrim('(')->rtrim(')')) : "'{$value}'";
1✔
204
            }
205

206
            return "{$key}={$value}";
4✔
207
        })->values()->all();
4✔
208
}
209

210
/**
211
 * Refresh router lookups.
212
 *
213
 * @api
214
 *
215
 * @param  \Illuminate\Routing\Router  $router
216
 * @return void
217
 */
218
function refresh_router_lookups(Router $router): void
219
{
220
    $router->getRoutes()->refreshNameLookups();
146✔
221
}
222

223
/**
224
 * Transform relative path.
225
 *
226
 * @api
227
 *
228
 * @param  string  $path
229
 * @param  string  $workingPath
230
 * @return string
231
 */
232
function transform_relative_path(string $path, string $workingPath): string
233
{
234
    return str_starts_with($path, './')
23✔
235
        ? rtrim($workingPath, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.mb_substr($path, 2)
1✔
236
        : $path;
23✔
237
}
238

239
/**
240
 * Get the default skeleton path.
241
 *
242
 * @api
243
 *
244
 * @param  string  $path
245
 * @return string
246
 */
247
function default_skeleton_path(string $path = ''): string
248
{
249
    return (string) realpath(join_paths(__DIR__, '..', 'laravel', ...Arr::wrap($path)));
143✔
250
}
251

252
/**
253
 * Get the path to the package folder.
254
 *
255
 * @api
256
 *
257
 * @param  array|string  $path
258
 * @return string
259
 */
260
function package_path(array|string $path = ''): string
261
{
262
    $argumentCount = \func_num_args();
48✔
263

264
    $workingPath = \defined('TESTBENCH_WORKING_PATH')
48✔
265
        ? TESTBENCH_WORKING_PATH
17✔
266
        : Env::get('TESTBENCH_WORKING_PATH', getcwd());
31✔
267

268
    if ($argumentCount === 1 && \is_string($path) && str_starts_with($path, './')) {
48✔
269
        return transform_relative_path($path, $workingPath);
×
270
    }
271

272
    $path = join_paths(...Arr::wrap($argumentCount > 1 ? \func_get_args() : $path));
48✔
273

274
    return str_starts_with($path, './')
48✔
275
        ? transform_relative_path($path, $workingPath)
×
276
        : join_paths(rtrim($workingPath, DIRECTORY_SEPARATOR), $path);
48✔
277
}
278

279
/**
280
 * Get the workbench configuration.
281
 *
282
 * @api
283
 *
284
 * @return array<string, mixed>
285
 */
286
function workbench(): array
287
{
288
    /** @var \Orchestra\Testbench\Contracts\Config $config */
289
    $config = app()->bound(Contracts\Config::class)
24✔
290
        ? app()->make(Contracts\Config::class)
22✔
291
        : new Foundation\Config;
2✔
292

293
    return $config->getWorkbenchAttributes();
24✔
294
}
295

296
/**
297
 * Get the path to the workbench folder.
298
 *
299
 * @api
300
 *
301
 * @param  array|string  $path
302
 * @return string
303
 */
304
function workbench_path(array|string $path = ''): string
305
{
306
    return package_path(join_paths('workbench', ...Arr::wrap(\func_num_args() > 1 ? \func_get_args() : $path)));
29✔
307
}
308

309
/**
310
 * Get the migration path by type.
311
 *
312
 * @api
313
 *
314
 * @param  string|null  $type
315
 * @return string
316
 *
317
 * @throws \InvalidArgumentException
318
 */
319
function laravel_migration_path(?string $type = null): string
320
{
321
    $path = realpath(
33✔
322
        \is_null($type) ? base_path('migrations') : base_path(join_paths('migrations', $type))
33✔
323
    );
33✔
324

325
    if ($path === false) {
33✔
326
        throw new InvalidArgumentException(\sprintf('Unable to resolve migration path for type [%s]', $type ?? 'laravel'));
×
327
    }
328

329
    return $path;
33✔
330
}
331

332
/**
333
 * Laravel version compare.
334
 *
335
 * @api
336
 *
337
 * @param  string  $version
338
 * @param  string|null  $operator
339
 * @return int|bool
340
 */
341
function laravel_version_compare(string $version, ?string $operator = null)
342
{
343
    /** @phpstan-ignore identical.alwaysFalse */
344
    $laravel = Application::VERSION === '9.x-dev' ? '9.0.0' : Application::VERSION;
5✔
345

346
    if (\is_null($operator)) {
5✔
347
        return version_compare($laravel, $version);
1✔
348
    }
349

350
    return version_compare($laravel, $version, $operator);
5✔
351
}
352

353
/**
354
 * PHPUnit version compare.
355
 *
356
 * @api
357
 *
358
 * @param  string  $version
359
 * @param  string|null  $operator
360
 * @return int|bool
361
 *
362
 * @throws \RuntimeException
363
 */
364
function phpunit_version_compare(string $version, ?string $operator = null)
365
{
366
    if (! class_exists(Version::class)) {
3✔
367
        throw new RuntimeException('Unable to verify PHPUnit version');
×
368
    }
369

370
    if (\is_null($operator)) {
3✔
371
        return version_compare(Version::id(), $version);
1✔
372
    }
373

374
    return version_compare(Version::id(), $version, $operator);
3✔
375
}
376

377
/**
378
 * Join the given paths together.
379
 *
380
 * @param  string|null  $basePath
381
 * @param  string  ...$paths
382
 * @return string
383
 */
384
function join_paths(?string $basePath, string ...$paths): string
385
{
386
    foreach ($paths as $index => $path) {
146✔
387
        if (empty($path) && $path !== '0') {
146✔
388
            unset($paths[$index]);
143✔
389
        } else {
390
            $paths[$index] = DIRECTORY_SEPARATOR.ltrim($path, DIRECTORY_SEPARATOR);
146✔
391
        }
392
    }
393

394
    return $basePath.implode('', $paths);
146✔
395
}
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