PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/Cake/Test/Case/Model/CakeSchemaTest.php

https://bitbucket.org/udeshika/fake_twitter
PHP | 1024 lines | 553 code | 97 blank | 374 comment | 4 complexity | 44cd742e31a8388753c04aacfd0b6996 MD5 | raw file
  1. <?php
  2. /**
  3. * Test for Schema database management
  4. *
  5. *
  6. * PHP 5
  7. *
  8. * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
  9. * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  10. *
  11. * Licensed under The MIT License
  12. * Redistributions of files must retain the above copyright notice
  13. *
  14. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  15. * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
  16. * @package Cake.Test.Case.Model
  17. * @since CakePHP(tm) v 1.2.0.5550
  18. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  19. */
  20. App::uses('CakeSchema', 'Model');
  21. App::uses('CakeTestFixture', 'TestSuite/Fixture');
  22. /**
  23. * Test for Schema database management
  24. *
  25. * @package Cake.Test.Case.Model
  26. */
  27. class MyAppSchema extends CakeSchema {
  28. /**
  29. * name property
  30. *
  31. * @var string 'MyApp'
  32. */
  33. public $name = 'MyApp';
  34. /**
  35. * connection property
  36. *
  37. * @var string 'test'
  38. */
  39. public $connection = 'test';
  40. /**
  41. * comments property
  42. *
  43. * @var array
  44. */
  45. public $comments = array(
  46. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  47. 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
  48. 'user_id' => array('type' => 'integer', 'null' => false),
  49. 'title' => array('type' => 'string', 'null' => false, 'length' => 100),
  50. 'comment' => array('type' => 'text', 'null' => false, 'default' => null),
  51. 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
  52. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  53. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  54. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  55. );
  56. /**
  57. * posts property
  58. *
  59. * @var array
  60. */
  61. public $posts = array(
  62. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  63. 'author_id' => array('type' => 'integer', 'null' => true, 'default' => ''),
  64. 'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'),
  65. 'body' => array('type' => 'text', 'null' => true, 'default' => null),
  66. 'summary' => array('type' => 'text', 'null' => true),
  67. 'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1),
  68. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  69. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  70. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  71. );
  72. /**
  73. * _foo property
  74. *
  75. * @var array
  76. */
  77. protected $_foo = array('bar');
  78. /**
  79. * setup method
  80. *
  81. * @param mixed $version
  82. * @return void
  83. */
  84. public function setup($version) {
  85. }
  86. /**
  87. * teardown method
  88. *
  89. * @param mixed $version
  90. * @return void
  91. */
  92. public function teardown($version) {
  93. }
  94. /**
  95. * getVar method
  96. *
  97. * @param string $var Name of var
  98. * @return mixed
  99. */
  100. public function getVar($var) {
  101. if (!isset($this->$var)) {
  102. return null;
  103. }
  104. return $this->$var;
  105. }
  106. }
  107. /**
  108. * TestAppSchema class
  109. *
  110. * @package Cake.Test.Case.Model
  111. */
  112. class TestAppSchema extends CakeSchema {
  113. /**
  114. * name property
  115. *
  116. * @var string 'MyApp'
  117. */
  118. public $name = 'MyApp';
  119. /**
  120. * comments property
  121. *
  122. * @var array
  123. */
  124. public $comments = array(
  125. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0,'key' => 'primary'),
  126. 'article_id' => array('type' => 'integer', 'null' => false),
  127. 'user_id' => array('type' => 'integer', 'null' => false),
  128. 'comment' => array('type' => 'text', 'null' => true, 'default' => null),
  129. 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
  130. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  131. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  132. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  133. 'tableParameters' => array(),
  134. );
  135. /**
  136. * posts property
  137. *
  138. * @var array
  139. */
  140. public $posts = array(
  141. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  142. 'author_id' => array('type' => 'integer', 'null' => false),
  143. 'title' => array('type' => 'string', 'null' => false),
  144. 'body' => array('type' => 'text', 'null' => true, 'default' => null),
  145. 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
  146. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  147. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  148. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  149. 'tableParameters' => array(),
  150. );
  151. /**
  152. * posts_tags property
  153. *
  154. * @var array
  155. */
  156. public $posts_tags = array(
  157. 'post_id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
  158. 'tag_id' => array('type' => 'string', 'null' => false, 'key' => 'primary'),
  159. 'indexes' => array('posts_tag' => array('column' => array('tag_id', 'post_id'), 'unique' => 1)),
  160. 'tableParameters' => array()
  161. );
  162. /**
  163. * tags property
  164. *
  165. * @var array
  166. */
  167. public $tags = array(
  168. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  169. 'tag' => array('type' => 'string', 'null' => false),
  170. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  171. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  172. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  173. 'tableParameters' => array()
  174. );
  175. /**
  176. * datatypes property
  177. *
  178. * @var array
  179. */
  180. public $datatypes = array(
  181. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  182. 'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => ''),
  183. 'bool' => array('type' => 'boolean', 'null' => false, 'default' => false),
  184. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  185. 'tableParameters' => array()
  186. );
  187. /**
  188. * setup method
  189. *
  190. * @param mixed $version
  191. * @return void
  192. */
  193. public function setup($version) {
  194. }
  195. /**
  196. * teardown method
  197. *
  198. * @param mixed $version
  199. * @return void
  200. */
  201. public function teardown($version) {
  202. }
  203. }
  204. /**
  205. * SchmeaPost class
  206. *
  207. * @package Cake.Test.Case.Model
  208. */
  209. class SchemaPost extends CakeTestModel {
  210. /**
  211. * name property
  212. *
  213. * @var string 'SchemaPost'
  214. */
  215. public $name = 'SchemaPost';
  216. /**
  217. * useTable property
  218. *
  219. * @var string 'posts'
  220. */
  221. public $useTable = 'posts';
  222. /**
  223. * hasMany property
  224. *
  225. * @var array
  226. */
  227. public $hasMany = array('SchemaComment');
  228. /**
  229. * hasAndBelongsToMany property
  230. *
  231. * @var array
  232. */
  233. public $hasAndBelongsToMany = array('SchemaTag');
  234. }
  235. /**
  236. * SchemaComment class
  237. *
  238. * @package Cake.Test.Case.Model
  239. */
  240. class SchemaComment extends CakeTestModel {
  241. /**
  242. * name property
  243. *
  244. * @var string 'SchemaComment'
  245. */
  246. public $name = 'SchemaComment';
  247. /**
  248. * useTable property
  249. *
  250. * @var string 'comments'
  251. */
  252. public $useTable = 'comments';
  253. /**
  254. * belongsTo property
  255. *
  256. * @var array
  257. */
  258. public $belongsTo = array('SchemaPost');
  259. }
  260. /**
  261. * SchemaTag class
  262. *
  263. * @package Cake.Test.Case.Model
  264. */
  265. class SchemaTag extends CakeTestModel {
  266. /**
  267. * name property
  268. *
  269. * @var string 'SchemaTag'
  270. */
  271. public $name = 'SchemaTag';
  272. /**
  273. * useTable property
  274. *
  275. * @var string 'tags'
  276. */
  277. public $useTable = 'tags';
  278. /**
  279. * hasAndBelongsToMany property
  280. *
  281. * @var array
  282. */
  283. public $hasAndBelongsToMany = array('SchemaPost');
  284. }
  285. /**
  286. * SchemaDatatype class
  287. *
  288. * @package Cake.Test.Case.Model
  289. */
  290. class SchemaDatatype extends CakeTestModel {
  291. /**
  292. * name property
  293. *
  294. * @var string 'SchemaDatatype'
  295. */
  296. public $name = 'SchemaDatatype';
  297. /**
  298. * useTable property
  299. *
  300. * @var string 'datatypes'
  301. */
  302. public $useTable = 'datatypes';
  303. }
  304. /**
  305. * Testdescribe class
  306. *
  307. * This class is defined purely to inherit the cacheSources variable otherwise
  308. * testSchemaCreatTable will fail if listSources has already been called and
  309. * its source cache populated - I.e. if the test is run within a group
  310. *
  311. * @uses CakeTestModel
  312. * @package
  313. * @package Cake.Test.Case.Model
  314. */
  315. class Testdescribe extends CakeTestModel {
  316. /**
  317. * name property
  318. *
  319. * @var string 'Testdescribe'
  320. */
  321. public $name = 'Testdescribe';
  322. }
  323. /**
  324. * SchemaCrossDatabase class
  325. *
  326. * @package Cake.Test.Case.Model
  327. */
  328. class SchemaCrossDatabase extends CakeTestModel {
  329. /**
  330. * name property
  331. *
  332. * @var string 'SchemaCrossDatabase'
  333. */
  334. public $name = 'SchemaCrossDatabase';
  335. /**
  336. * useTable property
  337. *
  338. * @var string 'posts'
  339. */
  340. public $useTable = 'cross_database';
  341. /**
  342. * useDbConfig property
  343. *
  344. * @var string 'test2'
  345. */
  346. public $useDbConfig = 'test2';
  347. }
  348. /**
  349. * SchemaCrossDatabaseFixture class
  350. *
  351. * @package Cake.Test.Case.Model
  352. */
  353. class SchemaCrossDatabaseFixture extends CakeTestFixture {
  354. /**
  355. * name property
  356. *
  357. * @var string 'CrossDatabase'
  358. */
  359. public $name = 'CrossDatabase';
  360. /**
  361. * table property
  362. *
  363. */
  364. public $table = 'cross_database';
  365. /**
  366. * fields property
  367. *
  368. * @var array
  369. */
  370. public $fields = array(
  371. 'id' => array('type' => 'integer', 'key' => 'primary'),
  372. 'name' => 'string'
  373. );
  374. /**
  375. * records property
  376. *
  377. * @var array
  378. */
  379. public $records = array(
  380. array('id' => 1, 'name' => 'First'),
  381. array('id' => 2, 'name' => 'Second'),
  382. );
  383. }
  384. /**
  385. * SchemaPrefixAuthUser class
  386. *
  387. * @package Cake.Test.Case.Model
  388. */
  389. class SchemaPrefixAuthUser extends CakeTestModel {
  390. /**
  391. * name property
  392. *
  393. * @var string
  394. */
  395. public $name = 'SchemaPrefixAuthUser';
  396. /**
  397. * table prefix
  398. *
  399. * @var string
  400. */
  401. public $tablePrefix = 'auth_';
  402. /**
  403. * useTable
  404. *
  405. * @var string
  406. */
  407. public $useTable = 'users';
  408. }
  409. /**
  410. * CakeSchemaTest
  411. *
  412. * @package Cake.Test.Case.Model
  413. */
  414. class CakeSchemaTest extends CakeTestCase {
  415. /**
  416. * fixtures property
  417. *
  418. * @var array
  419. */
  420. public $fixtures = array(
  421. 'core.post', 'core.tag', 'core.posts_tag', 'core.test_plugin_comment',
  422. 'core.datatype', 'core.auth_user', 'core.author',
  423. 'core.test_plugin_article', 'core.user', 'core.comment',
  424. 'core.prefix_test'
  425. );
  426. /**
  427. * setUp method
  428. *
  429. * @return void
  430. */
  431. public function setUp() {
  432. parent::setUp();
  433. ConnectionManager::getDataSource('test')->cacheSources = false;
  434. $this->Schema = new TestAppSchema();
  435. }
  436. /**
  437. * tearDown method
  438. *
  439. * @return void
  440. */
  441. public function tearDown() {
  442. parent::tearDown();
  443. if (file_exists(TMP . 'tests' . DS .'schema.php')) {
  444. unlink(TMP . 'tests' . DS .'schema.php');
  445. }
  446. unset($this->Schema);
  447. CakePlugin::unload();
  448. }
  449. /**
  450. * testSchemaName method
  451. *
  452. * @return void
  453. */
  454. public function testSchemaName() {
  455. $Schema = new CakeSchema();
  456. $this->assertEquals(strtolower($Schema->name), strtolower(APP_DIR));
  457. Configure::write('App.dir', 'Some.name.with.dots');
  458. $Schema = new CakeSchema();
  459. $this->assertEquals($Schema->name, 'SomeNameWithDots');
  460. Configure::write('App.dir', 'app');
  461. }
  462. /**
  463. * testSchemaRead method
  464. *
  465. * @return void
  466. */
  467. public function testSchemaRead() {
  468. $read = $this->Schema->read(array(
  469. 'connection' => 'test',
  470. 'name' => 'TestApp',
  471. 'models' => array('SchemaPost', 'SchemaComment', 'SchemaTag', 'SchemaDatatype')
  472. ));
  473. unset($read['tables']['missing']);
  474. $expected = array('comments', 'datatypes', 'posts', 'posts_tags', 'tags');
  475. foreach ($expected as $table) {
  476. $this->assertTrue(isset($read['tables'][$table]), 'Missing table ' . $table);
  477. }
  478. foreach ($this->Schema->tables as $table => $fields) {
  479. $this->assertEquals(array_keys($fields), array_keys($read['tables'][$table]));
  480. }
  481. if (isset($read['tables']['datatypes']['float_field']['length'])) {
  482. $this->assertEquals(
  483. $read['tables']['datatypes']['float_field']['length'],
  484. $this->Schema->tables['datatypes']['float_field']['length']
  485. );
  486. }
  487. $this->assertEquals(
  488. $read['tables']['datatypes']['float_field']['type'],
  489. $this->Schema->tables['datatypes']['float_field']['type']
  490. );
  491. $this->assertEquals(
  492. $read['tables']['datatypes']['float_field']['null'],
  493. $this->Schema->tables['datatypes']['float_field']['null']
  494. );
  495. $db = ConnectionManager::getDataSource('test');
  496. $config = $db->config;
  497. $config['prefix'] = 'schema_test_prefix_';
  498. ConnectionManager::create('schema_prefix', $config);
  499. $read = $this->Schema->read(array('connection' => 'schema_prefix', 'models' => false));
  500. $this->assertTrue(empty($read['tables']));
  501. $read = $this->Schema->read(array(
  502. 'connection' => 'test',
  503. 'name' => 'TestApp',
  504. 'models' => array('SchemaComment', 'SchemaTag', 'SchemaPost')
  505. ));
  506. $this->assertFalse(isset($read['tables']['missing']['posts_tags']), 'Join table marked as missing');
  507. }
  508. /**
  509. * testSchemaReadWithAppModel method
  510. *
  511. * @access public
  512. * @return void
  513. */
  514. public function testSchemaReadWithAppModel() {
  515. $connections = ConnectionManager::enumConnectionObjects();
  516. ConnectionManager::drop('default');
  517. ConnectionManager::create('default', $connections['test']);
  518. try {
  519. $read = $this->Schema->read(array(
  520. 'connection' => 'default',
  521. 'name' => 'TestApp',
  522. 'models' => array('AppModel')
  523. ));
  524. } catch(MissingTableException $mte) {
  525. ConnectionManager::drop('default');
  526. $this->fail($mte->getMessage());
  527. }
  528. ConnectionManager::drop('default');
  529. }
  530. /**
  531. * testSchemaReadWithOddTablePrefix method
  532. *
  533. * @return void
  534. */
  535. public function testSchemaReadWithOddTablePrefix() {
  536. $config = ConnectionManager::getDataSource('test')->config;
  537. $this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
  538. $SchemaPost = ClassRegistry::init('SchemaPost');
  539. $SchemaPost->tablePrefix = 'po';
  540. $SchemaPost->useTable = 'sts';
  541. $read = $this->Schema->read(array(
  542. 'connection' => 'test',
  543. 'name' => 'TestApp',
  544. 'models' => array('SchemaPost')
  545. ));
  546. $this->assertFalse(isset($read['tables']['missing']['posts']), 'Posts table was not read from tablePrefix');
  547. }
  548. /**
  549. * test read() with tablePrefix properties.
  550. *
  551. * @return void
  552. */
  553. public function testSchemaReadWithTablePrefix() {
  554. $config = ConnectionManager::getDataSource('test')->config;
  555. $this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
  556. $model = new SchemaPrefixAuthUser();
  557. $Schema = new CakeSchema();
  558. $read = $Schema->read(array(
  559. 'connection' => 'test',
  560. 'name' => 'TestApp',
  561. 'models' => array('SchemaPrefixAuthUser')
  562. ));
  563. unset($read['tables']['missing']);
  564. $this->assertTrue(isset($read['tables']['auth_users']), 'auth_users key missing %s');
  565. }
  566. /**
  567. * test reading schema with config prefix.
  568. *
  569. * @return void
  570. */
  571. public function testSchemaReadWithConfigPrefix() {
  572. $this->skipIf($this->db instanceof Sqlite, 'Cannot open 2 connections to Sqlite');
  573. $db = ConnectionManager::getDataSource('test');
  574. $config = $db->config;
  575. $this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
  576. $config['prefix'] = 'schema_test_prefix_';
  577. ConnectionManager::create('schema_prefix', $config);
  578. $read = $this->Schema->read(array('connection' => 'schema_prefix', 'models' => false));
  579. $this->assertTrue(empty($read['tables']));
  580. $config['prefix'] = 'prefix_';
  581. ConnectionManager::create('schema_prefix2', $config);
  582. $read = $this->Schema->read(array(
  583. 'connection' => 'schema_prefix2',
  584. 'name' => 'TestApp',
  585. 'models' => false));
  586. $this->assertTrue(isset($read['tables']['prefix_tests']));
  587. }
  588. /**
  589. * test reading schema from plugins.
  590. *
  591. * @return void
  592. */
  593. public function testSchemaReadWithPlugins() {
  594. App::objects('model', null, false);
  595. App::build(array(
  596. 'plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
  597. ));
  598. CakePlugin::load('TestPlugin');
  599. $Schema = new CakeSchema();
  600. $Schema->plugin = 'TestPlugin';
  601. $read = $Schema->read(array(
  602. 'connection' => 'test',
  603. 'name' => 'TestApp',
  604. 'models' => true
  605. ));
  606. unset($read['tables']['missing']);
  607. $this->assertTrue(isset($read['tables']['auth_users']));
  608. $this->assertTrue(isset($read['tables']['authors']));
  609. $this->assertTrue(isset($read['tables']['test_plugin_comments']));
  610. $this->assertTrue(isset($read['tables']['posts']));
  611. $this->assertTrue(count($read['tables']) >= 4);
  612. App::build();
  613. }
  614. /**
  615. * test reading schema with tables from another database.
  616. *
  617. * @return void
  618. */
  619. public function testSchemaReadWithCrossDatabase() {
  620. $config = new DATABASE_CONFIG();
  621. $this->skipIf(
  622. !isset($config->test) || !isset($config->test2),
  623. 'Primary and secondary test databases not configured, skipping cross-database join tests.'
  624. . ' To run these tests, you must define $test and $test2 in your database configuration.'
  625. );
  626. $db2 = ConnectionManager::getDataSource('test2');
  627. $fixture = new SchemaCrossDatabaseFixture();
  628. $fixture->create($db2);
  629. $fixture->insert($db2);
  630. $read = $this->Schema->read(array(
  631. 'connection' => 'test',
  632. 'name' => 'TestApp',
  633. 'models' => array('SchemaCrossDatabase', 'SchemaPost')
  634. ));
  635. $this->assertTrue(isset($read['tables']['posts']));
  636. $this->assertFalse(isset($read['tables']['cross_database']), 'Cross database should not appear');
  637. $this->assertFalse(isset($read['tables']['missing']['cross_database']), 'Cross database should not appear');
  638. $read = $this->Schema->read(array(
  639. 'connection' => 'test2',
  640. 'name' => 'TestApp',
  641. 'models' => array('SchemaCrossDatabase', 'SchemaPost')
  642. ));
  643. $this->assertFalse(isset($read['tables']['posts']), 'Posts should not appear');
  644. $this->assertFalse(isset($read['tables']['posts']), 'Posts should not appear');
  645. $this->assertTrue(isset($read['tables']['cross_database']));
  646. $fixture->drop($db2);
  647. }
  648. /**
  649. * test that tables are generated correctly
  650. *
  651. * @return void
  652. */
  653. public function testGenerateTable() {
  654. $posts = array(
  655. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  656. 'author_id' => array('type' => 'integer', 'null' => false),
  657. 'title' => array('type' => 'string', 'null' => false),
  658. 'body' => array('type' => 'text', 'null' => true, 'default' => null),
  659. 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
  660. 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
  661. 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
  662. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
  663. );
  664. $result = $this->Schema->generateTable('posts', $posts);
  665. $this->assertRegExp('/public \$posts/', $result);
  666. }
  667. /**
  668. * testSchemaWrite method
  669. *
  670. * @return void
  671. */
  672. public function testSchemaWrite() {
  673. $write = $this->Schema->write(array('name' => 'MyOtherApp', 'tables' => $this->Schema->tables, 'path' => TMP . 'tests'));
  674. $file = file_get_contents(TMP . 'tests' . DS .'schema.php');
  675. $this->assertEquals($write, $file);
  676. require_once( TMP . 'tests' . DS .'schema.php');
  677. $OtherSchema = new MyOtherAppSchema();
  678. $this->assertEquals($this->Schema->tables, $OtherSchema->tables);
  679. }
  680. /**
  681. * testSchemaComparison method
  682. *
  683. * @return void
  684. */
  685. public function testSchemaComparison() {
  686. $New = new MyAppSchema();
  687. $compare = $New->compare($this->Schema);
  688. $expected = array(
  689. 'comments' => array(
  690. 'add' => array(
  691. 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'after' => 'id'),
  692. 'title' => array('type' => 'string', 'null' => false, 'length' => 100, 'after' => 'user_id'),
  693. ),
  694. 'drop' => array(
  695. 'article_id' => array('type' => 'integer', 'null' => false),
  696. 'tableParameters' => array(),
  697. ),
  698. 'change' => array(
  699. 'comment' => array('type' => 'text', 'null' => false, 'default' => null),
  700. )
  701. ),
  702. 'posts' => array(
  703. 'add' => array(
  704. 'summary' => array('type' => 'text', 'null' => true, 'after' => 'body'),
  705. ),
  706. 'drop' => array(
  707. 'tableParameters' => array(),
  708. ),
  709. 'change' => array(
  710. 'author_id' => array('type' => 'integer', 'null' => true, 'default' => ''),
  711. 'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'),
  712. 'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1)
  713. )
  714. ),
  715. );
  716. $this->assertEquals($expected, $compare);
  717. $this->assertNull($New->getVar('comments'));
  718. $this->assertEquals($New->getVar('_foo'), array('bar'));
  719. $tables = array(
  720. 'missing' => array(
  721. 'categories' => array(
  722. 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
  723. 'created' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
  724. 'modified' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
  725. 'name' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 100),
  726. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
  727. 'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
  728. )
  729. ),
  730. 'ratings' => array(
  731. 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
  732. 'foreign_key' => array('type' => 'integer', 'null' => false, 'default' => NULL),
  733. 'model' => array('type' => 'varchar', 'null' => false, 'default' => NULL),
  734. 'value' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => NULL),
  735. 'created' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
  736. 'modified' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
  737. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
  738. 'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
  739. )
  740. );
  741. $compare = $New->compare($this->Schema, $tables);
  742. $expected = array(
  743. 'ratings' => array(
  744. 'add' => array(
  745. 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
  746. 'foreign_key' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'after' => 'id'),
  747. 'model' => array('type' => 'varchar', 'null' => false, 'default' => NULL, 'after' => 'foreign_key'),
  748. 'value' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => NULL, 'after' => 'model'),
  749. 'created' => array('type' => 'datetime', 'null' => false, 'default' => NULL, 'after' => 'value'),
  750. 'modified' => array('type' => 'datetime', 'null' => false, 'default' => NULL, 'after' => 'created'),
  751. 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
  752. 'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
  753. )
  754. )
  755. );
  756. $this->assertEquals($expected, $compare);
  757. }
  758. /**
  759. * test comparing '' and null and making sure they are different.
  760. *
  761. * @return void
  762. */
  763. public function testCompareEmptyStringAndNull() {
  764. $One = new CakeSchema(array(
  765. 'posts' => array(
  766. 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
  767. 'name' => array('type' => 'string', 'null' => false, 'default' => '')
  768. )
  769. ));
  770. $Two = new CakeSchema(array(
  771. 'posts' => array(
  772. 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
  773. 'name' => array('type' => 'string', 'null' => false, 'default' => null)
  774. )
  775. ));
  776. $compare = $One->compare($Two);
  777. $expected = array(
  778. 'posts' => array(
  779. 'change' => array(
  780. 'name' => array('type' => 'string', 'null' => false, 'default' => null)
  781. )
  782. )
  783. );
  784. $this->assertEquals($expected, $compare);
  785. }
  786. /**
  787. * Test comparing tableParameters and indexes.
  788. *
  789. * @return void
  790. */
  791. public function testTableParametersAndIndexComparison() {
  792. $old = array(
  793. 'posts' => array(
  794. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  795. 'author_id' => array('type' => 'integer', 'null' => false),
  796. 'title' => array('type' => 'string', 'null' => false),
  797. 'indexes' => array(
  798. 'PRIMARY' => array('column' => 'id', 'unique' => true)
  799. ),
  800. 'tableParameters' => array(
  801. 'charset' => 'latin1',
  802. 'collate' => 'latin1_general_ci'
  803. )
  804. ),
  805. 'comments' => array(
  806. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  807. 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
  808. 'comment' => array('type' => 'text'),
  809. 'indexes' => array(
  810. 'PRIMARY' => array('column' => 'id', 'unique' => true),
  811. 'post_id' => array('column' => 'post_id'),
  812. ),
  813. 'tableParameters' => array(
  814. 'engine' => 'InnoDB',
  815. 'charset' => 'latin1',
  816. 'collate' => 'latin1_general_ci'
  817. )
  818. )
  819. );
  820. $new = array(
  821. 'posts' => array(
  822. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  823. 'author_id' => array('type' => 'integer', 'null' => false),
  824. 'title' => array('type' => 'string', 'null' => false),
  825. 'indexes' => array(
  826. 'PRIMARY' => array('column' => 'id', 'unique' => true),
  827. 'author_id' => array('column' => 'author_id'),
  828. ),
  829. 'tableParameters' => array(
  830. 'charset' => 'utf8',
  831. 'collate' => 'utf8_general_ci',
  832. 'engine' => 'MyISAM'
  833. )
  834. ),
  835. 'comments' => array(
  836. 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
  837. 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
  838. 'comment' => array('type' => 'text'),
  839. 'indexes' => array(
  840. 'PRIMARY' => array('column' => 'id', 'unique' => true),
  841. ),
  842. 'tableParameters' => array(
  843. 'charset' => 'utf8',
  844. 'collate' => 'utf8_general_ci'
  845. )
  846. )
  847. );
  848. $compare = $this->Schema->compare($old, $new);
  849. $expected = array(
  850. 'posts' => array(
  851. 'add' => array(
  852. 'indexes' => array('author_id' => array('column' => 'author_id')),
  853. ),
  854. 'change' => array(
  855. 'tableParameters' => array(
  856. 'charset' => 'utf8',
  857. 'collate' => 'utf8_general_ci',
  858. 'engine' => 'MyISAM'
  859. )
  860. )
  861. ),
  862. 'comments' => array(
  863. 'drop' => array(
  864. 'indexes' => array('post_id' => array('column' => 'post_id')),
  865. ),
  866. 'change' => array(
  867. 'tableParameters' => array(
  868. 'charset' => 'utf8',
  869. 'collate' => 'utf8_general_ci',
  870. )
  871. )
  872. )
  873. );
  874. $this->assertEquals($expected, $compare);
  875. }
  876. /**
  877. * testSchemaLoading method
  878. *
  879. * @return void
  880. */
  881. public function testSchemaLoading() {
  882. $Other = $this->Schema->load(array('name' => 'MyOtherApp', 'path' => TMP . 'tests'));
  883. $this->assertEquals($Other->name, 'MyOtherApp');
  884. $this->assertEquals($Other->tables, $this->Schema->tables);
  885. }
  886. /**
  887. * test loading schema files inside of plugins.
  888. *
  889. * @return void
  890. */
  891. public function testSchemaLoadingFromPlugin() {
  892. App::build(array(
  893. 'plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
  894. ));
  895. CakePlugin::load('TestPlugin');
  896. $Other = $this->Schema->load(array('name' => 'TestPluginApp', 'plugin' => 'TestPlugin'));
  897. $this->assertEquals($Other->name, 'TestPluginApp');
  898. $this->assertEquals(array_keys($Other->tables), array('test_plugin_acos'));
  899. App::build();
  900. }
  901. /**
  902. * testSchemaCreateTable method
  903. *
  904. * @return void
  905. */
  906. public function testSchemaCreateTable() {
  907. $db = ConnectionManager::getDataSource('test');
  908. $db->cacheSources = false;
  909. $Schema = new CakeSchema(array(
  910. 'connection' => 'test',
  911. 'testdescribes' => array(
  912. 'id' => array('type' => 'integer', 'key' => 'primary'),
  913. 'int_null' => array('type' => 'integer', 'null' => true),
  914. 'int_not_null' => array('type' => 'integer', 'null' => false),
  915. ),
  916. ));
  917. $sql = $db->createSchema($Schema);
  918. $col = $Schema->tables['testdescribes']['int_null'];
  919. $col['name'] = 'int_null';
  920. $column = $this->db->buildColumn($col);
  921. $this->assertRegExp('/' . preg_quote($column, '/') . '/', $sql);
  922. $col = $Schema->tables['testdescribes']['int_not_null'];
  923. $col['name'] = 'int_not_null';
  924. $column = $this->db->buildColumn($col);
  925. $this->assertRegExp('/' . preg_quote($column, '/') . '/', $sql);
  926. }
  927. }