Browse Source

Fix table output when keys are inconsistent.

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.
Mark Story 8 years ago
parent
commit
62b8066aee
2 changed files with 38 additions and 5 deletions
  1. 6 3
      src/Shell/Helper/TableHelper.php
  2. 32 2
      tests/TestCase/Shell/Helper/TableHelperTest.php

+ 6 - 3
src/Shell/Helper/TableHelper.php

@@ -43,8 +43,8 @@ class TableHelper extends Helper
     {
         $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;
                 }
@@ -85,7 +85,7 @@ class TableHelper extends Helper
         }
 
         $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']);
@@ -99,6 +99,9 @@ class TableHelper extends Helper
     /**
      * 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
      */

+ 32 - 2
tests/TestCase/Shell/Helper/TableHelperTest.php

@@ -58,7 +58,7 @@ class TableHelperTest extends TestCase
      *
      * @return void
      */
-    public function testDefaultOutput()
+    public function testOutputDefaultOutput()
     {
         $data = [
             ['Header 1', 'Header', 'Long Header'],
@@ -78,9 +78,39 @@ class TableHelperTest extends TestCase
     }
 
     /**
+     * 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'],