Passed
Branch add-more-test-schema (1ebac6)
by Wilmer
02:54
created

CommandTest   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 710
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 361
c 1
b 0
f 0
dl 0
loc 710
rs 9.1199
wmc 41

How to fix   Complexity   

Complex Class

Complex classes like CommandTest 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 CommandTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Tests\Command;
6
7
use Yiisoft\Cache\Dependency\TagDependency;
8
use Yiisoft\Db\Command\CommandInterface;
9
use Yiisoft\Db\Exception\NotSupportedException;
10
use Yiisoft\Db\Schema\Schema;
11
use Yiisoft\Db\Tests\AbstractCommandTest;
12
use Yiisoft\Db\Tests\Support\Assert;
13
use Yiisoft\Db\Tests\Support\DbHelper;
14
use Yiisoft\Db\Tests\Support\TestTrait;
15
16
/**
17
 * @group db
18
 *
19
 * @psalm-suppress PropertyNotSetInConstructor
20
 */
21
final class CommandTest extends AbstractCommandTest
22
{
23
    use TestTrait;
24
25
    public function testAddCheck(): void
26
    {
27
        $db = $this->getConnection();
28
29
        $command = $db->createCommand();
30
        $sql = $command->addCheck('name', 'table', 'id > 0')->getSql();
31
32
33
        $this->assertSame(
34
            DbHelper::replaceQuotes(
35
                <<<SQL
36
                ALTER TABLE [[table]] ADD CONSTRAINT [[name]] CHECK (id > 0)
37
                SQL,
38
                $db->getName(),
39
            ),
40
            $sql,
41
        );
42
    }
43
44
    public function testAddColumn(): void
45
    {
46
        $db = $this->getConnection();
47
48
        $command = $db->createCommand();
49
        $sql = $command->addColumn('table', 'column', Schema::TYPE_INTEGER)->getSql();
50
51
        $this->assertSame(
52
            DbHelper::replaceQuotes(
53
                <<<SQL
54
                ALTER TABLE [[table]] ADD [[column]] integer
55
                SQL,
56
                $db->getName(),
57
            ),
58
            $sql,
59
        );
60
    }
61
62
    public function testAddCommentOnColumn(): void
63
    {
64
        $db = $this->getConnection();
65
66
        $command = $db->createCommand();
67
        $sql = $command->addCommentOnColumn('customer', 'id', 'Primary key.')->getSql();
68
69
        $this->assertStringContainsString(
70
            DbHelper::replaceQuotes(
71
                <<<SQL
72
                COMMENT ON COLUMN [[customer]].[[id]] IS 'Primary key.'
73
                SQL,
74
                $db->getName(),
75
            ),
76
            $sql,
77
        );
78
    }
79
80
    public function testAddCommentOnTable(): void
81
    {
82
        $db = $this->getConnection();
83
84
        $command = $db->createCommand();
85
        $sql = $command->addCommentOnTable('table', 'comment')->getSql();
86
87
        $this->assertSame(
88
            DbHelper::replaceQuotes(
89
                <<<SQL
90
                COMMENT ON TABLE [[table]] IS 'comment'
91
                SQL,
92
                $db->getName(),
93
            ),
94
            $sql,
95
        );
96
    }
97
98
    public function testAddDefaultValue(): void
99
    {
100
        $db = $this->getConnection();
101
102
        $command = $db->createCommand();
103
104
        $this->expectException(NotSupportedException::class);
105
        $this->expectExceptionMessage(
106
            'Yiisoft\Db\QueryBuilder\DDLQueryBuilder::addDefaultValue is not supported by this DBMS.'
107
        );
108
109
        $command->addDefaultValue('name', 'table', 'column', 'value');
110
    }
111
112
    /**
113
     * @dataProvider \Yiisoft\Db\Tests\Provider\CommandProvider::addForeignKeySql()
114
     */
115
    public function testAddForeignKeySql(
116
        string $name,
117
        string $tableName,
118
        array|string $column1,
119
        array|string $column2,
120
        string|null $delete,
121
        string|null $update,
122
        string $expected
123
    ): void {
124
        $db = $this->getConnection();
125
126
        $command = $db->createCommand();
127
        $sql = $command->addForeignKey($name, $tableName, $column1, $tableName, $column2, $delete, $update)->getSql();
128
129
        $this->assertSame($expected, $sql);
130
    }
131
132
    /**
133
     * @dataProvider \Yiisoft\Db\Tests\Provider\CommandProvider::addPrimaryKeySql()
134
     */
135
    public function testAddPrimaryKeySql(string $name, string $tableName, array|string $column, string $expected): void
136
    {
137
        $db = $this->getConnection();
138
139
        $command = $db->createCommand();
140
        $sql = $command->addPrimaryKey($name, $tableName, $column)->getSql();
141
142
143
        $this->assertSame($expected, $sql);
144
    }
145
146
    /**
147
     * @dataProvider \Yiisoft\Db\Tests\Provider\CommandProvider::addUniqueSql()
148
     */
149
    public function testAddUniqueSql(string $name, string $tableName, array|string $column, string $expected): void
150
    {
151
        $db = $this->getConnection();
152
153
        $command = $db->createCommand();
154
        $sql = $command->addUnique($name, $tableName, $column)->getSql();
155
156
        $this->assertSame($expected, $sql);
157
    }
158
159
    public function testAlterColumn(): void
160
    {
161
        $db = $this->getConnection();
162
163
        $command = $db->createCommand();
164
        $sql = $command->alterColumn('table', 'column', Schema::TYPE_INTEGER)->getSql();
165
166
        $this->assertSame(
167
            DbHelper::replaceQuotes(
168
                <<<SQL
169
                ALTER TABLE [[table]] CHANGE [[column]] [[column]] integer
170
                SQL,
171
                $db->getName(),
172
            ),
173
            $sql,
174
        );
175
    }
176
177
    public function testBatchInsert(): void
178
    {
179
        $db = $this->getConnection();
180
181
        $command = $db->createCommand();
182
183
        $this->expectException(NotSupportedException::class);
184
        $this->expectExceptionMessage(
185
            'Yiisoft\Db\Tests\Support\Stub\Schema::loadTableSchema is not supported by this DBMS.'
186
        );
187
188
        $command->batchInsert('table', ['column1', 'column2'], [['value1', 'value2'], ['value3', 'value4']]);
189
    }
190
191
    public function testCache(): void
192
    {
193
        $db = $this->getConnection();
194
195
        $tagDependency = new TagDependency('tag');
196
        $command = $db->createCommand();
197
        $command->cache(100, $tagDependency);
198
199
        $this->assertInstanceOf(CommandInterface::class, $command);
200
        $this->assertSame(100, Assert::getInaccessibleProperty($command, 'queryCacheDuration'));
201
        $this->assertSame($tagDependency, Assert::getInaccessibleProperty($command, 'queryCacheDependency'));
202
    }
203
204
    /**
205
     * @dataProvider \Yiisoft\Db\Tests\Provider\CommandProvider::createIndexSql()
206
     */
207
    public function testCreateIndexSql(
208
        string $name,
209
        string $table,
210
        array|string $column,
211
        string $indexType,
212
        string $indexMethod,
213
        string $expected,
214
    ): void {
215
        $db = $this->getConnection();
216
217
        $command = $db->createCommand();
218
219
        $sql = $command->createIndex($name, $table, $column, $indexType, $indexMethod)->getSql();
220
221
        $this->assertSame($expected, $sql);
222
    }
223
224
    public function testCheckIntegrity(): void
225
    {
226
        $db = $this->getConnection();
227
228
        $command = $db->createCommand();
229
230
        $this->expectException(NotSupportedException::class);
231
        $this->expectExceptionMessage(
232
            'Yiisoft\Db\QueryBuilder\DDLQueryBuilder::checkIntegrity is not supported by this DBMS.'
233
        );
234
235
        $command->checkIntegrity('schema', 'table')->execute();
236
    }
237
238
    public function testCreateTable(): void
239
    {
240
        $db = $this->getConnection();
241
242
        $command = $db->createCommand();
243
        $mb = $db->getMigrationBuilder();
244
245
        $expected = <<<SQL
246
        CREATE TABLE [test_table] (
247
        \t[id] pk,
248
        \t[name] string(255) NOT NULL,
249
        \t[email] string(255) NOT NULL,
250
        \t[address] string(255) NOT NULL,
251
        \t[status] integer NOT NULL,
252
        \t[profile_id] integer NOT NULL,
253
        \t[created_at] timestamp NOT NULL,
254
        \t[updated_at] timestamp NOT NULL
255
        ) CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB
256
        SQL;
257
        $columns = [
258
            'id' => $mb->primaryKey(5),
259
            'name' => $mb->string(255)->notNull(),
260
            'email' => $mb->string(255)->notNull(),
261
            'address' => $mb->string(255)->notNull(),
262
            'status' => $mb->integer()->notNull(),
263
            'profile_id' => $mb->integer()->notNull(),
264
            'created_at' => $mb->timestamp()->notNull(),
265
            'updated_at' => $mb->timestamp()->notNull(),
266
        ];
267
        $options = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
268
        $sql = $command->createTable('test_table', $columns, $options)->getSql();
269
270
        Assert::equalsWithoutLE($expected, $sql);
271
    }
272
273
    public function testCreateView(): void
274
    {
275
        $db = $this->getConnection();
276
277
        $command = $db->createCommand();
278
279
        $sql = $command->createView(
280
            'view',
281
            <<<SQL
282
            SELECT * FROM [[table]]
283
            SQL,
284
        )->getSql();
285
286
        $this->assertSame(
287
            DbHelper::replaceQuotes(
288
                <<<SQL
289
                CREATE VIEW [[view]] AS SELECT * FROM [[table]]
290
                SQL,
291
                $db->getName(),
292
            ),
293
            $sql,
294
        );
295
    }
296
297
    public function testDelete(): void
298
    {
299
        $db = $this->getConnection();
300
301
        $command = $db->createCommand();
302
        $sql = $command->delete('table', ['column' => 'value'])->getSql();
303
304
        $this->assertSame(
305
            DbHelper::replaceQuotes(
306
                <<<SQL
307
                DELETE FROM [[table]] WHERE [[column]]=:qp0
308
                SQL,
309
                $db->getName(),
310
            ),
311
            $sql,
312
        );
313
    }
314
315
    public function testDropCheck(): void
316
    {
317
        $db = $this->getConnection();
318
319
        $command = $db->createCommand();
320
        $sql = $command->dropCheck('name', 'table')->getSql();
321
322
        $this->assertSame(
323
            DbHelper::replaceQuotes(
324
                <<<SQL
325
                ALTER TABLE [[table]] DROP CONSTRAINT [[name]]
326
                SQL,
327
                $db->getName(),
328
            ),
329
            $sql,
330
        );
331
    }
332
333
    public function testDropColumn(): void
334
    {
335
        $db = $this->getConnection();
336
337
        $command = $db->createCommand();
338
        $sql = $command->dropColumn('table', 'column')->getSql();
339
340
        $this->assertSame(
341
            DbHelper::replaceQuotes(
342
                <<<SQL
343
                ALTER TABLE [[table]] DROP COLUMN [[column]]
344
                SQL,
345
                $db->getName(),
346
            ),
347
            $sql,
348
        );
349
    }
350
351
    public function testDropCommentFromColumn(): void
352
    {
353
        $db = $this->getConnection();
354
355
        $command = $db->createCommand();
356
        $sql = $command->dropCommentFromColumn('table', 'column')->getSql();
357
358
        $this->assertSame(
359
            DbHelper::replaceQuotes(
360
                <<<SQL
361
                COMMENT ON COLUMN [[table]].[[column]] IS NULL
362
                SQL,
363
                $db->getName(),
364
            ),
365
            $sql,
366
        );
367
    }
368
369
    public function testDropCommentFromTable(): void
370
    {
371
        $db = $this->getConnection();
372
373
        $command = $db->createCommand();
374
        $sql = $command->dropCommentFromTable('table')->getSql();
375
376
        $this->assertSame(
377
            DbHelper::replaceQuotes(
378
                <<<SQL
379
                COMMENT ON TABLE [[table]] IS NULL
380
                SQL,
381
                $db->getName(),
382
            ),
383
            $sql,
384
        );
385
    }
386
387
    public function testDropDefaultValue(): void
388
    {
389
        $db = $this->getConnection();
390
391
        $command = $db->createCommand();
392
393
        $this->expectException(NotSupportedException::class);
394
        $this->expectExceptionMessage(
395
            'Yiisoft\Db\QueryBuilder\DDLQueryBuilder::dropDefaultValue is not supported by this DBMS.'
396
        );
397
398
        $command->dropDefaultValue('column', 'table');
399
    }
400
401
    public function testDropForeingKey(): void
402
    {
403
        $db = $this->getConnection();
404
405
        $command = $db->createCommand();
406
        $sql = $command->dropForeignKey('name', 'table')->getSql();
407
408
        $this->assertSame(
409
            DbHelper::replaceQuotes(
410
                <<<SQL
411
                ALTER TABLE [[table]] DROP CONSTRAINT [[name]]
412
                SQL,
413
                $db->getName(),
414
            ),
415
            $sql,
416
        );
417
    }
418
419
    public function testDropIndex(): void
420
    {
421
        $db = $this->getConnection();
422
423
        $command = $db->createCommand();
424
        $sql = $command->dropIndex('name', 'table')->getSql();
425
426
        $this->assertSame(
427
            DbHelper::replaceQuotes(
428
                <<<SQL
429
                DROP INDEX [[name]] ON [[table]]
430
                SQL,
431
                $db->getName(),
432
            ),
433
            $sql,
434
        );
435
    }
436
437
    public function testDropPrimaryKey(): void
438
    {
439
        $db = $this->getConnection();
440
441
        $command = $db->createCommand();
442
        $sql = $command->dropPrimaryKey('name', 'table')->getSql();
443
444
        $this->assertSame(
445
            DbHelper::replaceQuotes(
446
                <<<SQL
447
                ALTER TABLE [[table]] DROP CONSTRAINT [[name]]
448
                SQL,
449
                $db->getName(),
450
            ),
451
            $sql,
452
        );
453
    }
454
455
    public function testDropView(): void
456
    {
457
        $db = $this->getConnection();
458
459
        $command = $db->createCommand();
460
        $sql = $command->dropView('view')->getSql();
461
462
        $this->assertSame(
463
            DbHelper::replaceQuotes(
464
                <<<SQL
465
                DROP VIEW [[view]]
466
                SQL,
467
                $db->getName(),
468
            ),
469
            $sql,
470
        );
471
    }
472
473
    public function testDropTable(): void
474
    {
475
        $db = $this->getConnection();
476
477
        $command = $db->createCommand();
478
        $sql = $command->dropTable('table')->getSql();
479
480
        $this->assertSame(
481
            DbHelper::replaceQuotes(
482
                <<<SQL
483
                DROP TABLE [[table]]
484
                SQL,
485
                $db->getName(),
486
            ),
487
            $sql,
488
        );
489
    }
490
491
    public function testDropUnique(): void
492
    {
493
        $db = $this->getConnection();
494
495
        $command = $db->createCommand();
496
        $sql = $command->dropUnique('name', 'table')->getSql();
497
498
        $this->assertSame(
499
            DbHelper::replaceQuotes(
500
                <<<SQL
501
                ALTER TABLE [[table]] DROP CONSTRAINT [[name]]
502
                SQL,
503
                $db->getName(),
504
            ),
505
            $sql,
506
        );
507
    }
508
509
    public function testExecute(): void
510
    {
511
        $db = $this->getConnection();
512
513
        $command = $db->createCommand();
514
515
        $this->expectException(NotSupportedException::class);
516
        $this->expectExceptionMessage(
517
            'Yiisoft\Db\Tests\Support\Stub\Command::internalExecute is not supported by this DBMS.'
518
        );
519
520
        $command->createTable('customer', ['id' => 'pk'])->execute();
521
    }
522
523
    public function testInsert(): void
524
    {
525
        $db = $this->getConnection();
526
527
        $command = $db->createCommand();
528
529
        $this->expectException(NotSupportedException::class);
530
        $this->expectExceptionMessage(
531
            'Yiisoft\Db\Tests\Support\Stub\Schema::loadTableSchema is not supported by this DBMS.'
532
        );
533
534
        $command->insert('customer', ['email' => '[email protected]', 'name' => 'test', 'address' => 'test address']);
535
    }
536
537
    public function testQuery(): void
538
    {
539
        $db = $this->getConnection(true);
540
541
        $command = $db->createCommand();
542
        $command->setSql(
543
            <<<SQL
544
            SELECT * FROM [[customer]]
545
            SQL
546
        );
547
548
        $this->expectException(NotSupportedException::class);
549
        $this->expectExceptionMessage(
550
            'Yiisoft\Db\Tests\Support\Stub\Command::internalExecute is not supported by this DBMS.'
551
        );
552
553
        $command->query();
554
    }
555
556
    public function testQueryAll(): void
557
    {
558
        $db = $this->getConnection(true);
559
560
        $command = $db->createCommand();
561
        $command->setSql(
562
            <<<SQL
563
            SELECT * FROM [[customer]]
564
            SQL,
565
        );
566
567
        $this->expectException(NotSupportedException::class);
568
        $this->expectExceptionMessage(
569
            'Yiisoft\Db\Tests\Support\Stub\Command::internalExecute is not supported by this DBMS.'
570
        );
571
572
        $command->queryAll();
573
    }
574
575
    public function testQueryColumn(): void
576
    {
577
        $db = $this->getConnection(true);
578
579
        $command = $db->createCommand();
580
        $command->setSql(
581
            <<<SQL
582
            SELECT * FROM [[customer]]
583
            SQL
584
        );
585
586
        $this->expectException(NotSupportedException::class);
587
        $this->expectExceptionMessage(
588
            'Yiisoft\Db\Tests\Support\Stub\Command::internalExecute is not supported by this DBMS.'
589
        );
590
591
        $command->queryColumn();
592
    }
593
594
    public function testQueryOne(): void
595
    {
596
        $db = $this->getConnection(true);
597
598
        $command = $db->createCommand();
599
        $sql = <<<SQL
600
        SELECT * FROM [[customer]] ORDER BY [[id]]
601
        SQL;
602
603
        $this->expectException(NotSupportedException::class);
604
        $this->expectExceptionMessage(
605
            'Yiisoft\Db\Tests\Support\Stub\Command::internalExecute is not supported by this DBMS.'
606
        );
607
608
        $command->setSql($sql)->queryOne();
609
    }
610
611
    public function testQueryScalar(): void
612
    {
613
        $db = $this->getConnection(true);
614
615
        $command = $db->createCommand();
616
        $sql = <<<SQL
617
        SELECT * FROM [[customer]] ORDER BY [[id]]
618
        SQL;
619
620
        $this->expectException(NotSupportedException::class);
621
        $this->expectExceptionMessage(
622
            'Yiisoft\Db\Tests\Support\Stub\Command::internalExecute is not supported by this DBMS.'
623
        );
624
625
        $this->assertEquals(1, $command->setSql($sql)->queryScalar());
626
    }
627
628
    public function testRenameColumn(): void
629
    {
630
        $db = $this->getConnection();
631
632
        $sql = $db->createCommand()->renameColumn('table', 'oldname', 'newname')->getSql();
633
634
        $this->assertSame(
635
            DbHelper::replaceQuotes(
636
                <<<SQL
637
                ALTER TABLE [[table]] RENAME COLUMN [[oldname]] TO [[newname]]
638
                SQL,
639
                $db->getName(),
640
            ),
641
            $sql,
642
        );
643
    }
644
645
    public function testRenameTable(): void
646
    {
647
        $db = $this->getConnection();
648
649
        $sql = $db->createCommand()->renameTable('table', 'newname')->getSql();
650
651
        $this->assertSame(
652
            DbHelper::replaceQuotes(
653
                <<<SQL
654
                RENAME TABLE [[table]] TO [[newname]]
655
                SQL,
656
                $db->getName(),
657
            ),
658
            $sql,
659
        );
660
    }
661
662
    public function testResetSequence(): void
663
    {
664
        $db = $this->getConnection();
665
666
        $this->expectException(NotSupportedException::class);
667
        $this->expectExceptionMessage(
668
            'Yiisoft\Db\QueryBuilder\DMLQueryBuilder::resetSequence() is not supported by this DBMS.'
669
        );
670
671
        $db->createCommand()->resetSequence('table', 5);
672
    }
673
674
    public function testSetRetryHandler(): void
675
    {
676
        $db = $this->getConnection();
677
678
        $command = $db->createCommand();
679
680
        $handler = static fn (): bool => true;
681
682
        Assert::invokeMethod($command, 'setRetryHandler', [$handler]);
683
684
        $this->assertSame($handler, Assert::getInaccessibleProperty($command, 'retryHandler'));
685
    }
686
687
    public function testTruncateTable(): void
688
    {
689
        $db = $this->getConnection();
690
691
        $command = $db->createCommand();
692
        $sql = $command->truncateTable('{{table}}')->getSql();
693
694
        $this->assertSame(
695
            DbHelper::replaceQuotes(
696
                <<<SQL
697
                TRUNCATE TABLE [[table]]
698
                SQL,
699
                $db->getName(),
700
            ),
701
            $sql,
702
        );
703
    }
704
705
    public function testUpdate(): void
706
    {
707
        $db = $this->getConnection();
708
709
        $command = $db->createCommand();
710
711
        $this->expectException(NotSupportedException::class);
712
        $this->expectExceptionMessage(
713
            'Yiisoft\Db\Tests\Support\Stub\Schema::loadTableSchema is not supported by this DBMS.'
714
        );
715
716
        $command->update('{{table}}', [], [], []);
717
    }
718
719
    public function testUpsert(): void
720
    {
721
        $db = $this->getConnection();
722
723
        $command = $db->createCommand();
724
725
        $this->expectException(NotSupportedException::class);
726
        $this->expectExceptionMessage(
727
            'Yiisoft\Db\QueryBuilder\DMLQueryBuilder::upsert is not supported by this DBMS.'
728
        );
729
730
        $command->upsert('{{table}}', []);
731
    }
732
}
733