From 479dba69c751e5739de2af3ac6e1bba8e90a2560 Mon Sep 17 00:00:00 2001 From: Antoine Lamirault Date: Sat, 9 Apr 2022 20:26:13 +0200 Subject: [PATCH 1/4] [Console] Header with column max width is now well wrap with separator --- Helper/Table.php | 93 +++++++++++++++++++++++--------------- Tests/Helper/TableTest.php | 35 ++++++++++++++ 2 files changed, 92 insertions(+), 36 deletions(-) diff --git a/Helper/Table.php b/Helper/Table.php index 868374ab3..a5f34cb14 100644 --- a/Helper/Table.php +++ b/Helper/Table.php @@ -369,41 +369,59 @@ public function render() $this->calculateNumberOfColumns($rows); - $rows = $this->buildTableRows($rows); - $this->calculateColumnsWidth($rows); + $rowGroups = $this->buildTableRows($rows); + $this->calculateColumnsWidth($rowGroups); $isHeader = !$this->horizontal; $isFirstRow = $this->horizontal; $hasTitle = (bool) $this->headerTitle; - foreach ($rows as $row) { - if ($divider === $row) { - $isHeader = false; - $isFirstRow = true; - continue; - } - if ($row instanceof TableSeparator) { - $this->renderRowSeparator(); + foreach ($rowGroups as $rowGroup) { + $isHeaderSeparatorRendered = false; - continue; - } - if (!$row) { - continue; - } + foreach ($rowGroup as $row) { + if ($divider === $row) { + $isHeader = false; + $isFirstRow = true; - if ($isHeader || $isFirstRow) { - $this->renderRowSeparator( - $isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM, - $hasTitle ? $this->headerTitle : null, - $hasTitle ? $this->style->getHeaderTitleFormat() : null - ); - $isFirstRow = false; - $hasTitle = false; - } - if ($this->horizontal) { - $this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat()); - } else { - $this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat()); + continue; + } + + if ($row instanceof TableSeparator) { + $this->renderRowSeparator(); + + continue; + } + + if (!$row) { + continue; + } + + if ($isHeader && !$isHeaderSeparatorRendered) { + $this->renderRowSeparator( + $isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM, + $hasTitle ? $this->headerTitle : null, + $hasTitle ? $this->style->getHeaderTitleFormat() : null + ); + $hasTitle = false; + $isHeaderSeparatorRendered = true; + } + + if ($isFirstRow) { + $this->renderRowSeparator( + $isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM, + $hasTitle ? $this->headerTitle : null, + $hasTitle ? $this->style->getHeaderTitleFormat() : null + ); + $isFirstRow = false; + $hasTitle = false; + } + + if ($this->horizontal) { + $this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat()); + } else { + $this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat()); + } } } $this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat()); @@ -587,13 +605,14 @@ private function buildTableRows(array $rows): TableRows return new TableRows(function () use ($rows, $unmergedRows): \Traversable { foreach ($rows as $rowKey => $row) { - yield $row instanceof TableSeparator ? $row : $this->fillCells($row); + $rowGroup = [$row instanceof TableSeparator ? $row : $this->fillCells($row)]; if (isset($unmergedRows[$rowKey])) { foreach ($unmergedRows[$rowKey] as $row) { - yield $row instanceof TableSeparator ? $row : $this->fillCells($row); + $rowGroup[] = $row instanceof TableSeparator ? $row : $this->fillCells($row); } } + yield $rowGroup; } }); } @@ -734,14 +753,15 @@ private function getRowColumns(array $row): array /** * Calculates columns widths. */ - private function calculateColumnsWidth(iterable $rows) + private function calculateColumnsWidth(iterable $groups) { for ($column = 0; $column < $this->numberOfColumns; ++$column) { $lengths = []; - foreach ($rows as $row) { - if ($row instanceof TableSeparator) { - continue; - } + foreach ($groups as $group) { + foreach ($group as $row) { + if ($row instanceof TableSeparator) { + continue; + } foreach ($row as $i => $cell) { if ($cell instanceof TableCell) { @@ -756,7 +776,8 @@ private function calculateColumnsWidth(iterable $rows) } } - $lengths[] = $this->getCellWidth($row, $column); + $lengths[] = $this->getCellWidth($row, $column); + } } $this->effectiveColumnWidths[$column] = max($lengths) + Helper::strlen($this->style->getCellRowContentFormat()) - 2; diff --git a/Tests/Helper/TableTest.php b/Tests/Helper/TableTest.php index d69e81742..14ea5c6bb 100644 --- a/Tests/Helper/TableTest.php +++ b/Tests/Helper/TableTest.php @@ -1158,6 +1158,41 @@ public function testColumnMaxWidths() | | ities | | | +---------------+-------+------------+-----------------+ +TABLE; + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + public function testColumnMaxWidthsHeaders() + { + $table = new Table($output = $this->getOutputStream()); + $table + ->setHeaders([ + [ + 'Publication', + 'Very long header with a lot of information', + ], + ]) + ->setRows([ + [ + '1954', + 'The Lord of the Rings, by J.R.R. Tolkien', + ], + ]) + ->setColumnMaxWidth(1, 30); + + $table->render(); + + $expected = + <<assertEquals($expected, $this->getOutputContent($output)); From 0e1e62083b20ccb39c2431293de060f756af905c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Tue, 12 Apr 2022 17:18:48 +0200 Subject: [PATCH 2/4] Add missing license header --- Tests/Helper/ProgressIndicatorTest.php | 9 +++++++++ Tests/Helper/SymfonyQuestionHelperTest.php | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/Tests/Helper/ProgressIndicatorTest.php b/Tests/Helper/ProgressIndicatorTest.php index bbbde217c..cd97d406e 100644 --- a/Tests/Helper/ProgressIndicatorTest.php +++ b/Tests/Helper/ProgressIndicatorTest.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Component\Console\Tests\Helper; use PHPUnit\Framework\TestCase; diff --git a/Tests/Helper/SymfonyQuestionHelperTest.php b/Tests/Helper/SymfonyQuestionHelperTest.php index fd5442b7f..b8623e199 100644 --- a/Tests/Helper/SymfonyQuestionHelperTest.php +++ b/Tests/Helper/SymfonyQuestionHelperTest.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Component\Console\Tests\Helper; use Symfony\Component\Console\Exception\RuntimeException; From ffe3aed36c4d60da2cf1b0a1cee6b8f2e5fa881b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Tue, 12 Apr 2022 17:53:34 +0200 Subject: [PATCH 3/4] Add missing license header --- Formatter/NullOutputFormatterStyle.php | 1 + Tests/Command/DumpCompletionCommandTest.php | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/Formatter/NullOutputFormatterStyle.php b/Formatter/NullOutputFormatterStyle.php index bfd0afedd..9232510f4 100644 --- a/Formatter/NullOutputFormatterStyle.php +++ b/Formatter/NullOutputFormatterStyle.php @@ -1,4 +1,5 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Component\Console\Tests\Command; use PHPUnit\Framework\TestCase; From 0d00aa289215353aa8746a31d101f8e60826285c Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Wed, 20 Apr 2022 17:01:42 +0200 Subject: [PATCH 4/4] Minor @requires function tests cleanup --- Tests/Helper/QuestionHelperTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/Tests/Helper/QuestionHelperTest.php b/Tests/Helper/QuestionHelperTest.php index 1297b92f9..95ab1b302 100644 --- a/Tests/Helper/QuestionHelperTest.php +++ b/Tests/Helper/QuestionHelperTest.php @@ -714,9 +714,6 @@ public function testNoInteraction() $this->assertEquals('not yet', $dialog->ask($this->createStreamableInputInterfaceMock(null, false), $this->createOutputInterface(), $question)); } - /** - * @requires function mb_strwidth - */ public function testChoiceOutputFormattingQuestionForUtf8Keys() { $question = 'Lorem ipsum?';