[Console] Fix clearing sections containing questions

This commit is contained in:
Robin Chalas 2018-09-29 17:25:52 +02:00
parent 0e47775d62
commit 81ec57d7ce
3 changed files with 42 additions and 6 deletions

View File

@ -17,6 +17,7 @@ use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\StreamableInputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\Question;
@ -123,6 +124,10 @@ class QuestionHelper extends Helper
$ret = trim($this->autocomplete($output, $question, $inputStream, \is_array($autocomplete) ? $autocomplete : iterator_to_array($autocomplete, false)));
}
if ($output instanceof ConsoleSectionOutput) {
$output->addContent($ret);
}
$ret = \strlen($ret) > 0 ? $ret : $question->getDefault();
if ($normalizer = $question->getNormalizer()) {

View File

@ -77,6 +77,18 @@ class ConsoleSectionOutput extends StreamOutput
return implode('', $this->content);
}
/**
* @internal
*/
public function addContent(string $input)
{
foreach (explode(PHP_EOL, $input) as $lineContent) {
$this->lines += ceil($this->getDisplayLength($lineContent) / $this->terminal->getWidth()) ?: 1;
$this->content[] = $lineContent;
$this->content[] = PHP_EOL;
}
}
/**
* {@inheritdoc}
*/
@ -88,11 +100,7 @@ class ConsoleSectionOutput extends StreamOutput
$erasedContent = $this->popStreamContentUntilCurrentSection();
foreach (explode(PHP_EOL, $message) as $lineContent) {
$this->lines += ceil($this->getDisplayLength($lineContent) / $this->terminal->getWidth()) ?: 1;
$this->content[] = $lineContent;
$this->content[] = PHP_EOL;
}
$this->addContent($message);
parent::doWrite($message, true);
parent::doWrite($erasedContent, false);

View File

@ -13,9 +13,12 @@ namespace Symfony\Component\Console\Tests\Output;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\StreamableInputInterface;
use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Question\Question;
class ConsoleSectionOutputTest extends TestCase
{
@ -23,7 +26,7 @@ class ConsoleSectionOutputTest extends TestCase
protected function setUp()
{
$this->stream = fopen('php://memory', 'r+', false);
$this->stream = fopen('php://memory', 'r+b', false);
}
protected function tearDown()
@ -137,4 +140,24 @@ class ConsoleSectionOutputTest extends TestCase
rewind($output->getStream());
$this->assertEquals('Foo'.PHP_EOL.'Bar'.PHP_EOL."\x1b[2A\x1b[0JBar".PHP_EOL."\x1b[1A\x1b[0JBaz".PHP_EOL.'Bar'.PHP_EOL."\x1b[1A\x1b[0JFoobar".PHP_EOL, stream_get_contents($output->getStream()));
}
public function testClearSectionContainingQuestion()
{
$inputStream = fopen('php://memory', 'r+b', false);
fwrite($inputStream, "Batman & Robin\n");
rewind($inputStream);
$input = $this->getMockBuilder(StreamableInputInterface::class)->getMock();
$input->expects($this->once())->method('isInteractive')->willReturn(true);
$input->expects($this->once())->method('getStream')->willReturn($inputStream);
$sections = array();
$output = new ConsoleSectionOutput($this->stream, $sections, OutputInterface::VERBOSITY_NORMAL, true, new OutputFormatter());
(new QuestionHelper())->ask($input, $output, new Question('What\'s your favorite super hero?'));
$output->clear();
rewind($output->getStream());
$this->assertSame('What\'s your favorite super hero?'.PHP_EOL."\x1b[2A\x1b[0J", stream_get_contents($output->getStream()));
}
}