Completed
Pull Request — 2.10.x (#3936)
by Asmir
24:12
created

ComparatorTest   F

Complexity

Total Complexity 59

Size/Duplication

Total Lines 1340
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
wmc 59
eloc 691
c 5
b 0
f 0
dl 0
loc 1340
rs 3.989

58 Methods

Rating   Name   Duplication   Size   Complexity  
A testCompareChangedColumnsChangeType() 0 8 1
A testCompareOnlyAutoincrementChanged() 0 9 1
A testCompareNewField() 0 35 1
A testCompareMissingTable() 0 12 1
A testCompareSame1() 0 22 1
A testCompareNewTable() 0 12 1
A testCompareSame2() 0 24 1
A testCompareMissingField() 0 36 1
A testForeignKeyRemovalWithRenamedLocalColumn() 0 46 1
A getCompareColumnComments() 0 22 1
A testCompareColumnsOverriddenType() 0 15 1
A testCompareColumnsMultipleTypeInstances() 0 11 1
A testCompareChangedIndex() 0 61 1
A testCompareChangeColumnsMultipleNewColumnsRename() 0 18 1
A testCompareChangedIndexFieldPositions() 0 46 1
A testCompareRemovedIndex() 0 52 1
A testCompareChangedColumnsChangeCustomSchemaOption() 0 14 1
A testCompareNewIndex() 0 50 1
A testFqnSchemaComparisonDifferentSchemaNameButSameTableNoDiff() 0 15 1
A testCompareColumnCompareCaseInsensitive() 0 12 1
A testChangedSequence() 0 12 1
A testDetectRenameColumn() 0 15 1
A testFqnSchemaComparison() 0 15 1
A testCompareRenamePrimaryKeyAndChangeColumnsDropsItAndCreatesIt() 0 31 1
A testCompareForeignKeyRestrictNoActionAreTheSame() 0 7 1
A testRemovedSequence() 0 12 1
A testComplexDiffColumn() 0 15 1
A testDetectChangeIdentifierType() 0 15 1
A testSequencesCaseInsensitive() 0 18 1
A testCompareGuidColumns() 0 13 1
A testFqnSchemaComparisonNoSchemaSame() 0 14 1
A testCompareColumnComments() 0 16 2
A testCompareChangedBinaryColumn() 0 20 1
A testAvoidMultipleDropForeignKey() 0 31 1
A testCompareSequences() 0 12 1
A testTableAddForeignKey() 0 17 1
A testDiffColumnPlatformOptions() 0 15 1
A testCompareIndexBasedOnPropertiesNotName() 0 18 1
A assertSchemaSequenceChangeCount() 0 9 1
A testAddedSequence() 0 12 1
A testNamespacesComparison() 0 22 1
A testTablesCaseInsensitive() 0 18 1
A testAutoIncrementSequences() 0 17 1
A testTableUpdateForeignKey() 0 18 1
A assertSchemaTableChangeCount() 0 5 1
A testDetectRenameColumnAmbiguous() 0 18 1
A testDetectRenameIndexAmbiguous() 0 21 1
A testAutoIncrementNoSequences() 0 17 1
A testComparesNamespaces() 0 44 1
A testCompareForeignKeyNamesUnqualifiedAsNoSchemaInformationIsAvailable() 0 7 1
A testMovedForeignKeyForeignTable() 0 21 1
A testDiff() 0 22 1
A testTableRemoveForeignKey() 0 17 1
A testDetectRenameIndex() 0 18 1
A testDiffDecimalWithNullPrecision() 0 9 1
A testCompareQuotedAndUnquotedForeignKeyColumns() 0 9 1
A testCompareChangedColumn() 0 20 1
A testCompareForeignKeyBasedOnPropertiesNotName() 0 14 1

How to fix   Complexity   

Complex Class

Complex classes like ComparatorTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ComparatorTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Doctrine\Tests\DBAL\Schema;
4
5
use Doctrine\DBAL\Platforms\MySqlPlatform;
6
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
7
use Doctrine\DBAL\Schema\Column;
8
use Doctrine\DBAL\Schema\ColumnDiff;
9
use Doctrine\DBAL\Schema\Comparator;
10
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
11
use Doctrine\DBAL\Schema\Index;
12
use Doctrine\DBAL\Schema\Schema;
13
use Doctrine\DBAL\Schema\SchemaConfig;
14
use Doctrine\DBAL\Schema\SchemaDiff;
15
use Doctrine\DBAL\Schema\Sequence;
16
use Doctrine\DBAL\Schema\Table;
17
use Doctrine\DBAL\Schema\TableDiff;
18
use Doctrine\DBAL\Types\Type;
19
use PHPUnit\Framework\TestCase;
20
use function array_keys;
21
use function get_class;
22
23
class ComparatorTest extends TestCase
24
{
25
    public function testCompareSame1() : void
26
    {
27
        $schema1 = new Schema([
28
            'bugdb' => new Table(
29
                'bugdb',
30
                [
31
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
32
                ]
33
            ),
34
        ]);
35
        $schema2 = new Schema([
36
            'bugdb' => new Table(
37
                'bugdb',
38
                [
39
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
40
                ]
41
            ),
42
        ]);
43
44
        $expected             = new SchemaDiff();
45
        $expected->fromSchema = $schema1;
46
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
47
    }
48
49
    public function testCompareSame2() : void
50
    {
51
        $schema1 = new Schema([
52
            'bugdb' => new Table(
53
                'bugdb',
54
                [
55
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
56
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
57
                ]
58
            ),
59
        ]);
60
        $schema2 = new Schema([
61
            'bugdb' => new Table(
62
                'bugdb',
63
                [
64
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
65
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
66
                ]
67
            ),
68
        ]);
69
70
        $expected             = new SchemaDiff();
71
        $expected->fromSchema = $schema1;
72
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
73
    }
74
75
    public function testCompareMissingTable() : void
76
    {
77
        $schemaConfig = new SchemaConfig();
78
        $table        = new Table('bugdb', ['integerfield1' => new Column('integerfield1', Type::getType('integer'))]);
79
        $table->setSchemaConfig($schemaConfig);
80
81
        $schema1 = new Schema([$table], [], $schemaConfig);
82
        $schema2 = new Schema([], [], $schemaConfig);
83
84
        $expected = new SchemaDiff([], [], ['bugdb' => $table], $schema1);
85
86
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
87
    }
88
89
    public function testCompareNewTable() : void
90
    {
91
        $schemaConfig = new SchemaConfig();
92
        $table        = new Table('bugdb', ['integerfield1' => new Column('integerfield1', Type::getType('integer'))]);
93
        $table->setSchemaConfig($schemaConfig);
94
95
        $schema1 = new Schema([], [], $schemaConfig);
96
        $schema2 = new Schema([$table], [], $schemaConfig);
97
98
        $expected = new SchemaDiff(['bugdb' => $table], [], [], $schema1);
99
100
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
101
    }
102
103
    public function testCompareOnlyAutoincrementChanged() : void
104
    {
105
        $column1 = new Column('foo', Type::getType('integer'), ['autoincrement' => true]);
106
        $column2 = new Column('foo', Type::getType('integer'), ['autoincrement' => false]);
107
108
        $comparator        = new Comparator();
109
        $changedProperties = $comparator->diffColumn($column1, $column2);
110
111
        self::assertEquals(['autoincrement'], $changedProperties);
112
    }
113
114
    public function testCompareMissingField() : void
115
    {
116
        $missingColumn = new Column('integerfield1', Type::getType('integer'));
117
        $schema1       = new Schema([
118
            'bugdb' => new Table(
119
                'bugdb',
120
                [
121
                    'integerfield1' => $missingColumn,
122
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
123
                ]
124
            ),
125
        ]);
126
        $schema2       = new Schema([
127
            'bugdb' => new Table(
128
                'bugdb',
129
                [
130
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
131
                ]
132
            ),
133
        ]);
134
135
        $expected                                    = new SchemaDiff(
136
            [],
137
            [
138
                'bugdb' => new TableDiff(
139
                    'bugdb',
140
                    [],
141
                    [],
142
                    ['integerfield1' => $missingColumn]
143
                ),
144
            ]
145
        );
146
        $expected->fromSchema                        = $schema1;
147
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
148
149
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
150
    }
151
152
    public function testCompareNewField() : void
153
    {
154
        $schema1 = new Schema([
155
            'bugdb' => new Table(
156
                'bugdb',
157
                [
158
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
159
                ]
160
            ),
161
        ]);
162
        $schema2 = new Schema([
163
            'bugdb' => new Table(
164
                'bugdb',
165
                [
166
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
167
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
168
                ]
169
            ),
170
        ]);
171
172
        $expected                                    = new SchemaDiff(
173
            [],
174
            [
175
                'bugdb' => new TableDiff(
176
                    'bugdb',
177
                    [
178
                        'integerfield2' => new Column('integerfield2', Type::getType('integer')),
179
                    ]
180
                ),
181
            ]
182
        );
183
        $expected->fromSchema                        = $schema1;
184
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
185
186
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
187
    }
188
189
    public function testCompareChangedColumnsChangeType() : void
190
    {
191
        $column1 = new Column('charfield1', Type::getType('string'));
192
        $column2 = new Column('charfield1', Type::getType('integer'));
193
194
        $c = new Comparator();
195
        self::assertEquals(['type'], $c->diffColumn($column1, $column2));
196
        self::assertEquals([], $c->diffColumn($column1, $column1));
197
    }
198
199
    public function testCompareColumnsMultipleTypeInstances() : void
200
    {
201
        $integerType1 = Type::getType('integer');
202
        Type::overrideType('integer', get_class($integerType1));
203
        $integerType2 = Type::getType('integer');
204
205
        $column1 = new Column('integerfield1', $integerType1);
206
        $column2 = new Column('integerfield1', $integerType2);
207
208
        $c = new Comparator();
209
        self::assertEquals([], $c->diffColumn($column1, $column2));
210
    }
211
212
    public function testCompareColumnsOverriddenType() : void
213
    {
214
        $oldStringInstance = Type::getType('string');
215
        $integerType       = Type::getType('integer');
216
217
        Type::overrideType('string', get_class($integerType));
218
        $overriddenStringType = Type::getType('string');
219
220
        Type::overrideType('string', get_class($oldStringInstance));
221
222
        $column1 = new Column('integerfield1', $integerType);
223
        $column2 = new Column('integerfield1', $overriddenStringType);
224
225
        $c = new Comparator();
226
        self::assertEquals([], $c->diffColumn($column1, $column2));
227
    }
228
229
    public function testCompareChangedColumnsChangeCustomSchemaOption() : void
230
    {
231
        $column1 = new Column('charfield1', Type::getType('string'));
232
        $column2 = new Column('charfield1', Type::getType('string'));
233
234
        $column1->setCustomSchemaOption('foo', 'bar');
235
        $column2->setCustomSchemaOption('foo', 'bar');
236
237
        $column1->setCustomSchemaOption('foo1', 'bar1');
238
        $column2->setCustomSchemaOption('foo2', 'bar2');
239
240
        $c = new Comparator();
241
        self::assertEquals(['foo1', 'foo2'], $c->diffColumn($column1, $column2));
242
        self::assertEquals([], $c->diffColumn($column1, $column1));
243
    }
244
245
    public function testCompareChangeColumnsMultipleNewColumnsRename() : void
246
    {
247
        $tableA = new Table('foo');
248
        $tableA->addColumn('datefield1', 'datetime');
249
250
        $tableB = new Table('foo');
251
        $tableB->addColumn('new_datefield1', 'datetime');
252
        $tableB->addColumn('new_datefield2', 'datetime');
253
254
        $c         = new Comparator();
255
        $tableDiff = $c->diffTable($tableA, $tableB);
256
257
        self::assertCount(1, $tableDiff->renamedColumns, 'we should have one rename datefield1 => new_datefield1.');
258
        self::assertArrayHasKey('datefield1', $tableDiff->renamedColumns, "'datefield1' should be set to be renamed to new_datefield1");
259
        self::assertCount(1, $tableDiff->addedColumns, "'new_datefield2' should be added");
260
        self::assertArrayHasKey('new_datefield2', $tableDiff->addedColumns, "'new_datefield2' should be added, not created through renaming!");
261
        self::assertCount(0, $tableDiff->removedColumns, 'Nothing should be removed.');
262
        self::assertCount(0, $tableDiff->changedColumns, 'Nothing should be changed as all fields old & new have diff names.');
263
    }
264
265
    public function testCompareRemovedIndex() : void
266
    {
267
        $schema1 = new Schema([
268
            'bugdb' => new Table(
269
                'bugdb',
270
                [
271
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
272
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
273
                ],
274
                [
275
                    'primary' => new Index(
276
                        'primary',
277
                        ['integerfield1'],
278
                        true
279
                    ),
280
                ]
281
            ),
282
        ]);
283
        $schema2 = new Schema([
284
            'bugdb' => new Table(
285
                'bugdb',
286
                [
287
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
288
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
289
                ]
290
            ),
291
        ]);
292
293
        $expected                                    = new SchemaDiff(
294
            [],
295
            [
296
                'bugdb' => new TableDiff(
297
                    'bugdb',
298
                    [],
299
                    [],
300
                    [],
301
                    [],
302
                    [],
303
                    [
304
                        'primary' => new Index(
305
                            'primary',
306
                            ['integerfield1'],
307
                            true
308
                        ),
309
                    ]
310
                ),
311
            ]
312
        );
313
        $expected->fromSchema                        = $schema1;
314
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
315
316
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
317
    }
318
319
    public function testCompareNewIndex() : void
320
    {
321
        $schema1 = new Schema([
322
            'bugdb' => new Table(
323
                'bugdb',
324
                [
325
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
326
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
327
                ]
328
            ),
329
        ]);
330
        $schema2 = new Schema([
331
            'bugdb' => new Table(
332
                'bugdb',
333
                [
334
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
335
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
336
                ],
337
                [
338
                    'primary' => new Index(
339
                        'primary',
340
                        ['integerfield1'],
341
                        true
342
                    ),
343
                ]
344
            ),
345
        ]);
346
347
        $expected                                    = new SchemaDiff(
348
            [],
349
            [
350
                'bugdb' => new TableDiff(
351
                    'bugdb',
352
                    [],
353
                    [],
354
                    [],
355
                    [
356
                        'primary' => new Index(
357
                            'primary',
358
                            ['integerfield1'],
359
                            true
360
                        ),
361
                    ]
362
                ),
363
            ]
364
        );
365
        $expected->fromSchema                        = $schema1;
366
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
367
368
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
369
    }
370
371
    public function testCompareChangedIndex() : void
372
    {
373
        $schema1 = new Schema([
374
            'bugdb' => new Table(
375
                'bugdb',
376
                [
377
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
378
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
379
                ],
380
                [
381
                    'primary' => new Index(
382
                        'primary',
383
                        ['integerfield1'],
384
                        true
385
                    ),
386
                ]
387
            ),
388
        ]);
389
        $schema2 = new Schema([
390
            'bugdb' => new Table(
391
                'bugdb',
392
                [
393
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
394
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
395
                ],
396
                [
397
                    'primary' => new Index(
398
                        'primary',
399
                        ['integerfield1', 'integerfield2'],
400
                        true
401
                    ),
402
                ]
403
            ),
404
        ]);
405
406
        $expected                                    = new SchemaDiff(
407
            [],
408
            [
409
                'bugdb' => new TableDiff(
410
                    'bugdb',
411
                    [],
412
                    [],
413
                    [],
414
                    [],
415
                    [
416
                        'primary' => new Index(
417
                            'primary',
418
                            [
419
                                'integerfield1',
420
                                'integerfield2',
421
                            ],
422
                            true
423
                        ),
424
                    ]
425
                ),
426
            ]
427
        );
428
        $expected->fromSchema                        = $schema1;
429
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
430
431
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
432
    }
433
434
    public function testCompareChangedIndexFieldPositions() : void
435
    {
436
        $schema1 = new Schema([
437
            'bugdb' => new Table(
438
                'bugdb',
439
                [
440
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
441
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
442
                ],
443
                [
444
                    'primary' => new Index('primary', ['integerfield1', 'integerfield2'], true),
445
                ]
446
            ),
447
        ]);
448
        $schema2 = new Schema([
449
            'bugdb' => new Table(
450
                'bugdb',
451
                [
452
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
453
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
454
                ],
455
                [
456
                    'primary' => new Index('primary', ['integerfield2', 'integerfield1'], true),
457
                ]
458
            ),
459
        ]);
460
461
        $expected                                    = new SchemaDiff(
462
            [],
463
            [
464
                'bugdb' => new TableDiff(
465
                    'bugdb',
466
                    [],
467
                    [],
468
                    [],
469
                    [],
470
                    [
471
                        'primary' => new Index('primary', ['integerfield2', 'integerfield1'], true),
472
                    ]
473
                ),
474
            ]
475
        );
476
        $expected->fromSchema                        = $schema1;
477
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
478
479
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
480
    }
481
482
    public function testCompareRenamePrimaryKeyAndChangeColumnsDropsItAndCreatesIt() : void
483
    {
484
        $table = new Table('users');
485
        $table->addColumn('id', 'integer', ['notnull' => true]);
486
        $table->addColumn('code', 'integer', ['notnull' => true]);
487
        $table->setPrimaryKey(['id'], 'users_pkey');
488
489
        $toTable = new Table('users');
490
        $toTable->addColumn('id', 'integer', ['notnull' => true]);
491
        $toTable->addColumn('code', 'integer', ['notnull' => true]);
492
        $toTable->setPrimaryKey(['id', 'code'], 'pkey_test');
493
494
        $c         = new Comparator();
495
        $tableDiff = $c->diffTable($table, $toTable);
496
497
        self::assertNotNull($tableDiff);
498
        self::assertCount(1, $tableDiff->addedIndexes);
499
        self::assertSame(['id', 'code'], $tableDiff->addedIndexes['pkey_test']->getColumns());
500
501
        self::assertCount(1, $tableDiff->removedIndexes);
502
        self::assertSame(['id'], $tableDiff->removedIndexes['users_pkey']->getColumns());
503
504
        $platform = new PostgreSQL94Platform();
505
        $sql      = $platform->getAlterTableSQL($tableDiff);
0 ignored issues
show
Bug introduced by
It seems like $tableDiff can also be of type false; however, parameter $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() does only seem to accept Doctrine\DBAL\Schema\TableDiff, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

505
        $sql      = $platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $tableDiff);
Loading history...
506
        self::assertSame('DROP INDEX users_pkey', $sql[0]);
507
        self::assertSame('ALTER TABLE users ADD PRIMARY KEY (id, code)', $sql[1]);
508
509
        $platform = new MySqlPlatform();
510
        $sql      = $platform->getAlterTableSQL($tableDiff);
0 ignored issues
show
Bug introduced by
It seems like $tableDiff can also be of type false; however, parameter $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() does only seem to accept Doctrine\DBAL\Schema\TableDiff, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

510
        $sql      = $platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $tableDiff);
Loading history...
511
        self::assertSame('ALTER TABLE users DROP PRIMARY KEY', $sql[0]);
512
        self::assertSame('ALTER TABLE users ADD PRIMARY KEY (id, code)', $sql[1]);
513
    }
