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

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Shadow\Mutation\Table;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use ZtdQuery\Platform\MySql\Shadow\Mutation\Table\TableMutationResolver;
10
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\AlterTableMutation::class)]
12#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\ColumnAction::class)]
13#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\ColumnAlteration::class)]
14#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\ColumnDefinitionParser::class)]
15#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\CreateTableRenderer::class)]
16#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\OperationApplier::class)]
17#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\PrimaryKeyAlteration::class)]
18#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\StoredColumns::class)]
19#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\UnsupportedKeyword::class)]
20#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\MySqlColumnTypeMapper::class)]
21#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\Key\MySqlForeignKeyDefinitionParser::class)]
22#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::class)]
23#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlParser::class)]
24#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\Partition\MySqlPartitioningParser::class)]
25#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\MySqlSchemaParser::class)]
26#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Alter\OptionList::class)]
27#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\OptionalInsertIntoNormalizer::class)]
28#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\DefinitionBuilder::class)]
29#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\Key\DefinitionReader::class)]
30#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\Key\TokenReader::class)]
31#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\Partition\PredicateCompiler::class)]
32#[CoversClass(TableMutationResolver::class)]
33final class TableMutationResolverTest extends TestCase
34{
35    public function testResolveCreateTable(): void
36    {
37        $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
38        $schemaParser = new \ZtdQuery\Platform\MySql\Schema\MySqlSchemaParser(new \ZtdQuery\Platform\MySql\Sql\MySqlParser());
39        $resolver = new TableMutationResolver($registry, $schemaParser);
40        $statement = (new \PhpMyAdmin\SqlParser\Parser('CREATE TABLE users (id INT PRIMARY KEY)'))->statements[0];
41        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $statement);
42        $mutation = $resolver->resolveCreateTable($statement, $statement->build());
43        $mutation->apply(new \ZtdQuery\Shadow\ShadowStore(), []);
44        $definition = $registry->get('users');
45        self::assertNotNull($definition);
46        self::assertSame(['id'], $definition->columns);
47        self::assertSame(['id'], $definition->primaryKeys);
48    }
49
50    public function testResolveDropTable(): void
51    {
52        $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
53        $schemaParser = new \ZtdQuery\Platform\MySql\Schema\MySqlSchemaParser(new \ZtdQuery\Platform\MySql\Sql\MySqlParser());
54        $resolver = new TableMutationResolver($registry, $schemaParser);
55        $statement = (new \PhpMyAdmin\SqlParser\Parser('DROP TABLE users'))->statements[0];
56        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\DropStatement::class, $statement);
57        $registry->register('users', new \ZtdQuery\Schema\TableDefinition(['id'], [], ['id'], [], []));
58        $mutation = $resolver->resolveDropTable($statement, $statement->build());
59        $mutation->apply(new \ZtdQuery\Shadow\ShadowStore(), []);
60        self::assertFalse($registry->has('users'));
61    }
62
63    public function testResolveAlterTable(): void
64    {
65        $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
66        $schemaParser = new \ZtdQuery\Platform\MySql\Schema\MySqlSchemaParser(new \ZtdQuery\Platform\MySql\Sql\MySqlParser());
67        $resolver = new TableMutationResolver($registry, $schemaParser);
68        $statement = (new \PhpMyAdmin\SqlParser\Parser('ALTER TABLE users ADD COLUMN name TEXT'))->statements[0];
69        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\AlterStatement::class, $statement);
70        $registry->register('users', new \ZtdQuery\Schema\TableDefinition(['id'], ['id' => 'INT'], ['id'], [], []));
71        $mutation = $resolver->resolveAlterTable($statement, $statement->build());
72        $mutation->apply(new \ZtdQuery\Shadow\ShadowStore(), []);
73        $definition = $registry->get('users');
74        self::assertNotNull($definition);
75        self::assertSame(['id', 'name'], $definition->columns);
76    }
77
78    public function testExtractSelectColumnNames(): void
79    {
80        $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
81        $schemaParser = new \ZtdQuery\Platform\MySql\Schema\MySqlSchemaParser(new \ZtdQuery\Platform\MySql\Sql\MySqlParser());
82        $resolver = new TableMutationResolver($registry, $schemaParser);
83        $statement = (new \PhpMyAdmin\SqlParser\Parser('SELECT id, 1 AS number, 1 + 2, * FROM users'))->statements[0];
84        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\SelectStatement::class, $statement);
85        self::assertSame(['id', 'number', '1___2'], $resolver->extractSelectColumnNames($statement));
86    }
87
88    public function testResolveTruncate(): void
89    {
90        $parser = new \ZtdQuery\Platform\MySql\Sql\MySqlParser();
91        $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
92        $registry->register('users', new \ZtdQuery\Schema\TableDefinition(['id', 'name'], [], ['id'], [], []));
93        $store = new \ZtdQuery\Shadow\ShadowStore();
94        $store->set('users', [['id' => 1, 'name' => 'old']]);
95        $resolver = new TableMutationResolver($registry, new \ZtdQuery\Platform\MySql\Schema\MySqlSchemaParser($parser));
96        $statement = (new \PhpMyAdmin\SqlParser\Parser('TRUNCATE TABLE users'))->statements[0];
97        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\TruncateStatement::class, $statement);
98        $mutation = $resolver->resolveTruncate($statement, $statement->build());
99        self::assertInstanceOf(\ZtdQuery\Shadow\Mutation\Table\TruncateMutation::class, $mutation);
100        self::assertSame('users', $mutation->tableName());
101        $mutation->apply($store, []);
102        self::assertSame([], $store->get('users'));
103    }
104
105}
106