[TASK] Doctrine: Migrate SqlSchemaMigrationService
[Packages/TYPO3.CMS.git] / typo3 / sysext / dbal / Tests / Unit / Service / SqlSchemaMigrationServiceTest.php
1 <?php
2 namespace TYPO3\CMS\Dbal\Tests\Unit\Service;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Tests\UnitTestCase;
18 use TYPO3\CMS\Dbal\Service\SqlSchemaMigrationService;
19
20 /**
21 * Test case
22 */
23 class SqlSchemaMigrationServiceTest extends UnitTestCase
24 {
25 /**
26 * Get a SchemaService instance with mocked DBAL enable database connection, DBAL not enabled
27 *
28 * @return \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
29 */
30 protected function getSqlSchemaMigrationService()
31 {
32 /** @var \TYPO3\CMS\Dbal\Database\DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $databaseConnection */
33 $subject = $this->getAccessibleMock(SqlSchemaMigrationService::class, ['isDbalEnabled'], [], '', false);
34 $subject->expects($this->any())->method('isDbalEnabled')->will($this->returnValue(false));
35
36 return $subject;
37 }
38
39 /**
40 * Get a SchemaService instance with mocked DBAL enable database connection, DBAL enabled
41 *
42 * @return \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
43 */
44 protected function getDbalEnabledSqlSchemaMigrationService()
45 {
46 /** @var \TYPO3\CMS\Dbal\Database\DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $databaseConnection */
47 $databaseConnection = $this->getAccessibleMock(\TYPO3\CMS\Dbal\Database\DatabaseConnection::class, ['dummy'], [], '', false);
48 $databaseConnection->_set(
49 'dbmsSpecifics',
50 new \TYPO3\CMS\Dbal\Database\Specifics\PostgresSpecifics()
51 );
52
53 $subject = $this->getAccessibleMock(SqlSchemaMigrationService::class, ['isDbalEnabled', 'getDatabaseConnection'], [], '', false);
54 $subject->expects($this->any())->method('isDbalEnabled')->will($this->returnValue(true));
55 $subject->expects($this->any())->method('getDatabaseConnection')->will($this->returnValue($databaseConnection));
56
57 return $subject;
58 }
59
60 /**
61 * @test
62 */
63 public function getFieldDefinitionsFileContentHandlesMultipleWhitespacesInFieldDefinitions()
64 {
65 $subject = $this->getSqlSchemaMigrationService();
66 // Multiple whitespaces and tabs in field definition
67 $inputString = 'CREATE table atable (' . LF . 'aFieldName int(11)' . TAB . TAB . TAB . 'unsigned DEFAULT \'0\'' . LF . ');';
68 $result = $subject->getFieldDefinitions_fileContent($inputString);
69
70 $this->assertEquals(
71 [
72 'atable' => [
73 'fields' => [
74 'aFieldName' => 'int(11) unsigned default \'0\'',
75 ],
76 'extra' => [
77 'COLLATE' => '',
78 ],
79 ],
80 ],
81 $result
82 );
83 }
84
85 /**
86 * @test
87 */
88 public function getDatabaseExtraFindsChangedFields()
89 {
90 $subject = $this->getSqlSchemaMigrationService();
91 $differenceArray = $subject->getDatabaseExtra(
92 [
93 'tx_foo' => [
94 'fields' => [
95 'foo' => 'varchar(999) DEFAULT \'0\' NOT NULL'
96 ]
97 ]
98 ],
99 [
100 'tx_foo' => [
101 'fields' => [
102 'foo' => 'varchar(255) DEFAULT \'0\' NOT NULL'
103 ]
104 ]
105 ]
106 );
107
108 $this->assertEquals(
109 $differenceArray,
110 [
111 'extra' => [],
112 'diff' => [
113 'tx_foo' => [
114 'fields' => [
115 'foo' => 'varchar(999) DEFAULT \'0\' NOT NULL'
116 ]
117 ]
118 ],
119 'diff_currentValues' => [
120 'tx_foo' => [
121 'fields' => [
122 'foo' => 'varchar(255) DEFAULT \'0\' NOT NULL'
123 ]
124 ]
125 ]
126 ]
127 );
128 }
129
130 /**
131 * @test
132 */
133 public function getDatabaseExtraFindsChangedFieldsIncludingNull()
134 {
135 $subject = $this->getSqlSchemaMigrationService();
136 $differenceArray = $subject->getDatabaseExtra(
137 [
138 'tx_foo' => [
139 'fields' => [
140 'foo' => 'varchar(999) NULL'
141 ]
142 ]
143 ],
144 [
145 'tx_foo' => [
146 'fields' => [
147 'foo' => 'varchar(255) NULL'
148 ]
149 ]
150 ]
151 );
152
153 $this->assertEquals(
154 $differenceArray,
155 [
156 'extra' => [],
157 'diff' => [
158 'tx_foo' => [
159 'fields' => [
160 'foo' => 'varchar(999) NULL'
161 ]
162 ]
163 ],
164 'diff_currentValues' => [
165 'tx_foo' => [
166 'fields' => [
167 'foo' => 'varchar(255) NULL'
168 ]
169 ]
170 ]
171 ]
172 );
173 }
174
175 /**
176 * @test
177 */
178 public function getDatabaseExtraFindsChangedFieldsIgnoreNotNull()
179 {
180 $subject = $this->getSqlSchemaMigrationService();
181 $differenceArray = $subject->getDatabaseExtra(
182 [
183 'tx_foo' => [
184 'fields' => [
185 'foo' => 'varchar(999) DEFAULT \'0\' NOT NULL'
186 ]
187 ]
188 ],
189 [
190 'tx_foo' => [
191 'fields' => [
192 'foo' => 'varchar(255) DEFAULT \'0\' NOT NULL'
193 ]
194 ]
195 ],
196 '',
197 true
198 );
199
200 $this->assertEquals(
201 $differenceArray,
202 [
203 'extra' => [],
204 'diff' => [
205 'tx_foo' => [
206 'fields' => [
207 'foo' => 'varchar(999) DEFAULT \'0\''
208 ]
209 ]
210 ],
211 'diff_currentValues' => [
212 'tx_foo' => [
213 'fields' => [
214 'foo' => 'varchar(255) DEFAULT \'0\''
215 ]
216 ]
217 ]
218 ]
219 );
220 }
221
222 /**
223 * @test
224 */
225 public function getDatabaseExtraIgnoresCaseDifference()
226 {
227 $subject = $this->getSqlSchemaMigrationService();
228 $differenceArray = $subject->getDatabaseExtra(
229 [
230 'tx_foo' => [
231 'fields' => [
232 'foo' => 'INT(11) DEFAULT \'0\' NOT NULL',
233 ]
234 ]
235 ],
236 [
237 'tx_foo' => [
238 'fields' => [
239 'foo' => 'int(11) DEFAULT \'0\' NOT NULL',
240 ]
241 ]
242 ]
243 );
244
245 $this->assertEquals(
246 $differenceArray,
247 [
248 'extra' => [],
249 'diff' => [],
250 'diff_currentValues' => null,
251 ]
252 );
253 }
254
255 /**
256 * @test
257 */
258 public function getDatabaseExtraIgnoresCaseDifferenceButKeepsCaseInSetIntact()
259 {
260 $subject = $this->getSqlSchemaMigrationService();
261 $differenceArray = $subject->getDatabaseExtra(
262 [
263 'tx_foo' => [
264 'fields' => [
265 'subtype' => 'SET(\'Tx_MyExt_Domain_Model_Xyz\',\'Tx_MyExt_Domain_Model_Abc\',\'\') NOT NULL DEFAULT \'\',',
266 ]
267 ]
268 ],
269 [
270 'tx_foo' => [
271 'fields' => [
272 'subtype' => 'set(\'Tx_MyExt_Domain_Model_Xyz\',\'Tx_MyExt_Domain_Model_Abc\',\'\') NOT NULL DEFAULT \'\',',
273 ]
274 ]
275 ]
276 );
277
278 $this->assertEquals(
279 $differenceArray,
280 [
281 'extra' => [],
282 'diff' => [],
283 'diff_currentValues' => null,
284 ]
285 );
286 }
287
288 /**
289 * @test
290 */
291 public function getDatabaseExtraDoesNotLowercaseReservedWordsForTheComparison()
292 {
293 $subject = $this->getSqlSchemaMigrationService();
294 $differenceArray = $subject->getDatabaseExtra(
295 [
296 'tx_foo' => [
297 'fields' => [
298 'PRIMARY KEY (md5hash)',
299 ]
300 ]
301 ],
302 [
303 'tx_foo' => [
304 'fields' => [
305 'PRIMARY KEY (md5hash)'],
306 ]
307 ]
308 );
309
310 $this->assertEquals(
311 $differenceArray,
312 [
313 'extra' => [],
314 'diff' => [],
315 'diff_currentValues' => null,
316 ]
317 );
318 }
319
320 /**
321 * @test
322 */
323 public function getDatabaseExtraFindsNewSpatialKeys()
324 {
325 $subject = $this->getSqlSchemaMigrationService();
326 $differenceArray = $subject->getDatabaseExtra(
327 [
328 'tx_foo' => [
329 'keys' => [
330 'foo' => 'SPATIAL foo (foo)'
331 ]
332 ]
333 ],
334 [
335 'tx_foo' => [
336 'keys' => []
337 ]
338 ]
339 );
340
341 $this->assertEquals(
342 $differenceArray,
343 [
344 'extra' => [
345 'tx_foo' => [
346 'keys' => [
347 'foo' => 'SPATIAL foo (foo)'
348 ]
349 ]
350 ],
351 'diff' => [],
352 'diff_currentValues' => null
353 ]
354 );
355 }
356
357 /**
358 * @test
359 */
360 public function checkColumnDefinitionIfCommentIsSupplied()
361 {
362 $subject = $this->getSqlSchemaMigrationService();
363 $fieldDefinition = $subject->assembleFieldDefinition(
364 [
365 'Field' => 'uid',
366 'Type' => 'int(11)',
367 'Null' => 'NO',
368 'Key' => 'PRI',
369 'Default' => null,
370 'Extra' => 'auto_increment',
371 'Comment' => 'I am a comment',
372 ]
373 );
374
375 $this->assertSame(
376 'int(11) NOT NULL auto_increment COMMENT \'I am a comment\'',
377 $fieldDefinition
378 );
379 }
380
381 /**
382 * @test
383 */
384 public function checkColumnDefinitionIfNoCommentIsSupplied()
385 {
386 $subject = $this->getSqlSchemaMigrationService();
387 $fieldDefinition = $subject->assembleFieldDefinition(
388 [
389 'Field' => 'uid',
390 'Type' => 'int(11)',
391 'Null' => 'NO',
392 'Key' => 'PRI',
393 'Default' => null,
394 'Extra' => 'auto_increment',
395 ]
396 );
397
398 $this->assertSame(
399 'int(11) NOT NULL auto_increment',
400 $fieldDefinition
401 );
402 }
403
404 /**
405 * @test
406 */
407 public function getDatabaseExtraIncludesEngineIfMySQLIsUsed()
408 {
409 $subject = $this->getSqlSchemaMigrationService();
410 $differenceArray = $subject->getDatabaseExtra(
411 [
412 'tx_foo' => [
413 'fields' => [
414 'foo' => 'INT(11) DEFAULT \'0\' NOT NULL',
415 ],
416 'extra' => [
417 'ENGINE' => 'InnoDB'
418 ]
419 ]
420 ],
421 [
422 'tx_foo' => [
423 'fields' => [
424 'foo' => 'int(11) DEFAULT \'0\' NOT NULL',
425 ],
426 'extra' => [
427 'ENGINE' => 'InnoDB'
428 ]
429 ]
430 ]
431 );
432
433 $this->assertSame(
434 $differenceArray,
435 [
436 'extra' => [],
437 'diff' => [],
438 'diff_currentValues' => null,
439 ]
440 );
441 }
442
443 /**
444 * @test
445 */
446 public function getDatabaseExtraExcludesEngineIfDbalIsUsed()
447 {
448 $subject = $this->getDbalEnabledSqlSchemaMigrationService();
449 $differenceArray = $subject->getDatabaseExtra(
450 [
451 'tx_foo' => [
452 'fields' => [
453 'foo' => 'INT(11) DEFAULT \'0\' NOT NULL',
454 ],
455 'extra' => [
456 'ENGINE' => 'InnoDB'
457 ]
458 ]
459 ],
460 [
461 'tx_foo' => [
462 'fields' => [
463 'foo' => 'int(11) DEFAULT \'0\' NOT NULL',
464 ],
465 'extra' => []
466 ]
467 ]
468 );
469
470 $this->assertSame(
471 $differenceArray,
472 [
473 'extra' => [],
474 'diff' => [],
475 'diff_currentValues' => null,
476 ]
477 );
478 }
479
480 /**
481 * @test
482 */
483 public function getDatabaseExtraIncludesUnsignedAttributeIfMySQLIsUsed()
484 {
485 $subject = $this->getSqlSchemaMigrationService();
486 $differenceArray = $subject->getDatabaseExtra(
487 [
488 'tx_foo' => [
489 'fields' => [
490 'foo' => 'INT(11) UNSIGNED DEFAULT \'0\' NOT NULL',
491 ],
492 'extra' => [
493 'ENGINE' => 'InnoDB'
494 ]
495 ]
496 ],
497 [
498 'tx_foo' => [
499 'fields' => [
500 'foo' => 'int(11) DEFAULT \'0\' NOT NULL',
501 ],
502 'extra' => [
503 'ENGINE' => 'InnoDB'
504 ]
505 ]
506 ]
507 );
508
509 $this->assertSame(
510 $differenceArray,
511 [
512 'extra' => [],
513 'diff' => [
514 'tx_foo' => [
515 'fields' => [
516 'foo' => 'int(11) UNSIGNED DEFAULT \'0\' NOT NULL',
517 ],
518 ]
519 ],
520 'diff_currentValues' => [
521 'tx_foo' => [
522 'fields' => [
523 'foo' => 'int(11) DEFAULT \'0\' NOT NULL',
524 ],
525 ]
526 ]
527 ]
528 );
529 }
530
531 /**
532 * @test
533 */
534 public function getDatabaseExtraExcludesUnsignedAttributeIfDbalIsUsed()
535 {
536 $subject = $this->getDbalEnabledSqlSchemaMigrationService();
537 $differenceArray = $subject->getDatabaseExtra(
538 [
539 'tx_foo' => [
540 'fields' => [
541 'foo' => 'INT(11) UNSIGNED DEFAULT \'0\' NOT NULL',
542 ],
543 'extra' => [
544 'ENGINE' => 'InnoDB'
545 ]
546 ]
547 ],
548 [
549 'tx_foo' => [
550 'fields' => [
551 'foo' => 'int(11) DEFAULT \'0\' NOT NULL',
552 ],
553 'extra' => [
554 'ENGINE' => 'InnoDB'
555 ]
556 ]
557 ]
558 );
559
560 $this->assertSame(
561 $differenceArray,
562 [
563 'extra' => [],
564 'diff' => [],
565 'diff_currentValues' => null
566 ]
567 );
568 }
569
570 /**
571 * @test
572 */
573 public function getDatabaseExtraIgnoresIndexPrefixLengthIfDbalIsUsed()
574 {
575 $subject = $this->getDbalEnabledSqlSchemaMigrationService();
576 $differenceArray = $subject->getDatabaseExtra(
577 [
578 'tx_foo' => [
579 'keys' => [
580 'foo' => 'KEY foo (foo(199))'
581 ]
582 ]
583 ],
584 [
585 'tx_foo' => [
586 'keys' => [
587 'foo' => 'KEY foo (foo)'
588 ]
589 ]
590 ]
591 );
592
593 $this->assertSame(
594 $differenceArray,
595 [
596 'extra' => [],
597 'diff' => [],
598 'diff_currentValues' => null,
599 ]
600 );
601 }
602
603 /**
604 * @test
605 */
606 public function getDatabaseExtraComparesIndexPrefixLengthIfMySQLIsUsed()
607 {
608 $subject = $this->getSqlSchemaMigrationService();
609 $differenceArray = $subject->getDatabaseExtra(
610 [
611 'tx_foo' => [
612 'keys' => [
613 'foo' => 'KEY foo (foo(199))'
614 ]
615 ]
616 ],
617 [
618 'tx_foo' => [
619 'keys' => [
620 'foo' => 'KEY foo (foo)'
621 ]
622 ]
623 ]
624 );
625
626 $this->assertSame(
627 $differenceArray,
628 [
629 'extra' => [],
630 'diff' => [
631 'tx_foo' => [
632 'keys' => [
633 'foo' => 'KEY foo (foo(199))'
634 ]
635 ]
636 ],
637 'diff_currentValues' => [
638 'tx_foo' => [
639 'keys' => [
640 'foo' => 'KEY foo (foo)'
641 ]
642 ]
643 ]
644 ]
645 );
646 }
647 }