514
515
    public function testCompareSequences() : void
516
    {
517
        $seq1 = new Sequence('foo', 1, 1);
518
        $seq2 = new Sequence('foo', 1, 2);
519
        $seq3 = new Sequence('foo', 2, 1);
520
        $seq4 = new Sequence('foo', '1', '1');
521
522
        $c = new Comparator();
523
524
        self::assertTrue($c->diffSequence($seq1, $seq2));
525
        self::assertTrue($c->diffSequence($seq1, $seq3));
526
        self::assertFalse($c->diffSequence($seq1, $seq4));
527
    }
528
529
    public function testRemovedSequence() : void
530
    {
531
        $schema1 = new Schema();
532
        $seq     = $schema1->createSequence('foo');
533
534
        $schema2 = new Schema();
535
536
        $c          = new Comparator();
537
        $diffSchema = $c->compare($schema1, $schema2);
538
539
        self::assertCount(1, $diffSchema->removedSequences);
540
        self::assertSame($seq, $diffSchema->removedSequences[0]);
541
    }
542
543
    public function testAddedSequence() : void
544
    {
545
        $schema1 = new Schema();
546
547
        $schema2 = new Schema();
548
        $seq     = $schema2->createSequence('foo');
549
550
        $c          = new Comparator();
551
        $diffSchema = $c->compare($schema1, $schema2);
552
553
        self::assertCount(1, $diffSchema->newSequences);
554
        self::assertSame($seq, $diffSchema->newSequences[0]);
555
    }
