-
Notifications
You must be signed in to change notification settings - Fork 1
/
ConsoleTrait.php
109 lines (89 loc) · 3.21 KB
/
ConsoleTrait.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<?php
declare(strict_types=1);
namespace YourNamespace\App\Tests\Traits;
use PHPUnit\Framework\AssertionFailedError;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Tester\ApplicationTester;
/**
* Trait ConsoleTrait.
*
* Helpers to work with Console.
*
* @phpstan-ignore trait.unused
*/
trait ConsoleTrait {
use ReflectionTrait;
/**
* Application tester.
*/
protected ApplicationTester $appTester;
/**
* Initialize application tester.
*
* @param string|object $object_or_class
* Command class or object.
* @param bool $is_single_command
* Is single command. Defaults to TRUE.
*/
protected function consoleInitApplicationTester(string|object $object_or_class, bool $is_single_command = TRUE): void {
$application = new Application();
$instance = is_object($object_or_class) ? $object_or_class : new $object_or_class();
if (!$instance instanceof Command) {
throw new \InvalidArgumentException('The provided object is not an instance of Command');
}
$application->add($instance);
$name = $instance->getName();
if (empty($name)) {
$ret = $this->getProtectedValue($instance, 'defaultName');
if (!empty($ret) || !is_string($ret)) {
throw new \InvalidArgumentException('The provided object does not have a valid name');
}
$name = $ret;
}
$application->setDefaultCommand($name, $is_single_command);
$application->setAutoExit(FALSE);
$application->setCatchExceptions(FALSE);
$application->setCatchErrors(FALSE);
$this->appTester = new ApplicationTester($application);
}
/**
* Run console application.
*
* @param array<string, string> $input
* Input arguments.
* @param array<string, string> $options
* Options.
* @param bool $expect_fail
* Whether a failure is expected. Defaults to FALSE.
*
* @return string
* Run output (stdout or stderr).
*/
protected function consoleApplicationRun(array $input = [], array $options = [], bool $expect_fail = FALSE): string {
$output = '';
$options += ['capture_stderr_separately' => TRUE];
try {
$this->appTester->run($input, $options);
$output = $this->appTester->getDisplay();
if ($this->appTester->getStatusCode() !== 0) {
throw new \Exception(sprintf("Application exited with non-zero code.\nThe output was:\n%s\nThe error output was:\n%s", $this->appTester->getDisplay(), $this->appTester->getErrorOutput()));
}
if ($expect_fail) {
throw new AssertionFailedError(sprintf("Application exited successfully but should not.\nThe output was:\n%s\nThe error output was:\n%s", $this->appTester->getDisplay(), $this->appTester->getErrorOutput()));
}
}
catch (\RuntimeException $exception) {
if (!$expect_fail) {
throw new AssertionFailedError('Application exited with an error:' . PHP_EOL . $exception->getMessage());
}
$output = $exception->getMessage();
}
catch (\Exception $exception) {
if (!$expect_fail) {
throw new AssertionFailedError('Application exited with an error:' . PHP_EOL . $exception->getMessage());
}
}
return $output;
}
}