CompletionCommandTest.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * For full copyright and license information, please see the LICENSE.txt
  9. * Redistributions of files must retain the above copyright notice.
  10. *
  11. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  12. * @link https://cakephp.org CakePHP Project
  13. * @since 2.5.0
  14. * @license https://opensource.org/licenses/mit-license.php MIT License
  15. */
  16. namespace Cake\Test\TestCase\Command;
  17. use Cake\Console\CommandInterface;
  18. use Cake\Console\TestSuite\ConsoleIntegrationTestTrait;
  19. use Cake\Core\Configure;
  20. use Cake\Routing\Router;
  21. use Cake\TestSuite\TestCase;
  22. /**
  23. * CompletionCommandTest
  24. */
  25. class CompletionCommandTest extends TestCase
  26. {
  27. use ConsoleIntegrationTestTrait;
  28. /**
  29. * setUp method
  30. */
  31. public function setUp(): void
  32. {
  33. parent::setUp();
  34. static::setAppNamespace();
  35. Configure::write('Plugins.autoload', ['TestPlugin', 'TestPluginTwo']);
  36. }
  37. /**
  38. * tearDown
  39. */
  40. public function tearDown(): void
  41. {
  42. parent::tearDown();
  43. Router::reload();
  44. $this->clearPlugins();
  45. }
  46. /**
  47. * test that the startup method suppresses the command header
  48. */
  49. public function testStartup(): void
  50. {
  51. $this->exec('completion');
  52. $this->assertExitCode(CommandInterface::CODE_ERROR);
  53. $this->assertOutputNotContains('Welcome to CakePHP');
  54. }
  55. /**
  56. * test commands method that list all available commands
  57. */
  58. public function testCommands(): void
  59. {
  60. $this->exec('completion commands');
  61. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  62. $expected = [
  63. 'test_plugin.example',
  64. 'test_plugin.sample',
  65. 'test_plugin_two.example',
  66. 'unique',
  67. 'welcome',
  68. 'cache',
  69. 'help',
  70. 'i18n',
  71. 'plugin',
  72. 'routes',
  73. 'schema_cache',
  74. 'server',
  75. 'version',
  76. 'abort',
  77. 'auto_load_model',
  78. 'demo',
  79. 'integration',
  80. 'sample',
  81. ];
  82. foreach ($expected as $value) {
  83. $this->assertOutputContains($value);
  84. }
  85. }
  86. /**
  87. * test that options without argument returns nothing
  88. */
  89. public function testOptionsNoArguments(): void
  90. {
  91. $this->exec('completion options');
  92. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  93. $this->assertOutputEmpty();
  94. }
  95. /**
  96. * test that options with a nonexistent command returns nothing
  97. */
  98. public function testOptionsNonExistentCommand(): void
  99. {
  100. $this->exec('completion options foo');
  101. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  102. $this->assertOutputEmpty();
  103. }
  104. /**
  105. * test that options with an existing command returns the proper options
  106. */
  107. public function testOptionsCommand(): void
  108. {
  109. $this->exec('completion options schema_cache');
  110. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  111. $expected = [
  112. '--connection -c',
  113. '--help -h',
  114. '--quiet -q',
  115. '--verbose -v',
  116. ];
  117. foreach ($expected as $value) {
  118. $this->assertOutputContains($value);
  119. }
  120. }
  121. /**
  122. * test that options with an existing command / subcommand pair returns the proper options
  123. */
  124. public function testOptionsSubCommand(): void
  125. {
  126. $this->exec('completion options cache list');
  127. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  128. $expected = [
  129. '--help -h',
  130. '--quiet -q',
  131. '--verbose -v',
  132. ];
  133. foreach ($expected as $value) {
  134. $this->assertOutputContains($value);
  135. }
  136. }
  137. /**
  138. * test that nested command returns subcommand's options not command.
  139. */
  140. public function testOptionsNestedCommand(): void
  141. {
  142. $this->exec('completion options i18n extract');
  143. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  144. $expected = [
  145. '--plugin',
  146. '--app',
  147. ];
  148. foreach ($expected as $value) {
  149. $this->assertOutputContains($value);
  150. }
  151. }
  152. /**
  153. * test that subCommands with a existing CORE command returns the proper sub commands
  154. */
  155. public function testSubCommandsCorePlugin(): void
  156. {
  157. $this->exec('completion subcommands schema_cache');
  158. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  159. $expected = 'build clear';
  160. $this->assertOutputContains($expected);
  161. }
  162. /**
  163. * test that subCommands with a existing APP command returns the proper sub commands (in this case none)
  164. */
  165. public function testSubCommandsAppPlugin(): void
  166. {
  167. $this->exec('completion subcommands sample');
  168. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  169. $this->assertOutputContains('sub');
  170. }
  171. /**
  172. * test that subCommands with a existing CORE command
  173. */
  174. public function testSubCommandsCoreMultiwordCommand(): void
  175. {
  176. $this->exec('completion subcommands cache');
  177. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  178. $expected = [
  179. 'list', 'clear', 'clear_all',
  180. ];
  181. foreach ($expected as $value) {
  182. $this->assertOutputContains($value);
  183. }
  184. }
  185. /**
  186. * test that subCommands with an existing plugin command returns the proper sub commands
  187. * when the command name is unique and the dot notation not mandatory
  188. */
  189. public function testSubCommandsPlugin(): void
  190. {
  191. $this->exec('completion subcommands welcome');
  192. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  193. $expected = 'say_hello';
  194. $this->assertOutputContains($expected);
  195. }
  196. /**
  197. * test that using the dot notation when not mandatory works to provide backward compatibility
  198. */
  199. public function testSubCommandsPluginDotNotationBackwardCompatibility(): void
  200. {
  201. $this->exec('completion subcommands test_plugin_two.welcome');
  202. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  203. $expected = 'say_hello';
  204. $this->assertOutputContains($expected);
  205. }
  206. /**
  207. * test that subCommands with an app command that is also defined in a plugin and without the prefix "app."
  208. * returns proper sub commands
  209. */
  210. public function testSubCommandsAppDuplicatePluginNoDot(): void
  211. {
  212. $this->exec('completion subcommands sample');
  213. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  214. $this->assertOutputContains('sub');
  215. }
  216. /**
  217. * test that subCommands with a plugin command that is also defined in the returns proper sub commands
  218. */
  219. public function testSubCommandsPluginDuplicateApp(): void
  220. {
  221. $this->exec('completion subcommands test_plugin.sample');
  222. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  223. $expected = 'sub';
  224. $this->assertOutputContains($expected);
  225. }
  226. /**
  227. * test that subcommands without arguments returns nothing
  228. */
  229. public function testSubCommandsNoArguments(): void
  230. {
  231. $this->exec('completion subcommands');
  232. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  233. $this->assertOutputEmpty();
  234. }
  235. /**
  236. * test that subcommands with a nonexistent command returns nothing
  237. */
  238. public function testSubCommandsNonExistentCommand(): void
  239. {
  240. $this->exec('completion subcommands foo');
  241. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  242. $this->assertOutputEmpty();
  243. }
  244. /**
  245. * test that subcommands returns the available subcommands for the given command
  246. */
  247. public function testSubCommands(): void
  248. {
  249. $this->exec('completion subcommands schema_cache');
  250. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  251. $expected = 'build clear';
  252. $this->assertOutputContains($expected);
  253. }
  254. /**
  255. * test that help returns content
  256. */
  257. public function testHelp(): void
  258. {
  259. $this->exec('completion --help');
  260. $this->assertExitCode(CommandInterface::CODE_SUCCESS);
  261. $this->assertOutputContains('Output a list of available commands');
  262. $this->assertOutputContains('Output a list of available sub-commands');
  263. }
  264. }