556
557
    public function testTableAddForeignKey() : void
558
    {
559
        $tableForeign = new Table('bar');
560
        $tableForeign->addColumn('id', 'integer');
561
562
        $table1 = new Table('foo');
563
        $table1->addColumn('fk', 'integer');
564
565
        $table2 = new Table('foo');
566
        $table2->addColumn('fk', 'integer');
567
        $table2->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
568
569
        $c         = new Comparator();
570
        $tableDiff = $c->diffTable($table1, $table2);
571
572
        self::assertInstanceOf(TableDiff::class, $tableDiff);
573
        self::assertCount(1, $tableDiff->addedForeignKeys);
574
    }
575
576
    public function testTableRemoveForeignKey() : void
577
    {
578
        $tableForeign = new Table('bar');
579
        $tableForeign->addColumn('id', 'integer');
580
581
        $table1 = new Table('foo');
582
        $table1->addColumn('fk', 'integer');
583
584
        $table2 = new Table('foo');
585
        $table2->addColumn('fk', 'integer');
586
        $table2->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
587
588
        $c         = new Comparator();
589
        $tableDiff = $c->diffTable($table2, $table1);
590
591
        self::assertInstanceOf(TableDiff::class, $tableDiff);
592
        self::assertCount(1, $tableDiff->removedForeignKeys);
593
    }
