Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 35d41c6

Browse files
cdekokchalasr
authored andcommitted
[Console] Add support for error ouput in the CommandTester
1 parent a26bd36 commit 35d41c6

File tree

6 files changed

+115
-68
lines changed

6 files changed

+115
-68
lines changed

src/Symfony/Component/Console/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
pass it the command as an array of its arguments instead
1111
* made the `ProcessHelper` class final
1212
* added `WrappableOutputFormatterInterface::formatAndWrap()` (implemented in `OutputFormatter`)
13+
* added `capture_stderr_separately` option to `CommandTester::execute()`
1314

1415
4.1.0
1516
-----

src/Symfony/Component/Console/Tester/ApplicationTester.php

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313

1414
use Symfony\Component\Console\Application;
1515
use Symfony\Component\Console\Input\ArrayInput;
16-
use Symfony\Component\Console\Output\ConsoleOutput;
17-
use Symfony\Component\Console\Output\StreamOutput;
1816

1917
/**
2018
* Eases the testing of console applications.
@@ -33,7 +31,6 @@ class ApplicationTester
3331
private $application;
3432
private $input;
3533
private $statusCode;
36-
private $captureStreamsIndependently = false;
3734

3835
public function __construct(Application $application)
3936
{
@@ -69,65 +66,12 @@ public function run(array $input, $options = array())
6966
putenv('SHELL_INTERACTIVE=1');
7067
}
7168

72-
$this->captureStreamsIndependently = array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately'];
73-
if (!$this->captureStreamsIndependently) {
74-
$this->output = new StreamOutput(fopen('php://memory', 'w', false));
75-
if (isset($options['decorated'])) {
76-
$this->output->setDecorated($options['decorated']);
77-
}
78-
if (isset($options['verbosity'])) {
79-
$this->output->setVerbosity($options['verbosity']);
80-
}
81-
} else {
82-
$this->output = new ConsoleOutput(
83-
isset($options['verbosity']) ? $options['verbosity'] : ConsoleOutput::VERBOSITY_NORMAL,
84-
isset($options['decorated']) ? $options['decorated'] : null
85-
);
86-
87-
$errorOutput = new StreamOutput(fopen('php://memory', 'w', false));
88-
$errorOutput->setFormatter($this->output->getFormatter());
89-
$errorOutput->setVerbosity($this->output->getVerbosity());
90-
$errorOutput->setDecorated($this->output->isDecorated());
91-
92-
$reflectedOutput = new \ReflectionObject($this->output);
93-
$strErrProperty = $reflectedOutput->getProperty('stderr');
94-
$strErrProperty->setAccessible(true);
95-
$strErrProperty->setValue($this->output, $errorOutput);
96-
97-
$reflectedParent = $reflectedOutput->getParentClass();
98-
$streamProperty = $reflectedParent->getProperty('stream');
99-
$streamProperty->setAccessible(true);
100-
$streamProperty->setValue($this->output, fopen('php://memory', 'w', false));
101-
}
69+
$this->initOutput($options);
10270

10371
$this->statusCode = $this->application->run($this->input, $this->output);
10472

10573
putenv($shellInteractive ? "SHELL_INTERACTIVE=$shellInteractive" : 'SHELL_INTERACTIVE');
10674

10775
return $this->statusCode;
10876
}
109-
110-
/**
111-
* Gets the output written to STDERR by the application.
112-
*
113-
* @param bool $normalize Whether to normalize end of lines to \n or not
114-
*
115-
* @return string
116-
*/
117-
public function getErrorOutput($normalize = false)
118-
{
119-
if (!$this->captureStreamsIndependently) {
120-
throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.');
121-
}
122-
123-
rewind($this->output->getErrorOutput()->getStream());
124-
125-
$display = stream_get_contents($this->output->getErrorOutput()->getStream());
126-
127-
if ($normalize) {
128-
$display = str_replace(PHP_EOL, "\n", $display);
129-
}
130-
131-
return $display;
132-
}
13377
}

src/Symfony/Component/Console/Tester/CommandTester.php

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use Symfony\Component\Console\Command\Command;
1515
use Symfony\Component\Console\Input\ArrayInput;
16-
use Symfony\Component\Console\Output\StreamOutput;
1716

