packages/ztd-query-postgres/tests/Unit/Schema/Definition/TableFieldsTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Schema\Definition;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9
10#[CoversClass(\ZtdQuery\Platform\Postgres\Schema\Definition\TableFields::class)]
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Schema\PgSqlColumnTypeMapper::class)]
12#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::class)]
13#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Partition\PgSqlPartitionParser::class)]
14#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Schema\Definition\ColumnDefinition::class)]
15#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Schema\Definition\ColumnTypeDeclaration::class)]
16#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Schema\Definition\TableConstraint::class)]
17#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Partition\BoundPredicate::class)]
18#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Partition\ClauseTokens::class)]
19final class TableFieldsTest extends TestCase
20{
21    public function testAppendEntryPreservesInlineAndTableConstraints(): void
22    {
23        $fields = new \ZtdQuery\Platform\Postgres\Schema\Definition\TableFields();
24        $fields->appendEntry('id SERIAL PRIMARY KEY');
25        $fields->appendEntry("name TEXT UNIQUE DEFAULT 'guest'");
26        $fields->appendEntry('CONSTRAINT unique_pair UNIQUE (id, name)');
27        $definition = $fields->definition('CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT)', []);
28        self::assertNotNull($definition);
29        self::assertSame(['id', 'name'], $definition->columns);
30        self::assertSame(['id'], $definition->primaryKeys);
31        self::assertSame(['id'], $definition->notNullColumns);
32        self::assertSame("'guest'", $definition->columnDefaults['name']);
33        self::assertSame(\ZtdQuery\Schema\Key\IdentityGenerationStrategy::Sequence, $definition->identityStrategies['id']);
34        self::assertSame(['id', 'name'], $definition->uniqueConstraints['unique_pair']);
35    }
36
37    public function testAppendColumnRecordsGeneratedExpressions(): void
38    {
39        $fields = new \ZtdQuery\Platform\Postgres\Schema\Definition\TableFields();
40        $column = (new \ZtdQuery\Platform\Postgres\Schema\Definition\ColumnDefinition())->parseColumnDefinition('total NUMERIC GENERATED ALWAYS AS (price * quantity) STORED');
41        self::assertNotNull($column);
42        $fields->appendColumn($column);
43        $definition = $fields->definition('CREATE TABLE totals (total NUMERIC)', []);
44        self::assertNotNull($definition);
45        self::assertSame('(price * quantity)', $definition->generatedExpressions['total']);
46        self::assertSame('NUMERIC', $definition->columnTypes['total']);
47    }
48
49    public function testDefinitionRejectsEmptyTablesAndUnknownUniqueColumns(): void
50    {
51        $fields = new \ZtdQuery\Platform\Postgres\Schema\Definition\TableFields();
52        self::assertNull($fields->definition('CREATE TABLE empty ()', []));
53        $fields->appendEntry('id INT');
54        $fields->appendEntry('UNIQUE (missing)');
55        self::assertNull($fields->definition('CREATE TABLE broken (id INT)', []));
56    }
57}
58