594
595
    public function testTableUpdateForeignKey() : void
596
    {
597
        $tableForeign = new Table('bar');
598
        $tableForeign->addColumn('id', 'integer');
599
600
        $table1 = new Table('foo');
601
        $table1->addColumn('fk', 'integer');
602
        $table1->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
603
604
        $table2 = new Table('foo');
605
        $table2->addColumn('fk', 'integer');
606
        $table2->addForeignKeyConstraint($tableForeign, ['fk'], ['id'], ['onUpdate' => 'CASCADE']);
607
608
        $c         = new Comparator();
609
        $tableDiff = $c->diffTable($table1, $table2);
610
611
        self::assertInstanceOf(TableDiff::class, $tableDiff);
612
        self::assertCount(1, $tableDiff->changedForeignKeys);
613
    }
614
615
    public function testMovedForeignKeyForeignTable() : void
616
    {
617
        $tableForeign = new Table('bar');
618
        $tableForeign->addColumn('id', 'integer');
619
620
        $tableForeign2 = new Table('bar2');
621
        $tableForeign2->addColumn('id', 'integer');
622
623
        $table1 = new Table('foo');
624
        $table1->addColumn('fk', 'integer');
625
        $table1->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
626
627
        $table2 = new Table('foo');
628
        $table2->addColumn('fk', 'integer');
629
        $table2->addForeignKeyConstraint($tableForeign2, ['fk'], ['id']);
630
631
        $c         = new Comparator();
632
        $tableDiff = $c->diffTable($table1, $table2);
633
634
        self::assertInstanceOf(TableDiff::class, $tableDiff);
635
        self::assertCount(1, $tableDiff->changedForeignKeys);
636
    }
637
638
    public function testTablesCaseInsensitive() : void
639
    {
640
        $schemaA = new Schema();
641
        $schemaA->createTable('foo');
642
        $schemaA->createTable('bAr');
643
        $schemaA->createTable('BAZ');
644
        $schemaA->createTable('new');
645
646
        $schemaB = new Schema();
647
        $schemaB->createTable('FOO');
648
        $schemaB->createTable('bar');
649
        $schemaB->createTable('Baz');
650
        $schemaB->createTable('old');
651
652
        $c    = new Comparator();
653
        $diff = $c->compare($schemaA, $schemaB);
654
655
        $this->assertSchemaTableChangeCount($diff, 1, 0, 1);
656
    }
657
658
    public function testSequencesCaseInsensitive() : void
659
    {
660
        $schemaA = new Schema();
661
        $schemaA->createSequence('foo');
662
        $schemaA->createSequence('BAR');
663
        $schemaA->createSequence('Baz');
664
        $schemaA->createSequence('new');
665
666
        $schemaB = new Schema();
667
        $schemaB->createSequence('FOO');
668
        $schemaB->createSequence('Bar');
669
        $schemaB->createSequence('baz');
670
        $schemaB->createSequence('old');
671
672
        $c    = new Comparator();
673
        $diff = $c->compare($schemaA, $schemaB);
674
675
        $this->assertSchemaSequenceChangeCount($diff, 1, 0, 1);
676
    }
677
678
    public function testCompareColumnCompareCaseInsensitive() : void
679
    {
680
        $tableA = new Table('foo');
681
        $tableA->addColumn('id', 'integer');
682
683
        $tableB = new Table('foo');
684
        $tableB->addColumn('ID', 'integer');
685
686
        $c         = new Comparator();
687
        $tableDiff = $c->diffTable($tableA, $tableB);
688
689
        self::assertFalse($tableDiff);
690
    }
691
692
    public function testCompareIndexBasedOnPropertiesNotName() : void
693
    {
694
        $tableA = new Table('foo');
695
        $tableA->addColumn('id', 'integer');
696
        $tableA->addIndex(['id'], 'foo_bar_idx');
697
698
        $tableB = new Table('foo');
699
        $tableB->addColumn('ID', 'integer');
700
        $tableB->addIndex(['id'], 'bar_foo_idx');
701
702
        $c                                        = new Comparator();
703
        $tableDiff                                = new TableDiff('foo');
704
        $tableDiff->fromTable                     = $tableA;
705
        $tableDiff->renamedIndexes['foo_bar_idx'] = new Index('bar_foo_idx', ['id']);
706
707
        self::assertEquals(
708
            $tableDiff,
709
            $c->diffTable($tableA, $tableB)
710
        );
711
    }