1817
/**
1918
* Eases the testing of console commands.
@@ -39,9 +38,10 @@ public function __construct(Command $command)
3938
*
4039
* Available execution options:
4140
*
42-
* * interactive: Sets the input interactive flag
43-
* * decorated: Sets the output decorated flag
44-
* * verbosity: Sets the output verbosity flag
41+
* * interactive: Sets the input interactive flag
42+
* * decorated: Sets the output decorated flag
43+
* * verbosity: Sets the output verbosity flag
44+
* * capture_stderr_separately: Make output of stdOut and stdErr separately available
4545
*
4646
* @param array $input An array of command arguments and options
4747
* @param array $options An array of execution options
@@ -68,11 +68,7 @@ public function execute(array $input, array $options = array())
6868
$this->input->setInteractive($options['interactive']);
6969
}
7070

71-
$this->output = new StreamOutput(fopen('php://memory', 'w', false));
72-
$this->output->setDecorated(isset($options['decorated']) ? $options['decorated'] : false);
73-
if (isset($options['verbosity'])) {
74-
$this->output->setVerbosity($options['verbosity']);
75-
}
71+
$this->initOutput($options);
7672

7773
return $this->statusCode = $this->command->run($this->input, $this->output);
7874
}

src/Symfony/Component/Console/Tester/TesterTrait.php

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,19 @@
1212
namespace Symfony\Component\Console\Tester;
1313

1414
use Symfony\Component\Console\Input\InputInterface;
15+
use Symfony\Component\Console\Output\ConsoleOutput;
1516
use Symfony\Component\Console\Output\OutputInterface;
1617
use Symfony\Component\Console\Output\StreamOutput;
1718

1819
/**
1920
* @author Amrouche Hamza <[email protected]>
20-
*
21-
* @internal
2221
*/
2322
trait TesterTrait
2423
{
2524
/** @var StreamOutput */
2625
private $output;
2726
private $inputs = array();
27+
private $captureStreamsIndependently = false;
2828

2929
/**
3030
* Gets the display returned by the last execution of the command or application.
@@ -46,6 +46,30 @@ public function getDisplay($normalize = false)
4646
return $display;
4747
}
4848

49+
/**
50+
* Gets the output written to STDERR by the application.
51+
*
52+
* @param bool $normalize Whether to normalize end of lines to \n or not
53+
*
54+
* @return string
55+
*/
56+
public function getErrorOutput($normalize = false)
57+
{
58+
if (!$this->captureStreamsIndependently) {
59+
throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.');
60+
}
61+
62+
rewind($this->output->getErrorOutput()->getStream());
63+
64+
$display = stream_get_contents($this->output->getErrorOutput()->getStream());
65+
66+
if ($normalize) {
67+
$display = str_replace(PHP_EOL, "\n", $display);
68+
}
69+
70+
return $display;
71+
}
72+
4973
/**
5074
* Gets the input instance used by the last execution of the command or application.
5175
*
@@ -91,6 +115,49 @@ public function setInputs(array $inputs)
91115
return $this;
92116
}
93117

118+
/**
119+
* Initializes the output property.
120+
*
121+
* Available options:
122+
*
123+
* * decorated: Sets the output decorated flag
124+
* * verbosity: Sets the output verbosity flag
125+
* * capture_stderr_separately: Make output of stdOut and stdErr separately available
126+
*/
127+
private function initOutput(array $options)
128+
{
129+
$this->captureStreamsIndependently = array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately'];
130+
if (!$this->captureStreamsIndependently) {
131+
$this->output = new StreamOutput(fopen('php://memory', 'w', false));
132+
if (isset($options['decorated'])) {
133+
$this->output->setDecorated($options['decorated']);
134+
}
135+
if (isset($options['verbosity'])) {
136+
$this->output->setVerbosity($options['verbosity']);
137+
}
138+
} else {
139+
$this->output = new ConsoleOutput(
140+
isset($options['verbosity']) ? $options['verbosity'] : ConsoleOutput::VERBOSITY_NORMAL,
141+
isset($options['decorated']) ? $options['decorated'] : null
142+
);
143+
144+
$errorOutput = new StreamOutput(fopen('php://memory', 'w', false));
145+
$errorOutput->setFormatter($this->output->getFormatter());
146+
$errorOutput->setVerbosity($this->output->getVerbosity());
147+
$errorOutput->setDecorated($this->output->isDecorated());
148+
149+
$reflectedOutput = new \ReflectionObject($this->output);
150+
$strErrProperty = $reflectedOutput->getProperty('stderr');
151+
$strErrProperty->setAccessible(true);
152+
$strErrProperty->setValue($this->output, $errorOutput);
153+
154+
$reflectedParent = $reflectedOutput->getParentClass();
155+
$streamProperty = $reflectedParent->getProperty('stream');
156+
$streamProperty->setAccessible(true);
157+
$streamProperty->setValue($this->output, fopen('php://memory', 'w', false));
158+
}
159+
}
160+
94161
private static function createStream(array $inputs)
95162
{
96163
$stream = fopen('php://memory', 'r+', false);

src/Symfony/Component/Console/Tests/Tester/ApplicationTesterTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,24 @@ public function testGetStatusCode()
9090
{
9191
$this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code');
9292
}
93+
94+
public function testErrorOutput()
95+
{
96+
$application = new Application();
97+
$application->setAutoExit(false);
98+
$application->register('foo')
99+
->addArgument('foo')
100+
->setCode(function ($input, $output) {
101+
$output->getErrorOutput()->write('foo');
102+
})
103+
;
104+
105+
$tester = new ApplicationTester($application);
106+
$tester->run(
107+
array('command' => 'foo', 'foo' => 'bar'),
108+
array('capture_stderr_separately' => true)
109+
);
110+
111+
$this->assertSame('foo', $tester->getErrorOutput());
112+
}
93113
}

src/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,23 @@ public function testSymfonyStyleCommandWithInputs()
160160

161161
$this->assertEquals(0, $tester->getStatusCode());
162162
}
163+
164+
public function testErrorOutput()
165+
{
166+
$command = new Command('foo');
167+
$command->addArgument('command');
168+
$command->addArgument('foo');
169+
$command->setCode(function ($input, $output) {
170+
$output->getErrorOutput()->write('foo');
171+
}
172+
);
173+
174+
$tester = new CommandTester($command);
175+
$tester->execute(
176+
array('foo' => 'bar'),
177+
array('capture_stderr_separately' => true)
178+
);
179+
180+
$this->assertSame('foo', $tester->getErrorOutput());
181+
}
163182
}

0 commit comments

Comments
 (0)