diff --git a/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php b/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php index d4c2f20c71741..527c1a224f8b2 100644 --- a/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php +++ b/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php @@ -87,6 +87,14 @@ public function addContent(string $input) } } + /** + * @internal + */ + public function incrementLines() + { + ++$this->lines; + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Console/Style/SymfonyStyle.php b/src/Symfony/Component/Console/Style/SymfonyStyle.php index f13c313d3a5c2..1de3b552f333d 100644 --- a/src/Symfony/Component/Console/Style/SymfonyStyle.php +++ b/src/Symfony/Component/Console/Style/SymfonyStyle.php @@ -22,6 +22,7 @@ use Symfony\Component\Console\Helper\TableSeparator; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Console\Output\ConsoleSectionOutput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\TrimmedBufferOutput; use Symfony\Component\Console\Question\ChoiceQuestion; @@ -350,6 +351,11 @@ public function askQuestion(Question $question): mixed if ($this->input->isInteractive()) { $this->newLine(); $this->bufferedOutput->write("\n"); + if ($this->output instanceof ConsoleSectionOutput) { + // add one line more to the ConsoleSectionOutput because of the `return` to submit the input + // this is relevant when a `ConsoleSectionOutput::clear` is called. + $this->output->incrementLines(); + } } return $answer; diff --git a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php index 74c24034095b1..3441449da9c60 100644 --- a/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php +++ b/src/Symfony/Component/Console/Tests/Style/SymfonyStyleTest.php @@ -16,11 +16,13 @@ use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\Input; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\ConsoleSectionOutput; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\StreamOutput; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Console\Tester\CommandTester; @@ -181,4 +183,38 @@ public function testMemoryConsumption() $this->assertSame(0, memory_get_usage() - $start); } + + public function testAskAndClearExpectFullSectionCleared() + { + $answer = 'Answer'; + $inputStream = fopen('php://memory', 'r+'); + fwrite($inputStream, $answer.\PHP_EOL); + rewind($inputStream); + $input = $this->createMock(Input::class); + $sections = []; + $output = new ConsoleSectionOutput(fopen('php://memory', 'r+', false), $sections, StreamOutput::VERBOSITY_NORMAL, true, new OutputFormatter()); + $input + ->method('isInteractive') + ->willReturn(true); + $input + ->method('getStream') + ->willReturn($inputStream); + + $style = new SymfonyStyle($input, $output); + + $style->write('foo'); + $givenAnswer = $style->ask('Dummy question?'); + $output->write('bar'); + $output->clear(); + + rewind($output->getStream()); + $this->assertEquals($answer, $givenAnswer); + $this->assertEquals( + 'foo'.\PHP_EOL. // write foo + \PHP_EOL.\PHP_EOL.\PHP_EOL." \033[32mDummy question?\033[39m:".\PHP_EOL.' > '.\PHP_EOL.\PHP_EOL.\PHP_EOL. // question + 'bar'.\PHP_EOL. // write bar + "\033[10A\033[0J", // clear 10 lines (9 output lines and one from the answer input return) + stream_get_contents($output->getStream()) + ); + } }