TestTaskTest.php 17 KB

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