Completed
Pull Request — master (#3610)
by Sergei
03:03
created

ComparatorTest   F

Complexity

Total Complexity 58

Size/Duplication

Total Lines 1309
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 17

Importance

Changes 0
Metric Value
wmc 58
lcom 2
cbo 17
dl 0
loc 1309
rs 3.36
c 0
b 0
f 0

57 Methods

Rating   Name   Duplication   Size   Complexity  
A testCompareSame1() 0 23 1
A testCompareSame2() 0 25 1
A testCompareMissingTable() 0 13 1
A testCompareNewTable() 0 13 1
A testCompareOnlyAutoincrementChanged() 0 10 1
A testCompareMissingField() 0 37 1
A testCompareNewField() 0 36 1
A testCompareChangedColumnsChangeType() 0 9 1
A testCompareColumnsMultipleTypeInstances() 0 12 1
A testCompareColumnsOverriddenType() 0 16 1
A testCompareChangedColumnsChangeCustomSchemaOption() 0 15 1
A testCompareChangeColumnsMultipleNewColumnsRename() 0 19 1
A testCompareRemovedIndex() 0 53 1
A testCompareNewIndex() 0 51 1
B testCompareChangedIndex() 0 62 1
A testCompareChangedIndexFieldPositions() 0 47 1
A testCompareSequences() 0 11 1
A testRemovedSequence() 0 13 1
A testAddedSequence() 0 13 1
A testTableAddForeignKey() 0 18 1
A testTableRemoveForeignKey() 0 18 1
A testTableUpdateForeignKey() 0 19 1
A testMovedForeignKeyForeignTable() 0 22 1
A testTablesCaseInsensitive() 0 19 1
A testSequencesCaseInsensitive() 0 19 1
A testCompareColumnCompareCaseInsensitive() 0 13 1
A testCompareIndexBasedOnPropertiesNotName() 0 20 1
A testCompareForeignKeyBasedOnPropertiesNotName() 0 15 1
A testCompareForeignKeyRestrictNoActionAreTheSame() 0 8 1
A testCompareForeignKeyNamesUnqualifiedAsNoSchemaInformationIsAvailable() 0 8 1
A testDetectRenameColumn() 0 16 1
A testDetectRenameColumnAmbiguous() 0 19 1
A testDetectRenameIndex() 0 19 1
A testDetectRenameIndexAmbiguous() 0 22 1
A testDetectChangeIdentifierType() 0 16 1
A testDiff() 0 23 1
A testChangedSequence() 0 13 1
A testDiffDecimalWithNullPrecision() 0 10 1
A testFqnSchemaComparison() 0 16 1
A testNamespacesComparison() 0 23 1
A testFqnSchemaComparisonDifferentSchemaNameButSameTableNoDiff() 0 16 1
A testFqnSchemaComparisonNoSchemaSame() 0 15 1
A testAutoIncrementSequences() 0 18 1
A testAutoIncrementNoSequences() 0 18 1
A testAvoidMultipleDropForeignKey() 0 32 1
A testCompareChangedColumn() 0 21 1
A testCompareChangedBinaryColumn() 0 21 1
A testCompareQuotedAndUnquotedForeignKeyColumns() 0 10 1
A assertSchemaTableChangeCount() 0 6 1
A assertSchemaSequenceChangeCount() 0 10 1
A testDiffColumnPlatformOptions() 0 16 1
A testComplexDiffColumn() 0 16 1
A testComparesNamespaces() 0 45 1
A testCompareGuidColumns() 0 14 1
A testCompareColumnComments() 0 17 2
A getCompareColumnComments() 0 24 1
A testForeignKeyRemovalWithRenamedLocalColumn() 0 49 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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
declare(strict_types=1);
4
5
namespace Doctrine\Tests\DBAL\Schema;
6
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");
0 ignored issues
show
Documentation introduced by
$tableDiff->addedColumns is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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.');
0 ignored issues
show
Documentation introduced by
$tableDiff->removedColumns is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
262
        self::assertCount(0, $tableDiff->changedColumns, 'Nothing should be changed as all fields old & new have diff names.');
0 ignored issues
show
Documentation introduced by
$tableDiff->changedColumns is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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 testCompareSequences() : void
483
    {
484
        $seq1 = new Sequence('foo', 1, 1);
485
        $seq2 = new Sequence('foo', 1, 2);
486
        $seq3 = new Sequence('foo', 2, 1);
487
488
        $c = new Comparator();
489
490
        self::assertTrue($c->diffSequence($seq1, $seq2));
491
        self::assertTrue($c->diffSequence($seq1, $seq3));
492
    }
493
494
    public function testRemovedSequence() : void
495
    {
496
        $schema1 = new Schema();
497
        $seq     = $schema1->createSequence('foo');
498
499
        $schema2 = new Schema();
500
501
        $c          = new Comparator();
502
        $diffSchema = $c->compare($schema1, $schema2);
503
504
        self::assertCount(1, $diffSchema->removedSequences);
0 ignored issues
show
Documentation introduced by
$diffSchema->removedSequences is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
505
        self::assertSame($seq, $diffSchema->removedSequences[0]);
506
    }
507
508
    public function testAddedSequence() : void
509
    {
510
        $schema1 = new Schema();
511
512
        $schema2 = new Schema();
513
        $seq     = $schema2->createSequence('foo');
514
515
        $c          = new Comparator();
516
        $diffSchema = $c->compare($schema1, $schema2);
517
518
        self::assertCount(1, $diffSchema->newSequences);
0 ignored issues
show
Documentation introduced by
$diffSchema->newSequences is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
519
        self::assertSame($seq, $diffSchema->newSequences[0]);
520
    }
521
522
    public function testTableAddForeignKey() : void
523
    {
524
        $tableForeign = new Table('bar');
525
        $tableForeign->addColumn('id', 'integer');
526
527
        $table1 = new Table('foo');
528
        $table1->addColumn('fk', 'integer');
529
530
        $table2 = new Table('foo');
531
        $table2->addColumn('fk', 'integer');
532
        $table2->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
533
534
        $c         = new Comparator();
535
        $tableDiff = $c->diffTable($table1, $table2);
536
537
        self::assertInstanceOf(TableDiff::class, $tableDiff);
538
        self::assertCount(1, $tableDiff->addedForeignKeys);
539
    }
540
541
    public function testTableRemoveForeignKey() : void
542
    {
543
        $tableForeign = new Table('bar');
544
        $tableForeign->addColumn('id', 'integer');
545
546
        $table1 = new Table('foo');
547
        $table1->addColumn('fk', 'integer');
548
549
        $table2 = new Table('foo');
550
        $table2->addColumn('fk', 'integer');
551
        $table2->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
552
553
        $c         = new Comparator();
554
        $tableDiff = $c->diffTable($table2, $table1);
555
556
        self::assertInstanceOf(TableDiff::class, $tableDiff);
557
        self::assertCount(1, $tableDiff->removedForeignKeys);
558
    }
559
560
    public function testTableUpdateForeignKey() : void
561
    {
562
        $tableForeign = new Table('bar');
563
        $tableForeign->addColumn('id', 'integer');
564
565
        $table1 = new Table('foo');
566
        $table1->addColumn('fk', 'integer');
567
        $table1->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
568
569
        $table2 = new Table('foo');
570
        $table2->addColumn('fk', 'integer');
571
        $table2->addForeignKeyConstraint($tableForeign, ['fk'], ['id'], ['onUpdate' => 'CASCADE']);
572
573
        $c         = new Comparator();
574
        $tableDiff = $c->diffTable($table1, $table2);
575
576
        self::assertInstanceOf(TableDiff::class, $tableDiff);
577
        self::assertCount(1, $tableDiff->changedForeignKeys);
578
    }
579
580
    public function testMovedForeignKeyForeignTable() : void
581
    {
582
        $tableForeign = new Table('bar');
583
        $tableForeign->addColumn('id', 'integer');
584
585
        $tableForeign2 = new Table('bar2');
586
        $tableForeign2->addColumn('id', 'integer');
587
588
        $table1 = new Table('foo');
589
        $table1->addColumn('fk', 'integer');
590
        $table1->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
591
592
        $table2 = new Table('foo');
593
        $table2->addColumn('fk', 'integer');
594
        $table2->addForeignKeyConstraint($tableForeign2, ['fk'], ['id']);
595
596
        $c         = new Comparator();
597
        $tableDiff = $c->diffTable($table1, $table2);
598
599
        self::assertInstanceOf(TableDiff::class, $tableDiff);
600
        self::assertCount(1, $tableDiff->changedForeignKeys);
601
    }
602
603
    public function testTablesCaseInsensitive() : void
604
    {
605
        $schemaA = new Schema();
606
        $schemaA->createTable('foo');
607
        $schemaA->createTable('bAr');
608
        $schemaA->createTable('BAZ');
609
        $schemaA->createTable('new');
610
611
        $schemaB = new Schema();
612
        $schemaB->createTable('FOO');
613
        $schemaB->createTable('bar');
614
        $schemaB->createTable('Baz');
615
        $schemaB->createTable('old');
616
617
        $c    = new Comparator();
618
        $diff = $c->compare($schemaA, $schemaB);
619
620
        $this->assertSchemaTableChangeCount($diff, 1, 0, 1);
621
    }
622
623
    public function testSequencesCaseInsensitive() : void
624
    {
625
        $schemaA = new Schema();
626
        $schemaA->createSequence('foo');
627
        $schemaA->createSequence('BAR');
628
        $schemaA->createSequence('Baz');
629
        $schemaA->createSequence('new');
630
631
        $schemaB = new Schema();
632
        $schemaB->createSequence('FOO');
633
        $schemaB->createSequence('Bar');
634
        $schemaB->createSequence('baz');
635
        $schemaB->createSequence('old');
636
637
        $c    = new Comparator();
638
        $diff = $c->compare($schemaA, $schemaB);
639
640
        $this->assertSchemaSequenceChangeCount($diff, 1, 0, 1);
641
    }
642
643
    public function testCompareColumnCompareCaseInsensitive() : void
644
    {
645
        $tableA = new Table('foo');
646
        $tableA->addColumn('id', 'integer');
647
648
        $tableB = new Table('foo');
649
        $tableB->addColumn('ID', 'integer');
650
651
        $c         = new Comparator();
652
        $tableDiff = $c->diffTable($tableA, $tableB);
653
654
        self::assertNull($tableDiff);
655
    }
656
657
    public function testCompareIndexBasedOnPropertiesNotName() : void
658
    {
659
        $tableA = new Table('foo');
660
        $tableA->addColumn('id', 'integer');
661
        $tableA->addIndex(['id'], 'foo_bar_idx');
662
663
        $tableB = new Table('foo');
664
        $tableB->addColumn('ID', 'integer');
665
        $tableB->addIndex(['id'], 'bar_foo_idx');
666
667
        $c                                        = new Comparator();
668
        $tableDiff                                = new TableDiff('foo');
669
        $tableDiff->fromTable                     = $tableA;
670
        $tableDiff->renamedIndexes['foo_bar_idx'] = new Index('bar_foo_idx', ['id']);
671
672
        self::assertEquals(
673
            $tableDiff,
674
            $c->diffTable($tableA, $tableB)
675
        );
676
    }
677
678
    public function testCompareForeignKeyBasedOnPropertiesNotName() : void
679
    {
680
        $tableA = new Table('foo');
681
        $tableA->addColumn('id', 'integer');
682
        $tableA->addForeignKeyConstraint('bar', ['id'], ['id'], [], 'foo_constraint');
683
684
        $tableB = new Table('foo');
685
        $tableB->addColumn('ID', 'integer');
686
        $tableB->addForeignKeyConstraint('bar', ['id'], ['id'], [], 'bar_constraint');
687
688
        $c         = new Comparator();
689
        $tableDiff = $c->diffTable($tableA, $tableB);
690
691
        self::assertNull($tableDiff);
692
    }
693
694
    public function testCompareForeignKeyRestrictNoActionAreTheSame() : void
695
    {
696
        $fk1 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk1', ['onDelete' => 'NO ACTION']);
697
        $fk2 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk1', ['onDelete' => 'RESTRICT']);
698
699
        $c = new Comparator();
700
        self::assertFalse($c->diffForeignKey($fk1, $fk2));
701
    }
702
703
    /**
704
     * @group DBAL-492
705
     */
706
    public function testCompareForeignKeyNamesUnqualifiedAsNoSchemaInformationIsAvailable() : void
707
    {
708
        $fk1 = new ForeignKeyConstraint(['foo'], 'foo.bar', ['baz'], 'fk1');
709
        $fk2 = new ForeignKeyConstraint(['foo'], 'baz.bar', ['baz'], 'fk1');
710
711
        $c = new Comparator();
712
        self::assertFalse($c->diffForeignKey($fk1, $fk2));
713
    }
714
715
    public function testDetectRenameColumn() : void
716
    {
717
        $tableA = new Table('foo');
718
        $tableA->addColumn('foo', 'integer');
719
720
        $tableB = new Table('foo');
721
        $tableB->addColumn('bar', 'integer');
722
723
        $c         = new Comparator();
724
        $tableDiff = $c->diffTable($tableA, $tableB);
725
726
        self::assertCount(0, $tableDiff->addedColumns);
727
        self::assertCount(0, $tableDiff->removedColumns);
0 ignored issues
show
Documentation introduced by
$tableDiff->removedColumns is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
728
        self::assertArrayHasKey('foo', $tableDiff->renamedColumns);
729
        self::assertEquals('bar', $tableDiff->renamedColumns['foo']->getName());
730
    }
731
732
    /**
733
     * You can easily have ambiguities in the column renaming. If these
734
     * are detected no renaming should take place, instead adding and dropping
735
     * should be used exclusively.
736
     *
737
     * @group DBAL-24
738
     */
739
    public function testDetectRenameColumnAmbiguous() : void
740
    {
741
        $tableA = new Table('foo');
742
        $tableA->addColumn('foo', 'integer');
743
        $tableA->addColumn('bar', 'integer');
744
745
        $tableB = new Table('foo');
746
        $tableB->addColumn('baz', 'integer');
747
748
        $c         = new Comparator();
749
        $tableDiff = $c->diffTable($tableA, $tableB);
750
751
        self::assertCount(1, $tableDiff->addedColumns, "'baz' should be added, not created through renaming!");
752
        self::assertArrayHasKey('baz', $tableDiff->addedColumns, "'baz' should be added, not created through renaming!");
753
        self::assertCount(2, $tableDiff->removedColumns, "'foo' and 'bar' should both be dropped, an ambiguity exists which one could be renamed to 'baz'.");
0 ignored issues
show
Documentation introduced by
$tableDiff->removedColumns is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
754
        self::assertArrayHasKey('foo', $tableDiff->removedColumns, "'foo' should be removed.");
755
        self::assertArrayHasKey('bar', $tableDiff->removedColumns, "'bar' should be removed.");
756
        self::assertCount(0, $tableDiff->renamedColumns, 'no renamings should take place.');
0 ignored issues
show
Documentation introduced by
$tableDiff->renamedColumns is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
757
    }
758
759
    /**
760
     * @group DBAL-1063
761
     */
762
    public function testDetectRenameIndex() : void
763
    {
764
        $table1 = new Table('foo');
765
        $table1->addColumn('foo', 'integer');
766
767
        $table2 = clone $table1;
768
769
        $table1->addIndex(['foo'], 'idx_foo');
770
771
        $table2->addIndex(['foo'], 'idx_bar');
772
773
        $comparator = new Comparator();
774
        $tableDiff  = $comparator->diffTable($table1, $table2);
775
776
        self::assertCount(0, $tableDiff->addedIndexes);
777
        self::assertCount(0, $tableDiff->removedIndexes);
0 ignored issues
show
Documentation introduced by
$tableDiff->removedIndexes is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
778
        self::assertArrayHasKey('idx_foo', $tableDiff->renamedIndexes);
779
        self::assertEquals('idx_bar', $tableDiff->renamedIndexes['idx_foo']->getName());
780
    }
781
782
    /**
783
     * You can easily have ambiguities in the index renaming. If these
784
     * are detected no renaming should take place, instead adding and dropping
785
     * should be used exclusively.
786
     *
787
     * @group DBAL-1063
788
     */
789
    public function testDetectRenameIndexAmbiguous() : void
790
    {
791
        $table1 = new Table('foo');
792
        $table1->addColumn('foo', 'integer');
793
794
        $table2 = clone $table1;
795
796
        $table1->addIndex(['foo'], 'idx_foo');
797
        $table1->addIndex(['foo'], 'idx_bar');
798
799
        $table2->addIndex(['foo'], 'idx_baz');
800
801
        $comparator = new Comparator();
802
        $tableDiff  = $comparator->diffTable($table1, $table2);
803
804
        self::assertCount(1, $tableDiff->addedIndexes);
805
        self::assertArrayHasKey('idx_baz', $tableDiff->addedIndexes);
806
        self::assertCount(2, $tableDiff->removedIndexes);
0 ignored issues
show
Documentation introduced by
$tableDiff->removedIndexes is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
807
        self::assertArrayHasKey('idx_foo', $tableDiff->removedIndexes);
808
        self::assertArrayHasKey('idx_bar', $tableDiff->removedIndexes);
809
        self::assertCount(0, $tableDiff->renamedIndexes);
0 ignored issues
show
Documentation introduced by
$tableDiff->renamedIndexes is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
810
    }
811
812
    public function testDetectChangeIdentifierType() : void
813
    {
814
        $this->markTestSkipped('DBAL-2 was reopened, this test cannot work anymore.');
815
816
        $tableA = new Table('foo');
817
        $tableA->addColumn('id', 'integer', ['autoincrement' => false]);
818
819
        $tableB = new Table('foo');
820
        $tableB->addColumn('id', 'integer', ['autoincrement' => true]);
821
822
        $c         = new Comparator();
823
        $tableDiff = $c->diffTable($tableA, $tableB);
824
825
        self::assertInstanceOf(TableDiff::class, $tableDiff);
826
        self::assertArrayHasKey('id', $tableDiff->changedColumns);
827
    }
828
829
    /**
830
     * @group DBAL-105
831
     */
832
    public function testDiff() : void
833
    {
834
        $table = new Table('twitter_users');
835
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
836
        $table->addColumn('twitterId', 'integer');
837
        $table->addColumn('displayName', 'string');
838
        $table->setPrimaryKey(['id']);
839
840
        $newtable = new Table('twitter_users');
841
        $newtable->addColumn('id', 'integer', ['autoincrement' => true]);
842
        $newtable->addColumn('twitter_id', 'integer');
843
        $newtable->addColumn('display_name', 'string');
844
        $newtable->addColumn('logged_in_at', 'datetime');
845
        $newtable->setPrimaryKey(['id']);
846
847
        $c         = new Comparator();
848
        $tableDiff = $c->diffTable($table, $newtable);
849
850
        self::assertInstanceOf(TableDiff::class, $tableDiff);
851
        self::assertEquals(['twitterid', 'displayname'], array_keys($tableDiff->renamedColumns));
852
        self::assertEquals(['logged_in_at'], array_keys($tableDiff->addedColumns));
853
        self::assertCount(0, $tableDiff->removedColumns);
0 ignored issues
show
Documentation introduced by
$tableDiff->removedColumns is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
854
    }
855
856
    /**
857
     * @group DBAL-112
858
     */
859
    public function testChangedSequence() : void
860
    {
861
        $schema   = new Schema();
862
        $sequence = $schema->createSequence('baz');
0 ignored issues
show
Unused Code introduced by
$sequence is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
863
864
        $schemaNew = clone $schema;
865
        $schemaNew->getSequence('baz')->setAllocationSize(20);
866
867
        $c    = new Comparator();
868
        $diff = $c->compare($schema, $schemaNew);
869
870
        self::assertSame($diff->changedSequences[0], $schemaNew->getSequence('baz'));
871
    }
872
873
    /**
874
     * @group DBAL-106
875
     */
876
    public function testDiffDecimalWithNullPrecision() : void
877
    {
878
        $column = new Column('foo', Type::getType('decimal'));
879
        $column->setPrecision(null);
880
881
        $column2 = new Column('foo', Type::getType('decimal'));
882
883
        $c = new Comparator();
884
        self::assertEquals([], $c->diffColumn($column, $column2));
885
    }
886
887
    /**
888
     * @group DBAL-204
889
     */
890
    public function testFqnSchemaComparison() : void
891
    {
892
        $config = new SchemaConfig();
893
        $config->setName('foo');
894
895
        $oldSchema = new Schema([], [], $config);
896
        $oldSchema->createTable('bar');
897
898
        $newSchema = new Schema([], [], $config);
899
        $newSchema->createTable('foo.bar');
900
901
        $expected             = new SchemaDiff();
902
        $expected->fromSchema = $oldSchema;
903
904
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
905
    }
906
907
    /**
908
     * @group DBAL-669
909
     */
910
    public function testNamespacesComparison() : void
911
    {
912
        $config = new SchemaConfig();
913
        $config->setName('schemaName');
914
915
        $oldSchema = new Schema([], [], $config);
916
        $oldSchema->createTable('taz');
917
        $oldSchema->createTable('war.tab');
918
919
        $newSchema = new Schema([], [], $config);
920
        $newSchema->createTable('bar.tab');
921
        $newSchema->createTable('baz.tab');
922
        $newSchema->createTable('war.tab');
923
924
        $expected                = new SchemaDiff();
925
        $expected->fromSchema    = $oldSchema;
926
        $expected->newNamespaces = ['bar' => 'bar', 'baz' => 'baz'];
927
928
        $diff = Comparator::compareSchemas($oldSchema, $newSchema);
929
930
        self::assertEquals(['bar' => 'bar', 'baz' => 'baz'], $diff->newNamespaces);
931
        self::assertCount(2, $diff->newTables);
0 ignored issues
show
Documentation introduced by
$diff->newTables is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
932
    }
933
934
    /**
935
     * @group DBAL-204
936
     */
937
    public function testFqnSchemaComparisonDifferentSchemaNameButSameTableNoDiff() : void
938
    {
939
        $config = new SchemaConfig();
940
        $config->setName('foo');
941
942
        $oldSchema = new Schema([], [], $config);
943
        $oldSchema->createTable('foo.bar');
944
945
        $newSchema = new Schema();
946
        $newSchema->createTable('bar');
947
948
        $expected             = new SchemaDiff();
949
        $expected->fromSchema = $oldSchema;
950
951
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
952
    }
953
954
    /**
955
     * @group DBAL-204
956
     */
957
    public function testFqnSchemaComparisonNoSchemaSame() : void
958
    {
959
        $config = new SchemaConfig();
960
        $config->setName('foo');
961
        $oldSchema = new Schema([], [], $config);
962
        $oldSchema->createTable('bar');
963
964
        $newSchema = new Schema();
965
        $newSchema->createTable('bar');
966
967
        $expected             = new SchemaDiff();
968
        $expected->fromSchema = $oldSchema;
969
970
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
971
    }
972
973
    /**
974
     * @group DDC-1657
975
     */
976
    public function testAutoIncrementSequences() : void
977
    {
978
        $oldSchema = new Schema();
979
        $table     = $oldSchema->createTable('foo');
980
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
981
        $table->setPrimaryKey(['id']);
982
        $oldSchema->createSequence('foo_id_seq');
983
984
        $newSchema = new Schema();
985
        $table     = $newSchema->createTable('foo');
986
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
987
        $table->setPrimaryKey(['id']);
988
989
        $c    = new Comparator();
990
        $diff = $c->compare($oldSchema, $newSchema);
991
992
        self::assertCount(0, $diff->removedSequences);
0 ignored issues
show
Documentation introduced by
$diff->removedSequences is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
993
    }
994
995
    /**
996
     * Check that added autoincrement sequence is not populated in newSequences
997
     *
998
     * @group DBAL-562
999
     */
1000
    public function testAutoIncrementNoSequences() : void
1001
    {
1002
        $oldSchema = new Schema();
1003
        $table     = $oldSchema->createTable('foo');
1004
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
1005
        $table->setPrimaryKey(['id']);
1006
1007
        $newSchema = new Schema();
1008
        $table     = $newSchema->createTable('foo');
1009
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
1010
        $table->setPrimaryKey(['id']);
1011
        $newSchema->createSequence('foo_id_seq');
1012
1013
        $c    = new Comparator();
1014
        $diff = $c->compare($oldSchema, $newSchema);
1015
1016
        self::assertCount(0, $diff->newSequences);
0 ignored issues
show
Documentation introduced by
$diff->newSequences is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1017
    }
1018
1019
    /**
1020
     * You can get multiple drops for a FK when a table referenced by a foreign
1021
     * key is deleted, as this FK is referenced twice, once on the orphanedForeignKeys
1022
     * array because of the dropped table, and once on changedTables array. We
1023
     * now check that the key is present once.
1024
     */
1025
    public function testAvoidMultipleDropForeignKey() : void
1026
    {
1027
        $oldSchema = new Schema();
1028
1029
        $tableA = $oldSchema->createTable('table_a');
1030
        $tableA->addColumn('id', 'integer');
1031
1032
        $tableB = $oldSchema->createTable('table_b');
1033
        $tableB->addColumn('id', 'integer');
1034
1035
        $tableC = $oldSchema->createTable('table_c');
1036
        $tableC->addColumn('id', 'integer');
1037
        $tableC->addColumn('table_a_id', 'integer');
1038
        $tableC->addColumn('table_b_id', 'integer');
1039
1040
        $tableC->addForeignKeyConstraint($tableA, ['table_a_id'], ['id']);
1041
        $tableC->addForeignKeyConstraint($tableB, ['table_b_id'], ['id']);
1042
1043
        $newSchema = new Schema();
1044
1045
        $tableB = $newSchema->createTable('table_b');
1046
        $tableB->addColumn('id', 'integer');
1047
1048
        $tableC = $newSchema->createTable('table_c');
1049
        $tableC->addColumn('id', 'integer');
1050
1051
        $comparator = new Comparator();
1052
        $schemaDiff = $comparator->compare($oldSchema, $newSchema);
1053
1054
        self::assertCount(1, $schemaDiff->changedTables['table_c']->removedForeignKeys);
1055
        self::assertCount(1, $schemaDiff->orphanedForeignKeys);
0 ignored issues
show
Documentation introduced by
$schemaDiff->orphanedForeignKeys is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1056
    }
1057
1058
    public function testCompareChangedColumn() : void
1059
    {
1060
        $oldSchema = new Schema();
1061
1062
        $tableFoo = $oldSchema->createTable('foo');
1063
        $tableFoo->addColumn('id', 'integer');
1064
1065
        $newSchema = new Schema();
1066
        $table     = $newSchema->createTable('foo');
1067
        $table->addColumn('id', 'string');
1068
1069
        $expected                      = new SchemaDiff();
1070
        $expected->fromSchema          = $oldSchema;
1071
        $tableDiff                     = $expected->changedTables['foo'] = new TableDiff('foo');
1072
        $tableDiff->fromTable          = $tableFoo;
1073
        $columnDiff                    = $tableDiff->changedColumns['id'] = new ColumnDiff('id', $table->getColumn('id'));
1074
        $columnDiff->fromColumn        = $tableFoo->getColumn('id');
1075
        $columnDiff->changedProperties = ['type'];
1076
1077
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
1078
    }
1079
1080
    public function testCompareChangedBinaryColumn() : void
1081
    {
1082
        $oldSchema = new Schema();
1083
1084
        $tableFoo = $oldSchema->createTable('foo');
1085
        $tableFoo->addColumn('id', 'binary');
1086
1087
        $newSchema = new Schema();
1088
        $table     = $newSchema->createTable('foo');
1089
        $table->addColumn('id', 'binary', ['length' => 42, 'fixed' => true]);
1090
1091
        $expected                      = new SchemaDiff();
1092
        $expected->fromSchema          = $oldSchema;
1093
        $tableDiff                     = $expected->changedTables['foo'] = new TableDiff('foo');
1094
        $tableDiff->fromTable          = $tableFoo;
1095
        $columnDiff                    = $tableDiff->changedColumns['id'] = new ColumnDiff('id', $table->getColumn('id'));
1096
        $columnDiff->fromColumn        = $tableFoo->getColumn('id');
1097
        $columnDiff->changedProperties = ['length', 'fixed'];
1098
1099
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
1100
    }
1101
1102
    /**
1103
     * @group DBAL-617
1104
     */
1105
    public function testCompareQuotedAndUnquotedForeignKeyColumns() : void
1106
    {
1107
        $fk1 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk1', ['onDelete' => 'NO ACTION']);
1108
        $fk2 = new ForeignKeyConstraint(['`foo`'], 'bar', ['`baz`'], 'fk1', ['onDelete' => 'NO ACTION']);
1109
1110
        $comparator = new Comparator();
1111
        $diff       = $comparator->diffForeignKey($fk1, $fk2);
1112
1113
        self::assertFalse($diff);
1114
    }
1115
1116
    public function assertSchemaTableChangeCount(SchemaDiff $diff, int $newTableCount = 0, int $changeTableCount = 0, int $removeTableCount = 0) : void
1117
    {
1118
        self::assertCount($newTableCount, $diff->newTables);
0 ignored issues
show
Documentation introduced by
$diff->newTables is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1119
        self::assertCount($changeTableCount, $diff->changedTables);
0 ignored issues
show
Documentation introduced by
$diff->changedTables is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1120
        self::assertCount($removeTableCount, $diff->removedTables);
0 ignored issues
show
Documentation introduced by
$diff->removedTables is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1121
    }
1122
1123
    public function assertSchemaSequenceChangeCount(
1124
        SchemaDiff $diff,
1125
        int $newSequenceCount = 0,
1126
        int $changeSequenceCount = 0,
1127
        int $removeSequenceCount = 0
1128
    ) : void {
1129
        self::assertCount($newSequenceCount, $diff->newSequences, 'Expected number of new sequences is wrong.');
0 ignored issues
show
Documentation introduced by
$diff->newSequences is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1130
        self::assertCount($changeSequenceCount, $diff->changedSequences, 'Expected number of changed sequences is wrong.');
0 ignored issues
show
Documentation introduced by
$diff->changedSequences is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1131
        self::assertCount($removeSequenceCount, $diff->removedSequences, 'Expected number of removed sequences is wrong.');
0 ignored issues
show
Documentation introduced by
$diff->removedSequences is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1132
    }
1133
1134
    public function testDiffColumnPlatformOptions() : void
1135
    {
1136
        $column1 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'bar' => 'bar']]);