712
713
    public function testCompareForeignKeyBasedOnPropertiesNotName() : void
714
    {
715
        $tableA = new Table('foo');
716
        $tableA->addColumn('id', 'integer');
717
        $tableA->addNamedForeignKeyConstraint('foo_constraint', 'bar', ['id'], ['id']);
718
719
        $tableB = new Table('foo');
720
        $tableB->addColumn('ID', 'integer');
721
        $tableB->addNamedForeignKeyConstraint('bar_constraint', 'bar', ['id'], ['id']);
722
723
        $c         = new Comparator();
724
        $tableDiff = $c->diffTable($tableA, $tableB);
725
726
        self::assertFalse($tableDiff);
727
    }
728
729
    public function testCompareForeignKeyRestrictNoActionAreTheSame() : void
730
    {
731
        $fk1 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk1', ['onDelete' => 'NO ACTION']);
732
        $fk2 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk1', ['onDelete' => 'RESTRICT']);
733
734
        $c = new Comparator();
735
        self::assertFalse($c->diffForeignKey($fk1, $fk2));
736
    }
737
738
    /**
739
     * @group DBAL-492
740
     */
741
    public function testCompareForeignKeyNamesUnqualifiedAsNoSchemaInformationIsAvailable() : void
742
    {
743
        $fk1 = new ForeignKeyConstraint(['foo'], 'foo.bar', ['baz'], 'fk1');
744
        $fk2 = new ForeignKeyConstraint(['foo'], 'baz.bar', ['baz'], 'fk1');
745
746
        $c = new Comparator();
747
        self::assertFalse($c->diffForeignKey($fk1, $fk2));
748
    }
749
750
    public function testDetectRenameColumn() : void
751
    {
752
        $tableA = new Table('foo');
753
        $tableA->addColumn('foo', 'integer');
754
755
        $tableB = new Table('foo');
756
        $tableB->addColumn('bar', 'integer');
757
758
        $c         = new Comparator();
759
        $tableDiff = $c->diffTable($tableA, $tableB);
760
761
        self::assertCount(0, $tableDiff->addedColumns);
762
        self::assertCount(0, $tableDiff->removedColumns);
763
        self::assertArrayHasKey('foo', $tableDiff->renamedColumns);
764
        self::assertEquals('bar', $tableDiff->renamedColumns['foo']->getName());
765
    }
766
767
    /**
768
     * You can easily have ambiguities in the column renaming. If these
769
     * are detected no renaming should take place, instead adding and dropping
770
     * should be used exclusively.
771
     *
772
     * @group DBAL-24
773
     */
774
    public function testDetectRenameColumnAmbiguous() : void
775
    {
776
        $tableA = new Table('foo');
777
        $tableA->addColumn('foo', 'integer');
778
        $tableA->addColumn('bar', 'integer');
779
780
        $tableB = new Table('foo');
781
        $tableB->addColumn('baz', 'integer');
782
783
        $c         = new Comparator();
784
        $tableDiff = $c->diffTable($tableA, $tableB);
785
786
        self::assertCount(1, $tableDiff->addedColumns, "'baz' should be added, not created through renaming!");
787
        self::assertArrayHasKey('baz', $tableDiff->addedColumns, "'baz' should be added, not created through renaming!");
788
        self::assertCount(2, $tableDiff->removedColumns, "'foo' and 'bar' should both be dropped, an ambiguity exists which one could be renamed to 'baz'.");
789
        self::assertArrayHasKey('foo', $tableDiff->removedColumns, "'foo' should be removed.");
790
        self::assertArrayHasKey('bar', $tableDiff->removedColumns, "'bar' should be removed.");
791
        self::assertCount(0, $tableDiff->renamedColumns, 'no renamings should take place.');
792
    }
793
794
    /**
795
     * @group DBAL-1063
796
     */
797
    public function testDetectRenameIndex() : void
798
    {
799
        $table1 = new Table('foo');
800
        $table1->addColumn('foo', 'integer');
801
802
        $table2 = clone $table1;
803
804
        $table1->addIndex(['foo'], 'idx_foo');
805
806
        $table2->addIndex(['foo'], 'idx_bar');
807
808
        $comparator = new Comparator();
809
        $tableDiff  = $comparator->diffTable($table1, $table2);
810
811
        self::assertCount(0, $tableDiff->addedIndexes);
812
        self::assertCount(0, $tableDiff->removedIndexes);
813
        self::assertArrayHasKey('idx_foo', $tableDiff->renamedIndexes);
814
        self::assertEquals('idx_bar', $tableDiff->renamedIndexes['idx_foo']->getName());
815
    }
816
817
    /**
818
     * You can easily have ambiguities in the index renaming. If these
819
     * are detected no renaming should take place, instead adding and dropping
820
     * should be used exclusively.
821
     *
822
     * @group DBAL-1063
823
     */
824
    public function testDetectRenameIndexAmbiguous() : void
825
    {
826
        $table1 = new Table('foo');
827
        $table1->addColumn('foo', 'integer');
828
829
        $table2 = clone $table1;
830
831
        $table1->addIndex(['foo'], 'idx_foo');
832
        $table1->addIndex(['foo'], 'idx_bar');
833
834
        $table2->addIndex(['foo'], 'idx_baz');
835
836
        $comparator = new Comparator();
837
        $tableDiff  = $comparator->diffTable($table1, $table2);
838
839
        self::assertCount(1, $tableDiff->addedIndexes);
840
        self::assertArrayHasKey('idx_baz', $tableDiff->addedIndexes);
841
        self::assertCount(2, $tableDiff->removedIndexes);
842
        self::assertArrayHasKey('idx_foo', $tableDiff->removedIndexes);
843
        self::assertArrayHasKey('idx_bar', $tableDiff->removedIndexes);
844
        self::assertCount(0, $tableDiff->renamedIndexes);
845
    }
846
847
    public function testDetectChangeIdentifierType() : void
848
    {
849
        $this->markTestSkipped('DBAL-2 was reopened, this test cannot work anymore.');
850
851
        $tableA = new Table('foo');
852
        $tableA->addColumn('id', 'integer', ['autoincrement' => false]);
853
854
        $tableB = new Table('foo');
855
        $tableB->addColumn('id', 'integer', ['autoincrement' => true]);
856
857
        $c         = new Comparator();
858
        $tableDiff = $c->diffTable($tableA, $tableB);
859
860
        self::assertInstanceOf(TableDiff::class, $tableDiff);
861
        self::assertArrayHasKey('id', $tableDiff->changedColumns);
862
    }
