Merge branch '1.3-console' into 1.3

This commit is contained in:
gwoo 2009-07-30 11:26:23 -07:00
commit 6cb70f0929
4 changed files with 729 additions and 181 deletions

View file

@ -135,15 +135,21 @@ class ShellDispatcher {
/**
* Constructor
*
* @param array $args the argv.
* The execution of the script is stopped after dispatching the request with
* a status code of either 0 or 1 according to the result of the dispatch.
*
* @param array $args the argv
* @return void
* @access public
*/
function __construct($args = array()) {
set_time_limit(0);
$this->__initConstants();
$this->parseParams($args);
$this->_initEnvironment();
$this->__buildPaths();
$this->_stop($this->dispatch());
$this->_stop($this->dispatch() === false ? 1 : 0);
}
/**
@ -305,118 +311,134 @@ class ShellDispatcher {
/**
* Dispatches a CLI request
*
* @return boolean
* @access public
*/
function dispatch() {
if (isset($this->args[0])) {
$plugin = null;
$shell = $this->args[0];
if (strpos($shell, '.') !== false) {
list($plugin, $shell) = explode('.', $this->args[0]);
}
$arg = $this->shiftArgs();
$this->shell = $shell;
$this->shiftArgs();
$this->shellName = Inflector::camelize($this->shell);
$this->shellClass = $this->shellName . 'Shell';
if ($this->shell === 'help') {
$this->help();
} else {
$loaded = false;
foreach ($this->shellPaths as $path) {
$this->shellPath = $path . $this->shell . '.php';
$isPlugin = ($plugin && strpos($path, DS . $plugin . DS . 'vendors' . DS . 'shells' . DS) !== false);
if (($isPlugin && file_exists($this->shellPath)) || (!$plugin && file_exists($this->shellPath))) {
$loaded = true;
break;
}
}
if ($loaded) {
if (!class_exists('Shell')) {
require CONSOLE_LIBS . 'shell.php';
}
require $this->shellPath;
if (class_exists($this->shellClass)) {
$command = null;
if (isset($this->args[0])) {
$command = $this->args[0];
}
$this->shellCommand = Inflector::variable($command);
$shell = new $this->shellClass($this);
if (strtolower(get_parent_class($shell)) == 'shell') {
$shell->initialize();
$shell->loadTasks();
foreach ($shell->taskNames as $task) {
if (strtolower(get_parent_class($shell)) == 'shell') {
$shell->{$task}->initialize();
$shell->{$task}->loadTasks();
}
}
$task = Inflector::camelize($command);
if (in_array($task, $shell->taskNames)) {
$this->shiftArgs();
$shell->{$task}->startup();
if (isset($this->args[0]) && $this->args[0] == 'help') {
if (method_exists($shell->{$task}, 'help')) {
$shell->{$task}->help();
$this->_stop();
} else {
$this->help();
}
}
return $shell->{$task}->execute();
}
}
$classMethods = get_class_methods($shell);
$privateMethod = $missingCommand = false;
if ((in_array($command, $classMethods) || in_array(strtolower($command), $classMethods)) && strpos($command, '_', 0) === 0) {
$privateMethod = true;
}
if (!in_array($command, $classMethods) && !in_array(strtolower($command), $classMethods)) {
$missingCommand = true;
}
$protectedCommands = array(
'initialize','in','out','err','hr',
'createfile', 'isdir','copydir','object','tostring',
'requestaction','log','cakeerror', 'shelldispatcher',
'__initconstants','__initenvironment','__construct',
'dispatch','__bootstrap','getinput','stdout','stderr','parseparams','shiftargs'
);
if (in_array(strtolower($command), $protectedCommands)) {
$missingCommand = true;
}
if ($missingCommand && method_exists($shell, 'main')) {
$shell->startup();
return $shell->main();
} elseif (!$privateMethod && method_exists($shell, $command)) {
$this->shiftArgs();
$shell->startup();
return $shell->{$command}();
} else {
$this->stderr("Unknown {$this->shellName} command '$command'.\nFor usage, try 'cake {$this->shell} help'.\n\n");
}
} else {
$this->stderr('Class '.$this->shellClass.' could not be loaded');
}
} else {
$this->help();
}
}
} else {
if (!$arg) {
$this->help();
return false;
}
if ($arg == 'help') {
$this->help();
return true;
}
if (strpos($arg, '.') !== false) {
list($plugin, $shell) = explode('.', $arg);
} else {
$plugin = null;
$shell = $arg;
}
$this->shell = $shell;
$this->shellName = Inflector::camelize($shell);
$this->shellClass = $this->shellName . 'Shell';
$arg = null;
if (isset($this->args[0])) {
$arg = $this->args[0];
$this->shellCommand = Inflector::variable($arg);
}
$Shell = $this->_getShell($plugin);
if (!$Shell) {
$title = sprintf(__('Error: Class %s could not be loaded.', true), $this->shellClass);
$this->stderr($title . "\n");
return false;
}
$methods = array();
if (is_a($Shell, 'Shell')) {
$Shell->initialize();
$Shell->loadTasks();
foreach ($Shell->taskNames as $task) {
if (is_a($Shell->{$task}, 'Shell')) {
$Shell->{$task}->initialize();
$Shell->{$task}->loadTasks();
}
}
$task = Inflector::camelize($arg);
if (in_array($task, $Shell->taskNames)) {
$this->shiftArgs();
$Shell->{$task}->startup();
if (isset($this->args[0]) && $this->args[0] == 'help') {
if (method_exists($Shell->{$task}, 'help')) {
$Shell->{$task}->help();
} else {
$this->help();
}
return true;
}
return $Shell->{$task}->execute();
}
$methods = array_diff(get_class_methods('Shell'), array('help'));
}
$methods = array_diff(get_class_methods($Shell), $methods);
$added = in_array(strtolower($arg), array_map('strtolower', $methods));
$private = $arg[0] == '_' && method_exists($Shell, $arg);
if (!$private) {
if ($added) {
$this->shiftArgs();
$Shell->startup();
return $Shell->{$arg}();
}
if (method_exists($Shell, 'main')) {
$Shell->startup();
return $Shell->main();
}
}
$title = sprintf(__('Error: Unknown %1$s command %2$s.', true), $this->shellName, $arg);
$message = sprintf(__('For usage try `cake %s help`', true), $this->shell);
$this->stderr($title . "\n" . $message . "\n");
return false;
}
/**
* Get shell to use, either plugin shell or application shell
*
* All paths in the shellPaths property are searched.
* shell, shellPath and shellClass properties are taken into account.
*
* @param string $plugin Optionally the name of a plugin
* @return mixed False if no shell could be found or an object on success
* @access protected
*/
function _getShell($plugin = null) {
foreach ($this->shellPaths as $path) {
$this->shellPath = $path . $this->shell . '.php';
$pluginShellPath = DS . $plugin . DS . 'vendors' . DS . 'shells' . DS;
if ((strpos($path, $pluginShellPath) !== false || !$plugin) && file_exists($this->shellPath)) {
$loaded = true;
break;
}
}
if (!isset($loaded)) {
return false;
}
if (!class_exists('Shell')) {
require CONSOLE_LIBS . 'shell.php';
}
if (!class_exists($this->shellClass)) {
require $this->shellPath;
}
if (!class_exists($this->shellClass)) {
return false;
}
$Shell = new $this->shellClass($this);
return $Shell;
}
/**
@ -475,7 +497,7 @@ class ShellDispatcher {
* @access public
*/
function stderr($string) {
fwrite($this->stderr, 'Error: '. $string);
fwrite($this->stderr, $string);
}
/**
@ -521,7 +543,7 @@ class ShellDispatcher {
}
/**
* Helper for recursively paraing params
* Helper for recursively parsing params
*
* @return array params
* @access private
@ -555,16 +577,11 @@ class ShellDispatcher {
/**
* Removes first argument and shifts other arguments up
*
* @return boolean False if there are no arguments
* @return mixed Null if there are no arguments otherwise the shifted argument
* @access public
*/
function shiftArgs() {
if (empty($this->args)) {
return false;
}
unset($this->args[0]);
$this->args = array_values($this->args);
return true;
return array_shift($this->args);
}
/**
@ -603,6 +620,7 @@ class ShellDispatcher {
} else {
sort($shells);
foreach ($shells as $shell) {
if ($shell !== 'shell.php') {
$this->stdout("\t " . str_replace('.php', '', $shell));
}
@ -612,7 +630,6 @@ class ShellDispatcher {
}
$this->stdout("\nTo run a command, type 'cake shell_name [args]'");
$this->stdout("To get help on a specific command, type 'cake shell_name help'");
$this->_stop();
}
/**

View file

@ -363,69 +363,78 @@ class Shell extends Object {
}
/**
* Outputs to the stdout filehandle.
* Outputs a single or multiple messages to stdout.
*
* @param string $string String to output.
* @param boolean $newline If true, the outputs gets an added newline.
* @param mixed $message A string or a an array of strings to output
* @param mixed $after Appended to message, if true a newline is used
* @access public
*/
function out($string, $newline = true) {
if (is_array($string)) {
$str = '';
foreach ($string as $message) {
$str .= $message ."\n";
}
$string = $str;
function out($message, $after = true) {
if (is_array($message)) {
$message = implode($this->nl(), $message);
}
return $this->Dispatch->stdout($string, $newline);
$this->Dispatch->stdout($message . $this->nl($after), false);
}
/**
* Outputs to the stderr filehandle.
* Outputs a single or multiple error messages to stderr.
*
* @param string $string Error text to output.
* @param mixed $message A string or a an array of strings to output
* @param mixed $after Appended to message, if true a newline is used
* @access public
*/
function err($string) {
if (is_array($string)) {
$str = '';
foreach ($string as $message) {
$str .= $message ."\n";
}
$string = $str;
function err($message, $after = true) {
if (is_array($message)) {
$message = implode($this->nl(), $message);
}
return $this->Dispatch->stderr($string."\n");
$this->Dispatch->stderr($message . $this->nl($after));
}
/**
* Returns a single or multiple linefeeds sequences.
*
* @param mixed $format If true returns a linefeed sequence, if false null,
* if a string is given that is returned,
* if an integer is given it is used as a multiplier to return multiple linefeed sequences
* @access public
* @return string
*/
function nl($format = true) {
if (is_string($format)) {
return $format . "\n";
}
if (is_int($format)) {
return str_repeat("\n", $format);
}
return $format ? "\n" : null;
}
/**
* Outputs a series of minus characters to the standard output, acts as a visual separator.
*
* @param boolean $newline If true, the outputs gets an added newline.
* @param mixed $surround If true, the outputs gets surrounded by newlines.
* @access public
*/
function hr($newline = false) {
if ($newline) {
$this->out("\n");
}
function hr($surround = false) {
$this->out(null, $surround);
$this->out('---------------------------------------------------------------');
if ($newline) {
$this->out("\n");
}
$this->out(null, $surround);
}
/**
* Displays a formatted error message and exits the application
* Displays a formatted error message
* and exits the application with status code 1
*
* @param string $title Title of the error message
* @param string $msg Error message
* @param string $title Title of the error
* @param string $message An optional error message
* @access public
*/
function error($title, $msg) {
$out = "$title\n";
$out .= "$msg\n";
$out .= "\n";
$this->err($out);
$this->_stop();
function error($title, $message = null) {
$this->err(sprintf(__('Error: %s', true), $title));
if (!empty($message)) {
$this->err($message);
}
$this->_stop(1);
}
/**

View file

@ -36,6 +36,8 @@ if (!class_exists('ShellDispatcher')) {
ob_end_clean();
}
require_once CONSOLE_LIBS . 'shell.php';
/**
* TestShellDispatcher class
*
@ -76,6 +78,13 @@ class TestShellDispatcher extends ShellDispatcher {
*/
var $stopped = null;
/**
* TestShell
*
* @var mixed
* @access public
*/
var $TestShell;
/**
* _initEnvironment method
*
@ -127,6 +136,30 @@ class TestShellDispatcher extends ShellDispatcher {
*/
function _stop($status = 0) {
$this->stopped = 'Stopped with status: ' . $status;
return $status;
}
/**
* getShell
*
* @param mixed $plugin
* @access public
* @return mixed
*/
function getShell($plugin = null) {
return $this->_getShell($plugin);
}
/**
* _getShell
*
* @param mixed $plugin
* @access protected
* @return mixed
*/
function _getShell($plugin = null) {
if (isset($this->TestShell)) {
return $this->TestShell;
}
return parent::_getShell($plugin);
}
}
@ -136,7 +169,7 @@ class TestShellDispatcher extends ShellDispatcher {
* @package cake
* @subpackage cake.tests.cases.libs
*/
class ShellDispatcherTest extends UnitTestCase {
class ShellDispatcherTest extends CakeTestCase {
/**
* setUp method
@ -444,20 +477,418 @@ class ShellDispatcherTest extends UnitTestCase {
}
/**
* testDispatch method
* Verify loading of (plugin-) shells
*
* @access public
* @return void
*/
function testDispatch() {
$Dispatcher =& new TestShellDispatcher(array('sample'));
$this->assertPattern('/This is the main method called from SampleShell/', $Dispatcher->stdout);
function testGetShell() {
$this->skipIf(class_exists('SampleShell'), '%s SampleShell Class already loaded');
$this->skipIf(class_exists('ExampleShell'), '%s ExampleShell Class already loaded');
$Dispatcher =& new TestShellDispatcher(array('test_plugin_two.example'));
$this->assertPattern('/This is the main method called from TestPluginTwo.ExampleShell/', $Dispatcher->stdout);
$Dispatcher =& new TestShellDispatcher();
$Dispatcher =& new TestShellDispatcher(array('test_plugin_two.welcome', 'say_hello'));
$this->assertPattern('/This is the say_hello method called from TestPluginTwo.WelcomeShell/', $Dispatcher->stdout);
$Dispatcher->shell = 'sample';
$Dispatcher->shellName = 'Sample';
$Dispatcher->shellClass = 'SampleShell';
$result = $Dispatcher->getShell();
$this->assertIsA($result, 'SampleShell');
$Dispatcher =& new TestShellDispatcher();
$Dispatcher->shell = 'example';
$Dispatcher->shellName = 'Example';
$Dispatcher->shellClass = 'ExampleShell';
$result = $Dispatcher->getShell('test_plugin');
$this->assertIsA($result, 'ExampleShell');
}
/**
* Verify correct dispatch of Shell subclasses with a main method
*
* @access public
* @return void
*/
function testDispatchShellWithMain() {
Mock::generate('Shell', 'MockWithMainShell', array('main', '_secret'));
$Dispatcher =& new TestShellDispatcher();
$Shell = new MockWithMainShell();
$Shell->setReturnValue('main', true);
$Shell->expectOnce('initialize');
$Shell->expectOnce('loadTasks');
$Shell->expectOnce('startup');
$Shell->expectOnce('main');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array());
$Shell = new MockWithMainShell();
$Shell->setReturnValue('main', true);
$Shell->expectOnce('startup');
$Shell->expectOnce('main');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main', 'initdb');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array('initdb'));
$Shell = new MockWithMainShell();
$Shell->setReturnValue('main', true);
$Shell->expectOnce('startup');
$Shell->expectOnce('help');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main', 'help');
$result = $Dispatcher->dispatch();
$this->assertNull($result);
$this->assertEqual($Dispatcher->args, array());
$Shell = new MockWithMainShell();
$Shell->setReturnValue('main', true);
$Shell->expectNever('hr');
$Shell->expectOnce('startup');
$Shell->expectOnce('main');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main', 'hr');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array('hr'));
$Shell = new MockWithMainShell();
$Shell->setReturnValue('main', true);
$Shell->expectOnce('startup');
$Shell->expectOnce('main');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main', 'dispatch');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array('dispatch'));
$Shell = new MockWithMainShell();
$Shell->setReturnValue('main', true);
$Shell->expectOnce('startup');
$Shell->expectOnce('main');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main', 'idontexist');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array('idontexist'));
$Shell = new MockWithMainShell();
$Shell->expectNever('startup');
$Shell->expectNever('main');
$Shell->expectNever('_secret');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main', '_secret');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
}
/**
* Verify correct dispatch of Shell subclasses without a main method
*
* @access public
* @return void
*/
function testDispatchShellWithoutMain() {
Mock::generate('Shell', 'MockWithoutMainShell', array('initDb', '_secret'));
$Dispatcher =& new TestShellDispatcher();
$Shell = new MockWithoutMainShell();
$Shell->setReturnValue('initDb', true);
$Shell->expectOnce('initialize');
$Shell->expectOnce('loadTasks');
$Shell->expectNever('startup');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
$this->assertEqual($Dispatcher->args, array());
$Shell = new MockWithoutMainShell();
$Shell->setReturnValue('initDb', true);
$Shell->expectOnce('startup');
$Shell->expectOnce('initDb');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main', 'initdb');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array());
$Shell = new MockWithoutMainShell();
$Shell->setReturnValue('initDb', true);
$Shell->expectNever('startup');
$Shell->expectNever('hr');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main', 'hr');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
$this->assertEqual($Dispatcher->args, array('hr'));
$Shell = new MockWithoutMainShell();
$Shell->setReturnValue('initDb', true);
$Shell->expectNever('startup');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main', 'dispatch');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
$Shell = new MockWithoutMainShell();
$Shell->expectNever('startup');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main', 'idontexist');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
$Shell = new MockWithoutMainShell();
$Shell->expectNever('startup');
$Shell->expectNever('_secret');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main', '_secret');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
}
/**
* Verify correct dispatch of custom classes with a main method
*
* @access public
* @return void
*/
function testDispatchNotAShellWithMain() {
Mock::generate('Object', 'MockWithMainNotAShell',
array('main', 'initialize', 'loadTasks', 'startup', '_secret'));
$Dispatcher =& new TestShellDispatcher();
$Shell = new MockWithMainNotAShell();
$Shell->setReturnValue('main', true);
$Shell->expectNever('initialize');
$Shell->expectNever('loadTasks');
$Shell->expectOnce('startup');
$Shell->expectOnce('main');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main_not_a');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array());
$Shell = new MockWithMainNotAShell();
$Shell->setReturnValue('main', true);
$Shell->expectOnce('startup');
$Shell->expectOnce('main');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main_not_a', 'initdb');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array('initdb'));
$Shell = new MockWithMainNotAShell();
$Shell->setReturnValue('main', true);
$Shell->expectOnce('startup');
$Shell->expectOnce('main');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main_not_a', 'hr');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array('hr'));
$Shell = new MockWithMainNotAShell();
$Shell->setReturnValue('main', true);
$Shell->expectOnce('startup');
$Shell->expectOnce('main');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main_not_a', 'dispatch');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array('dispatch'));
$Shell = new MockWithMainNotAShell();
$Shell->setReturnValue('main', true);
$Shell->expectOnce('startup');
$Shell->expectOnce('main');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main_not_a', 'idontexist');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array('idontexist'));
$Shell = new MockWithMainNotAShell();
$Shell->expectNever('startup');
$Shell->expectNever('main');
$Shell->expectNever('_secret');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_with_main_not_a', '_secret');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
}
/**
* Verify correct dispatch of custom classes without a main method
*
* @access public
* @return void
*/
function testDispatchNotAShellWithoutMain() {
Mock::generate('Object', 'MockWithoutMainNotAShell',
array('initDb', 'initialize', 'loadTasks', 'startup', '_secret'));
$Dispatcher =& new TestShellDispatcher();
$Shell = new MockWithoutMainNotAShell();
$Shell->setReturnValue('initDb', true);
$Shell->expectNever('initialize');
$Shell->expectNever('loadTasks');
$Shell->expectNever('startup');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main_not_a');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
$Shell = new MockWithoutMainNotAShell();
$Shell->setReturnValue('initDb', true);
$Shell->expectOnce('startup');
$Shell->expectOnce('initDb');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main_not_a', 'initdb');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array());
$Shell = new MockWithoutMainNotAShell();
$Shell->setReturnValue('initDb', true);
$Shell->expectNever('startup');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main_not_a', 'hr');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
$Shell = new MockWithoutMainNotAShell();
$Shell->setReturnValue('initDb', true);
$Shell->expectNever('startup');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main_not_a', 'dispatch');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
$Shell = new MockWithoutMainNotAShell();
$Shell->expectNever('startup');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main_not_a', 'idontexist');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
$Shell = new MockWithoutMainNotAShell();
$Shell->expectNever('startup');
$Shell->expectNever('_secret');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_without_main_not_a', '_secret');
$result = $Dispatcher->dispatch();
$this->assertFalse($result);
}
/**
* Verify that a task is called instead of the shell if the first arg equals
* the name of the task
*
* @access public
* @return void
*/
function testDispatchTask() {
Mock::generate('Shell', 'MockWeekShell', array('main'));
Mock::generate('Shell', 'MockOnSundayTask', array('execute'));
$Dispatcher =& new TestShellDispatcher();
$Shell = new MockWeekShell();
$Shell->expectOnce('initialize');
$Shell->expectOnce('loadTasks');
$Shell->expectNever('startup');
$Shell->expectNever('main');
$Task = new MockOnSundayTask();
$Task->setReturnValue('execute', true);
$Task->expectOnce('initialize');
$Task->expectOnce('loadTasks');
$Task->expectOnce('startup');
$Task->expectOnce('execute');
$Shell->MockOnSunday =& $Task;
$Shell->taskNames = array('MockOnSunday');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_week', 'mock_on_sunday');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
$this->assertEqual($Dispatcher->args, array());
$Shell = new MockWeekShell();
$Task = new MockOnSundayTask();
$Task->expectNever('execute');
$Task->expectOnce('help');
$Shell->MockOnSunday =& $Task;
$Shell->taskNames = array('MockOnSunday');
$Dispatcher->TestShell =& $Shell;
$Dispatcher->args = array('mock_week', 'mock_on_sunday', 'help');
$result = $Dispatcher->dispatch();
$this->assertTrue($result);
}
/**
* Verify shifting of arguments
*
* @access public
* @return void
*/
function testShiftArgs() {
$Dispatcher =& new TestShellDispatcher();
$Dispatcher->args = array('a', 'b', 'c');
$this->assertEqual($Dispatcher->shiftArgs(), 'a');
$this->assertIdentical($Dispatcher->args, array('b', 'c'));
$Dispatcher->args = array('a' => 'b', 'c', 'd');
$this->assertEqual($Dispatcher->shiftArgs(), 'b');
$this->assertIdentical($Dispatcher->args, array('c', 'd'));
$Dispatcher->args = array('a', 'b' => 'c', 'd');
$this->assertEqual($Dispatcher->shiftArgs(), 'a');
$this->assertIdentical($Dispatcher->args, array('b' => 'c', 'd'));
$Dispatcher->args = array(0 => 'a', 2 => 'b', 30 => 'c');
$this->assertEqual($Dispatcher->shiftArgs(), 'a');
$this->assertIdentical($Dispatcher->args, array(0 => 'b', 1 => 'c'));
$Dispatcher->args = array();
$this->assertNull($Dispatcher->shiftArgs());
$this->assertIdentical($Dispatcher->args, array());
}
/**
@ -502,7 +933,7 @@ class ShellDispatcherTest extends UnitTestCase {
$expected = "/ CORE(\\\|\/)tests(\\\|\/)test_app(\\\|\/)vendors(\\\|\/)shells:";
$expected .= "\n\t sample";
$expected .= "\n/";
$this->assertPattern($expected, $Dispatcher->stdout);
$this->assertPattern($expected, $Dispatcher->stdout);
}
}
?>

View file

@ -52,6 +52,23 @@ Mock::generatePartial(
* @subpackage cake.tests.cases.console.libs
*/
class TestShell extends Shell {
/**
* stopped property
*
* @var integer
* @access public
*/
var $stopped;
/**
* stop method
*
* @param integer $status
* @access protected
* @return void
*/
function _stop($status = 0) {
$this->stopped = $status;
}
}
/**
@ -157,20 +174,6 @@ class ShellTest extends CakeTestCase {
App::build();
}
/**
* testOut method
*
* @return void
* @access public
*/
function testOut() {
$this->Shell->Dispatch->expectAt(0, 'stdout', array('Just a test', true));
$this->Shell->out('Just a test');
$this->Shell->Dispatch->expectAt(1, 'stdout', array("Just\na\ntest\n", true));
$this->Shell->out(array('Just', 'a', 'test'));
}
/**
* testIn method
*
@ -209,6 +212,94 @@ class ShellTest extends CakeTestCase {
$this->assertEqual($result, 'n');
}
/**
* testOut method
*
* @return void
* @access public
*/
function testOut() {
$this->Shell->Dispatch->expectAt(0, 'stdout', array("Just a test\n", false));
$this->Shell->out('Just a test');
$this->Shell->Dispatch->expectAt(1, 'stdout', array("Just\na\ntest\n", false));
$this->Shell->out(array('Just', 'a', 'test'));
$this->Shell->Dispatch->expectAt(2, 'stdout', array("Just\na\ntest\n\n", false));
$this->Shell->out(array('Just', 'a', 'test'), 2);
}
/**
* testErr method
*
* @return void
* @access public
*/
function testErr() {
$this->Shell->Dispatch->expectAt(0, 'stderr', array("Just a test\n"));
$this->Shell->err('Just a test');
$this->Shell->Dispatch->expectAt(1, 'stderr', array("Just\na\ntest\n"));
$this->Shell->err(array('Just', 'a', 'test'));
$this->Shell->Dispatch->expectAt(2, 'stderr', array("Just\na\ntest\n\n"));
$this->Shell->err(array('Just', 'a', 'test'), 2);
}
/**
* testNl
*
* @access public
* @return void
*/
function testNl() {
$this->assertEqual($this->Shell->nl(), "\n");
$this->assertEqual($this->Shell->nl(true), "\n");
$this->assertEqual($this->Shell->nl(false), "");
$this->assertEqual($this->Shell->nl(2), "\n\n");
$this->assertEqual($this->Shell->nl(1), "\n");
$this->assertEqual($this->Shell->nl("custom"), "custom\n");
}
/**
* testHr
*
* @access public
* @return void
*/
function testHr() {
$bar = '---------------------------------------------------------------';
$this->Shell->Dispatch->expectAt(0, 'stdout', array('', false));
$this->Shell->Dispatch->expectAt(1, 'stdout', array($bar . "\n", false));
$this->Shell->Dispatch->expectAt(2, 'stdout', array('', false));
$this->Shell->hr();
$this->Shell->Dispatch->expectAt(3, 'stdout', array("\n", false));
$this->Shell->Dispatch->expectAt(4, 'stdout', array($bar . "\n", false));
$this->Shell->Dispatch->expectAt(5, 'stdout', array("\n", false));
$this->Shell->hr(true);
$this->Shell->Dispatch->expectAt(3, 'stdout', array("\n\n", false));
$this->Shell->Dispatch->expectAt(4, 'stdout', array($bar . "\n", false));
$this->Shell->Dispatch->expectAt(5, 'stdout', array("\n\n", false));
$this->Shell->hr(2);
}
/**
* testError
*
* @access public
* @return void
*/
function testError() {
$this->Shell->Dispatch->expectAt(0, 'stderr', array("Error: Foo Not Found\n"));
$this->Shell->error('Foo Not Found');
$this->assertIdentical($this->Shell->stopped, 1);
$this->Shell->stopped = null;
$this->Shell->Dispatch->expectAt(1, 'stderr', array("Error: Foo Not Found\n"));
$this->Shell->Dispatch->expectAt(2, 'stderr', array("Searched all...\n"));
$this->Shell->error('Foo Not Found', 'Searched all...');
$this->assertIdentical($this->Shell->stopped, 1);
}
/**
* testLoadTasks method
*