1137
        $column2 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'foobar' => 'foobar']]);
1138
        $column3 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'bar' => 'rab']]);
1139
        $column4 = new Column('foo', Type::getType('string'));
1140
1141
        $comparator = new Comparator();
1142
1143
        self::assertEquals([], $comparator->diffColumn($column1, $column2));
1144
        self::assertEquals([], $comparator->diffColumn($column2, $column1));
1145
        self::assertEquals(['bar'], $comparator->diffColumn($column1, $column3));
1146
        self::assertEquals(['bar'], $comparator->diffColumn($column3, $column1));
1147
        self::assertEquals([], $comparator->diffColumn($column1, $column4));
1148
        self::assertEquals([], $comparator->diffColumn($column4, $column1));
1149
    }
1150
1151
    public function testComplexDiffColumn() : void
1152
    {
1153
        $column1 = new Column('foo', Type::getType('string'), [
1154
            'platformOptions' => ['foo' => 'foo'],
1155
            'customSchemaOptions' => ['foo' => 'bar'],
1156
        ]);
1157
1158
        $column2 = new Column('foo', Type::getType('string'), [
1159
            'platformOptions' => ['foo' => 'bar'],
1160
        ]);
1161
1162
        $comparator = new Comparator();
1163
1164
        self::assertEquals([], $comparator->diffColumn($column1, $column2));
1165
        self::assertEquals([], $comparator->diffColumn($column2, $column1));
1166
    }
