TableTest.php 12 KB

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