diff --git a/app/Vendor/cake.bash b/app/Vendor/cake.bash deleted file mode 100644 index 685108191..000000000 --- a/app/Vendor/cake.bash +++ /dev/null @@ -1,50 +0,0 @@ -# bash completion for CakePHP console - -_cake() -{ - local cur prev opts cake - COMPREPLY=() - cake="${COMP_WORDS[0]}" - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - - if [[ "$cur" == -* ]] ; then - if [[ ${COMP_CWORD} = 1 ]] ; then - opts=$(${cake} Completion options) - elif [[ ${COMP_CWORD} = 2 ]] ; then - opts=$(${cake} Completion options "${COMP_WORDS[1]}") - else - opts=$(${cake} Completion options "${COMP_WORDS[1]}" "${COMP_WORDS[2]}") - fi - - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - fi - - if [[ ${COMP_CWORD} = 1 ]] ; then - opts=$(${cake} Completion commands) - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - fi - - if [[ ${COMP_CWORD} = 2 ]] ; then - opts=$(${cake} Completion subcommands $prev) - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - if [[ $COMPREPLY = "" ]] ; then - COMPREPLY=( $(compgen -df -- ${cur}) ) - return 0 - fi - return 0 - fi - - - opts=$(${cake} Completion fuzzy "${COMP_WORDS[@]:1}") - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - if [[ $COMPREPLY = "" ]] ; then - COMPREPLY=( $(compgen -df -- ${cur}) ) - return 0 - fi - return 0; -} - -complete -F _cake cake Console/cake diff --git a/lib/Cake/Console/Command/CompletionShell.php b/lib/Cake/Console/Command/CompletionShell.php index da704a674..d5793d90f 100644 --- a/lib/Cake/Console/Command/CompletionShell.php +++ b/lib/Cake/Console/Command/CompletionShell.php @@ -1,27 +1,49 @@ out($this->OptionParser->help()); + return $this->out($this->OptionParser->help()); } /** * list commands + * + * @return void */ public function commands() { $options = $this->_commands(); @@ -30,6 +52,8 @@ class CompletionShell extends CommandListShell { /** * list options for the named command + * + * @return void */ public function options() { if (!$this->args) { @@ -57,6 +81,8 @@ class CompletionShell extends CommandListShell { /** * list subcommands for the named command + * + * @return void */ public function subCommands() { if (!$this->args) { @@ -69,6 +95,8 @@ class CompletionShell extends CommandListShell { /** * Guess autocomplete from the whole argument string + * + * @return void */ public function fuzzy() { return $this->_output(); @@ -76,6 +104,8 @@ class CompletionShell extends CommandListShell { /** * getOptionParser for _this_ shell + * + * @return ConsoleOptionParser */ public function getOptionParser() { $translationDomain = 'bash_completion'; @@ -186,19 +216,22 @@ class CompletionShell extends CommandListShell { } /** - * _getShell + * Get Shell instance for the given command * * @param mixed $commandName + * @return mixed */ protected function _getShell($commandName) { list($plugin, $name) = pluginSplit($commandName, true); + if ($plugin === 'CORE.' || $plugin === 'APP.' || $plugin === 'core.' || $plugin === 'app.') { + $commandName = $name; + $plugin = ''; + } + if (!in_array($commandName, $this->_commands())) { return false; } - if ($plugin === 'CORE.' || $plugin === 'APP.') { - $plugin = ''; - } $name = Inflector::camelize($name); $plugin = Inflector::camelize($plugin); @@ -217,10 +250,11 @@ class CompletionShell extends CommandListShell { * Emit results as a string, space delimited * * @param array $options + * @return void */ protected function _output($options = array()) { if ($options) { - $this->out(implode($options, ' ')); + return $this->out(implode($options, ' ')); } } } diff --git a/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php b/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php index ea81b3db1..2ab7ed089 100644 --- a/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php +++ b/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php @@ -98,7 +98,7 @@ class CommandListShellTest extends CakeTestCase { $expected = "/\[.*TestPluginTwo.*\] example, welcome/"; $this->assertRegExp($expected, $output); - $expected = "/\[.*CORE.*\] acl, api, bake, command_list, console, i18n, schema, server, test, testsuite, upgrade/"; + $expected = "/\[.*CORE.*\] acl, api, bake, command_list, completion, console, i18n, schema, server, test, testsuite, upgrade/"; $this->assertRegExp($expected, $output); $expected = "/\[.*app.*\] sample/"; diff --git a/lib/Cake/Test/Case/Console/Command/CompletionShellTest.php b/lib/Cake/Test/Case/Console/Command/CompletionShellTest.php new file mode 100644 index 000000000..9471f66e0 --- /dev/null +++ b/lib/Cake/Test/Case/Console/Command/CompletionShellTest.php @@ -0,0 +1,254 @@ +output .= $message; + } + +} + +/** + * Class CompletionShellTest + * + * @package Cake.Test.Case.Console.Command + */ +class CompletionShellTest extends CakeTestCase { + +/** + * setUp method + * + * @return void + */ + public function setUp() { + parent::setUp(); + App::build(array( + 'Plugin' => array( + CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS + ), + 'Console/Command' => array( + CAKE . 'Test' . DS . 'test_app' . DS . 'Console' . DS . 'Command' . DS + ) + ), App::RESET); + CakePlugin::load(array('TestPlugin', 'TestPluginTwo')); + + $out = new TestCompletionStringOutput(); + $in = $this->getMock('ConsoleInput', array(), array(), '', false); + + $this->Shell = $this->getMock( + 'CompletionShell', + array('in', '_stop', 'clear'), + array($out, $out, $in) + ); + } + +/** + * tearDown + * + * @return void + */ + public function tearDown() { + parent::tearDown(); + unset($this->Shell); + CakePlugin::unload(); + } + +/** + * test that the startup method supresses the shell header + * + * @return void + */ + public function testStartup() { + $this->Shell->runCommand('main', array()); + $output = $this->Shell->stdout->output; + + $needle = 'Welcome to CakePHP'; + $this->assertTextNotContains($needle, $output); + } + +/** + * test that main displays a warning + * + * @return void + */ + public function testMain() { + $this->Shell->runCommand('main', array()); + $output = $this->Shell->stdout->output; + + $expected = "/This command is not intended to be called manually/"; + $this->assertRegExp($expected, $output); + } + +/** + * test commands method that list all available commands + * + * @return void + */ + public function testCommands() { + $this->Shell->runCommand('commands', array()); + $output = $this->Shell->stdout->output; + + $expected = "TestPlugin.example TestPluginTwo.example TestPluginTwo.welcome acl api bake command_list completion console i18n schema server test testsuite upgrade sample\n"; + $this->assertEquals($expected, $output); + } + +/** + * test that options without argument returns the default options + * + * @return void + */ + public function testOptionsNoArguments() { + $this->Shell->runCommand('options', array()); + $output = $this->Shell->stdout->output; + + $expected = "--help -h --verbose -v --quiet -q\n"; + $this->assertEquals($expected, $output); + } + +/** + * test that options with a nonexisting command returns the default options + * + * @return void + */ + public function testOptionsNonExistingCommand() { + $this->Shell->runCommand('options', array('options', 'foo')); + $output = $this->Shell->stdout->output; + + $expected = "--help -h --verbose -v --quiet -q\n"; + $this->assertEquals($expected, $output); + } + +/** + * test that options with a existing command returns the proper options + * + * @return void + */ + public function testOptions() { + $this->Shell->runCommand('options', array('options', 'bake')); + $output = $this->Shell->stdout->output; + + $expected = "--help -h --verbose -v --quiet -q --connection -c --theme -t\n"; + $this->assertEquals($expected, $output); + } + +/** + * test that subCommands with a existing CORE command returns the proper sub commands + * + * @return void + */ + public function testSubCommandsCorePlugin() { + $this->Shell->runCommand('subCommands', array('subCommands', 'CORE.bake')); + $output = $this->Shell->stdout->output; + + $expected = "controller db_config fixture model plugin project test view\n"; + $this->assertEquals($expected, $output); + } + +/** + * test that subCommands with a existing APP command returns the proper sub commands (in this case none) + * + * @return void + */ + public function testSubCommandsAppPlugin() { + $this->Shell->runCommand('subCommands', array('subCommands', 'app.sample')); + $output = $this->Shell->stdout->output; + + $expected = ''; + $this->assertEquals($expected, $output); + } + +/** + * test that subCommands with a existing plugin command returns the proper sub commands + * + * @return void + */ + public function testSubCommandsPlugin() { + $this->Shell->runCommand('subCommands', array('subCommands', 'TestPluginTwo.welcome')); + $output = $this->Shell->stdout->output; + + $expected = "say_hello\n"; + $this->assertEquals($expected, $output); + } + +/** + * test that subcommands without arguments returns nothing + * + * @return void + */ + public function testSubCommandsNoArguments() { + $this->Shell->runCommand('subCommands', array()); + $output = $this->Shell->stdout->output; + + $expected = ''; + $this->assertEquals($expected, $output); + } + +/** + * test that subcommands with a nonexisting command returns nothing + * + * @return void + */ + public function testSubCommandsNonExistingCommand() { + $this->Shell->runCommand('subCommands', array('subCommands', 'foo')); + $output = $this->Shell->stdout->output; + + $expected = ''; + $this->assertEquals($expected, $output); + } + +/** + * test that subcommands returns the available subcommands for the given command + * + * @return void + */ + public function testSubCommands() { + $this->Shell->runCommand('subCommands', array('subCommands', 'bake')); + $output = $this->Shell->stdout->output; + + $expected = "controller db_config fixture model plugin project test view\n"; + $this->assertEquals($expected, $output); + } + +/** + * test that fuzzy returns nothing + * + * @return void + */ + public function testFuzzy() { + $this->Shell->runCommand('fuzzy', array()); + $output = $this->Shell->stdout->output; + + $expected = ''; + $this->assertEquals($expected, $output); + } +}