1167
1168
    /**
1169
     * @group DBAL-669
1170
     */
1171
    public function testComparesNamespaces() : void
1172
    {
1173
        $comparator = new Comparator();
1174
        $fromSchema = $this->getMockBuilder(Schema::class)
1175
            ->onlyMethods(['getNamespaces', 'hasNamespace'])
1176
            ->getMock();
1177
        $toSchema   = $this->getMockBuilder(Schema::class)
1178
            ->onlyMethods(['getNamespaces', 'hasNamespace'])
1179
            ->getMock();
1180
1181
        $fromSchema->expects($this->once())
1182
            ->method('getNamespaces')
1183
            ->will($this->returnValue(['foo', 'bar']));
1184
1185
        $fromSchema->expects($this->at(0))
1186
            ->method('hasNamespace')
1187
            ->with('bar')
1188
            ->will($this->returnValue(true));
1189
1190
        $fromSchema->expects($this->at(1))
1191
            ->method('hasNamespace')
1192
            ->with('baz')
1193
            ->will($this->returnValue(false));
1194
1195
        $toSchema->expects($this->once())
1196
            ->method('getNamespaces')
1197
            ->will($this->returnValue(['bar', 'baz']));
1198
1199
        $toSchema->expects($this->at(1))
1200
            ->method('hasNamespace')
1201
            ->with('foo')
1202
            ->will($this->returnValue(false));
1203
1204
        $toSchema->expects($this->at(2))
1205
            ->method('hasNamespace')
1206
            ->with('bar')
1207
            ->will($this->returnValue(true));
1208
1209
        $expected                    = new SchemaDiff();
1210
        $expected->fromSchema        = $fromSchema;
0 ignored issues
show
Documentation Bug introduced by
It seems like $fromSchema of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Doctrine\DBAL\Schema\Schema>|null of property $fromSchema.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
1211
        $expected->newNamespaces     = ['baz' => 'baz'];
1212
        $expected->removedNamespaces = ['foo' => 'foo'];
1213
1214
        self::assertEquals($expected, $comparator->compare($fromSchema, $toSchema));
0 ignored issues
show
Documentation introduced by
$fromSchema is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\DBAL\Schema\Schema>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
$toSchema is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\DBAL\Schema\Schema>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1215
    }
