packages/ztd-query-sqlite/tests/Unit/Shadow/Mutation/Table/Alter/AlteredTableProjectionTest.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\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Platform\Sqlite\Shadow\Mutation\Table\Alter\AlteredTableProjection;
11use ZtdQuery\Platform\Sqlite\Shadow\Mutation\Table\AlterTableMutation;
12use ZtdQuery\Schema\TableDefinition;
13use ZtdQuery\Schema\TableDefinitionRegistry;
14use ZtdQuery\Shadow\ShadowStore;
15
16#[CoversClass(AlteredTableProjection::class)]
17#[UsesClass(AlterTableMutation::class)]
18#[UsesClass(\ZtdQuery\Platform\Sqlite\Sql\SqliteIdentifierQuoter::class)]
19final class AlteredTableProjectionTest extends TestCase
20{
21    public function testAlterMutationBuildsProjectionWithoutApplyingIt(): void
22    {
23        $registry = new TableDefinitionRegistry();
24        $definition = new TableDefinition(['id', 'name'], ['id' => 'INTEGER', 'name' => 'TEXT'], ['id'], ['id'], []);
25        $registry->register('users', $definition);
26        $store = new ShadowStore();
27        $store->set('users', [['id' => 1, 'name' => 'Alice']]);
28        $mutation = (new AlteredTableProjection($registry))->alterMutation('ALTER TABLE users RENAME TO people', 'users', 'people', $definition, ['"id"', '"name"']);
29        self::assertSame('SELECT "id", "name" FROM "users"', $mutation->resultSelect());
30        self::assertSame('users', $mutation->tableName());
31        self::assertFalse($registry->has('people'));
32    }
33
34    public function testAlterMutationRejectsRemovingEveryColumn(): void
35    {
36        $registry = new TableDefinitionRegistry();
37        $definition = new TableDefinition(['id', 'name'], ['id' => 'INTEGER', 'name' => 'TEXT'], ['id'], ['id'], []);
38        $registry->register('users', $definition);
39        $store = new ShadowStore();
40        $store->set('users', [['id' => 1, 'name' => 'Alice']]);
41        $this->expectException(\ZtdQuery\Exception\UnsupportedSqlException::class);
42        (new AlteredTableProjection($registry))->alterMutation('ALTER TABLE users DROP COLUMN id', 'users', 'users', $definition, []);
43    }
44
45    public function testExistingColumnPreservesCanonicalName(): void
46    {
47        $registry = new TableDefinitionRegistry();
48        $definition = new TableDefinition(['id', 'name'], ['id' => 'INTEGER', 'name' => 'TEXT'], ['id'], ['id'], []);
49        $registry->register('users', $definition);
50        $store = new ShadowStore();
51        $store->set('users', [['id' => 1, 'name' => 'Alice']]);
52        $projection = new AlteredTableProjection($registry);
53        self::assertSame('name', $projection->existingColumn($definition, 'NAME'));
54        self::assertNull($projection->existingColumn($definition, 'missing'));
55    }
56
57    public function testQuotedColumnsPreservesOrder(): void
58    {
59        self::assertSame(['"id"', '"full name"'], (new AlteredTableProjection(new TableDefinitionRegistry()))->quotedColumns(['id', 'full name']));
60    }
61
62    public function testQuoteEscapesEmbeddedDoubleQuotes(): void
63    {
64        self::assertSame('"a""b"', (new AlteredTableProjection(new TableDefinitionRegistry()))->quote('a"b'));
65    }
66
67}
68