TestTaskTest.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. <?php
  2. /**
  3. * TestTaskTest file
  4. *
  5. * Test Case for test generation shell task
  6. *
  7. * PHP 5
  8. *
  9. * CakePHP : Rapid Development Framework (http://cakephp.org)
  10. * Copyright 2005-2011, Cake Software Foundation, Inc.
  11. *
  12. * Licensed under The MIT License
  13. * Redistributions of files must retain the above copyright notice.
  14. *
  15. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc.
  16. * @link http://cakephp.org CakePHP Project
  17. * @package Cake.Test.Case.Console.Command.Task
  18. * @since CakePHP v 1.2.0.7726
  19. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  20. */
  21. App::uses('ShellDispatcher', 'Console');
  22. App::uses('ConsoleOutput', 'Console');
  23. App::uses('ConsoleInput', 'Console');
  24. App::uses('Shell', 'Console');
  25. App::uses('TestTask', 'Console/Command/Task');
  26. App::uses('TemplateTask', 'Console/Command/Task');
  27. App::uses('Controller', 'Controller');
  28. App::uses('Model', 'Model');
  29. /**
  30. * Test Article model
  31. *
  32. * @package Cake.Test.Case.Console.Command.Task
  33. * @package Cake.Test.Case.Console.Command.Task
  34. */
  35. class TestTaskArticle extends Model {
  36. /**
  37. * Model name
  38. *
  39. * @var string
  40. */
  41. public $name = 'TestTaskArticle';
  42. /**
  43. * Table name to use
  44. *
  45. * @var string
  46. */
  47. public $useTable = 'articles';
  48. /**
  49. * HasMany Associations
  50. *
  51. * @var array
  52. */
  53. public $hasMany = array(
  54. 'Comment' => array(
  55. 'className' => 'TestTask.TestTaskComment',
  56. 'foreignKey' => 'article_id',
  57. )
  58. );
  59. /**
  60. * Has and Belongs To Many Associations
  61. *
  62. * @var array
  63. */
  64. public $hasAndBelongsToMany = array(
  65. 'Tag' => array(
  66. 'className' => 'TestTaskTag',
  67. 'joinTable' => 'articles_tags',
  68. 'foreignKey' => 'article_id',
  69. 'associationForeignKey' => 'tag_id'
  70. )
  71. );
  72. /**
  73. * Example public method
  74. *
  75. * @return void
  76. */
  77. public function doSomething() {
  78. }
  79. /**
  80. * Example Secondary public method
  81. *
  82. * @return void
  83. */
  84. public function doSomethingElse() {
  85. }
  86. /**
  87. * Example protected method
  88. *
  89. * @return void
  90. */
  91. protected function _innerMethod() {
  92. }
  93. }
  94. /**
  95. * Tag Testing Model
  96. *
  97. * @package Cake.Test.Case.Console.Command.Task
  98. * @package Cake.Test.Case.Console.Command.Task
  99. */
  100. class TestTaskTag extends Model {
  101. /**
  102. * Model name
  103. *
  104. * @var string
  105. */
  106. public $name = 'TestTaskTag';
  107. /**
  108. * Table name
  109. *
  110. * @var string
  111. */
  112. public $useTable = 'tags';
  113. /**
  114. * Has and Belongs To Many Associations
  115. *
  116. * @var array
  117. */
  118. public $hasAndBelongsToMany = array(
  119. 'Article' => array(
  120. 'className' => 'TestTaskArticle',
  121. 'joinTable' => 'articles_tags',
  122. 'foreignKey' => 'tag_id',
  123. 'associationForeignKey' => 'article_id'
  124. )
  125. );
  126. }
  127. /**
  128. * Simulated plugin
  129. *
  130. * @package Cake.Test.Case.Console.Command.Task
  131. * @package Cake.Test.Case.Console.Command.Task
  132. */
  133. class TestTaskAppModel extends Model {
  134. }
  135. /**
  136. * Testing AppMode (TaskComment)
  137. *
  138. * @package Cake.Test.Case.Console.Command.Task
  139. * @package Cake.Test.Case.Console.Command.Task
  140. */
  141. class TestTaskComment extends TestTaskAppModel {
  142. /**
  143. * Model name
  144. *
  145. * @var string
  146. */
  147. public $name = 'TestTaskComment';
  148. /**
  149. * Table name
  150. *
  151. * @var string
  152. */
  153. public $useTable = 'comments';
  154. /**
  155. * Belongs To Associations
  156. *
  157. * @var array
  158. */
  159. public $belongsTo = array(
  160. 'Article' => array(
  161. 'className' => 'TestTaskArticle',
  162. 'foreignKey' => 'article_id',
  163. )
  164. );
  165. }
  166. /**
  167. * Test Task Comments Controller
  168. *
  169. * @package Cake.Test.Case.Console.Command.Task
  170. * @package Cake.Test.Case.Console.Command.Task
  171. */
  172. class TestTaskCommentsController extends Controller {
  173. /**
  174. * Controller Name
  175. *
  176. * @var string
  177. */
  178. public $name = 'TestTaskComments';
  179. /**
  180. * Models to use
  181. *
  182. * @var array
  183. */
  184. public $uses = array('TestTaskComment', 'TestTaskTag');
  185. }
  186. /**
  187. * TestTaskTest class
  188. *
  189. * @package Cake.Test.Case.Console.Command.Task
  190. */
  191. class TestTaskTest extends CakeTestCase {
  192. /**
  193. * Fixtures
  194. *
  195. * @var string
  196. */
  197. public $fixtures = array('core.article', 'core.comment', 'core.articles_tag', 'core.tag');
  198. /**
  199. * setup method
  200. *
  201. * @return void
  202. */
  203. public function setup() {
  204. parent::setup();
  205. $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
  206. $in = $this->getMock('ConsoleInput', array(), array(), '', false);
  207. $this->Task = $this->getMock('TestTask',
  208. array('in', 'err', 'createFile', '_stop', 'isLoadableClass'),
  209. array($out, $out, $in)
  210. );
  211. $this->Task->name = 'Test';
  212. $this->Task->Template = new TemplateTask($out, $out, $in);
  213. }
  214. /**
  215. * endTest method
  216. *
  217. * @return void
  218. */
  219. public function tearDown() {
  220. parent::tearDown();
  221. unset($this->Task);
  222. CakePlugin::unload();
  223. }
  224. /**
  225. * Test that file path generation doesn't continuously append paths.
  226. *
  227. * @return void
  228. */
  229. public function testFilePathGenerationModelRepeated() {
  230. $this->Task->expects($this->never())->method('err');
  231. $this->Task->expects($this->never())->method('_stop');
  232. $file = TESTS . 'Case' . DS . 'Model' . DS . 'MyClassTest.php';
  233. $this->Task->expects($this->at(1))->method('createFile')
  234. ->with($file, new PHPUnit_Framework_Constraint_IsAnything());
  235. $this->Task->expects($this->at(3))->method('createFile')
  236. ->with($file, new PHPUnit_Framework_Constraint_IsAnything());
  237. $file = TESTS . 'Case' . DS . 'Controller' . DS . 'CommentsControllerTest.php';
  238. $this->Task->expects($this->at(5))->method('createFile')
  239. ->with($file, new PHPUnit_Framework_Constraint_IsAnything());
  240. $this->Task->bake('Model', 'MyClass');
  241. $this->Task->bake('Model', 'MyClass');
  242. $this->Task->bake('Controller', 'Comments');
  243. }
  244. /**
  245. * Test that method introspection pulls all relevant non parent class
  246. * methods into the test case.
  247. *
  248. * @return void
  249. */
  250. public function testMethodIntrospection() {
  251. $result = $this->Task->getTestableMethods('TestTaskArticle');
  252. $expected = array('dosomething', 'dosomethingelse');
  253. $this->assertEqual(array_map('strtolower', $result), $expected);
  254. }
  255. /**
  256. * test that the generation of fixtures works correctly.
  257. *
  258. * @return void
  259. */
  260. public function testFixtureArrayGenerationFromModel() {
  261. $subject = ClassRegistry::init('TestTaskArticle');
  262. $result = $this->Task->generateFixtureList($subject);
  263. $expected = array('plugin.test_task.test_task_comment', 'app.articles_tags',
  264. 'app.test_task_article', 'app.test_task_tag');
  265. $this->assertEqual(sort($result), sort($expected));
  266. }
  267. /**
  268. * test that the generation of fixtures works correctly.
  269. *
  270. * @return void
  271. */
  272. public function testFixtureArrayGenerationFromController() {
  273. $subject = new TestTaskCommentsController();
  274. $result = $this->Task->generateFixtureList($subject);
  275. $expected = array('plugin.test_task.test_task_comment', 'app.articles_tags',
  276. 'app.test_task_article', 'app.test_task_tag');
  277. $this->assertEqual(sort($result), sort($expected));
  278. }
  279. /**
  280. * test user interaction to get object type
  281. *
  282. * @return void
  283. */
  284. public function testGetObjectType() {
  285. $this->Task->expects($this->once())->method('_stop');
  286. $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('q'));
  287. $this->Task->expects($this->at(2))->method('in')->will($this->returnValue(2));
  288. $this->Task->getObjectType();
  289. $result = $this->Task->getObjectType();
  290. $this->assertEqual($result, $this->Task->classTypes['Controller']);
  291. }
  292. /**
  293. * creating test subjects should clear the registry so the registry is always fresh
  294. *
  295. * @return void
  296. */
  297. public function testRegistryClearWhenBuildingTestObjects() {
  298. ClassRegistry::flush();
  299. $model = ClassRegistry::init('TestTaskComment');
  300. $model->bindModel(array(
  301. 'belongsTo' => array(
  302. 'Random' => array(
  303. 'className' => 'TestTaskArticle',
  304. 'foreignKey' => 'article_id',
  305. )
  306. )
  307. ));
  308. $keys = ClassRegistry::keys();
  309. $this->assertTrue(in_array('test_task_comment', $keys));
  310. $object = $this->Task->buildTestSubject('Model', 'TestTaskComment');
  311. $keys = ClassRegistry::keys();
  312. $this->assertFalse(in_array('random', $keys));
  313. }
  314. /**
  315. * test that getClassName returns the user choice as a classname.
  316. *
  317. * @return void
  318. */
  319. public function testGetClassName() {
  320. $objects = App::objects('model');
  321. $this->skipIf(empty($objects), 'No models in app.');
  322. $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('MyCustomClass'));
  323. $this->Task->expects($this->at(1))->method('in')->will($this->returnValue(1));
  324. $result = $this->Task->getClassName('Model');
  325. $this->assertEqual($result, 'MyCustomClass');
  326. $result = $this->Task->getClassName('Model');
  327. $options = App::objects('model');
  328. $this->assertEqual($result, $options[0]);
  329. }
  330. /**
  331. * Test the user interaction for defining additional fixtures.
  332. *
  333. * @return void
  334. */
  335. public function testGetUserFixtures() {
  336. $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
  337. $this->Task->expects($this->at(1))->method('in')
  338. ->will($this->returnValue('app.pizza, app.topping, app.side_dish'));
  339. $result = $this->Task->getUserFixtures();
  340. $expected = array('app.pizza', 'app.topping', 'app.side_dish');
  341. $this->assertEqual($expected, $result);
  342. }
  343. /**
  344. * test that resolving classnames works
  345. *
  346. * @return void
  347. */
  348. public function testGetRealClassname() {
  349. $result = $this->Task->getRealClassname('Model', 'Post');
  350. $this->assertEqual($result, 'Post');
  351. $result = $this->Task->getRealClassname('Controller', 'Posts');
  352. $this->assertEqual($result, 'PostsController');
  353. $result = $this->Task->getRealClassname('Helper', 'Form');
  354. $this->assertEqual($result, 'FormHelper');
  355. $result = $this->Task->getRealClassname('Behavior', 'Containable');
  356. $this->assertEqual($result, 'ContainableBehavior');
  357. $result = $this->Task->getRealClassname('Component', 'Auth');
  358. $this->assertEqual($result, 'AuthComponent');
  359. }
  360. /**
  361. * test baking files. The conditionally run tests are known to fail in PHP4
  362. * as PHP4 classnames are all lower case, breaking the plugin path inflection.
  363. *
  364. * @return void
  365. */
  366. public function testBakeModelTest() {
  367. $this->Task->expects($this->once())->method('createFile')->will($this->returnValue(true));
  368. $this->Task->expects($this->once())->method('isLoadableClass')->will($this->returnValue(true));
  369. $result = $this->Task->bake('Model', 'TestTaskArticle');
  370. $this->assertContains("App::uses('TestTaskArticle', 'Model')", $result);
  371. $this->assertContains('class TestTaskArticleTestCase extends CakeTestCase', $result);
  372. $this->assertContains('function setUp()', $result);
  373. $this->assertContains("\$this->TestTaskArticle = ClassRegistry::init('TestTaskArticle')", $result);
  374. $this->assertContains('function tearDown()', $result);
  375. $this->assertContains('unset($this->TestTaskArticle)', $result);
  376. $this->assertContains('function testDoSomething()', $result);
  377. $this->assertContains('function testDoSomethingElse()', $result);
  378. $this->assertContains("'app.test_task_article'", $result);
  379. $this->assertContains("'plugin.test_task.test_task_comment'", $result);
  380. $this->assertContains("'app.test_task_tag'", $result);
  381. $this->assertContains("'app.articles_tag'", $result);
  382. }
  383. /**
  384. * test baking controller test files, ensure that the stub class is generated.
  385. * Conditional assertion is known to fail on PHP4 as classnames are all lower case
  386. * causing issues with inflection of path name from classname.
  387. *
  388. * @return void
  389. */
  390. public function testBakeControllerTest() {
  391. $this->Task->expects($this->once())->method('createFile')->will($this->returnValue(true));
  392. $this->Task->expects($this->once())->method('isLoadableClass')->will($this->returnValue(true));
  393. $result = $this->Task->bake('Controller', 'TestTaskComments');
  394. $this->assertContains("App::uses('TestTaskCommentsController', 'Controller')", $result);
  395. $this->assertContains('class TestTaskCommentsControllerTestCase extends CakeTestCase', $result);
  396. $this->assertContains('class TestTestTaskCommentsController extends TestTaskCommentsController', $result);
  397. $this->assertContains('public $autoRender = false', $result);
  398. $this->assertContains('function redirect($url, $status = null, $exit = true)', $result);
  399. $this->assertContains('function setUp()', $result);
  400. $this->assertContains("\$this->TestTaskComments = new TestTestTaskCommentsController()", $result);
  401. $this->assertContains("\$this->TestTaskComments->constructClasses()", $result);
  402. $this->assertContains('function tearDown()', $result);
  403. $this->assertContains('unset($this->TestTaskComments)', $result);
  404. $this->assertContains("'app.test_task_article'", $result);
  405. $this->assertContains("'plugin.test_task.test_task_comment'", $result);
  406. $this->assertContains("'app.test_task_tag'", $result);
  407. $this->assertContains("'app.articles_tag'", $result);
  408. }
  409. /**
  410. * test Constructor generation ensure that constructClasses is called for controllers
  411. *
  412. * @return void
  413. */
  414. public function testGenerateConstructor() {
  415. $result = $this->Task->generateConstructor('controller', 'PostsController');
  416. $expected = "new TestPostsController();\n\t\t\$this->Posts->constructClasses();\n";
  417. $this->assertEqual($expected, $result);
  418. $result = $this->Task->generateConstructor('model', 'Post');
  419. $expected = "ClassRegistry::init('Post');\n";
  420. $this->assertEqual($expected, $result);
  421. $result = $this->Task->generateConstructor('helper', 'FormHelper');
  422. $expected = "new FormHelper();\n";
  423. $this->assertEqual($expected, $result);
  424. }
  425. /**
  426. * Test that mock class generation works for the appropriate classes
  427. *
  428. * @return void
  429. */
  430. public function testMockClassGeneration() {
  431. $result = $this->Task->hasMockClass('controller');
  432. $this->assertTrue($result);
  433. }
  434. /**
  435. * test bake() with a -plugin param
  436. *
  437. * @return void
  438. */
  439. public function testBakeWithPlugin() {
  440. $this->Task->plugin = 'TestTest';
  441. //fake plugin path
  442. CakePlugin::load('TestTest', array('path' => APP . 'Plugin' . DS . 'TestTest' . DS));
  443. $path = APP . 'Plugin' . DS . 'TestTest' . DS . 'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper' . DS .'FormHelperTest.php';
  444. $this->Task->expects($this->once())->method('createFile')
  445. ->with($path, new PHPUnit_Framework_Constraint_IsAnything());
  446. $this->Task->bake('Helper', 'Form');
  447. CakePlugin::unload();
  448. }
  449. /**
  450. * test interactive with plugins lists from the plugin
  451. *
  452. * @return void
  453. */
  454. public function testInteractiveWithPlugin() {
  455. $testApp = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS;
  456. App::build(array(
  457. 'plugins' => array($testApp)
  458. ), true);
  459. CakePlugin::load('TestPlugin');
  460. $this->Task->plugin = 'TestPlugin';
  461. $path = $testApp . 'TestPlugin' . DS . 'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper' . DS . 'OtherHelperHelperTest.php';
  462. $this->Task->expects($this->any())
  463. ->method('in')
  464. ->will($this->onConsecutiveCalls(
  465. 5, //helper
  466. 1 //OtherHelper
  467. ));
  468. $this->Task->expects($this->once())
  469. ->method('createFile')
  470. ->with($path, $this->anything());
  471. $this->Task->stdout->expects($this->at(21))
  472. ->method('write')
  473. ->with('1. OtherHelperHelper');
  474. $this->Task->execute();
  475. }
  476. /**
  477. * Test filename generation for each type + plugins
  478. *
  479. * @return void
  480. */
  481. public function testTestCaseFileName() {
  482. $this->Task->path = DS . 'my' . DS . 'path' . DS . 'tests' . DS;
  483. $result = $this->Task->testCaseFileName('Model', 'Post');
  484. $expected = $this->Task->path . 'Case' . DS . 'Model' . DS . 'PostTest.php';
  485. $this->assertEqual($expected, $result);
  486. $result = $this->Task->testCaseFileName('Helper', 'Form');
  487. $expected = $this->Task->path . 'Case' . DS . 'View' . DS . 'Helper' . DS . 'FormHelperTest.php';
  488. $this->assertEqual($expected, $result);
  489. $result = $this->Task->testCaseFileName('Controller', 'Posts');
  490. $expected = $this->Task->path . 'Case' . DS . 'Controller' . DS . 'PostsControllerTest.php';
  491. $this->assertEqual($expected, $result);
  492. $result = $this->Task->testCaseFileName('Behavior', 'Containable');
  493. $expected = $this->Task->path . 'Case' . DS . 'Model' . DS . 'Behavior' . DS . 'ContainableBehaviorTest.php';
  494. $this->assertEqual($expected, $result);
  495. $result = $this->Task->testCaseFileName('Component', 'Auth');
  496. $expected = $this->Task->path . 'Case' . DS . 'Controller' . DS . 'Component' . DS . 'AuthComponentTest.php';
  497. $this->assertEqual($expected, $result);
  498. CakePlugin::load('TestTest', array('path' => APP . 'Plugin' . DS . 'TestTest' . DS ));
  499. $this->Task->plugin = 'TestTest';
  500. $result = $this->Task->testCaseFileName('Model', 'Post');
  501. $expected = APP . 'Plugin' . DS . 'TestTest' . DS . 'Test' . DS . 'Case' . DS . 'Model' . DS . 'PostTest.php';
  502. $this->assertEqual($expected, $result);
  503. }
  504. /**
  505. * test execute with a type defined
  506. *
  507. * @return void
  508. */
  509. public function testExecuteWithOneArg() {
  510. $this->Task->args[0] = 'Model';
  511. $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('TestTaskTag'));
  512. $this->Task->expects($this->once())->method('isLoadableClass')->will($this->returnValue(true));
  513. $this->Task->expects($this->once())->method('createFile')
  514. ->with(
  515. new PHPUnit_Framework_Constraint_IsAnything(),
  516. $this->stringContains('class TestTaskTagTestCase extends CakeTestCase')
  517. );
  518. $this->Task->execute();
  519. }
  520. /**
  521. * test execute with type and class name defined
  522. *
  523. * @return void
  524. */
  525. public function testExecuteWithTwoArgs() {
  526. $this->Task->args = array('Model', 'TestTaskTag');
  527. $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('TestTaskTag'));
  528. $this->Task->expects($this->once())->method('createFile')
  529. ->with(
  530. new PHPUnit_Framework_Constraint_IsAnything(),
  531. $this->stringContains('class TestTaskTagTestCase extends CakeTestCase')
  532. );
  533. $this->Task->expects($this->any())->method('isLoadableClass')->will($this->returnValue(true));
  534. $this->Task->execute();
  535. }
  536. }