1216
1217
    public function testCompareGuidColumns() : void
1218
    {
1219
        $comparator = new Comparator();
1220
1221
        $column1 = new Column('foo', Type::getType('guid'), ['comment' => 'GUID 1']);
1222
        $column2 = new Column(
1223
            'foo',
1224
            Type::getType('guid'),
1225
            ['notnull' => false, 'length' => 36, 'fixed' => true, 'default' => 'NEWID()', 'comment' => 'GUID 2.']
1226
        );
1227
1228
        self::assertEquals(['notnull', 'default', 'comment'], $comparator->diffColumn($column1, $column2));
1229
        self::assertEquals(['notnull', 'default', 'comment'], $comparator->diffColumn($column2, $column1));
1230
    }
1231
1232
    /**
1233
     * @group DBAL-1009
1234
     * @dataProvider getCompareColumnComments
1235
     */
1236
    public function testCompareColumnComments(?string $comment1, ?string $comment2, bool $equals) : void
1237
    {
1238
        $column1 = new Column('foo', Type::getType('integer'), ['comment' => $comment1]);
1239
        $column2 = new Column('foo', Type::getType('integer'), ['comment' => $comment2]);
1240
1241
        $comparator = new Comparator();
1242
1243
        $expectedDiff = $equals ? [] : ['comment'];
1244
1245
        $actualDiff = $comparator->diffColumn($column1, $column2);
1246
1247
        self::assertSame($expectedDiff, $actualDiff);
1248
1249
        $actualDiff = $comparator->diffColumn($column2, $column1);
1250
1251
        self::assertSame($expectedDiff, $actualDiff);
1252
    }
