Skip to content

Commit

Permalink
Fix table output when keys are inconsistent.
Browse files Browse the repository at this point in the history
I noticed this when doing the workshops at Cakefest this year. Not
having to match the array keys up makes building tables easier as the
value order of the first row was being used implicit order.
  • Loading branch information
markstory committed Jun 17, 2017
1 parent e123f00 commit 62b8066
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
9 changes: 6 additions & 3 deletions src/Shell/Helper/TableHelper.php
Expand Up @@ -43,8 +43,8 @@ protected function _calculateWidths($rows)
{
$widths = [];
foreach ($rows as $line) {
foreach ($line as $k => $v) {
$columnLength = mb_strwidth($line[$k]);
foreach (array_values($line) as $k => $v) {
$columnLength = mb_strwidth($v);
if ($columnLength >= (isset($widths[$k]) ? $widths[$k] : 0)) {
$widths[$k] = $columnLength;
}
Expand Down Expand Up @@ -85,7 +85,7 @@ protected function _render(array $row, $widths, $options = [])
}

$out = '';
foreach ($row as $i => $column) {
foreach (array_values($row) as $i => $column) {
$pad = $widths[$i] - mb_strwidth($column);
if (!empty($options['style'])) {
$column = $this->_addStyle($column, $options['style']);
Expand All @@ -99,6 +99,9 @@ protected function _render(array $row, $widths, $options = [])
/**
* Output a table.
*
* Data will be output based on the order of the values
* in the array. The keys will not be used to align data.
*
* @param array $rows The data to render out.
* @return void
*/
Expand Down
34 changes: 32 additions & 2 deletions tests/TestCase/Shell/Helper/TableHelperTest.php
Expand Up @@ -58,7 +58,7 @@ public function setUp()
*
* @return void
*/
public function testDefaultOutput()
public function testOutputDefaultOutput()
{
$data = [
['Header 1', 'Header', 'Long Header'],
Expand All @@ -77,10 +77,40 @@ public function testDefaultOutput()
$this->assertEquals($expected, $this->stub->messages());
}

/**
* Test output with inconsistent keys.
*
* When outputting entities or other structured data,
* headers shouldn't need to have the same keys as it is
* annoying to use.
*
* @return void
*/
public function testOutputInconsistentKeys()
{
$data = [
['Header 1', 'Header', 'Long Header'],
['a' => 'short', 'b' => 'Longish thing', 'c' => 'short'],
['c' => 'Longer thing', 'a' => 'short', 'b' => 'Longest Value'],
];
$this->helper->output($data);
$expected = [
'+--------------+---------------+---------------+',
'| <info>Header 1</info> | <info>Header</info> | <info>Long Header</info> |',
'+--------------+---------------+---------------+',
'| short | Longish thing | short |',
'| Longer thing | short | Longest Value |',
'+--------------+---------------+---------------+',
];
$this->assertEquals($expected, $this->stub->messages());
}

/**
* Test that output works when data contains just empty strings.
*
* @return void
*/
public function testEmptyStrings()
public function testOutputEmptyStrings()
{
$data = [
['Header 1', 'Header', 'Empty'],
Expand Down

0 comments on commit 62b8066

Please sign in to comment.