863
864
    /**
865
     * @group DBAL-105
866
     */
867
    public function testDiff() : void
868
    {
869
        $table = new Table('twitter_users');
870
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
871
        $table->addColumn('twitterId', 'integer');
872
        $table->addColumn('displayName', 'string');
873
        $table->setPrimaryKey(['id']);
874
875
        $newtable = new Table('twitter_users');
876
        $newtable->addColumn('id', 'integer', ['autoincrement' => true]);
877
        $newtable->addColumn('twitter_id', 'integer');
878
        $newtable->addColumn('display_name', 'string');
879
        $newtable->addColumn('logged_in_at', 'datetime');
880
        $newtable->setPrimaryKey(['id']);
881
882
        $c         = new Comparator();
883
        $tableDiff = $c->diffTable($table, $newtable);
884
885
        self::assertInstanceOf(TableDiff::class, $tableDiff);
886
        self::assertEquals(['twitterid', 'displayname'], array_keys($tableDiff->renamedColumns));
887
        self::assertEquals(['logged_in_at'], array_keys($tableDiff->addedColumns));
888
        self::assertCount(0, $tableDiff->removedColumns);
889
    }
890
891
    /**
892
     * @group DBAL-112
893
     */
894
    public function testChangedSequence() : void
895
    {
896
        $schema   = new Schema();
897
        $sequence = $schema->createSequence('baz');
0 ignored issues
show
Unused Code introduced by
The assignment to $sequence is dead and can be removed.
Loading history...
898
899
        $schemaNew = clone $schema;
900
        $schemaNew->getSequence('baz')->setAllocationSize(20);
901
902
        $c    = new Comparator();
903
        $diff = $c->compare($schema, $schemaNew);
904
905
        self::assertSame($diff->changedSequences[0], $schemaNew->getSequence('baz'));
906
    }
907
908
    /**
909
     * @group DBAL-106
910
     */
911
    public function testDiffDecimalWithNullPrecision() : void
912
    {
913
        $column = new Column('foo', Type::getType('decimal'));
914
        $column->setPrecision(null);
915
916
        $column2 = new Column('foo', Type::getType('decimal'));
917
918
        $c = new Comparator();
919
        self::assertEquals([], $c->diffColumn($column, $column2));
920
    }
921
922
    /**
923
     * @group DBAL-204
924
     */
925
    public function testFqnSchemaComparison() : void
926
    {
927
        $config = new SchemaConfig();
928
        $config->setName('foo');
929
930
        $oldSchema = new Schema([], [], $config);
931
        $oldSchema->createTable('bar');
932
933
        $newSchema = new Schema([], [], $config);
934
        $newSchema->createTable('foo.bar');
935
936
        $expected             = new SchemaDiff();
937
        $expected->fromSchema = $oldSchema;
938
939
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
940
    }
941
942
    /**
943
     * @group DBAL-669
944
     */
945
    public function testNamespacesComparison() : void
946
    {
947
        $config = new SchemaConfig();
948
        $config->setName('schemaName');
949
950
        $oldSchema = new Schema([], [], $config);
951
        $oldSchema->createTable('taz');
952
        $oldSchema->createTable('war.tab');
953
954
        $newSchema = new Schema([], [], $config);
955
        $newSchema->createTable('bar.tab');
956
        $newSchema->createTable('baz.tab');
957
        $newSchema->createTable('war.tab');
958
959
        $expected                = new SchemaDiff();
960
        $expected->fromSchema    = $oldSchema;
961
        $expected->newNamespaces = ['bar' => 'bar', 'baz' => 'baz'];
962
963
        $diff = Comparator::compareSchemas($oldSchema, $newSchema);
964
965
        self::assertEquals(['bar' => 'bar', 'baz' => 'baz'], $diff->newNamespaces);
966
        self::assertCount(2, $diff->newTables);
967
    }
968
969
    /**
970
     * @group DBAL-204
971
     */
972
    public function testFqnSchemaComparisonDifferentSchemaNameButSameTableNoDiff() : void
973
    {
974
        $config = new SchemaConfig();
975
        $config->setName('foo');
976
977
        $oldSchema = new Schema([], [], $config);
978
        $oldSchema->createTable('foo.bar');
979
980
        $newSchema = new Schema();
981
        $newSchema->createTable('bar');
982
983
        $expected             = new SchemaDiff();
984
        $expected->fromSchema = $oldSchema;
985
986
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
987
    }
988
989
    /**
990
     * @group DBAL-204
991
     */
992
    public function testFqnSchemaComparisonNoSchemaSame() : void
993
    {
994
        $config = new SchemaConfig();
995
        $config->setName('foo');
996
        $oldSchema = new Schema([], [], $config);
997
        $oldSchema->createTable('bar');
998
999
        $newSchema = new Schema();
1000
        $newSchema->createTable('bar');
1001
1002
        $expected             = new SchemaDiff();
1003
        $expected->fromSchema = $oldSchema;
1004
1005
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
1006
    }
1007
1008
    /**
1009
     * @group DDC-1657
1010
     */
1011
    public function testAutoIncrementSequences() : void
1012
    {
1013
        $oldSchema = new Schema();
1014
        $table     = $oldSchema->createTable('foo');
1015
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
1016
        $table->setPrimaryKey(['id']);
1017
        $oldSchema->createSequence('foo_id_seq');
1018
1019
        $newSchema = new Schema();
1020
        $table     = $newSchema->createTable('foo');
1021
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
1022
        $table->setPrimaryKey(['id']);
1023
1024
        $c    = new Comparator();
1025
        $diff = $c->compare($oldSchema, $newSchema);
1026
1027
        self::assertCount(0, $diff->removedSequences);
1028
    }
1029
1030
    /**
1031
     * Check that added autoincrement sequence is not populated in newSequences
1032
     *
1033
     * @group DBAL-562
1034
     */
1035
    public function testAutoIncrementNoSequences() : void
1036
    {
1037
        $oldSchema = new Schema();
1038
        $table     = $oldSchema->createTable('foo');
1039
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
1040
        $table->setPrimaryKey(['id']);
1041
1042
        $newSchema = new Schema();
1043
        $table     = $newSchema->createTable('foo');
1044
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
1045
        $table->setPrimaryKey(['id']);
1046
        $newSchema->createSequence('foo_id_seq');
1047
1048
        $c    = new Comparator();
1049
        $diff = $c->compare($oldSchema, $newSchema);
1050
1051
        self::assertCount(0, $diff->newSequences);
1052
    }