1253
1254
    /**
1255
     * @return mixed[][]
1256
     */
1257
    public static function getCompareColumnComments() : iterable
1258
    {
1259
        return [
1260
            [null, null, true],
1261
            ['', '', true],
1262
            [' ', ' ', true],
1263
            ['0', '0', true],
1264
            ['foo', 'foo', true],
1265
1266
            [null, '', true],
1267
            [null, ' ', false],
1268
            [null, '0', false],
1269
            [null, 'foo', false],
1270
1271
            ['', ' ', false],
1272
            ['', '0', false],
1273
            ['', 'foo', false],
1274
1275
            [' ', '0', false],
1276
            [' ', 'foo', false],
1277
1278
            ['0', 'foo', false],
1279
        ];
1280
    }
1281
1282
    public function testForeignKeyRemovalWithRenamedLocalColumn() : void
1283
    {
1284
        $fromSchema = new Schema([
1285
            'table1' => new Table(
1286
                'table1',
1287
                [
1288
                    'id' => new Column('id', Type::getType('integer')),
1289
                ]
1290
            ),
1291
            'table2' => new Table(
1292
                'table2',
1293
                [
1294
                    'id' => new Column('id', Type::getType('integer')),
1295
                    'id_table1' => new Column('id_table1', Type::getType('integer')),
1296
                ],
1297
                [],
1298
                [],
1299
                [
1300
                    new ForeignKeyConstraint(['id_table1'], 'table1', ['id'], 'fk_table2_table1'),
1301
                ]
1302
            ),
1303
        ]);
1304
        $toSchema   = new Schema([
1305
            'table2' => new Table(
1306
                'table2',
1307
                [
1308
                    'id' => new Column('id', Type::getType('integer')),
1309
                    'id_table3' => new Column('id_table3', Type::getType('integer')),
1310
                ],
1311
                [],
1312
                [],
1313
                [
1314
                    new ForeignKeyConstraint(['id_table3'], 'table3', ['id'], 'fk_table2_table3'),
1315
                ]
1316
            ),
1317
            'table3' => new Table(
1318
                'table3',
1319
                [
1320
                    'id' => new Column('id', Type::getType('integer')),
1321
                ]
1322
            ),
1323
        ]);
1324
        $actual     = Comparator::compareSchemas($fromSchema, $toSchema);
1325
        self::assertArrayHasKey('table2', $actual->changedTables);
1326
        self::assertCount(1, $actual->orphanedForeignKeys);
0 ignored issues
show
Documentation introduced by
$actual->orphanedForeignKeys is of type array, but the function expects a object<Countable>|object...nit\Framework\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1327
        self::assertEquals('fk_table2_table1', $actual->orphanedForeignKeys[0]->getName());
1328
        self::assertCount(1, $actual->changedTables['table2']->addedForeignKeys, 'FK to table3 should be added.');
1329
        self::assertEquals('table3', $actual->changedTables['table2']->addedForeignKeys[0]->getForeignTableName());
1330
    }
1331
}
1332