From 3d4e95ef71041d5e4bf6b9d7ddc5b1d90b47be48 Mon Sep 17 00:00:00 2001 From: Rob Bast Date: Mon, 14 Sep 2015 18:17:21 +0200 Subject: [PATCH] [Console] default to stderr in the console helpers --- .../Component/Console/Helper/DialogHelper.php | 17 +++++ .../Console/Helper/ProgressHelper.php | 5 ++ .../Console/Tests/Helper/DialogHelperTest.php | 69 ++++++++++++++++++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Helper/DialogHelper.php b/src/Symfony/Component/Console/Helper/DialogHelper.php index fbb0f06623..6acbed071e 100644 --- a/src/Symfony/Component/Console/Helper/DialogHelper.php +++ b/src/Symfony/Component/Console/Helper/DialogHelper.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Console\Helper; +use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Formatter\OutputFormatterStyle; @@ -42,6 +43,10 @@ class DialogHelper extends Helper */ public function select(OutputInterface $output, $question, $choices, $default = null, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false) { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $width = max(array_map('strlen', array_keys($choices))); $messages = (array) $question; @@ -98,6 +103,10 @@ class DialogHelper extends Helper */ public function ask(OutputInterface $output, $question, $default = null, array $autocomplete = null) { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $output->write($question); $inputStream = $this->inputStream ?: STDIN; @@ -255,6 +264,10 @@ class DialogHelper extends Helper */ public function askHiddenResponse(OutputInterface $output, $question, $fallback = true) { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + if ('\\' === DIRECTORY_SEPARATOR) { $exe = __DIR__.'/../Resources/bin/hiddeninput.exe'; @@ -452,6 +465,10 @@ class DialogHelper extends Helper */ private function validateAttempts($interviewer, OutputInterface $output, $validator, $attempts) { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $e = null; while (false === $attempts || $attempts--) { if (null !== $e) { diff --git a/src/Symfony/Component/Console/Helper/ProgressHelper.php b/src/Symfony/Component/Console/Helper/ProgressHelper.php index 7d80107909..2c235079da 100644 --- a/src/Symfony/Component/Console/Helper/ProgressHelper.php +++ b/src/Symfony/Component/Console/Helper/ProgressHelper.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Console\Helper; +use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; /** @@ -182,6 +183,10 @@ class ProgressHelper extends Helper */ public function start(OutputInterface $output, $max = null) { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $this->startTime = time(); $this->current = 0; $this->max = (int) $max; diff --git a/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php b/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php index 8caf6569c6..3cee58f887 100644 --- a/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php @@ -14,6 +14,7 @@ namespace Symfony\Component\Console\Tests\Helper; use Symfony\Component\Console\Helper\DialogHelper; use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Helper\FormatterHelper; +use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Console\Output\StreamOutput; class DialogHelperTest extends \PHPUnit_Framework_TestCase @@ -50,6 +51,22 @@ class DialogHelperTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array('0', '1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, ' 0 , 1 ', false, 'Input "%s" is not a superhero!', true)); } + public function testSelectOnErrorOutput() + { + $dialog = new DialogHelper(); + + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $heroes = array('Superman', 'Batman', 'Spiderman'); + + $dialog->setInputStream($this->getInputStream("Stdout\n1\n")); + $this->assertEquals('1', $dialog->select($output = $this->getConsoleOutput($this->getOutputStream()), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', false)); + + rewind($output->getErrorOutput()->getStream()); + $this->assertContains('Input "Stdout" is not a superhero!', stream_get_contents($output->getErrorOutput()->getStream())); + } + public function testAsk() { $dialog = new DialogHelper(); @@ -63,6 +80,22 @@ class DialogHelperTest extends \PHPUnit_Framework_TestCase $this->assertEquals('What time is it?', stream_get_contents($output->getStream())); } + public function testAskOnErrorOutput() + { + if (!$this->hasSttyAvailable()) { + $this->markTestSkipped('`stderr` is required to test stderr output functionality'); + } + + $dialog = new DialogHelper(); + + $dialog->setInputStream($this->getInputStream("not stdout\n")); + + $this->assertEquals('not stdout', $dialog->ask($output = $this->getConsoleOutput($this->getOutputStream()), 'Where should output go?', 'stderr')); + + rewind($output->getErrorOutput()->getStream()); + $this->assertEquals('Where should output go?', stream_get_contents($output->getErrorOutput()->getStream())); + } + public function testAskWithAutocomplete() { if (!$this->hasSttyAvailable()) { @@ -110,6 +143,25 @@ class DialogHelperTest extends \PHPUnit_Framework_TestCase $this->assertEquals('8AM', $dialog->askHiddenResponse($this->getOutputStream(), 'What time is it?')); } + /** + * @group tty + */ + public function testAskHiddenResponseOnErrorOutput() + { + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('This test is not supported on Windows'); + } + + $dialog = new DialogHelper(); + + $dialog->setInputStream($this->getInputStream("8AM\n")); + + $this->assertEquals('8AM', $dialog->askHiddenResponse($output = $this->getConsoleOutput($this->getOutputStream()), 'What time is it?')); + + rewind($output->getErrorOutput()->getStream()); + $this->assertContains('What time is it?', stream_get_contents($output->getErrorOutput()->getStream())); + } + public function testAskConfirmation() { $dialog = new DialogHelper(); @@ -149,10 +201,12 @@ class DialogHelperTest extends \PHPUnit_Framework_TestCase $dialog->setInputStream($this->getInputStream("green\nyellow\norange\n")); try { - $this->assertEquals('white', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white')); + $this->assertEquals('white', $dialog->askAndValidate($output = $this->getConsoleOutput($this->getOutputStream()), $question, $validator, 2, 'white')); $this->fail(); } catch (\InvalidArgumentException $e) { $this->assertEquals($error, $e->getMessage()); + rewind($output->getErrorOutput()->getStream()); + $this->assertContains('What color was the white horse of Henry IV?', stream_get_contents($output->getErrorOutput()->getStream())); } } @@ -170,6 +224,19 @@ class DialogHelperTest extends \PHPUnit_Framework_TestCase return new StreamOutput(fopen('php://memory', 'r+', false)); } + protected function getConsoleOutput($stderr) + { + $output = new ConsoleOutput(); + $output->setErrorOutput($stderr); + + return $output; + } + + private function hasStderrSupport() + { + return false === $this->isRunningOS400(); + } + private function hasSttyAvailable() { exec('stty 2>&1', $output, $exitcode);