1053
1054
    /**
1055
     * You can get multiple drops for a FK when a table referenced by a foreign
1056
     * key is deleted, as this FK is referenced twice, once on the orphanedForeignKeys
1057
     * array because of the dropped table, and once on changedTables array. We
1058
     * now check that the key is present once.
1059
     */
1060
    public function testAvoidMultipleDropForeignKey() : void
1061
    {
1062
        $oldSchema = new Schema();
1063
1064
        $tableA = $oldSchema->createTable('table_a');
1065
        $tableA->addColumn('id', 'integer');
1066
1067
        $tableB = $oldSchema->createTable('table_b');
1068
        $tableB->addColumn('id', 'integer');
1069
1070
        $tableC = $oldSchema->createTable('table_c');
1071
        $tableC->addColumn('id', 'integer');
1072
        $tableC->addColumn('table_a_id', 'integer');
1073
        $tableC->addColumn('table_b_id', 'integer');
1074
1075
        $tableC->addForeignKeyConstraint($tableA, ['table_a_id'], ['id']);
1076
        $tableC->addForeignKeyConstraint($tableB, ['table_b_id'], ['id']);
1077
1078
        $newSchema = new Schema();
1079
1080
        $tableB = $newSchema->createTable('table_b');
1081
        $tableB->addColumn('id', 'integer');
1082
1083
        $tableC = $newSchema->createTable('table_c');
1084
        $tableC->addColumn('id', 'integer');
1085
1086
        $comparator = new Comparator();
1087
        $schemaDiff = $comparator->compare($oldSchema, $newSchema);
1088
1089
        self::assertCount(1, $schemaDiff->changedTables['table_c']->removedForeignKeys);
1090
        self::assertCount(1, $schemaDiff->orphanedForeignKeys);
1091
    }
1092
1093
    public function testCompareChangedColumn() : void
1094
    {
1095
        $oldSchema = new Schema();
1096
1097
        $tableFoo = $oldSchema->createTable('foo');
1098
        $tableFoo->addColumn('id', 'integer');
1099
1100
        $newSchema = new Schema();
1101
        $table     = $newSchema->createTable('foo');
1102
        $table->addColumn('id', 'string');
1103
1104
        $expected                      = new SchemaDiff();
1105
        $expected->fromSchema          = $oldSchema;
1106
        $tableDiff                     = $expected->changedTables['foo'] = new TableDiff('foo');
1107
        $tableDiff->fromTable          = $tableFoo;
1108
        $columnDiff                    = $tableDiff->changedColumns['id'] = new ColumnDiff('id', $table->getColumn('id'));
1109
        $columnDiff->fromColumn        = $tableFoo->getColumn('id');
1110
        $columnDiff->changedProperties = ['type'];
1111
1112
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
1113
    }
1114
1115
    public function testCompareChangedBinaryColumn() : void
1116
    {
1117
        $oldSchema = new Schema();
1118
1119
        $tableFoo = $oldSchema->createTable('foo');
1120
        $tableFoo->addColumn('id', 'binary');
1121
1122
        $newSchema = new Schema();
1123
        $table     = $newSchema->createTable('foo');
1124
        $table->addColumn('id', 'binary', ['length' => 42, 'fixed' => true]);
1125
1126
        $expected                      = new SchemaDiff();
1127
        $expected->fromSchema          = $oldSchema;
1128
        $tableDiff                     = $expected->changedTables['foo'] = new TableDiff('foo');
1129
        $tableDiff->fromTable          = $tableFoo;
1130
        $columnDiff                    = $tableDiff->changedColumns['id'] = new ColumnDiff('id', $table->getColumn('id'));
1131
        $columnDiff->fromColumn        = $tableFoo->getColumn('id');
1132
        $columnDiff->changedProperties = ['length', 'fixed'];
1133
1134
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
1135
    }
1136
1137
    /**
1138
     * @group DBAL-617
1139
     */
1140
    public function testCompareQuotedAndUnquotedForeignKeyColumns() : void
1141
    {
1142
        $fk1 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk1', ['onDelete' => 'NO ACTION']);
1143
        $fk2 = new ForeignKeyConstraint(['`foo`'], 'bar', ['`baz`'], 'fk1', ['onDelete' => 'NO ACTION']);
1144
1145
        $comparator = new Comparator();
1146
        $diff       = $comparator->diffForeignKey($fk1, $fk2);
1147
1148
        self::assertFalse($diff);
1149
    }
1150
1151
    public function assertSchemaTableChangeCount(SchemaDiff $diff, int $newTableCount = 0, int $changeTableCount = 0, int $removeTableCount = 0) : void
1152
    {
1153
        self::assertCount($newTableCount, $diff->newTables);
1154
        self::assertCount($changeTableCount, $diff->changedTables);
1155
        self::assertCount($removeTableCount, $diff->removedTables);
1156
    }
1157
1158
    public function assertSchemaSequenceChangeCount(
1159
        SchemaDiff $diff,
1160
        int $newSequenceCount = 0,
1161
        int $changeSequenceCount = 0,
1162
        int $removeSequenceCount = 0
1163
    ) : void {
1164
        self::assertCount($newSequenceCount, $diff->newSequences, 'Expected number of new sequences is wrong.');
1165
        self::assertCount($changeSequenceCount, $diff->changedSequences, 'Expected number of changed sequences is wrong.');
1166
        self::assertCount($removeSequenceCount, $diff->removedSequences, 'Expected number of removed sequences is wrong.');
1167
    }
1168
1169
    public function testDiffColumnPlatformOptions() : void
1170
    {
1171
        $column1 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'bar' => 'bar']]);
1172
        $column2 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'foobar' => 'foobar']]);
1173
        $column3 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'bar' => 'rab']]);
1174
        $column4 = new Column('foo', Type::getType('string'));
1175
1176
        $comparator = new Comparator();
1177
1178
        self::assertEquals([], $comparator->diffColumn($column1, $column2));
1179
        self::assertEquals([], $comparator->diffColumn($column2, $column1));
1180
        self::assertEquals(['bar'], $comparator->diffColumn($column1, $column3));
1181
        self::assertEquals(['bar'], $comparator->diffColumn($column3, $column1));
1182
        self::assertEquals([], $comparator->diffColumn($column1, $column4));
1183
        self::assertEquals([], $comparator->diffColumn($column4, $column1));
1184
    }
1185
1186
    public function testComplexDiffColumn() : void
