packages/sql-fixture/tests/Unit/Platform/MySql/Schema/TableDefinitionTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Platform\MySql\Schema;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use SqlFixture\Platform\MySql\Schema\TableDefinition as Subject;
10
11#[CoversClass(Subject::class)]
12#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Platform\MySql\Schema\ColumnParser::class)]
13#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Platform\MySql\Schema\DefaultExpression::class)]
14#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Platform\MySql\Schema\TypeParameters::class)]
15#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Schema\ColumnDefinition::class)]
16#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Schema\SchemaParseException::class)]
17#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Schema\TypeShape::class)]
18#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Schema\Exception\InvalidSqlException::class)]
19#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Schema\Exception\ExpectedCreateTableException::class)]
20#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFixture\Schema\Exception\MissingColumnDefinitionsException::class)]
21final class TableDefinitionTest extends TestCase
22{
23    public function testExtractTableNameUsesTheNativeTableIdentifier(): void
24    {
25        $sql = 'CREATE TABLE users (id INT NOT NULL PRIMARY KEY, amount DECIMAL(8, 2) UNSIGNED DEFAULT 12.5)';
26        $parser = new \PhpMyAdmin\SqlParser\Parser($sql);
27        $statement = $parser->statements[0];
28        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $statement);
29        self::assertSame('users', (new Subject())->extractTableName($statement, $sql));
30    }
31
32    public function testExtractColumnsPreservesDefinitions(): void
33    {
34        $sql = 'CREATE TABLE users (id INT NOT NULL PRIMARY KEY, amount DECIMAL(8, 2) UNSIGNED DEFAULT 12.5)';
35        $parser = new \PhpMyAdmin\SqlParser\Parser($sql);
36        $statement = $parser->statements[0];
37        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $statement);
38        $columns = (new Subject())->extractColumns($statement, 'users');
39        self::assertSame(['id', 'amount'], array_keys($columns));
40        self::assertSame(8, $columns['amount']->precision);
41        self::assertSame(12.5, $columns['amount']->default);
42    }
43
44    public function testExtractPrimaryKeysReadsInlineAndTableConstraints(): void
45    {
46        $sql = 'CREATE TABLE users (id INT NOT NULL PRIMARY KEY, amount DECIMAL(8, 2) UNSIGNED DEFAULT 12.5)';
47        $parser = new \PhpMyAdmin\SqlParser\Parser($sql);
48        $statement = $parser->statements[0];
49        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $statement);
50        self::assertSame(['id'], (new Subject())->extractPrimaryKeys($statement));
51    }
52
53    public function testNativeDecodedIdentifiersPreserveEmbeddedBackticks(): void
54    {
55        $sql = 'CREATE TABLE `user``data` (`user``id` INT, PRIMARY KEY (`user``id`))';
56        $parser = new \PhpMyAdmin\SqlParser\Parser($sql);
57        $statement = $parser->statements[0];
58        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $statement);
59        $definition = new Subject();
60        self::assertSame('user`data', $definition->extractTableName($statement, $sql));
61        self::assertSame(['user`id'], array_keys($definition->extractColumns($statement, 'user`data')));
62        self::assertSame(['user`id'], $definition->extractPrimaryKeys($statement));
63    }
64}
65