ShellTest.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. <?php
  2. /**
  3. * CakePHP : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP Project
  12. * @since 1.2.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Console;
  16. use Cake\Console\ConsoleOptionParser;
  17. use Cake\Console\Shell;
  18. use Cake\Core\App;
  19. use Cake\Core\Configure;
  20. use Cake\Core\Plugin;
  21. use Cake\Filesystem\Folder;
  22. use Cake\Log\Log;
  23. use Cake\TestSuite\TestCase;
  24. use Cake\Utility\Hash;
  25. /**
  26. * Class for testing merging vars
  27. */
  28. class MergeShell extends Shell {
  29. public $tasks = array('DbConfig', 'Fixture');
  30. public $modelClass = 'Articles';
  31. }
  32. /**
  33. * ShellTestShell class
  34. *
  35. */
  36. class ShellTestShell extends Shell {
  37. /**
  38. * name property
  39. *
  40. * @var name
  41. */
  42. public $name = 'ShellTestShell';
  43. /**
  44. * stopped property
  45. *
  46. * @var int
  47. */
  48. public $stopped;
  49. /**
  50. * testMessage property
  51. *
  52. * @var string
  53. */
  54. public $testMessage = 'all your base are belong to us';
  55. /**
  56. * stop method
  57. *
  58. * @param int $status
  59. * @return void
  60. */
  61. protected function _stop($status = 0) {
  62. $this->stopped = $status;
  63. }
  64. protected function _secret() {
  65. }
  66. //@codingStandardsIgnoreStart
  67. public function doSomething() {
  68. }
  69. protected function noAccess() {
  70. }
  71. public function logSomething() {
  72. $this->log($this->testMessage);
  73. }
  74. //@codingStandardsIgnoreEnd
  75. public function useLogger($enable = true) {
  76. $this->_useLogger($enable);
  77. }
  78. }
  79. /**
  80. * TestAppleTask class
  81. *
  82. */
  83. class TestAppleTask extends Shell {
  84. }
  85. /**
  86. * TestBananaTask class
  87. *
  88. */
  89. class TestBananaTask extends Shell {
  90. }
  91. class_alias(__NAMESPACE__ . '\TestAppleTask', 'Cake\Shell\Task\TestAppleTask');
  92. class_alias(__NAMESPACE__ . '\TestBananaTask', 'Cake\Shell\Task\TestBananaTask');
  93. /**
  94. * ShellTest class
  95. *
  96. */
  97. class ShellTest extends TestCase {
  98. /**
  99. * Fixtures used in this test case
  100. *
  101. * @var array
  102. */
  103. public $fixtures = [
  104. 'core.posts',
  105. 'core.comments',
  106. 'core.articles',
  107. 'core.users',
  108. 'core.tags',
  109. 'core.articles_tags',
  110. 'core.attachments'
  111. ];
  112. /**
  113. * setUp method
  114. *
  115. * @return void
  116. */
  117. public function setUp() {
  118. parent::setUp();
  119. $this->io = $this->getMock('Cake\Console\ConsoleIo', [], [], '', false);
  120. $this->Shell = new ShellTestShell($this->io);
  121. if (is_dir(TMP . 'shell_test')) {
  122. $Folder = new Folder(TMP . 'shell_test');
  123. $Folder->delete();
  124. }
  125. }
  126. /**
  127. * testConstruct method
  128. *
  129. * @return void
  130. */
  131. public function testConstruct() {
  132. $this->assertEquals('ShellTestShell', $this->Shell->name);
  133. $this->assertInstanceOf('Cake\Console\ConsoleIo', $this->Shell->io());
  134. }
  135. /**
  136. * testInitialize method
  137. *
  138. * @return void
  139. */
  140. public function testInitialize() {
  141. Configure::write('App.namespace', 'TestApp');
  142. Plugin::load('TestPlugin');
  143. $this->Shell->tasks = array('DbConfig' => array('one', 'two'));
  144. $this->Shell->plugin = 'TestPlugin';
  145. $this->Shell->modelClass = 'TestPlugin.TestPluginComments';
  146. $this->Shell->initialize();
  147. $this->Shell->loadModel();
  148. $this->assertTrue(isset($this->Shell->TestPluginComments));
  149. $this->assertInstanceOf(
  150. 'TestPlugin\Model\Table\TestPluginCommentsTable',
  151. $this->Shell->TestPluginComments
  152. );
  153. }
  154. /**
  155. * test LoadModel method
  156. *
  157. * @return void
  158. */
  159. public function testLoadModel() {
  160. Configure::write('App.namespace', 'TestApp');
  161. $Shell = new MergeShell();
  162. $this->assertInstanceOf(
  163. 'TestApp\Model\Table\ArticlesTable',
  164. $Shell->Articles
  165. );
  166. $this->assertEquals('Articles', $Shell->modelClass);
  167. Plugin::load('TestPlugin');
  168. $result = $this->Shell->loadModel('TestPlugin.TestPluginComments');
  169. $this->assertInstanceOf(
  170. 'TestPlugin\Model\Table\TestPluginCommentsTable',
  171. $result
  172. );
  173. $this->assertInstanceOf(
  174. 'TestPlugin\Model\Table\TestPluginCommentsTable',
  175. $this->Shell->TestPluginComments
  176. );
  177. }
  178. /**
  179. * testIn method
  180. *
  181. * @return void
  182. */
  183. public function testIn() {
  184. $this->io->expects($this->at(0))
  185. ->method('askChoice')
  186. ->with('Just a test?', ['y', 'n'], 'n')
  187. ->will($this->returnValue('n'));
  188. $this->io->expects($this->at(1))
  189. ->method('ask')
  190. ->with('Just a test?', 'n')
  191. ->will($this->returnValue('n'));
  192. $result = $this->Shell->in('Just a test?', array('y', 'n'), 'n');
  193. $this->assertEquals('n', $result);
  194. $result = $this->Shell->in('Just a test?', null, 'n');
  195. $this->assertEquals('n', $result);
  196. }
  197. /**
  198. * Test in() when not interactive.
  199. *
  200. * @return void
  201. */
  202. public function testInNonInteractive() {
  203. $this->io->expects($this->never())
  204. ->method('askChoice');
  205. $this->io->expects($this->never())
  206. ->method('ask');
  207. $this->Shell->interactive = false;
  208. $result = $this->Shell->in('Just a test?', 'y/n', 'n');
  209. $this->assertEquals('n', $result);
  210. }
  211. /**
  212. * testOut method
  213. *
  214. * @return void
  215. */
  216. public function testOut() {
  217. $this->io->expects($this->once())
  218. ->method('out')
  219. ->with('Just a test', 1);
  220. $this->Shell->out('Just a test');
  221. }
  222. /**
  223. * testErr method
  224. *
  225. * @return void
  226. */
  227. public function testErr() {
  228. $this->io->expects($this->once())
  229. ->method('err')
  230. ->with('Just a test', 1);
  231. $this->Shell->err('Just a test');
  232. }
  233. /**
  234. * testNl
  235. *
  236. * @return void
  237. */
  238. public function testNl() {
  239. $this->io->expects($this->once())
  240. ->method('nl')
  241. ->with(2);
  242. $this->Shell->nl(2);
  243. }
  244. /**
  245. * testHr
  246. *
  247. * @return void
  248. */
  249. public function testHr() {
  250. $this->io->expects($this->once())
  251. ->method('hr')
  252. ->with(2);
  253. $this->Shell->hr(2);
  254. }
  255. /**
  256. * testError
  257. *
  258. * @return void
  259. */
  260. public function testError() {
  261. $this->io->expects($this->at(0))
  262. ->method('err')
  263. ->with('<error>Error:</error> Foo Not Found');
  264. $this->io->expects($this->at(1))
  265. ->method('err')
  266. ->with("Searched all...");
  267. $this->Shell->error('Foo Not Found', 'Searched all...');
  268. $this->assertSame($this->Shell->stopped, 1);
  269. }
  270. /**
  271. * testLoadTasks method
  272. *
  273. * @return void
  274. */
  275. public function testLoadTasks() {
  276. $this->assertTrue($this->Shell->loadTasks());
  277. $this->Shell->tasks = null;
  278. $this->assertTrue($this->Shell->loadTasks());
  279. $this->Shell->tasks = false;
  280. $this->assertTrue($this->Shell->loadTasks());
  281. $this->Shell->tasks = true;
  282. $this->assertTrue($this->Shell->loadTasks());
  283. $this->Shell->tasks = array();
  284. $this->assertTrue($this->Shell->loadTasks());
  285. $this->Shell->tasks = array('TestApple');
  286. $this->assertTrue($this->Shell->loadTasks());
  287. $this->assertInstanceOf('Cake\Shell\Task\TestAppleTask', $this->Shell->TestApple);
  288. $this->Shell->tasks = 'TestBanana';
  289. $this->assertTrue($this->Shell->loadTasks());
  290. $this->assertInstanceOf('Cake\Shell\Task\TestAppleTask', $this->Shell->TestApple);
  291. $this->assertInstanceOf('Cake\Shell\Task\TestBananaTask', $this->Shell->TestBanana);
  292. unset($this->Shell->ShellTestApple, $this->Shell->TestBanana);
  293. $this->Shell->tasks = array('TestApple', 'TestBanana');
  294. $this->assertTrue($this->Shell->loadTasks());
  295. $this->assertInstanceOf('Cake\Shell\Task\TestAppleTask', $this->Shell->TestApple);
  296. $this->assertInstanceOf('Cake\Shell\Task\TestBananaTask', $this->Shell->TestBanana);
  297. }
  298. /**
  299. * test that __get() makes args and params references
  300. *
  301. * @return void
  302. */
  303. public function testMagicGetArgAndParamReferences() {
  304. $this->Shell->tasks = array('TestApple');
  305. $this->Shell->args = array('one');
  306. $this->Shell->params = array('help' => false);
  307. $this->Shell->loadTasks();
  308. $result = $this->Shell->TestApple;
  309. $this->Shell->args = array('one', 'two');
  310. $this->assertSame($this->Shell->args, $result->args);
  311. $this->assertSame($this->Shell->params, $result->params);
  312. }
  313. /**
  314. * testShortPath method
  315. *
  316. * @return void
  317. */
  318. public function testShortPath() {
  319. $path = $expected = DS . 'tmp/ab/cd';
  320. $this->assertPathEquals($expected, $this->Shell->shortPath($path));
  321. $path = $expected = DS . 'tmp/ab/cd/';
  322. $this->assertPathEquals($expected, $this->Shell->shortPath($path));
  323. $path = $expected = DS . 'tmp/ab/index.php';
  324. $this->assertPathEquals($expected, $this->Shell->shortPath($path));
  325. $path = DS . 'tmp/ab/' . DS . 'cd';
  326. $expected = DS . 'tmp/ab/cd';
  327. $this->assertPathEquals($expected, $this->Shell->shortPath($path));
  328. $path = 'tmp/ab';
  329. $expected = 'tmp/ab';
  330. $this->assertPathEquals($expected, $this->Shell->shortPath($path));
  331. $path = 'tmp/ab';
  332. $expected = 'tmp/ab';
  333. $this->assertPathEquals($expected, $this->Shell->shortPath($path));
  334. $path = APP;
  335. $result = $this->Shell->shortPath($path);
  336. $this->assertNotContains(ROOT, $result, 'Short paths should not contain ROOT');
  337. }
  338. /**
  339. * testCreateFile method
  340. *
  341. * @return void
  342. */
  343. public function testCreateFileNonInteractive() {
  344. $eol = PHP_EOL;
  345. $path = TMP . 'shell_test';
  346. $file = $path . DS . 'file1.php';
  347. new Folder($path, true);
  348. $contents = "<?php{$eol}echo 'test';${eol}\$te = 'st';{$eol}";
  349. $result = $this->Shell->createFile($file, $contents);
  350. $this->assertTrue($result);
  351. $this->assertTrue(file_exists($file));
  352. $this->assertEquals(file_get_contents($file), $contents);
  353. }
  354. /**
  355. * Test that files are not changed with a 'n' reply.
  356. *
  357. * @return void
  358. */
  359. public function testCreateFileNoReply() {
  360. $eol = PHP_EOL;
  361. $path = TMP . 'shell_test';
  362. $file = $path . DS . 'file1.php';
  363. new Folder($path, true);
  364. $this->io->expects($this->once())
  365. ->method('askChoice')
  366. ->will($this->returnValue('n'));
  367. touch($file);
  368. $this->assertTrue(file_exists($file));
  369. $contents = "My content";
  370. $result = $this->Shell->createFile($file, $contents);
  371. $this->assertTrue(file_exists($file));
  372. $this->assertTextEquals('', file_get_contents($file));
  373. $this->assertFalse($result, 'Did not create file.');
  374. }
  375. /**
  376. * Test that files are changed with a 'y' reply.
  377. *
  378. * @return void
  379. */
  380. public function testCreateFileOverwrite() {
  381. $eol = PHP_EOL;
  382. $path = TMP . 'shell_test';
  383. $file = $path . DS . 'file1.php';
  384. new Folder($path, true);
  385. $this->io->expects($this->once())
  386. ->method('askChoice')
  387. ->will($this->returnValue('y'));
  388. touch($file);
  389. $this->assertTrue(file_exists($file));
  390. $contents = "My content";
  391. $result = $this->Shell->createFile($file, $contents);
  392. $this->assertTrue(file_exists($file));
  393. $this->assertTextEquals($contents, file_get_contents($file));
  394. $this->assertTrue($result, 'Did create file.');
  395. }
  396. /**
  397. * Test that you can't create files that aren't writable.
  398. *
  399. * @return void
  400. */
  401. public function testCreateFileNoPermissions() {
  402. $this->skipIf(DS === '\\', 'Cant perform operations using permissions on windows.');
  403. $path = TMP . 'shell_test';
  404. $file = $path . DS . 'no_perms';
  405. if (!is_dir($path)) {
  406. mkdir($path);
  407. }
  408. chmod($path, 0444);
  409. $this->Shell->createFile($file, 'testing');
  410. $this->assertFalse(file_exists($file));
  411. chmod($path, 0744);
  412. rmdir($path);
  413. }
  414. /**
  415. * test hasTask method
  416. *
  417. * @return void
  418. */
  419. public function testHasTask() {
  420. $this->Shell->tasks = array('Extract', 'DbConfig');
  421. $this->Shell->loadTasks();
  422. $this->assertTrue($this->Shell->hasTask('extract'));
  423. $this->assertTrue($this->Shell->hasTask('Extract'));
  424. $this->assertFalse($this->Shell->hasTask('random'));
  425. $this->assertTrue($this->Shell->hasTask('db_config'));
  426. $this->assertTrue($this->Shell->hasTask('DbConfig'));
  427. }
  428. /**
  429. * test the hasMethod
  430. *
  431. * @return void
  432. */
  433. public function testHasMethod() {
  434. $this->assertTrue($this->Shell->hasMethod('doSomething'));
  435. $this->assertFalse($this->Shell->hasMethod('hr'), 'hr is callable');
  436. $this->assertFalse($this->Shell->hasMethod('_secret'), '_secret is callable');
  437. $this->assertFalse($this->Shell->hasMethod('no_access'), 'no_access is callable');
  438. }
  439. /**
  440. * test run command calling main.
  441. *
  442. * @return void
  443. */
  444. public function testRunCommandMain() {
  445. $io = $this->getMock('Cake\Console\ConsoleIo');
  446. $shell = $this->getMock('Cake\Console\Shell', ['main', 'startup'], [$io]);
  447. $shell->expects($this->once())->method('startup');
  448. $shell->expects($this->once())->method('main')
  449. ->with('cakes')
  450. ->will($this->returnValue(true));
  451. $result = $shell->runCommand(['cakes', '--verbose']);
  452. $this->assertTrue($result);
  453. }
  454. /**
  455. * test run command calling a real method with no subcommands defined.
  456. *
  457. * @return void
  458. */
  459. public function testRunCommandWithMethod() {
  460. $io = $this->getMock('Cake\Console\ConsoleIo');
  461. $shell = $this->getMock('Cake\Console\Shell', ['hitMe', 'startup'], [$io]);
  462. $shell->expects($this->once())->method('startup');
  463. $shell->expects($this->once())->method('hitMe')
  464. ->with('cakes')
  465. ->will($this->returnValue(true));
  466. $result = $shell->runCommand(['hit_me', 'cakes', '--verbose'], true);
  467. $this->assertTrue($result);
  468. }
  469. /**
  470. * Test that runCommand() doesn't call public methods when the second arg is false.
  471. *
  472. * @return void
  473. */
  474. public function testRunCommandAutoMethodOff() {
  475. $io = $this->getMock('Cake\Console\ConsoleIo');
  476. $shell = $this->getMock('Cake\Console\Shell', ['hit_me', 'startup'], [$io]);
  477. $shell->expects($this->never())->method('startup');
  478. $shell->expects($this->never())->method('hit_me');
  479. $result = $shell->runCommand(['hit_me', 'baseball'], false);
  480. $this->assertFalse($result);
  481. $result = $shell->runCommand(['hit_me', 'baseball']);
  482. $this->assertFalse($result, 'Default value of runCommand() should be false');
  483. }
  484. /**
  485. * test run command calling a real method with mismatching subcommands defined.
  486. *
  487. * @return void
  488. */
  489. public function testRunCommandWithMethodNotInSubcommands() {
  490. $parser = $this->getMock('Cake\Console\ConsoleOptionParser', ['help'], ['knife']);
  491. $io = $this->getMock('Cake\Console\ConsoleIo');
  492. $shell = $this->getMock('Cake\Console\Shell', ['getOptionParser', 'roll', 'startup'], [$io]);
  493. $parser->addSubCommand('slice');
  494. $shell->expects($this->any())
  495. ->method('getOptionParser')
  496. ->will($this->returnValue($parser));
  497. $parser->expects($this->once())
  498. ->method('help');
  499. $shell->expects($this->never())->method('startup');
  500. $shell->expects($this->never())->method('roll');
  501. $result = $shell->runCommand(['roll', 'cakes', '--verbose']);
  502. $this->assertFalse($result);
  503. }
  504. /**
  505. * test run command calling a real method with subcommands defined.
  506. *
  507. * @return void
  508. */
  509. public function testRunCommandWithMethodInSubcommands() {
  510. $parser = $this->getMock('Cake\Console\ConsoleOptionParser', ['help'], ['knife']);
  511. $io = $this->getMock('Cake\Console\ConsoleIo');
  512. $shell = $this->getMock('Cake\Console\Shell', ['getOptionParser', 'slice', 'startup'], [$io]);
  513. $parser->addSubCommand('slice');
  514. $shell->expects($this->any())
  515. ->method('getOptionParser')
  516. ->will($this->returnValue($parser));
  517. $shell->expects($this->once())->method('startup');
  518. $shell->expects($this->once())
  519. ->method('slice')
  520. ->with('cakes');
  521. $shell->runCommand(['slice', 'cakes', '--verbose']);
  522. }
  523. /**
  524. * test run command calling a missing method with subcommands defined.
  525. *
  526. * @return void
  527. */
  528. public function testRunCommandWithMissingMethodInSubcommands() {
  529. $parser = $this->getMock('Cake\Console\ConsoleOptionParser', ['help'], ['knife']);
  530. $parser->addSubCommand('slice');
  531. $io = $this->getMock('Cake\Console\ConsoleIo');
  532. $shell = $this->getMock('Cake\Console\Shell', ['getOptionParser', 'startup'], [$io]);
  533. $shell->expects($this->any())
  534. ->method('getOptionParser')
  535. ->will($this->returnValue($parser));
  536. $shell->expects($this->never())
  537. ->method('startup');
  538. $parser->expects($this->once())
  539. ->method('help');
  540. $shell->runCommand(['slice', 'cakes', '--verbose']);
  541. }
  542. /**
  543. * test run command causing exception on Shell method.
  544. *
  545. * @return void
  546. */
  547. public function testRunCommandBaseclassMethod() {
  548. $shell = $this->getMock('Cake\Console\Shell', array('startup', 'getOptionParser', 'out'), array(), '', false);
  549. $parser = $this->getMock('Cake\Console\ConsoleOptionParser', array(), array(), '', false);
  550. $parser->expects($this->once())->method('help');
  551. $shell->expects($this->once())->method('getOptionParser')
  552. ->will($this->returnValue($parser));
  553. $shell->expects($this->never())->method('hr');
  554. $shell->expects($this->once())->method('out');
  555. $shell->runCommand(['hr']);
  556. }
  557. /**
  558. * test run command causing exception on Shell method.
  559. *
  560. * @return void
  561. */
  562. public function testRunCommandMissingMethod() {
  563. $shell = $this->getMock('Cake\Console\Shell', array('startup', 'getOptionParser', 'out'), array(), '', false);
  564. $parser = $this->getMock('Cake\Console\ConsoleOptionParser', array(), array(), '', false);
  565. $parser->expects($this->once())->method('help');
  566. $shell->expects($this->once())->method('getOptionParser')
  567. ->will($this->returnValue($parser));
  568. $shell->expects($this->once())->method('out');
  569. $result = $shell->runCommand(['idontexist']);
  570. $this->assertFalse($result);
  571. }
  572. /**
  573. * test that a --help causes help to show.
  574. *
  575. * @return void
  576. */
  577. public function testRunCommandTriggeringHelp() {
  578. $Parser = $this->getMock('Cake\Console\ConsoleOptionParser', array(), array(), '', false);
  579. $Parser->expects($this->once())->method('parse')
  580. ->with(array('--help'))
  581. ->will($this->returnValue(array(array('help' => true), array())));
  582. $Parser->expects($this->once())->method('help');
  583. $Shell = $this->getMock('Cake\Console\Shell', array('getOptionParser', 'out', 'startup', '_welcome'), array(), '', false);
  584. $Shell->expects($this->once())->method('getOptionParser')
  585. ->will($this->returnValue($Parser));
  586. $Shell->expects($this->once())->method('out');
  587. $Shell->runCommand(['--help']);
  588. }
  589. /**
  590. * test that runCommand will not call runCommand on tasks that are not subcommands.
  591. *
  592. * @return void
  593. */
  594. public function testRunCommandNotCallUnexposedTask() {
  595. $shell = $this->getMock('Cake\Console\Shell', ['startup', 'hasTask', 'out'], [], '', false);
  596. $task = $this->getMock('Cake\Console\Shell', ['runCommand'], [], '', false);
  597. $task->expects($this->never())
  598. ->method('runCommand');
  599. $shell->expects($this->any())
  600. ->method('hasTask')
  601. ->will($this->returnValue(true));
  602. $shell->expects($this->never())->method('startup');
  603. $shell->expects($this->once())->method('out');
  604. $shell->RunCommand = $task;
  605. $result = $shell->runCommand(['run_command', 'one']);
  606. $this->assertFalse($result);
  607. }
  608. /**
  609. * test that runCommand will call runCommand on the task.
  610. *
  611. * @return void
  612. */
  613. public function testRunCommandHittingTaskInSubcommand() {
  614. $parser = new ConsoleOptionParser('knife');
  615. $parser->addSubcommand('slice');
  616. $shell = $this->getMock('Cake\Console\Shell', ['hasTask', 'startup', 'getOptionParser'], [], '', false);
  617. $task = $this->getMock('Cake\Console\Shell', ['main', 'runCommand'], [], '', false);
  618. $task->expects($this->once())
  619. ->method('runCommand')
  620. ->with(['one'], false);
  621. $shell->expects($this->once())->method('getOptionParser')
  622. ->will($this->returnValue($parser));
  623. $shell->expects($this->once())->method('startup');
  624. $shell->expects($this->any())
  625. ->method('hasTask')
  626. ->will($this->returnValue(true));
  627. $shell->Slice = $task;
  628. $shell->runCommand(['slice', 'one']);
  629. }
  630. /**
  631. * test wrapBlock wrapping text.
  632. *
  633. * @return void
  634. */
  635. public function testWrapText() {
  636. $text = 'This is the song that never ends. This is the song that never ends. This is the song that never ends.';
  637. $result = $this->Shell->wrapText($text, array('width' => 33));
  638. $expected = <<<TEXT
  639. This is the song that never ends.
  640. This is the song that never ends.
  641. This is the song that never ends.
  642. TEXT;
  643. $this->assertTextEquals($expected, $result, 'Text not wrapped.');
  644. $result = $this->Shell->wrapText($text, array('indent' => ' ', 'width' => 33));
  645. $expected = <<<TEXT
  646. This is the song that never ends.
  647. This is the song that never ends.
  648. This is the song that never ends.
  649. TEXT;
  650. $this->assertTextEquals($expected, $result, 'Text not wrapped.');
  651. }
  652. /**
  653. * Testing camel cased naming of tasks
  654. *
  655. * @return void
  656. */
  657. public function testShellNaming() {
  658. $this->Shell->tasks = array('TestApple');
  659. $this->Shell->loadTasks();
  660. $expected = 'TestApple';
  661. $this->assertEquals($expected, $this->Shell->TestApple->name);
  662. }
  663. /**
  664. * Test reading params
  665. *
  666. * @dataProvider paramReadingDataProvider
  667. */
  668. public function testParamReading($toRead, $expected) {
  669. $this->Shell->params = array(
  670. 'key' => 'value',
  671. 'help' => false,
  672. 'emptykey' => '',
  673. 'truthy' => true
  674. );
  675. $this->assertSame($expected, $this->Shell->param($toRead));
  676. }
  677. /**
  678. * Data provider for testing reading values with Shell::param()
  679. *
  680. * @return array
  681. */
  682. public function paramReadingDataProvider() {
  683. return array(
  684. array(
  685. 'key',
  686. 'value',
  687. ),
  688. array(
  689. 'help',
  690. false,
  691. ),
  692. array(
  693. 'emptykey',
  694. '',
  695. ),
  696. array(
  697. 'truthy',
  698. true,
  699. ),
  700. array(
  701. 'does_not_exist',
  702. null,
  703. )
  704. );
  705. }
  706. /**
  707. * Test that option parsers are created with the correct name/command.
  708. *
  709. * @return void
  710. */
  711. public function testGetOptionParser() {
  712. $this->Shell->name = 'test';
  713. $this->Shell->plugin = 'plugin';
  714. $parser = $this->Shell->getOptionParser();
  715. $this->assertEquals('plugin.test', $parser->command());
  716. }
  717. /**
  718. * Test file and console and logging quiet output
  719. *
  720. * @return void
  721. */
  722. public function testQuietLog() {
  723. $io = $this->getMock('Cake\Console\ConsoleIo', [], [], '', false);
  724. $io->expects($this->once())
  725. ->method('level')
  726. ->with(Shell::QUIET);
  727. $io->expects($this->at(0))
  728. ->method('setLoggers')
  729. ->with(true);
  730. $io->expects($this->at(2))
  731. ->method('setLoggers')
  732. ->with(false);
  733. $this->Shell = $this->getMock(__NAMESPACE__ . '\ShellTestShell', array('_useLogger'), array($io));
  734. $this->Shell->runCommand(['foo', '--quiet']);
  735. }
  736. }