packages/ztd-query-mysql/tests/Unit/Shadow/Mutation/Table/Alter/ColumnAlterationTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Shadow\Mutation\Table\Alter;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\ColumnAlteration;
10
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\ColumnDefinitionParser::class)]
12#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\StoredColumns::class)]
13#[CoversClass(ColumnAlteration::class)]
14final class ColumnAlterationTest extends TestCase
15{
16    public function testApplyAddColumn(): void
17    {
18        $create = (new \PhpMyAdmin\SqlParser\Parser('CREATE TABLE t (id INT, name TEXT)'))->statements[0];
19        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $create);
20        $definition = new \ZtdQuery\Schema\TableDefinition(['id', 'name'], ['id' => 'INT', 'name' => 'TEXT'], [], [], []);
21        $store = new \ZtdQuery\Shadow\ShadowStore();
22        $store->set('t', [['id' => 1, 'name' => 'old']]);
23        $alter = (new \PhpMyAdmin\SqlParser\Parser('ALTER TABLE t ADD COLUMN score INT'))->statements[0];
24        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\AlterStatement::class, $alter);
25        self::assertNotNull($alter->altered);
26        $op = $alter->altered[0];
27        (new ColumnAlteration($alter, 't'))->applyAddColumn($create, $op, $definition);
28        self::assertIsArray($create->fields);
29        self::assertSame(['id', 'name', 'score'], array_map(static fn ($field) => $field->name, $create->fields));
30    }
31
32    public function testApplyDropColumn(): void
33    {
34        $create = (new \PhpMyAdmin\SqlParser\Parser('CREATE TABLE t (id INT, name TEXT)'))->statements[0];
35        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $create);
36        $definition = new \ZtdQuery\Schema\TableDefinition(['id', 'name'], ['id' => 'INT', 'name' => 'TEXT'], [], [], []);
37        $store = new \ZtdQuery\Shadow\ShadowStore();
38        $store->set('t', [['id' => 1, 'name' => 'old']]);
39        $alter = (new \PhpMyAdmin\SqlParser\Parser('ALTER TABLE t DROP COLUMN name'))->statements[0];
40        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\AlterStatement::class, $alter);
41        self::assertNotNull($alter->altered);
42        $op = $alter->altered[0];
43        (new ColumnAlteration($alter, 't'))->applyDropColumn($create, $op, $store, $definition);
44        self::assertIsArray($create->fields);
45        self::assertSame(['id'], array_map(static fn ($field) => $field->name, $create->fields));
46        self::assertSame([['id' => 1]], $store->get('t'));
47    }
48
49    public function testApplyModifyColumn(): void
50    {
51        $create = (new \PhpMyAdmin\SqlParser\Parser('CREATE TABLE t (id INT, name TEXT)'))->statements[0];
52        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $create);
53        $definition = new \ZtdQuery\Schema\TableDefinition(['id', 'name'], ['id' => 'INT', 'name' => 'TEXT'], [], [], []);
54        $store = new \ZtdQuery\Shadow\ShadowStore();
55        $store->set('t', [['id' => 1, 'name' => 'old']]);
56        $alter = (new \PhpMyAdmin\SqlParser\Parser('ALTER TABLE t MODIFY COLUMN name VARCHAR(20)'))->statements[0];
57        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\AlterStatement::class, $alter);
58        self::assertNotNull($alter->altered);
59        $op = $alter->altered[0];
60        (new ColumnAlteration($alter, 't'))->applyModifyColumn($create, $op, $definition);
61        self::assertIsArray($create->fields);
62        self::assertNotNull($create->fields[1]->type);
63        self::assertSame('VARCHAR', $create->fields[1]->type->name);
64        self::assertSame(['20'], $create->fields[1]->type->parameters);
65    }
66
67    public function testApplyChangeColumn(): void
68    {
69        $create = (new \PhpMyAdmin\SqlParser\Parser('CREATE TABLE t (id INT, name TEXT)'))->statements[0];
70        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $create);
71        $definition = new \ZtdQuery\Schema\TableDefinition(['id', 'name'], ['id' => 'INT', 'name' => 'TEXT'], [], [], []);
72        $store = new \ZtdQuery\Shadow\ShadowStore();
73        $store->set('t', [['id' => 1, 'name' => 'old']]);
74        $alter = (new \PhpMyAdmin\SqlParser\Parser('ALTER TABLE t CHANGE COLUMN name label VARCHAR(30)'))->statements[0];
75        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\AlterStatement::class, $alter);
76        self::assertNotNull($alter->altered);
77        $op = $alter->altered[0];
78        (new ColumnAlteration($alter, 't'))->applyChangeColumn($create, $op, $store, $definition);
79        self::assertIsArray($create->fields);
80        self::assertSame('label', $create->fields[1]->name);
81        self::assertSame([['id' => 1, 'label' => 'old']], $store->get('t'));
82    }
83
84    public function testApplyRenameColumn(): void
85    {
86        $create = (new \PhpMyAdmin\SqlParser\Parser('CREATE TABLE t (id INT, name TEXT)'))->statements[0];
87        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $create);
88        $definition = new \ZtdQuery\Schema\TableDefinition(['id', 'name'], ['id' => 'INT', 'name' => 'TEXT'], [], [], []);
89        $store = new \ZtdQuery\Shadow\ShadowStore();
90        $store->set('t', [['id' => 1, 'name' => 'old']]);
91        $alter = (new \PhpMyAdmin\SqlParser\Parser('ALTER TABLE t RENAME COLUMN name TO label'))->statements[0];
92        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\AlterStatement::class, $alter);
93        self::assertNotNull($alter->altered);
94        $op = $alter->altered[0];
95        (new ColumnAlteration($alter, 't'))->applyRenameColumn($create, $op, $store, $definition);
96        self::assertIsArray($create->fields);
97        self::assertSame('label', $create->fields[1]->name);
98        self::assertSame([['id' => 1, 'label' => 'old']], $store->get('t'));
99    }
100
101}
102