PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php

https://bitbucket.org/udeshika/fake_twitter
PHP | 1152 lines | 761 code | 138 blank | 253 comment | 4 complexity | 0bc62df6274efe35bb1e575a2361818d MD5 | raw file
  1. <?php
  2. /**
  3. * ModelTaskTest 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.6
  19. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  20. */
  21. App::uses('ShellDispatcher', 'Console');
  22. App::uses('Shell', 'Console');
  23. App::uses('ConsoleOutput', 'Console');
  24. App::uses('ConsoleInput', 'Console');
  25. App::uses('FixtureTask', 'Console/Command/Task');
  26. App::uses('TemplateTask', 'Console/Command/Task');
  27. App::uses('ModelTask', 'Console/Command/Task');
  28. /**
  29. * ModelTaskTest class
  30. *
  31. * @package Cake.Test.Case.Console.Command.Task
  32. */
  33. class ModelTaskTest extends CakeTestCase {
  34. /**
  35. * fixtures
  36. *
  37. * @var array
  38. */
  39. public $fixtures = array(
  40. 'core.bake_article', 'core.bake_comment', 'core.bake_articles_bake_tag',
  41. 'core.bake_tag', 'core.category_thread'
  42. );
  43. /**
  44. * setUp method
  45. *
  46. * @return void
  47. */
  48. public function setUp() {
  49. parent::setUp();
  50. $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
  51. $in = $this->getMock('ConsoleInput', array(), array(), '', false);
  52. $this->Task = $this->getMock('ModelTask',
  53. array('in', 'err', 'createFile', '_stop', '_checkUnitTest'),
  54. array($out, $out, $in)
  55. );
  56. $this->_setupOtherMocks();
  57. }
  58. /**
  59. * Setup a mock that has out mocked. Normally this is not used as it makes $this->at() really tricky.
  60. *
  61. * @return void
  62. */
  63. protected function _useMockedOut() {
  64. $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
  65. $in = $this->getMock('ConsoleInput', array(), array(), '', false);
  66. $this->Task = $this->getMock('ModelTask',
  67. array('in', 'out', 'err', 'hr', 'createFile', '_stop', '_checkUnitTest'),
  68. array($out, $out, $in)
  69. );
  70. $this->_setupOtherMocks();
  71. }
  72. /**
  73. * sets up the rest of the dependencies for Model Task
  74. *
  75. * @return void
  76. */
  77. protected function _setupOtherMocks() {
  78. $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
  79. $in = $this->getMock('ConsoleInput', array(), array(), '', false);
  80. $this->Task->Fixture = $this->getMock('FixtureTask', array(), array($out, $out, $in));
  81. $this->Task->Test = $this->getMock('FixtureTask', array(), array($out, $out, $in));
  82. $this->Task->Template = new TemplateTask($out, $out, $in);
  83. $this->Task->name = 'Model';
  84. $this->Task->interactive = true;
  85. }
  86. /**
  87. * tearDown method
  88. *
  89. * @return void
  90. */
  91. public function tearDown() {
  92. parent::tearDown();
  93. unset($this->Task);
  94. }
  95. /**
  96. * Test that listAll scans the database connection and lists all the tables in it.s
  97. *
  98. * @return void
  99. */
  100. public function testListAllArgument() {
  101. $this->_useMockedOut();
  102. $result = $this->Task->listAll('test');
  103. $this->assertContains('bake_articles', $result);
  104. $this->assertContains('bake_articles_bake_tags', $result);
  105. $this->assertContains('bake_tags', $result);
  106. $this->assertContains('bake_comments', $result);
  107. $this->assertContains('category_threads', $result);
  108. }
  109. /**
  110. * Test that listAll uses the connection property
  111. *
  112. * @return void
  113. */
  114. public function testListAllConnection() {
  115. $this->_useMockedOut();
  116. $this->Task->connection = 'test';
  117. $result = $this->Task->listAll();
  118. $this->assertContains('bake_articles', $result);
  119. $this->assertContains('bake_articles_bake_tags', $result);
  120. $this->assertContains('bake_tags', $result);
  121. $this->assertContains('bake_comments', $result);
  122. $this->assertContains('category_threads', $result);
  123. }
  124. /**
  125. * Test that getName interacts with the user and returns the model name.
  126. *
  127. * @return void
  128. */
  129. public function testGetNameQuit() {
  130. $this->Task->expects($this->once())->method('in')->will($this->returnValue('q'));
  131. $this->Task->expects($this->once())->method('_stop');
  132. $this->Task->getName('test');
  133. }
  134. /**
  135. * test getName with a valid option.
  136. *
  137. * @return void
  138. */
  139. public function testGetNameValidOption() {
  140. $listing = $this->Task->listAll('test');
  141. $this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls(1, 4));
  142. $result = $this->Task->getName('test');
  143. $this->assertEquals(Inflector::classify($listing[0]), $result);
  144. $result = $this->Task->getName('test');
  145. $this->assertEquals(Inflector::classify($listing[3]), $result);
  146. }
  147. /**
  148. * test that an out of bounds option causes an error.
  149. *
  150. * @return void
  151. */
  152. public function testGetNameWithOutOfBoundsOption() {
  153. $this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls(99, 1));
  154. $this->Task->expects($this->once())->method('err');
  155. $result = $this->Task->getName('test');
  156. }
  157. /**
  158. * Test table name interactions
  159. *
  160. * @return void
  161. */
  162. public function testGetTableName() {
  163. $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
  164. $result = $this->Task->getTable('BakeArticle', 'test');
  165. $expected = 'bake_articles';
  166. $this->assertEquals($expected, $result);
  167. }
  168. /**
  169. * test gettting a custom table name.
  170. *
  171. * @return void
  172. */
  173. public function testGetTableNameCustom() {
  174. $this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls('n', 'my_table'));
  175. $result = $this->Task->getTable('BakeArticle', 'test');
  176. $expected = 'my_table';
  177. $this->assertEquals($expected, $result);
  178. }
  179. /**
  180. * test getTable with non-conventional tablenames
  181. *
  182. * @return void
  183. */
  184. public function testGetTableOddTableInteractive() {
  185. $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
  186. $in = $this->getMock('ConsoleInput', array(), array(), '', false);
  187. $this->Task = $this->getMock('ModelTask',
  188. array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables'),
  189. array($out, $out, $in)
  190. );
  191. $this->_setupOtherMocks();
  192. $this->Task->connection = 'test';
  193. $this->Task->path = '/my/path/';
  194. $this->Task->interactive = true;
  195. $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('articles', 'bake_odd')));
  196. $this->Task->expects($this->any())->method('in')
  197. ->will($this->onConsecutiveCalls(
  198. 2 // bake_odd
  199. ));
  200. $result = $this->Task->getName();
  201. $expected = 'BakeOdd';
  202. $this->assertEquals($expected, $result);
  203. $result = $this->Task->getTable($result);
  204. $expected = 'bake_odd';
  205. $this->assertEquals($expected, $result);
  206. }
  207. /**
  208. * test getTable with non-conventional tablenames
  209. *
  210. * @return void
  211. */
  212. public function testGetTableOddTable() {
  213. $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
  214. $in = $this->getMock('ConsoleInput', array(), array(), '', false);
  215. $this->Task = $this->getMock('ModelTask',
  216. array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables'),
  217. array($out, $out, $in)
  218. );
  219. $this->_setupOtherMocks();
  220. $this->Task->connection = 'test';
  221. $this->Task->path = '/my/path/';
  222. $this->Task->interactive = false;
  223. $this->Task->args = array('BakeOdd');
  224. $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('articles', 'bake_odd')));
  225. $this->Task->listAll();
  226. $result = $this->Task->getTable('BakeOdd');
  227. $expected = 'bake_odd';
  228. $this->assertEquals($expected, $result);
  229. }
  230. /**
  231. * test that initializing the validations works.
  232. *
  233. * @return void
  234. */
  235. public function testInitValidations() {
  236. $result = $this->Task->initValidations();
  237. $this->assertTrue(in_array('notempty', $result));
  238. }
  239. /**
  240. * test that individual field validation works, with interactive = false
  241. * tests the guessing features of validation
  242. *
  243. * @return void
  244. */
  245. public function testFieldValidationGuessing() {
  246. $this->Task->interactive = false;
  247. $this->Task->initValidations();
  248. $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
  249. $expected = array('notempty' => 'notempty');
  250. $result = $this->Task->fieldValidation('text', array('type' => 'date', 'length' => 10, 'null' => false));
  251. $expected = array('date' => 'date');
  252. $result = $this->Task->fieldValidation('text', array('type' => 'time', 'length' => 10, 'null' => false));
  253. $expected = array('time' => 'time');
  254. $result = $this->Task->fieldValidation('email', array('type' => 'string', 'length' => 10, 'null' => false));
  255. $expected = array('email' => 'email');
  256. $result = $this->Task->fieldValidation('test', array('type' => 'integer', 'length' => 10, 'null' => false));
  257. $expected = array('numeric' => 'numeric');
  258. $result = $this->Task->fieldValidation('test', array('type' => 'boolean', 'length' => 10, 'null' => false));
  259. $expected = array('numeric' => 'numeric');
  260. }
  261. /**
  262. * test that interactive field validation works and returns multiple validators.
  263. *
  264. * @return void
  265. */
  266. public function testInteractiveFieldValidation() {
  267. $this->Task->initValidations();
  268. $this->Task->interactive = true;
  269. $this->Task->expects($this->any())->method('in')
  270. ->will($this->onConsecutiveCalls('21', 'y', '17', 'n'));
  271. $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
  272. $expected = array('notempty' => 'notempty', 'maxlength' => 'maxlength');
  273. $this->assertEquals($expected, $result);
  274. }
  275. /**
  276. * test that a bogus response doesn't cause errors to bubble up.
  277. *
  278. * @return void
  279. */
  280. public function testInteractiveFieldValidationWithBogusResponse() {
  281. $this->_useMockedOut();
  282. $this->Task->initValidations();
  283. $this->Task->interactive = true;
  284. $this->Task->expects($this->any())->method('in')
  285. ->will($this->onConsecutiveCalls('999999', '21', 'n'));
  286. $this->Task->expects($this->at(7))->method('out')
  287. ->with($this->stringContains('make a valid'));
  288. $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
  289. $expected = array('notempty' => 'notempty');
  290. $this->assertEquals($expected, $result);
  291. }
  292. /**
  293. * test that a regular expression can be used for validation.
  294. *
  295. * @return void
  296. */
  297. public function testInteractiveFieldValidationWithRegexp() {
  298. $this->Task->initValidations();
  299. $this->Task->interactive = true;
  300. $this->Task->expects($this->any())->method('in')
  301. ->will($this->onConsecutiveCalls('/^[a-z]{0,9}$/', 'n'));
  302. $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
  303. $expected = array('a_z_0_9' => '/^[a-z]{0,9}$/');
  304. $this->assertEquals($expected, $result);
  305. }
  306. /**
  307. * test the validation Generation routine
  308. *
  309. * @return void
  310. */
  311. public function testNonInteractiveDoValidation() {
  312. $Model = $this->getMock('Model');
  313. $Model->primaryKey = 'id';
  314. $Model->expects($this->any())->method('schema')->will($this->returnValue(array(
  315. 'id' => array(
  316. 'type' => 'integer',
  317. 'length' => 11,
  318. 'null' => false,
  319. 'key' => 'primary',
  320. ),
  321. 'name' => array(
  322. 'type' => 'string',
  323. 'length' => 20,
  324. 'null' => false,
  325. ),
  326. 'email' => array(
  327. 'type' => 'string',
  328. 'length' => 255,
  329. 'null' => false,
  330. ),
  331. 'some_date' => array(
  332. 'type' => 'date',
  333. 'length' => '',
  334. 'null' => false,
  335. ),
  336. 'some_time' => array(
  337. 'type' => 'time',
  338. 'length' => '',
  339. 'null' => false,
  340. ),
  341. 'created' => array(
  342. 'type' => 'datetime',
  343. 'length' => '',
  344. 'null' => false,
  345. )
  346. )));
  347. $this->Task->interactive = false;
  348. $result = $this->Task->doValidation($Model);
  349. $expected = array(
  350. 'name' => array(
  351. 'notempty' => 'notempty'
  352. ),
  353. 'email' => array(
  354. 'email' => 'email',
  355. ),
  356. 'some_date' => array(
  357. 'date' => 'date'
  358. ),
  359. 'some_time' => array(
  360. 'time' => 'time'
  361. ),
  362. );
  363. $this->assertEquals($expected, $result);
  364. }
  365. /**
  366. * test that finding primary key works
  367. *
  368. * @return void
  369. */
  370. public function testFindPrimaryKey() {
  371. $fields = array(
  372. 'one' => array(),
  373. 'two' => array(),
  374. 'key' => array('key' => 'primary')
  375. );
  376. $anything = new PHPUnit_Framework_Constraint_IsAnything();
  377. $this->Task->expects($this->once())->method('in')
  378. ->with($anything, null, 'key')
  379. ->will($this->returnValue('my_field'));
  380. $result = $this->Task->findPrimaryKey($fields);
  381. $expected = 'my_field';
  382. $this->assertEquals($expected, $result);
  383. }
  384. /**
  385. * test finding Display field
  386. *
  387. * @return void
  388. */
  389. public function testFindDisplayFieldNone() {
  390. $fields = array(
  391. 'id' => array(), 'tagname' => array(), 'body' => array(),
  392. 'created' => array(), 'modified' => array()
  393. );
  394. $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('n'));
  395. $result = $this->Task->findDisplayField($fields);
  396. $this->assertFalse($result);
  397. }
  398. /**
  399. * Test finding a displayname from user input
  400. *
  401. * @return void
  402. */
  403. public function testFindDisplayName() {
  404. $fields = array(
  405. 'id' => array(), 'tagname' => array(), 'body' => array(),
  406. 'created' => array(), 'modified' => array()
  407. );
  408. $this->Task->expects($this->any())->method('in')
  409. ->will($this->onConsecutiveCalls('y', 2));
  410. $result = $this->Task->findDisplayField($fields);
  411. $this->assertEquals($result, 'tagname');
  412. }
  413. /**
  414. * test that belongsTo generation works.
  415. *
  416. * @return void
  417. */
  418. public function testBelongsToGeneration() {
  419. $model = new Model(array('ds' => 'test', 'name' => 'BakeComment'));
  420. $result = $this->Task->findBelongsTo($model, array());
  421. $expected = array(
  422. 'belongsTo' => array(
  423. array(
  424. 'alias' => 'BakeArticle',
  425. 'className' => 'BakeArticle',
  426. 'foreignKey' => 'bake_article_id',
  427. ),
  428. array(
  429. 'alias' => 'BakeUser',
  430. 'className' => 'BakeUser',
  431. 'foreignKey' => 'bake_user_id',
  432. ),
  433. )
  434. );
  435. $this->assertEquals($expected, $result);
  436. $model = new Model(array('ds' => 'test', 'name' => 'CategoryThread'));
  437. $result = $this->Task->findBelongsTo($model, array());
  438. $expected = array(
  439. 'belongsTo' => array(
  440. array(
  441. 'alias' => 'ParentCategoryThread',
  442. 'className' => 'CategoryThread',
  443. 'foreignKey' => 'parent_id',
  444. ),
  445. )
  446. );
  447. $this->assertEquals($expected, $result);
  448. }
  449. /**
  450. * test that hasOne and/or hasMany relations are generated properly.
  451. *
  452. * @return void
  453. */
  454. public function testHasManyHasOneGeneration() {
  455. $model = new Model(array('ds' => 'test', 'name' => 'BakeArticle'));
  456. $this->Task->connection = 'test';
  457. $this->Task->listAll();
  458. $result = $this->Task->findHasOneAndMany($model, array());
  459. $expected = array(
  460. 'hasMany' => array(
  461. array(
  462. 'alias' => 'BakeComment',
  463. 'className' => 'BakeComment',
  464. 'foreignKey' => 'bake_article_id',
  465. ),
  466. ),
  467. 'hasOne' => array(
  468. array(
  469. 'alias' => 'BakeComment',
  470. 'className' => 'BakeComment',
  471. 'foreignKey' => 'bake_article_id',
  472. ),
  473. ),
  474. );
  475. $this->assertEquals($expected, $result);
  476. $model = new Model(array('ds' => 'test', 'name' => 'CategoryThread'));
  477. $result = $this->Task->findHasOneAndMany($model, array());
  478. $expected = array(
  479. 'hasOne' => array(
  480. array(
  481. 'alias' => 'ChildCategoryThread',
  482. 'className' => 'CategoryThread',
  483. 'foreignKey' => 'parent_id',
  484. ),
  485. ),
  486. 'hasMany' => array(
  487. array(
  488. 'alias' => 'ChildCategoryThread',
  489. 'className' => 'CategoryThread',
  490. 'foreignKey' => 'parent_id',
  491. ),
  492. )
  493. );
  494. $this->assertEquals($expected, $result);
  495. }
  496. /**
  497. * Test that HABTM generation works
  498. *
  499. * @return void
  500. */
  501. public function testHasAndBelongsToManyGeneration() {
  502. $model = new Model(array('ds' => 'test', 'name' => 'BakeArticle'));
  503. $this->Task->connection = 'test';
  504. $this->Task->listAll();
  505. $result = $this->Task->findHasAndBelongsToMany($model, array());
  506. $expected = array(
  507. 'hasAndBelongsToMany' => array(
  508. array(
  509. 'alias' => 'BakeTag',
  510. 'className' => 'BakeTag',
  511. 'foreignKey' => 'bake_article_id',
  512. 'joinTable' => 'bake_articles_bake_tags',
  513. 'associationForeignKey' => 'bake_tag_id',
  514. ),
  515. ),
  516. );
  517. $this->assertEquals($expected, $result);
  518. }
  519. /**
  520. * test non interactive doAssociations
  521. *
  522. * @return void
  523. */
  524. public function testDoAssociationsNonInteractive() {
  525. $this->Task->connection = 'test';
  526. $this->Task->interactive = false;
  527. $model = new Model(array('ds' => 'test', 'name' => 'BakeArticle'));
  528. $result = $this->Task->doAssociations($model);
  529. $expected = array(
  530. 'hasMany' => array(
  531. array(
  532. 'alias' => 'BakeComment',
  533. 'className' => 'BakeComment',
  534. 'foreignKey' => 'bake_article_id',
  535. ),
  536. ),
  537. 'hasAndBelongsToMany' => array(
  538. array(
  539. 'alias' => 'BakeTag',
  540. 'className' => 'BakeTag',
  541. 'foreignKey' => 'bake_article_id',
  542. 'joinTable' => 'bake_articles_bake_tags',
  543. 'associationForeignKey' => 'bake_tag_id',
  544. ),
  545. ),
  546. );
  547. }
  548. /**
  549. * Ensure that the fixture object is correctly called.
  550. *
  551. * @return void
  552. */
  553. public function testBakeFixture() {
  554. $this->Task->plugin = 'TestPlugin';
  555. $this->Task->interactive = true;
  556. $this->Task->Fixture->expects($this->at(0))->method('bake')->with('BakeArticle', 'bake_articles');
  557. $this->Task->bakeFixture('BakeArticle', 'bake_articles');
  558. $this->assertEquals($this->Task->plugin, $this->Task->Fixture->plugin);
  559. $this->assertEquals($this->Task->connection, $this->Task->Fixture->connection);
  560. $this->assertEquals($this->Task->interactive, $this->Task->Fixture->interactive);
  561. }
  562. /**
  563. * Ensure that the test object is correctly called.
  564. *
  565. * @return void
  566. */
  567. public function testBakeTest() {
  568. $this->Task->plugin = 'TestPlugin';
  569. $this->Task->interactive = true;
  570. $this->Task->Test->expects($this->at(0))->method('bake')->with('Model', 'BakeArticle');
  571. $this->Task->bakeTest('BakeArticle');
  572. $this->assertEquals($this->Task->plugin, $this->Task->Test->plugin);
  573. $this->assertEquals($this->Task->connection, $this->Task->Test->connection);
  574. $this->assertEquals($this->Task->interactive, $this->Task->Test->interactive);
  575. }
  576. /**
  577. * test confirming of associations, and that when an association is hasMany
  578. * a question for the hasOne is also not asked.
  579. *
  580. * @return void
  581. */
  582. public function testConfirmAssociations() {
  583. $associations = array(
  584. 'hasOne' => array(
  585. array(
  586. 'alias' => 'ChildCategoryThread',
  587. 'className' => 'CategoryThread',
  588. 'foreignKey' => 'parent_id',
  589. ),
  590. ),
  591. 'hasMany' => array(
  592. array(
  593. 'alias' => 'ChildCategoryThread',
  594. 'className' => 'CategoryThread',
  595. 'foreignKey' => 'parent_id',
  596. ),
  597. ),
  598. 'belongsTo' => array(
  599. array(
  600. 'alias' => 'User',
  601. 'className' => 'User',
  602. 'foreignKey' => 'user_id',
  603. ),
  604. )
  605. );
  606. $model = new Model(array('ds' => 'test', 'name' => 'CategoryThread'));
  607. $this->Task->expects($this->any())->method('in')
  608. ->will($this->onConsecutiveCalls('n', 'y', 'n', 'n', 'n'));
  609. $result = $this->Task->confirmAssociations($model, $associations);
  610. $this->assertTrue(empty($result['hasOne']));
  611. $result = $this->Task->confirmAssociations($model, $associations);
  612. $this->assertTrue(empty($result['hasMany']));
  613. $this->assertTrue(empty($result['hasOne']));
  614. }
  615. /**
  616. * test that inOptions generates questions and only accepts a valid answer
  617. *
  618. * @return void
  619. */
  620. public function testInOptions() {
  621. $this->_useMockedOut();
  622. $options = array('one', 'two', 'three');
  623. $this->Task->expects($this->at(0))->method('out')->with('1. one');
  624. $this->Task->expects($this->at(1))->method('out')->with('2. two');
  625. $this->Task->expects($this->at(2))->method('out')->with('3. three');
  626. $this->Task->expects($this->at(3))->method('in')->will($this->returnValue(10));
  627. $this->Task->expects($this->at(4))->method('out')->with('1. one');
  628. $this->Task->expects($this->at(5))->method('out')->with('2. two');
  629. $this->Task->expects($this->at(6))->method('out')->with('3. three');
  630. $this->Task->expects($this->at(7))->method('in')->will($this->returnValue(2));
  631. $result = $this->Task->inOptions($options, 'Pick a number');
  632. $this->assertEquals($result, 1);
  633. }
  634. /**
  635. * test baking validation
  636. *
  637. * @return void
  638. */
  639. public function testBakeValidation() {
  640. $validate = array(
  641. 'name' => array(
  642. 'notempty' => 'notempty'
  643. ),
  644. 'email' => array(
  645. 'email' => 'email',
  646. ),
  647. 'some_date' => array(
  648. 'date' => 'date'
  649. ),
  650. 'some_time' => array(
  651. 'time' => 'time'
  652. )
  653. );
  654. $result = $this->Task->bake('BakeArticle', compact('validate'));
  655. $this->assertRegExp('/class BakeArticle extends AppModel \{/', $result);
  656. $this->assertRegExp('/\$validate \= array\(/', $result);
  657. $expected = <<< STRINGEND
  658. array(
  659. 'notempty' => array(
  660. 'rule' => array('notempty'),
  661. //'message' => 'Your custom message here',
  662. //'allowEmpty' => false,
  663. //'required' => false,
  664. //'last' => false, // Stop validation after this rule
  665. //'on' => 'create', // Limit validation to 'create' or 'update' operations
  666. ),
  667. STRINGEND;
  668. $this->assertRegExp('/' . preg_quote(str_replace("\r\n", "\n", $expected), '/') . '/', $result);
  669. }
  670. /**
  671. * test baking relations
  672. *
  673. * @return void
  674. */
  675. public function testBakeRelations() {
  676. $associations = array(
  677. 'belongsTo' => array(
  678. array(
  679. 'alias' => 'SomethingElse',
  680. 'className' => 'SomethingElse',
  681. 'foreignKey' => 'something_else_id',
  682. ),
  683. array(
  684. 'alias' => 'BakeUser',
  685. 'className' => 'BakeUser',
  686. 'foreignKey' => 'bake_user_id',
  687. ),
  688. ),
  689. 'hasOne' => array(
  690. array(
  691. 'alias' => 'OtherModel',
  692. 'className' => 'OtherModel',
  693. 'foreignKey' => 'other_model_id',
  694. ),
  695. ),
  696. 'hasMany' => array(
  697. array(
  698. 'alias' => 'BakeComment',
  699. 'className' => 'BakeComment',
  700. 'foreignKey' => 'parent_id',
  701. ),
  702. ),
  703. 'hasAndBelongsToMany' => array(
  704. array(
  705. 'alias' => 'BakeTag',
  706. 'className' => 'BakeTag',
  707. 'foreignKey' => 'bake_article_id',
  708. 'joinTable' => 'bake_articles_bake_tags',
  709. 'associationForeignKey' => 'bake_tag_id',
  710. ),
  711. )
  712. );
  713. $result = $this->Task->bake('BakeArticle', compact('associations'));
  714. $this->assertContains(' * @property BakeUser $BakeUser', $result);
  715. $this->assertContains(' * @property OtherModel $OtherModel', $result);
  716. $this->assertContains(' * @property BakeComment $BakeComment', $result);
  717. $this->assertContains(' * @property BakeTag $BakeTag', $result);
  718. $this->assertRegExp('/\$hasAndBelongsToMany \= array\(/', $result);
  719. $this->assertRegExp('/\$hasMany \= array\(/', $result);
  720. $this->assertRegExp('/\$belongsTo \= array\(/', $result);
  721. $this->assertRegExp('/\$hasOne \= array\(/', $result);
  722. $this->assertRegExp('/BakeTag/', $result);
  723. $this->assertRegExp('/OtherModel/', $result);
  724. $this->assertRegExp('/SomethingElse/', $result);
  725. $this->assertRegExp('/BakeComment/', $result);
  726. }
  727. /**
  728. * test bake() with a -plugin param
  729. *
  730. * @return void
  731. */
  732. public function testBakeWithPlugin() {
  733. $this->Task->plugin = 'ControllerTest';
  734. //fake plugin path
  735. CakePlugin::load('ControllerTest', array('path' => APP . 'Plugin' . DS . 'ControllerTest' . DS));
  736. $path = APP . 'Plugin' . DS . 'ControllerTest' . DS . 'Model' . DS . 'BakeArticle.php';
  737. $this->Task->expects($this->once())->method('createFile')
  738. ->with($path, $this->stringContains('BakeArticle extends ControllerTestAppModel'));
  739. $result = $this->Task->bake('BakeArticle', array(), array());
  740. $this->assertContains("App::uses('ControllerTestAppModel', 'ControllerTest.Model');", $result);
  741. $this->assertEquals(count(ClassRegistry::keys()), 0);
  742. $this->assertEquals(count(ClassRegistry::mapKeys()), 0);
  743. }
  744. /**
  745. * test that execute passes runs bake depending with named model.
  746. *
  747. * @return void
  748. */
  749. public function testExecuteWithNamedModel() {
  750. $this->Task->connection = 'test';
  751. $this->Task->path = '/my/path/';
  752. $this->Task->args = array('BakeArticle');
  753. $filename = '/my/path/BakeArticle.php';
  754. $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(1));
  755. $this->Task->expects($this->once())->method('createFile')
  756. ->with($filename, $this->stringContains('class BakeArticle extends AppModel'));
  757. $this->Task->execute();
  758. $this->assertEquals(count(ClassRegistry::keys()), 0);
  759. $this->assertEquals(count(ClassRegistry::mapKeys()), 0);
  760. }
  761. /**
  762. * data provider for testExecuteWithNamedModelVariations
  763. *
  764. * @return void
  765. */
  766. static function nameVariations() {
  767. return array(
  768. array('BakeArticles'), array('BakeArticle'), array('bake_article'), array('bake_articles')
  769. );
  770. }
  771. /**
  772. * test that execute passes with different inflections of the same name.
  773. *
  774. * @dataProvider nameVariations
  775. * @return void
  776. */
  777. public function testExecuteWithNamedModelVariations($name) {
  778. $this->Task->connection = 'test';
  779. $this->Task->path = '/my/path/';
  780. $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(1));
  781. $this->Task->args = array($name);
  782. $filename = '/my/path/BakeArticle.php';
  783. $this->Task->expects($this->at(0))->method('createFile')
  784. ->with($filename, $this->stringContains('class BakeArticle extends AppModel'));
  785. $this->Task->execute();
  786. }
  787. /**
  788. * test that execute with a model name picks up hasMany associations.
  789. *
  790. * @return void
  791. */
  792. public function testExecuteWithNamedModelHasManyCreated() {
  793. $this->Task->connection = 'test';
  794. $this->Task->path = '/my/path/';
  795. $this->Task->args = array('BakeArticle');
  796. $filename = '/my/path/BakeArticle.php';
  797. $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(1));
  798. $this->Task->expects($this->at(0))->method('createFile')
  799. ->with($filename, $this->stringContains("'BakeComment' => array("));
  800. $this->Task->execute();
  801. }
  802. /**
  803. * test that execute runs all() when args[0] = all
  804. *
  805. * @return void
  806. */
  807. public function testExecuteIntoAll() {
  808. $count = count($this->Task->listAll('test'));
  809. if ($count != count($this->fixtures)) {
  810. $this->markTestSkipped('Additional tables detected.');
  811. }
  812. $this->Task->connection = 'test';
  813. $this->Task->path = '/my/path/';
  814. $this->Task->args = array('all');
  815. $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
  816. $this->Task->Fixture->expects($this->exactly(5))->method('bake');
  817. $this->Task->Test->expects($this->exactly(5))->method('bake');
  818. $filename = '/my/path/BakeArticle.php';
  819. $this->Task->expects($this->at(1))->method('createFile')
  820. ->with($filename, $this->stringContains('class BakeArticle'));
  821. $filename = '/my/path/BakeArticlesBakeTag.php';
  822. $this->Task->expects($this->at(2))->method('createFile')
  823. ->with($filename, $this->stringContains('class BakeArticlesBakeTag'));
  824. $filename = '/my/path/BakeComment.php';
  825. $this->Task->expects($this->at(3))->method('createFile')
  826. ->with($filename, $this->stringContains('class BakeComment'));
  827. $filename = '/my/path/BakeComment.php';
  828. $this->Task->expects($this->at(3))->method('createFile')
  829. ->with($filename, $this->stringContains('public $primaryKey = \'otherid\';'));
  830. $filename = '/my/path/BakeTag.php';
  831. $this->Task->expects($this->at(4))->method('createFile')
  832. ->with($filename, $this->stringContains('class BakeTag'));
  833. $filename = '/my/path/BakeTag.php';
  834. $this->Task->expects($this->at(4))->method('createFile')
  835. ->with($filename, $this->logicalNot($this->stringContains('public $primaryKey')));
  836. $filename = '/my/path/CategoryThread.php';
  837. $this->Task->expects($this->at(5))->method('createFile')
  838. ->with($filename, $this->stringContains('class CategoryThread'));
  839. $this->Task->execute();
  840. $this->assertEquals(count(ClassRegistry::keys()), 0);
  841. $this->assertEquals(count(ClassRegistry::mapKeys()), 0);
  842. }
  843. /**
  844. * test that odd tablenames arent inflected back from modelname
  845. *
  846. * @return void
  847. */
  848. public function testExecuteIntoAllOddTables() {
  849. $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
  850. $in = $this->getMock('ConsoleInput', array(), array(), '', false);
  851. $this->Task = $this->getMock('ModelTask',
  852. array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables', '_getModelObject', 'bake', 'bakeFixture'),
  853. array($out, $out, $in)
  854. );
  855. $this->_setupOtherMocks();
  856. $this->Task->connection = 'test';
  857. $this->Task->path = '/my/path/';
  858. $this->Task->args = array('all');
  859. $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
  860. $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('bake_odd')));
  861. $object = new Model(array('name' => 'BakeOdd', 'table' => 'bake_odd', 'ds' => 'test'));
  862. $this->Task->expects($this->once())->method('_getModelObject')->with('BakeOdd', 'bake_odd')->will($this->returnValue($object));
  863. $this->Task->expects($this->at(3))->method('bake')->with($object, false)->will($this->returnValue(true));
  864. $this->Task->expects($this->once())->method('bakeFixture')->with('BakeOdd', 'bake_odd');
  865. $this->Task->execute();
  866. $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
  867. $in = $this->getMock('ConsoleInput', array(), array(), '', false);
  868. $this->Task = $this->getMock('ModelTask',
  869. array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables', '_getModelObject', 'doAssociations', 'doValidation', 'createFile'),
  870. array($out, $out, $in)
  871. );
  872. $this->_setupOtherMocks();
  873. $this->Task->connection = 'test';
  874. $this->Task->path = '/my/path/';
  875. $this->Task->args = array('all');
  876. $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
  877. $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('bake_odd')));
  878. $object = new Model(array('name' => 'BakeOdd', 'table' => 'bake_odd', 'ds' => 'test'));
  879. $this->Task->expects($this->once())->method('_getModelObject')->will($this->returnValue($object));
  880. $this->Task->expects($this->once())->method('doAssociations')->will($this->returnValue(array()));
  881. $this->Task->expects($this->once())->method('doValidation')->will($this->returnValue(array()));
  882. $filename = '/my/path/BakeOdd.php';
  883. $this->Task->expects($this->once())->method('createFile')
  884. ->with($filename, $this->stringContains('class BakeOdd'));
  885. $filename = '/my/path/BakeOdd.php';
  886. $this->Task->expects($this->once())->method('createFile')
  887. ->with($filename, $this->stringContains('public $useTable = \'bake_odd\''));
  888. $this->Task->execute();
  889. }
  890. /**
  891. * test that odd tablenames arent inflected back from modelname
  892. *
  893. * @return void
  894. */
  895. public function testExecuteIntoBakeOddTables() {
  896. $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
  897. $in = $this->getMock('ConsoleInput', array(), array(), '', false);
  898. $this->Task = $this->getMock('ModelTask',
  899. array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables', '_getModelObject', 'bake', 'bakeFixture'),
  900. array($out, $out, $in)
  901. );
  902. $this->_setupOtherMocks();
  903. $this->Task->connection = 'test';
  904. $this->Task->path = '/my/path/';
  905. $this->Task->args = array('BakeOdd');
  906. $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
  907. $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('articles', 'bake_odd')));
  908. $object = new Model(array('name' => 'BakeOdd', 'table' => 'bake_odd', 'ds' => 'test'));
  909. $this->Task->expects($this->once())->method('_getModelObject')->with('BakeOdd', 'bake_odd')->will($this->returnValue($object));
  910. $this->Task->expects($this->once())->method('bake')->with($object, false)->will($this->returnValue(true));
  911. $this->Task->expects($this->once())->method('bakeFixture')->with('BakeOdd', 'bake_odd');
  912. $this->Task->execute();
  913. $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
  914. $in = $this->getMock('ConsoleInput', array(), array(), '', false);
  915. $this->Task = $this->getMock('ModelTask',
  916. array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables', '_getModelObject', 'doAssociations', 'doValidation', 'createFile'),
  917. array($out, $out, $in)
  918. );
  919. $this->_setupOtherMocks();
  920. $this->Task->connection = 'test';
  921. $this->Task->path = '/my/path/';
  922. $this->Task->args = array('BakeOdd');
  923. $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
  924. $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('articles', 'bake_odd')));
  925. $object = new Model(array('name' => 'BakeOdd', 'table' => 'bake_odd', 'ds' => 'test'));
  926. $this->Task->expects($this->once())->method('_getModelObject')->will($this->returnValue($object));
  927. $this->Task->expects($this->once())->method('doAssociations')->will($this->returnValue(array()));
  928. $this->Task->expects($this->once())->method('doValidation')->will($this->returnValue(array()));
  929. $filename = '/my/path/BakeOdd.php';
  930. $this->Task->expects($this->once())->method('createFile')
  931. ->with($filename, $this->stringContains('class BakeOdd'));
  932. $filename = '/my/path/BakeOdd.php';
  933. $this->Task->expects($this->once())->method('createFile')
  934. ->with($filename, $this->stringContains('public $useTable = \'bake_odd\''));
  935. $this->Task->execute();
  936. }
  937. /**
  938. * test that skipTables changes how all() works.
  939. *
  940. * @return void
  941. */
  942. public function testSkipTablesAndAll() {
  943. $count = count($this->Task->listAll('test'));
  944. if ($count != count($this->fixtures)) {
  945. $this->markTestSkipped('Additional tables detected.');
  946. }
  947. $this->Task->connection = 'test';
  948. $this->Task->path = '/my/path/';
  949. $this->Task->args = array('all');
  950. $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
  951. $this->Task->skipTables = array('bake_tags');
  952. $this->Task->Fixture->expects($this->exactly(4))->method('bake');
  953. $this->Task->Test->expects($this->exactly(4))->method('bake');
  954. $filename = '/my/path/BakeArticle.php';
  955. $this->Task->expects($this->at(1))->method('createFile')
  956. ->with($filename, $this->stringContains('class BakeArticle'));
  957. $filename = '/my/path/BakeArticlesBakeTag.php';
  958. $this->Task->expects($this->at(2))->method('createFile')
  959. ->with($filename, $this->stringContains('class BakeArticlesBakeTag'));
  960. $filename = '/my/path/BakeComment.php';
  961. $this->Task->expects($this->at(3))->method('createFile')
  962. ->with($filename, $this->stringContains('class BakeComment'));
  963. $filename = '/my/path/CategoryThread.php';
  964. $this->Task->expects($this->at(4))->method('createFile')
  965. ->with($filename, $this->stringContains('class CategoryThread'));
  966. $this->Task->execute();
  967. }
  968. /**
  969. * test the interactive side of bake.
  970. *
  971. * @return void
  972. */
  973. public function testExecuteIntoInteractive() {
  974. $tables = $this->Task->listAll('test');
  975. $article = array_search('bake_articles', $tables) + 1;
  976. $this->Task->connection = 'test';
  977. $this->Task->path = '/my/path/';
  978. $this->Task->interactive = true;
  979. $this->Task->expects($this->any())->method('in')
  980. ->will($this->onConsecutiveCalls(
  981. $article, // article
  982. 'n', // no validation
  983. 'y', // associations
  984. 'y', // comment relation
  985. 'y', // user relation
  986. 'y', // tag relation
  987. 'n', // additional assocs
  988. 'y' // looks good?
  989. ));
  990. $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
  991. $this->Task->Test->expects($this->once())->method('bake');
  992. $this->Task->Fixture->expects($this->once())->method('bake');
  993. $filename = '/my/path/BakeArticle.php';
  994. $this->Task->expects($this->once())->method('createFile')
  995. ->with($filename, $this->stringContains('class BakeArticle'));
  996. $this->Task->execute();
  997. $this->assertEquals(count(ClassRegistry::keys()), 0);
  998. $this->assertEquals(count(ClassRegistry::mapKeys()), 0);
  999. }
  1000. /**
  1001. * test using bake interactively with a table that does not exist.
  1002. *
  1003. * @return void
  1004. */
  1005. public function testExecuteWithNonExistantTableName() {
  1006. $this->Task->connection = 'test';
  1007. $this->Task->path = '/my/path/';
  1008. $this->Task->expects($this->once())->method('_stop');
  1009. $this->Task->expects($this->once())->method('err');
  1010. $this->Task->expects($this->any())->method('in')
  1011. ->will($this->onConsecutiveCalls('Foobar', 'y'));
  1012. $this->Task->execute();
  1013. }
  1014. }