1187
    {
1188
        $column1 = new Column('foo', Type::getType('string'), [
1189
            'platformOptions' => ['foo' => 'foo'],
1190
            'customSchemaOptions' => ['foo' => 'bar'],
1191
        ]);
1192
1193
        $column2 = new Column('foo', Type::getType('string'), [
1194
            'platformOptions' => ['foo' => 'bar'],
1195
        ]);
1196
1197
        $comparator = new Comparator();
1198
1199
        self::assertEquals([], $comparator->diffColumn($column1, $column2));
1200
        self::assertEquals([], $comparator->diffColumn($column2, $column1));
1201
    }
1202
1203
    /**
1204
     * @group DBAL-669
1205
     */
1206
    public function testComparesNamespaces() : void
1207
    {
1208
        $comparator = new Comparator();
1209
        $fromSchema = $this->getMockBuilder(Schema::class)
1210
            ->onlyMethods(['getNamespaces', 'hasNamespace'])
1211
            ->getMock();
1212
        $toSchema   = $this->getMockBuilder(Schema::class)
1213
            ->onlyMethods(['getNamespaces', 'hasNamespace'])
1214
            ->getMock();
1215
1216
        $fromSchema->expects($this->once())
1217
            ->method('getNamespaces')
1218
            ->will($this->returnValue(['foo', 'bar']));
1219
1220
        $fromSchema->expects($this->at(0))
1221
            ->method('hasNamespace')
1222
            ->with('bar')
1223
            ->will($this->returnValue(true));
1224
1225
        $fromSchema->expects($this->at(1))
1226
            ->method('hasNamespace')
1227
            ->with('baz')
1228
            ->will($this->returnValue(false));
1229
1230
        $toSchema->expects($this->once())
1231
            ->method('getNamespaces')
1232
            ->will($this->returnValue(['bar', 'baz']));
1233
1234
        $toSchema->expects($this->at(1))
1235
            ->method('hasNamespace')
1236
            ->with('foo')
1237
            ->will($this->returnValue(false));
1238
1239
        $toSchema->expects($this->at(2))
1240
            ->method('hasNamespace')
1241
            ->with('bar')
1242
            ->will($this->returnValue(true));
1243
1244
        $expected                    = new SchemaDiff();
1245
        $expected->fromSchema        = $fromSchema;
1246
        $expected->newNamespaces     = ['baz' => 'baz'];
1247
        $expected->removedNamespaces = ['foo' => 'foo'];
1248
1249
        self::assertEquals($expected, $comparator->compare($fromSchema, $toSchema));
1250
    }
1251
1252
    public function testCompareGuidColumns() : void
1253
    {
1254
        $comparator = new Comparator();
1255
1256
        $column1 = new Column('foo', Type::getType('guid'), ['comment' => 'GUID 1']);
1257
        $column2 = new Column(
1258
            'foo',
1259
            Type::getType('guid'),
1260
            ['notnull' => false, 'length' => '36', 'fixed' => true, 'default' => 'NEWID()', 'comment' => 'GUID 2.']
1261
        );
1262
1263
        self::assertEquals(['notnull', 'default', 'comment'], $comparator->diffColumn($column1, $column2));
1264
        self::assertEquals(['notnull', 'default', 'comment'], $comparator->diffColumn($column2, $column1));
1265
    }
1266
1267
    /**
1268
     * @group DBAL-1009
1269
     * @dataProvider getCompareColumnComments
1270
     */
1271
    public function testCompareColumnComments(?string $comment1, ?string $comment2, bool $equals) : void
1272
    {
1273
        $column1 = new Column('foo', Type::getType('integer'), ['comment' => $comment1]);
1274
        $column2 = new Column('foo', Type::getType('integer'), ['comment' => $comment2]);
1275
1276
        $comparator = new Comparator();
1277
1278
        $expectedDiff = $equals ? [] : ['comment'];
1279
1280
        $actualDiff = $comparator->diffColumn($column1, $column2);
1281
1282
        self::assertSame($expectedDiff, $actualDiff);
1283
1284
        $actualDiff = $comparator->diffColumn($column2, $column1);
1285
1286
        self::assertSame($expectedDiff, $actualDiff);
1287
    }
1288
1289
    /**
1290
     * @return mixed[][]
1291
     */
1292
    public static function getCompareColumnComments() : iterable
1293
    {
1294
        return [
1295
            [null, null, true],
1296
            ['', '', true],
1297
            [' ', ' ', true],
1298
            ['0', '0', true],
1299
            ['foo', 'foo', true],
1300
1301
            [null, '', true],
1302
            [null, ' ', false],
1303
            [null, '0', false],
1304
            [null, 'foo', false],
1305
1306
            ['', ' ', false],
1307
            ['', '0', false],
1308
            ['', 'foo', false],
1309
1310
            [' ', '0', false],
1311
            [' ', 'foo', false],
1312
1313
            ['0', 'foo', false],
1314
        ];
1315
    }
1316
1317
    public function testForeignKeyRemovalWithRenamedLocalColumn() : void
1318
    {
1319
        $fromSchema = new Schema([
1320
            'table1' => new Table(
1321
                'table1',
1322
                [
1323
                    'id' => new Column('id', Type::getType('integer')),
1324
                ]
1325
            ),
1326
            'table2' => new Table(
1327
                'table2',
1328
                [
1329
                    'id' => new Column('id', Type::getType('integer')),
1330
                    'id_table1' => new Column('id_table1', Type::getType('integer')),
1331
                ],
1332
                [],
1333
                [
1334
                    new ForeignKeyConstraint(['id_table1'], 'table1', ['id'], 'fk_table2_table1'),
1335
                ]
1336
            ),
1337
        ]);
1338
        $toSchema   = new Schema([
1339
            'table2' => new Table(
1340
                'table2',
1341
                [
1342
                    'id' => new Column('id', Type::getType('integer')),
1343
                    'id_table3' => new Column('id_table3', Type::getType('integer')),
1344
                ],
1345
                [],
1346
                [
1347
                    new ForeignKeyConstraint(['id_table3'], 'table3', ['id'], 'fk_table2_table3'),
1348
                ]
1349
            ),
1350
            'table3' => new Table(
1351
                'table3',
1352
                [
1353
                    'id' => new Column('id', Type::getType('integer')),
1354
                ]
1355
            ),
1356
        ]);
1357
        $actual     = Comparator::compareSchemas($fromSchema, $toSchema);
1358
        self::assertArrayHasKey('table2', $actual->changedTables);
1359
        self::assertCount(1, $actual->orphanedForeignKeys);
1360
        self::assertEquals('fk_table2_table1', $actual->orphanedForeignKeys[0]->getName());
1361
        self::assertCount(1, $actual->changedTables['table2']->addedForeignKeys, 'FK to table3 should be added.');
1362
        self::assertEquals('table3', $actual->changedTables['table2']->addedForeignKeys[0]->getForeignTableName());
1363
    }
1364
}
1365