mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Merge pull request #7767 from garethellis36/backport-shell-helpers-to-2.8
Backport shell helpers to 2.8
This commit is contained in:
commit
e7d6e3b137
11 changed files with 1013 additions and 3 deletions
|
@ -79,6 +79,14 @@ class ConsoleOutput {
|
|||
*/
|
||||
protected $_output;
|
||||
|
||||
/**
|
||||
* The number of bytes last written to the output stream
|
||||
* used when overwriting the previous message.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_lastWritten = 0;
|
||||
|
||||
/**
|
||||
* The current output type. Manipulated with ConsoleOutput::outputAs();
|
||||
*
|
||||
|
@ -184,6 +192,35 @@ class ConsoleOutput {
|
|||
return $this->_write($this->styleText($message . str_repeat(static::LF, $newlines)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite some already output text.
|
||||
*
|
||||
* Useful for building progress bars, or when you want to replace
|
||||
* text already output to the screen with new text.
|
||||
*
|
||||
* **Warning** You cannot overwrite text that contains newlines.
|
||||
*
|
||||
* @param array|string $message The message to output.
|
||||
* @param int $newlines Number of newlines to append.
|
||||
* @param int|null $size The number of bytes to overwrite. Defaults to the
|
||||
* length of the last message output.
|
||||
* @return void
|
||||
*/
|
||||
public function overwrite($message, $newlines = 1, $size = null) {
|
||||
$size = $size ?: $this->_lastWritten;
|
||||
// Output backspaces.
|
||||
$this->write(str_repeat("\x08", $size), 0);
|
||||
$newBytes = $this->write($message, 0);
|
||||
// Fill any remaining bytes with spaces.
|
||||
$fill = $size - $newBytes;
|
||||
if ($fill > 0) {
|
||||
$this->write(str_repeat(' ', $fill), 0);
|
||||
}
|
||||
if ($newlines) {
|
||||
$this->write("", $newlines);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply styling to text.
|
||||
*
|
||||
|
@ -238,7 +275,8 @@ class ConsoleOutput {
|
|||
* @return bool success
|
||||
*/
|
||||
protected function _write($message) {
|
||||
return fwrite($this->_output, $message);
|
||||
$this->_lastWritten = fwrite($this->_output, $message);
|
||||
return $this->_lastWritten;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
82
lib/Cake/Console/Helper/BaseShellHelper.php
Normal file
82
lib/Cake/Console/Helper/BaseShellHelper.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?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://cakephp.org CakePHP(tm) Project
|
||||
* @since 2.8
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
abstract class BaseShellHelper {
|
||||
|
||||
/**
|
||||
* Default config for this helper.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_defaultConfig = array();
|
||||
|
||||
/**
|
||||
* ConsoleOutput instance.
|
||||
*
|
||||
* @var ConsoleOutput
|
||||
*/
|
||||
protected $_consoleOutput;
|
||||
|
||||
/**
|
||||
* Runtime config
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config = array();
|
||||
|
||||
/**
|
||||
* Whether the config property has already been configured with defaults
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_configInitialized = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ConsoleOutput $consoleOutput The ConsoleOutput instance to use.
|
||||
* @param array $config The settings for this helper.
|
||||
*/
|
||||
public function __construct(ConsoleOutput $consoleOutput, array $config = array()) {
|
||||
$this->_consoleOutput = $consoleOutput;
|
||||
$this->config($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize config & store config values
|
||||
*
|
||||
* @param null $config Config values to set
|
||||
* @return array|void
|
||||
*/
|
||||
public function config($config = null) {
|
||||
if ($config === null) {
|
||||
return $this->_config;
|
||||
}
|
||||
if (!$this->_configInitialized) {
|
||||
$this->_config = array_merge($this->_defaultConfig, $config);
|
||||
$this->_configInitialized = true;
|
||||
} else {
|
||||
$this->_config = array_merge($this->_config, $config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should output content using `$this->_consoleOutput`.
|
||||
*
|
||||
* @param array $args The arguments for the helper.
|
||||
* @return void
|
||||
*/
|
||||
abstract public function output($args);
|
||||
}
|
122
lib/Cake/Console/Helper/ProgressShellHelper.php
Normal file
122
lib/Cake/Console/Helper/ProgressShellHelper.php
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?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://cakephp.org CakePHP(tm) Project
|
||||
* @since 2.8
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
App::uses("BaseShellHelper", "Console/Helper");
|
||||
|
||||
/**
|
||||
* Create a progress bar using a supplied callback.
|
||||
*/
|
||||
class ProgressShellHelper extends BaseShellHelper {
|
||||
|
||||
/**
|
||||
* The current progress.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_progress = 0;
|
||||
|
||||
/**
|
||||
* The total number of 'items' to progress through.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_total = 0;
|
||||
|
||||
/**
|
||||
* The width of the bar.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_width = 0;
|
||||
|
||||
/**
|
||||
* Output a progress bar.
|
||||
*
|
||||
* Takes a number of options to customize the behavior:
|
||||
*
|
||||
* - `total` The total number of items in the progress bar. Defaults
|
||||
* to 100.
|
||||
* - `width` The width of the progress bar. Defaults to 80.
|
||||
* - `callback` The callback that will be called in a loop to advance the progress bar.
|
||||
*
|
||||
* @param array $args The arguments/options to use when outputing the progress bar.
|
||||
* @return void
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function output($args) {
|
||||
$args += array('callback' => null);
|
||||
if (isset($args[0])) {
|
||||
$args['callback'] = $args[0];
|
||||
}
|
||||
if (!$args['callback'] || !is_callable($args['callback'])) {
|
||||
throw new RuntimeException('Callback option must be a callable.');
|
||||
}
|
||||
$this->init($args);
|
||||
$callback = $args['callback'];
|
||||
while ($this->_progress < $this->_total) {
|
||||
$callback($this);
|
||||
$this->draw();
|
||||
}
|
||||
$this->_consoleOutput->write('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the progress bar for use.
|
||||
*
|
||||
* - `total` The total number of items in the progress bar. Defaults
|
||||
* to 100.
|
||||
* - `width` The width of the progress bar. Defaults to 80.
|
||||
*
|
||||
* @param array $args The initialization data.
|
||||
* @return void
|
||||
*/
|
||||
public function init(array $args = array()) {
|
||||
$args += array('total' => 100, 'width' => 80);
|
||||
$this->_progress = 0;
|
||||
$this->_width = $args['width'];
|
||||
$this->_total = $args['total'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the progress bar.
|
||||
*
|
||||
* @param int $num The amount of progress to advance by.
|
||||
* @return void
|
||||
*/
|
||||
public function increment($num = 1) {
|
||||
$this->_progress = min(max(0, $this->_progress + $num), $this->_total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the progress bar based on the current state.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function draw() {
|
||||
$numberLen = strlen(' 100%');
|
||||
$complete = round($this->_progress / $this->_total, 2);
|
||||
$barLen = ($this->_width - $numberLen) * ($this->_progress / $this->_total);
|
||||
$bar = '';
|
||||
if ($barLen > 1) {
|
||||
$bar = str_repeat('=', $barLen - 1) . '>';
|
||||
}
|
||||
$pad = ceil($this->_width - $numberLen - $barLen);
|
||||
if ($pad > 0) {
|
||||
$bar .= str_repeat(' ', $pad);
|
||||
}
|
||||
$percent = ($complete * 100) . '%';
|
||||
$bar .= str_pad($percent, $numberLen, ' ', STR_PAD_LEFT);
|
||||
$this->_consoleOutput->overwrite($bar, 0);
|
||||
}
|
||||
}
|
124
lib/Cake/Console/Helper/TableShellHelper.php
Normal file
124
lib/Cake/Console/Helper/TableShellHelper.php
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?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://cakephp.org CakePHP(tm) Project
|
||||
* @since 2.8
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
App::uses("BaseShellHelper", "Console/Helper");
|
||||
|
||||
/**
|
||||
* Create a visually pleasing ASCII art table
|
||||
* from 2 dimensional array data.
|
||||
*/
|
||||
class TableShellHelper extends BaseShellHelper {
|
||||
|
||||
/**
|
||||
* Default config for this helper.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_defaultConfig = array(
|
||||
'headers' => true,
|
||||
'rowSeparator' => false,
|
||||
'headerStyle' => 'info',
|
||||
);
|
||||
|
||||
/**
|
||||
* Calculate the column widths
|
||||
*
|
||||
* @param array $rows The rows on which the columns width will be calculated on.
|
||||
* @return array
|
||||
*/
|
||||
protected function _calculateWidths($rows) {
|
||||
$widths = array();
|
||||
foreach ($rows as $line) {
|
||||
for ($i = 0, $len = count($line); $i < $len; $i++) {
|
||||
$columnLength = mb_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->_consoleOutput->write($out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a row.
|
||||
*
|
||||
* @param array $row The row to output.
|
||||
* @param array $widths The widths of each column to output.
|
||||
* @param array $options Options to be passed.
|
||||
* @return void
|
||||
*/
|
||||
protected function _render($row, $widths, $options = array()) {
|
||||
$out = '';
|
||||
foreach ($row as $i => $column) {
|
||||
$pad = $widths[$i] - mb_strlen($column);
|
||||
if (!empty($options['style'])) {
|
||||
$column = $this->_addStyle($column, $options['style']);
|
||||
}
|
||||
$out .= '| ' . $column . str_repeat(' ', $pad) . ' ';
|
||||
}
|
||||
$out .= '|';
|
||||
$this->_consoleOutput->write($out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a table.
|
||||
*
|
||||
* @param array $rows The data to render out.
|
||||
* @return void
|
||||
*/
|
||||
public function output($rows) {
|
||||
$config = $this->config();
|
||||
$widths = $this->_calculateWidths($rows);
|
||||
$this->_rowSeparator($widths);
|
||||
if ($config['headers'] === true) {
|
||||
$this->_render(array_shift($rows), $widths, array('style' => $config['headerStyle']));
|
||||
$this->_rowSeparator($widths);
|
||||
}
|
||||
foreach ($rows as $line) {
|
||||
$this->_render($line, $widths);
|
||||
if ($config['rowSeparator'] === true) {
|
||||
$this->_rowSeparator($widths);
|
||||
}
|
||||
}
|
||||
if ($config['rowSeparator'] !== true) {
|
||||
$this->_rowSeparator($widths);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add style tags
|
||||
*
|
||||
* @param string $text The text to be surrounded
|
||||
* @param string $style The style to be applied
|
||||
* @return string
|
||||
*/
|
||||
protected function _addStyle($text, $style) {
|
||||
return '<' . $style . '>' . $text . '</' . $style . '>';
|
||||
}
|
||||
}
|
|
@ -174,6 +174,13 @@ class Shell extends Object {
|
|||
*/
|
||||
protected $_lastWritten = 0;
|
||||
|
||||
/**
|
||||
* Contains helpers which have been previously instantiated
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_helpers = array();
|
||||
|
||||
/**
|
||||
* Constructs this Shell instance.
|
||||
*
|
||||
|
@ -645,8 +652,7 @@ class Shell extends Object {
|
|||
*
|
||||
* @param array|string $message The message to output.
|
||||
* @param int $newlines Number of newlines to append.
|
||||
* @param int $size The number of bytes to overwrite. Defaults to the
|
||||
* length of the last message output.
|
||||
* @param int $size The number of bytes to overwrite. Defaults to the length of the last message output.
|
||||
* @return int|bool Returns the number of bytes returned from writing to stdout.
|
||||
*/
|
||||
public function overwrite($message, $newlines = 1, $size = null) {
|
||||
|
@ -779,6 +785,28 @@ class Shell extends Object {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load given shell helper class
|
||||
*
|
||||
* @param string $name Name of the helper class. Supports plugin syntax.
|
||||
* @return BaseShellHelper Instance of helper class
|
||||
* @throws RuntimeException If invalid class name is provided
|
||||
*/
|
||||
public function helper($name) {
|
||||
if (isset($this->_helpers[$name])) {
|
||||
return $this->_helpers[$name];
|
||||
}
|
||||
list($plugin, $helperClassName) = pluginSplit($name, true);
|
||||
$helperClassName = Inflector::camelize($name) . "ShellHelper";
|
||||
App::uses($helperClassName, $plugin . "Console/Helper");
|
||||
if (!class_exists($helperClassName)) {
|
||||
throw new RuntimeException("Class " . $helperClassName . " not found");
|
||||
}
|
||||
$helper = new $helperClassName($this->stdout);
|
||||
$this->_helpers[$name] = $helper;
|
||||
return $helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to create a Unit Test
|
||||
*
|
||||
|
|
|
@ -94,6 +94,27 @@ class ConsoleOutputTest extends CakeTestCase {
|
|||
$this->output->write(array('Line', 'Line', 'Line'));
|
||||
}
|
||||
|
||||
/**
|
||||
* test writing an array of messages.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOverwrite() {
|
||||
$testString = "Text";
|
||||
|
||||
$this->output->expects($this->at(0))->method('_write')
|
||||
->with($testString);
|
||||
|
||||
$this->output->expects($this->at(1))->method('_write')
|
||||
->with("");
|
||||
|
||||
$this->output->expects($this->at(2))->method('_write')
|
||||
->with("Overwriting text");
|
||||
|
||||
$this->output->write($testString, 0);
|
||||
$this->output->overwrite("Overwriting text");
|
||||
}
|
||||
|
||||
/**
|
||||
* test getting a style.
|
||||
*
|
||||
|
|
223
lib/Cake/Test/Case/Console/Helper/ProgressShellHelperTest.php
Normal file
223
lib/Cake/Test/Case/Console/Helper/ProgressShellHelperTest.php
Normal file
|
@ -0,0 +1,223 @@
|
|||
<?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://cakephp.org CakePHP(tm) Project
|
||||
* @since 2.8
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
App::uses("ProgressShellHelper", "Console/Helper");
|
||||
App::uses("ConsoleOutputStub", "TestSuite/Stub");
|
||||
|
||||
/**
|
||||
* ProgressHelper test.
|
||||
* @property ConsoleOutputStub $consoleOutput
|
||||
* @property ProgressShellHelper $helper
|
||||
*/
|
||||
class ProgressShellHelperTest extends CakeTestCase {
|
||||
|
||||
/**
|
||||
* setUp method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->consoleOutput = new ConsoleOutputStub();
|
||||
$this->helper = new ProgressShellHelper($this->consoleOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a callback is required.*
|
||||
*
|
||||
* @expectedException \RuntimeException
|
||||
* @return void
|
||||
*/
|
||||
public function testOutputFailure() {
|
||||
$this->helper->output(array('not a callback'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the callback is invoked until 100 is reached.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOutputSuccess() {
|
||||
$this->helper->output(array(function ($progress) {
|
||||
$progress->increment(20);
|
||||
}));
|
||||
$expected = array(
|
||||
'',
|
||||
'==============> 20%',
|
||||
'',
|
||||
'=============================> 40%',
|
||||
'',
|
||||
'============================================> 60%',
|
||||
'',
|
||||
'===========================================================> 80%',
|
||||
'',
|
||||
'==========================================================================> 100%',
|
||||
'',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test output with options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOutputSuccessOptions() {
|
||||
$this->helper->output(array(
|
||||
'total' => 10,
|
||||
'width' => 20,
|
||||
'callback' => function ($progress) {
|
||||
$progress->increment(2);
|
||||
}
|
||||
));
|
||||
$expected = array(
|
||||
'',
|
||||
'==> 20%',
|
||||
'',
|
||||
'=====> 40%',
|
||||
'',
|
||||
'========> 60%',
|
||||
'',
|
||||
'===========> 80%',
|
||||
'',
|
||||
'==============> 100%',
|
||||
'',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test using the helper manually.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIncrementAndRender() {
|
||||
$this->helper->init();
|
||||
$this->helper->increment(20);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(40);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(40);
|
||||
$this->helper->draw();
|
||||
$expected = array(
|
||||
'',
|
||||
'==============> 20%',
|
||||
'',
|
||||
'============================================> 60%',
|
||||
'',
|
||||
'==========================================================================> 100%',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test negative numbers
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIncrementWithNegatives() {
|
||||
$this->helper->init();
|
||||
$this->helper->increment(40);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(-60);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(80);
|
||||
$this->helper->draw();
|
||||
$expected = array(
|
||||
'',
|
||||
'=============================> 40%',
|
||||
'',
|
||||
' 0%',
|
||||
'',
|
||||
'===========================================================> 80%',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test increment and draw with options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIncrementWithOptions() {
|
||||
$this->helper->init(array(
|
||||
'total' => 10,
|
||||
'width' => 20,
|
||||
));
|
||||
$this->helper->increment(4);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(4);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(4);
|
||||
$this->helper->draw();
|
||||
|
||||
$expected = array(
|
||||
'',
|
||||
'=====> 40%',
|
||||
'',
|
||||
'===========> 80%',
|
||||
'',
|
||||
'==============> 100%',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test increment and draw with value that makes the pad
|
||||
* be a float
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIncrementFloatPad() {
|
||||
$this->helper->init(array(
|
||||
'total' => 50
|
||||
));
|
||||
$this->helper->increment(7);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(7);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(7);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(7);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(7);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(3);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(4);
|
||||
$this->helper->draw();
|
||||
$this->helper->increment(8);
|
||||
$this->helper->draw();
|
||||
$expected = array(
|
||||
'',
|
||||
'=========> 14%',
|
||||
'',
|
||||
'====================> 28%',
|
||||
'',
|
||||
'==============================> 42%',
|
||||
'',
|
||||
'=========================================> 56%',
|
||||
'',
|
||||
'===================================================> 70%',
|
||||
'',
|
||||
'========================================================> 76%',
|
||||
'',
|
||||
'==============================================================> 84%',
|
||||
'',
|
||||
'==========================================================================> 100%',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
}
|
201
lib/Cake/Test/Case/Console/Helper/TableShellHelperTest.php
Normal file
201
lib/Cake/Test/Case/Console/Helper/TableShellHelperTest.php
Normal file
|
@ -0,0 +1,201 @@
|
|||
<?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://cakephp.org CakePHP(tm) Project
|
||||
* @since 2.8
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
App::uses("TableShellHelper", "Console/Helper");
|
||||
App::uses("ConsoleOutputStub", "TestSuite/Stub");
|
||||
|
||||
/**
|
||||
* ProgressHelper test.
|
||||
* @property ConsoleOutputStub $consoleOutput
|
||||
* @property TableShellHelper $helper
|
||||
*/
|
||||
class TableShellHelperTest extends CakeTestCase {
|
||||
|
||||
/**
|
||||
* setUp method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->consoleOutput = new ConsoleOutputStub();
|
||||
$this->helper = new TableShellHelper($this->consoleOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test output
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDefaultOutput() {
|
||||
$data = array(
|
||||
array('Header 1', 'Header', 'Long Header'),
|
||||
array('short', 'Longish thing', 'short'),
|
||||
array('Longer thing', 'short', 'Longest Value'),
|
||||
);
|
||||
$this->helper->output($data);
|
||||
$expected = array(
|
||||
'+--------------+---------------+---------------+',
|
||||
'| <info>Header 1</info> | <info>Header</info> | <info>Long Header</info> |',
|
||||
'+--------------+---------------+---------------+',
|
||||
'| short | Longish thing | short |',
|
||||
'| Longer thing | short | Longest Value |',
|
||||
'+--------------+---------------+---------------+',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test output with multibyte characters
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOutputUtf8() {
|
||||
$data = array(
|
||||
array('Header 1', 'Head', 'Long Header'),
|
||||
array('short', 'ÄÄÄÜÜÜ', 'short'),
|
||||
array('Longer thing', 'longerish', 'Longest Value'),
|
||||
);
|
||||
$this->helper->output($data);
|
||||
$expected = array(
|
||||
'+--------------+-----------+---------------+',
|
||||
'| <info>Header 1</info> | <info>Head</info> | <info>Long Header</info> |',
|
||||
'+--------------+-----------+---------------+',
|
||||
'| short | ÄÄÄÜÜÜ | short |',
|
||||
'| Longer thing | longerish | Longest Value |',
|
||||
'+--------------+-----------+---------------+',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test output without headers
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOutputWithoutHeaderStyle() {
|
||||
$data = array(
|
||||
array('Header 1', 'Header', 'Long Header'),
|
||||
array('short', 'Longish thing', 'short'),
|
||||
array('Longer thing', 'short', 'Longest Value'),
|
||||
);
|
||||
$this->helper->config(array('headerStyle' => false));
|
||||
$this->helper->output($data);
|
||||
$expected = array(
|
||||
'+--------------+---------------+---------------+',
|
||||
'| Header 1 | Header | Long Header |',
|
||||
'+--------------+---------------+---------------+',
|
||||
'| short | Longish thing | short |',
|
||||
'| Longer thing | short | Longest Value |',
|
||||
'+--------------+---------------+---------------+',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test output with different header style
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOutputWithDifferentHeaderStyle() {
|
||||
$data = array(
|
||||
array('Header 1', 'Header', 'Long Header'),
|
||||
array('short', 'Longish thing', 'short'),
|
||||
array('Longer thing', 'short', 'Longest Value'),
|
||||
);
|
||||
$this->helper->config(array('headerStyle' => 'error'));
|
||||
$this->helper->output($data);
|
||||
$expected = array(
|
||||
'+--------------+---------------+---------------+',
|
||||
'| <error>Header 1</error> | <error>Header</error> | <error>Long Header</error> |',
|
||||
'+--------------+---------------+---------------+',
|
||||
'| short | Longish thing | short |',
|
||||
'| Longer thing | short | Longest Value |',
|
||||
'+--------------+---------------+---------------+',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test output without table headers
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOutputWithoutHeaders() {
|
||||
$data = array(
|
||||
array('short', 'Longish thing', 'short'),
|
||||
array('Longer thing', 'short', 'Longest Value'),
|
||||
);
|
||||
$this->helper->config(array('headers' => false));
|
||||
$this->helper->output($data);
|
||||
$expected = array(
|
||||
'+--------------+---------------+---------------+',
|
||||
'| short | Longish thing | short |',
|
||||
'| Longer thing | short | Longest Value |',
|
||||
'+--------------+---------------+---------------+',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test output with row separator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOutputWithRowSeparator() {
|
||||
$data = array(
|
||||
array('Header 1', 'Header', 'Long Header'),
|
||||
array('short', 'Longish thing', 'short'),
|
||||
array('Longer thing', 'short', 'Longest Value')
|
||||
);
|
||||
$this->helper->config(array('rowSeparator' => true));
|
||||
$this->helper->output($data);
|
||||
$expected = array(
|
||||
'+--------------+---------------+---------------+',
|
||||
'| <info>Header 1</info> | <info>Header</info> | <info>Long Header</info> |',
|
||||
'+--------------+---------------+---------------+',
|
||||
'| short | Longish thing | short |',
|
||||
'+--------------+---------------+---------------+',
|
||||
'| Longer thing | short | Longest Value |',
|
||||
'+--------------+---------------+---------------+',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test output with row separator and no headers
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOutputWithRowSeparatorAndHeaders() {
|
||||
$data = array(
|
||||
array('Header 1', 'Header', 'Long Header'),
|
||||
array('short', 'Longish thing', 'short'),
|
||||
array('Longer thing', 'short', 'Longest Value'),
|
||||
);
|
||||
$this->helper->config(array('rowSeparator' => true));
|
||||
$this->helper->output($data);
|
||||
$expected = array(
|
||||
'+--------------+---------------+---------------+',
|
||||
'| <info>Header 1</info> | <info>Header</info> | <info>Long Header</info> |',
|
||||
'+--------------+---------------+---------------+',
|
||||
'| short | Longish thing | short |',
|
||||
'+--------------+---------------+---------------+',
|
||||
'| Longer thing | short | Longest Value |',
|
||||
'+--------------+---------------+---------------+',
|
||||
);
|
||||
$this->assertEquals($expected, $this->consoleOutput->messages());
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@
|
|||
App::uses('ShellDispatcher', 'Console');
|
||||
App::uses('Shell', 'Console');
|
||||
App::uses('Folder', 'Utility');
|
||||
App::uses("ProgressHelper", "Console/Helper");
|
||||
|
||||
/**
|
||||
* ShellTestShell class
|
||||
|
@ -975,4 +976,23 @@ TEXT;
|
|||
$this->Shell->runCommand('foo', array('--quiet'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting an instance of a helper
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetInstanceOfHelper() {
|
||||
$actual = $this->Shell->helper("progress");
|
||||
$this->assertInstanceOf("ProgressShellHelper", $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting an invalid helper
|
||||
*
|
||||
* @expectedException RunTimeException
|
||||
* @return void
|
||||
*/
|
||||
public function testGetInvalidHelper() {
|
||||
$this->Shell->helper("tomato");
|
||||
}
|
||||
}
|
||||
|
|
62
lib/Cake/Test/Case/TestSuite/Stub/ConsoleOutputStubTest.php
Normal file
62
lib/Cake/Test/Case/TestSuite/Stub/ConsoleOutputStubTest.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?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://cakephp.org CakePHP(tm) Project
|
||||
* @since 2.8
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
App::uses("ConsoleOutputStub", "TestSuite/Stub");
|
||||
|
||||
/*
|
||||
* ConsoleOutputStub test
|
||||
*/
|
||||
class ConsoleOutputStubTest extends CakeTestCase {
|
||||
|
||||
/**
|
||||
* setUp method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->stub = new ConsoleOutputStub();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that stub can be used as an instance of ConsoleOutput
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCanActAsConsoleOutput() {
|
||||
$this->assertInstanceOf("ConsoleOutput", $this->stub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test write method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testWrite() {
|
||||
$this->stub->write(array("foo", "bar", "baz"));
|
||||
$this->assertEquals(array("foo", "bar", "baz"), $this->stub->messages());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test overwrite method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOverwrite() {
|
||||
$this->stub->write(array("foo", "bar", "baz"));
|
||||
$this->stub->overwrite("bat");
|
||||
$this->assertEquals(array("foo", "bar", "baz", "", "bat"), $this->stub->messages());
|
||||
}
|
||||
}
|
89
lib/Cake/TestSuite/Stub/ConsoleOutputStub.php
Normal file
89
lib/Cake/TestSuite/Stub/ConsoleOutputStub.php
Normal file
|
@ -0,0 +1,89 @@
|
|||
<?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://cakephp.org CakePHP(tm) Project
|
||||
* @since 2.8
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
App::uses("ConsoleOutput", "Console");
|
||||
|
||||
/**
|
||||
* StubOutput makes testing shell commands/shell helpers easier.
|
||||
*
|
||||
* You can use this class by injecting it into a Helper instance:
|
||||
*
|
||||
* ```
|
||||
* App::uses("ConsoleOutputStub", "TestSuite/Stub");
|
||||
*
|
||||
* $output = new ConsoleOutputStub();
|
||||
* $helper = new ProgressHelper($output);
|
||||
* ```
|
||||
*/
|
||||
class ConsoleOutputStub extends ConsoleOutput {
|
||||
|
||||
/**
|
||||
* Buffered messages.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_out = array();
|
||||
|
||||
/**
|
||||
* The number of bytes written by last call to write
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_lastWritten = 0;
|
||||
|
||||
/**
|
||||
* Write output to the buffer.
|
||||
*
|
||||
* @param string|array $message A string or an array of strings to output
|
||||
* @param int $newlines Number of newlines to append
|
||||
* @return void
|
||||
*/
|
||||
public function write($message, $newlines = 1) {
|
||||
foreach ((array)$message as $line) {
|
||||
$this->_out[] = $line;
|
||||
$this->_lastWritten = strlen($line);
|
||||
}
|
||||
$newlines--;
|
||||
while ($newlines > 0) {
|
||||
$this->_out[] = '';
|
||||
$this->_lastWritten = 0;
|
||||
$newlines--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite output already written to the buffer.
|
||||
*
|
||||
* @param array|string $message The message to output.
|
||||
* @param int $newlines Number of newlines to append.
|
||||
* @param int $size The number of bytes to overwrite. Defaults to the
|
||||
* length of the last message output.
|
||||
* @return void
|
||||
*/
|
||||
public function overwrite($message, $newlines = 1, $size = null) {
|
||||
//insert an empty array to mock deletion of existing output
|
||||
$this->_out[] = "";
|
||||
//append new message to output
|
||||
$this->write($message, $newlines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the buffered output.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function messages() {
|
||||
return $this->_out;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue