Browse Source

Add TableMacro

Add a pretty table formatting macro.
Mark Story 11 years ago
parent
commit
a089ded518
2 changed files with 178 additions and 0 deletions
  1. 95 0
      src/Shell/Macro/TableMacro.php
  2. 83 0
      tests/TestCase/Shell/Macro/TableMacroTest.php

+ 95 - 0
src/Shell/Macro/TableMacro.php

@@ -0,0 +1,95 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @since         3.1.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Shell\Macro;
+
+use Cake\Console\Macro;
+
+/**
+ * Create a visually pleasing ASCII art table
+ * from 2 dimensional array data.
+ */
+class TableMacro extends Macro
+{
+    /**
+     * Calculate the column widths
+     *
+     * @return array
+     */
+    protected function _calculateWidths($rows)
+    {
+        $widths = [];
+        foreach ($rows as $line) {
+            for ($i = 0, $len = count($line); $i < $len; $i++) {
+                $columnLength = strlen($line[$i]);
+                if ($columnLength > (isset($widths[$i]) ? $widths[$i] : 0)) {
+                    $widths[$i] = $columnLength;
+                }
+            }
+        }
+        return $widths;
+    }
+
+    /**
+     * Output a row separator.
+     *
+     * @param array $widths The widths of each column to output.
+     * @return void
+     */
+    protected function _rowSeparator($widths)
+    {
+        $out = '';
+        foreach ($widths as $column) {
+            $out .= '+' . str_repeat('-', $column + 2);
+        }
+        $out .= '+';
+        $this->_io->out($out);
+    }
+
+    /**
+     * Output a row separator.
+     *
+     * @param array $widths The widths of each column to output.
+     * @return void
+     */
+    protected function _render($row, $widths)
+    {
+        $out = '';
+        foreach ($row as $i => $column) {
+            $out .= '| ' . str_pad($column, $widths[$i], ' ', STR_PAD_RIGHT) . ' ';
+        }
+        $out .= '|';
+        $this->_io->out($out);
+    }
+
+    /**
+     * Output a table.
+     *
+     * @param array $args The data to render out.
+     * @return void
+     */
+    public function output($rows)
+    {
+        $widths = $this->_calculateWidths($rows);
+
+        $this->_rowSeparator($widths);
+        $this->_render(array_shift($rows), $widths);
+        $this->_rowSeparator($widths);
+
+        foreach ($rows as $line) {
+            $this->_render($line, $widths);
+        }
+        $this->_rowSeparator($widths);
+    }
+}

+ 83 - 0
tests/TestCase/Shell/Macro/TableMacroTest.php

@@ -0,0 +1,83 @@
+<?php
+/**
+ * CakePHP :  Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Test\TestCase\Shell\Macro;
+
+use Cake\Console\ConsoleIo;
+use Cake\Console\ConsoleOutput;
+use Cake\Shell\Macro\TableMacro;
+use Cake\TestSuite\TestCase;
+
+/**
+ * StubOutput makes testing easier.
+ */
+class StubOutput extends ConsoleOutput
+{
+    protected $_out = [];
+
+    public function write($message, $newlines = 1)
+    {
+        $this->_out[] = $message;
+    }
+
+    public function messages()
+    {
+        return $this->_out;
+    }
+}
+
+/**
+ * TableMacro test.
+ */
+class TableMacroTest extends TestCase
+{
+
+    /**
+     * setUp method
+     *
+     * @return void
+     */
+    public function setUp()
+    {
+        parent::setUp();
+
+        $this->stub = new StubOutput();
+        $this->io = new ConsoleIo($this->stub);
+        $this->macro = new TableMacro($this->io);
+    }
+
+    /**
+     * Test output
+     *
+     * @return voi
+     */
+    public function testOutput()
+    {
+        $data = [
+            ['Header 1', 'Header', 'Long Header'],
+            ['short', 'Longish thing', 'short'],
+            ['Longer thing', 'short', 'Longest Value'],
+        ];
+        $this->macro->output($data);
+        $expected = [
+            '+--------------+---------------+---------------+',
+            '| Header 1     | Header        | Long Header   |',
+            '+--------------+---------------+---------------+',
+            '| short        | Longish thing | short         |',
+            '| Longer thing | short         | Longest Value |',
+            '+--------------+---------------+---------------+',
+        ];
+        $this->assertEquals($expected, $this->stub->messages());
+    }
+}