TableTest.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Database\Schema;
  16. use Cake\Database\Schema\Table;
  17. use Cake\TestSuite\TestCase;
  18. /**
  19. * Test case for Table
  20. */
  21. class TableTest extends TestCase {
  22. /**
  23. * Test construction with columns
  24. *
  25. * @return void
  26. */
  27. public function testConstructWithColumns() {
  28. $columns = [
  29. 'id' => [
  30. 'type' => 'integer',
  31. 'length' => 11,
  32. ],
  33. 'title' => [
  34. 'type' => 'string',
  35. 'length' => 255
  36. ]
  37. ];
  38. $table = new Table('articles', $columns);
  39. $this->assertEquals(['id', 'title'], $table->columns());
  40. }
  41. /**
  42. * Test adding columns.
  43. *
  44. * @return void
  45. */
  46. public function testAddColumn() {
  47. $table = new Table('articles');
  48. $result = $table->addColumn('title', [
  49. 'type' => 'string',
  50. 'length' => 25,
  51. 'null' => false
  52. ]);
  53. $this->assertSame($table, $result);
  54. $this->assertEquals(['title'], $table->columns());
  55. $result = $table->addColumn('body', 'text');
  56. $this->assertSame($table, $result);
  57. $this->assertEquals(['title', 'body'], $table->columns());
  58. }
  59. /**
  60. * Test columnType method
  61. *
  62. * @return void
  63. */
  64. public function testColumnType() {
  65. $table = new Table('articles');
  66. $table->addColumn('title', [
  67. 'type' => 'string',
  68. 'length' => 25,
  69. 'null' => false
  70. ]);
  71. $this->assertEquals('string', $table->columnType('title'));
  72. $this->assertNull($table->columnType('not there'));
  73. }
  74. /**
  75. * Test columnType setter method
  76. *
  77. * @return void
  78. */
  79. public function testColumnTypeSet() {
  80. $table = new Table('articles');
  81. $table->addColumn('title', [
  82. 'type' => 'string',
  83. 'length' => 25,
  84. 'null' => false
  85. ]);
  86. $this->assertEquals('string', $table->columnType('title'));
  87. $table->columnType('title', 'json');
  88. $this->assertEquals('json', $table->columnType('title'));
  89. }
  90. /**
  91. * Attribute keys should be filtered and have defaults set.
  92. *
  93. * @return void
  94. */
  95. public function testAddColumnFiltersAttributes() {
  96. $table = new Table('articles');
  97. $table->addColumn('title', [
  98. 'type' => 'string'
  99. ]);
  100. $result = $table->column('title');
  101. $expected = [
  102. 'type' => 'string',
  103. 'length' => null,
  104. 'precision' => null,
  105. 'default' => null,
  106. 'null' => null,
  107. 'fixed' => null,
  108. 'comment' => null,
  109. ];
  110. $this->assertEquals($expected, $result);
  111. $table->addColumn('author_id', [
  112. 'type' => 'integer'
  113. ]);
  114. $result = $table->column('author_id');
  115. $expected = [
  116. 'type' => 'integer',
  117. 'length' => null,
  118. 'precision' => null,
  119. 'default' => null,
  120. 'null' => null,
  121. 'unsigned' => null,
  122. 'comment' => null,
  123. 'autoIncrement' => null,
  124. ];
  125. $this->assertEquals($expected, $result);
  126. $table->addColumn('amount', [
  127. 'type' => 'decimal'
  128. ]);
  129. $result = $table->column('amount');
  130. $expected = [
  131. 'type' => 'decimal',
  132. 'length' => null,
  133. 'precision' => null,
  134. 'default' => null,
  135. 'null' => null,
  136. 'unsigned' => null,
  137. 'comment' => null,
  138. ];
  139. $this->assertEquals($expected, $result);
  140. }
  141. /**
  142. * Test reading default values.
  143. *
  144. * @return void
  145. */
  146. public function testDefaultValues() {
  147. $table = new Table('articles');
  148. $table->addColumn('id', [
  149. 'type' => 'integer',
  150. 'default' => 0
  151. ])->addColumn('title', [
  152. 'type' => 'string',
  153. 'default' => 'A title'
  154. ])->addColumn('name', [
  155. 'type' => 'string',
  156. 'null' => false,
  157. 'default' => null,
  158. ])->addColumn('body', [
  159. 'type' => 'text',
  160. 'null' => true,
  161. 'default' => null,
  162. ]);
  163. $result = $table->defaultValues();
  164. $expected = [
  165. 'id' => 0,
  166. 'title' => 'A title',
  167. 'body' => null
  168. ];
  169. $this->assertEquals($expected, $result);
  170. }
  171. /**
  172. * Test adding an constraint.
  173. *>
  174. * @return void
  175. */
  176. public function testAddConstraint() {
  177. $table = new Table('articles');
  178. $table->addColumn('id', [
  179. 'type' => 'integer'
  180. ]);
  181. $result = $table->addConstraint('primary', [
  182. 'type' => 'primary',
  183. 'columns' => ['id']
  184. ]);
  185. $this->assertSame($result, $table);
  186. $this->assertEquals(['primary'], $table->constraints());
  187. }
  188. /**
  189. * Dataprovider for invalid addConstraint calls.
  190. *
  191. * @return array
  192. */
  193. public static function addConstaintErrorProvider() {
  194. return [
  195. // No properties
  196. [[]],
  197. // Empty columns
  198. [['columns' => '', 'type' => Table::CONSTRAINT_UNIQUE]],
  199. [['columns' => [], 'type' => Table::CONSTRAINT_UNIQUE]],
  200. // Missing column
  201. [['columns' => ['derp'], 'type' => Table::CONSTRAINT_UNIQUE]],
  202. // Invalid type
  203. [['columns' => 'author_id', 'type' => 'derp']],
  204. ];
  205. }
  206. /**
  207. * Test that an exception is raised when constraints
  208. * are added for fields that do not exist.
  209. *
  210. * @dataProvider addConstaintErrorProvider
  211. * @expectedException \Cake\Database\Exception
  212. * @return void
  213. */
  214. public function testAddConstraintError($props) {
  215. $table = new Table('articles');
  216. $table->addColumn('author_id', 'integer');
  217. $table->addConstraint('author_idx', $props);
  218. }
  219. /**
  220. * Test adding an index.
  221. *
  222. * @return void
  223. */
  224. public function testAddIndex() {
  225. $table = new Table('articles');
  226. $table->addColumn('title', [
  227. 'type' => 'string'
  228. ]);
  229. $result = $table->addIndex('faster', [
  230. 'type' => 'index',
  231. 'columns' => ['title']
  232. ]);
  233. $this->assertSame($result, $table);
  234. $this->assertEquals(['faster'], $table->indexes());
  235. }
  236. /**
  237. * Dataprovider for invalid addIndex calls
  238. *
  239. * @return array
  240. */
  241. public static function addIndexErrorProvider() {
  242. return [
  243. // Empty
  244. [[]],
  245. // Invalid type
  246. [['columns' => 'author_id', 'type' => 'derp']],
  247. // No columns
  248. [['columns' => ''], 'type' => Table::INDEX_INDEX],
  249. [['columns' => [], 'type' => Table::INDEX_INDEX]],
  250. // Missing column
  251. [['columns' => ['not_there'], 'type' => Table::INDEX_INDEX]],
  252. ];
  253. }
  254. /**
  255. * Test that an exception is raised when indexes
  256. * are added for fields that do not exist.
  257. *
  258. * @dataProvider addIndexErrorProvider
  259. * @expectedException \Cake\Database\Exception
  260. * @return void
  261. */
  262. public function testAddIndexError($props) {
  263. $table = new Table('articles');
  264. $table->addColumn('author_id', 'integer');
  265. $table->addIndex('author_idx', $props);
  266. }
  267. /**
  268. * Test adding different kinds of indexes.
  269. *
  270. * @return void
  271. */
  272. public function testAddIndexTypes() {
  273. $table = new Table('articles');
  274. $table->addColumn('id', 'integer')
  275. ->addColumn('title', 'string')
  276. ->addColumn('author_id', 'integer');
  277. $table->addIndex('author_idx', [
  278. 'columns' => ['author_id'],
  279. 'type' => 'index'
  280. ])->addIndex('texty', [
  281. 'type' => 'fulltext',
  282. 'columns' => ['title']
  283. ]);
  284. $this->assertEquals(
  285. ['author_idx', 'texty'],
  286. $table->indexes()
  287. );
  288. }
  289. /**
  290. * Test getting the primary key.
  291. *
  292. * @return void
  293. */
  294. public function testPrimaryKey() {
  295. $table = new Table('articles');
  296. $table->addColumn('id', 'integer')
  297. ->addColumn('title', 'string')
  298. ->addColumn('author_id', 'integer')
  299. ->addConstraint('author_idx', [
  300. 'columns' => ['author_id'],
  301. 'type' => 'unique'
  302. ])->addConstraint('primary', [
  303. 'type' => 'primary',
  304. 'columns' => ['id']
  305. ]);
  306. $this->assertEquals(['id'], $table->primaryKey());
  307. $table = new Table('articles');
  308. $table->addColumn('id', 'integer')
  309. ->addColumn('title', 'string')
  310. ->addColumn('author_id', 'integer');
  311. $this->assertEquals([], $table->primaryKey());
  312. }
  313. /**
  314. * Test the options method.
  315. *
  316. * @return void
  317. */
  318. public function testOptions() {
  319. $table = new Table('articles');
  320. $options = [
  321. 'engine' => 'InnoDB'
  322. ];
  323. $return = $table->options($options);
  324. $this->assertInstanceOf('Cake\Database\Schema\Table', $return);
  325. $this->assertEquals($options, $table->options());
  326. }
  327. /**
  328. * Add a basic foreign key constraint.
  329. *
  330. * @return void
  331. */
  332. public function testAddConstraintForeignKey() {
  333. $table = new Table('articles');
  334. $table->addColumn('author_id', 'integer')
  335. ->addConstraint('author_id_idx', [
  336. 'type' => Table::CONSTRAINT_FOREIGN,
  337. 'columns' => ['author_id'],
  338. 'references' => ['authors', 'id'],
  339. 'update' => 'cascade',
  340. 'delete' => 'cascade',
  341. ]);
  342. $this->assertEquals(['author_id_idx'], $table->constraints());
  343. }
  344. /**
  345. * Provider for exceptionally bad foreign key data.
  346. *
  347. * @return array
  348. */
  349. public static function badForeignKeyProvider() {
  350. return [
  351. 'references is bad' => [[
  352. 'type' => Table::CONSTRAINT_FOREIGN,
  353. 'columns' => ['author_id'],
  354. 'references' => ['authors'],
  355. 'delete' => 'derp',
  356. ]],
  357. 'bad update value' => [[
  358. 'type' => Table::CONSTRAINT_FOREIGN,
  359. 'columns' => ['author_id'],
  360. 'references' => ['authors', 'id'],
  361. 'update' => 'derp',
  362. ]],
  363. 'bad delete value' => [[
  364. 'type' => Table::CONSTRAINT_FOREIGN,
  365. 'columns' => ['author_id'],
  366. 'references' => ['authors', 'id'],
  367. 'delete' => 'derp',
  368. ]],
  369. ];
  370. }
  371. /**
  372. * Add a foreign key constraint with bad data
  373. *
  374. * @dataProvider badForeignKeyProvider
  375. * @expectedException \Cake\Database\Exception
  376. * @return void
  377. */
  378. public function testAddConstraintForeignKeyBadData($data) {
  379. $table = new Table('articles');
  380. $table->addColumn('author_id', 'integer')
  381. ->addConstraint('author_id_idx', $data);
  382. }
  383. /**
  384. * Tests the temporary() method
  385. *
  386. * @return void
  387. */
  388. public function testTemporary() {
  389. $table = new Table('articles');
  390. $this->assertFalse($table->temporary());
  391. $this->assertSame($table, $table->temporary(true));
  392. $this->assertTrue($table->temporary());
  393. $table->temporary(false);
  394. $this->assertFalse($table->temporary());
  395. }
  396. }