packages/sql-fixture/tests/Unit/Platform/PostgreSql/Schema/CatalogColumnTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Platform\PostgreSql\Schema;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use SqlFixture\Platform\PostgreSql\Schema\CatalogColumn as Subject;
10
11#[CoversClass(Subject::class)]
12final class CatalogColumnTest extends TestCase
13{
14    public function testMapDataTypeFormatsNumericAndLengthParameters(): void
15    {
16        $column = ['data_type' => 'numeric', 'character_maximum_length' => null, 'numeric_precision' => '8', 'numeric_scale' => '2', 'udt_name' => 'numeric'];
17        self::assertSame('NUMERIC(8, 2)', (new Subject())->mapDataType($column));
18        $column['data_type'] = 'character varying';
19        $column['character_maximum_length'] = '40';
20        self::assertSame('VARCHAR(40)', (new Subject())->mapDataType($column));
21    }
22
23    public function testResolveTypeNormalizesArrayElements(): void
24    {
25        $column = ['data_type' => 'ARRAY', 'character_maximum_length' => null, 'numeric_precision' => null, 'numeric_scale' => null, 'udt_name' => '_int4'];
26        self::assertSame('INT4_ARRAY', (new Subject())->resolveType($column));
27    }
28
29    public function testParseDefaultRemovesCastsAndRecognizesSequences(): void
30    {
31        $parser = new Subject();
32        self::assertSame('open', $parser->parseDefault("'open'::text"));
33        self::assertNull($parser->parseDefault("nextval('users_id_seq'::regclass)"));
34        self::assertSame(12.5, $parser->parseDefault('12.5'));
35        self::assertTrue($parser->parseDefault('true'));
36    }
37    #[\PHPUnit\Framework\Attributes\DataProvider('providerCatalogTypes')]
38    public function testMapDataTypeRetainsTheCatalogDeclaration(string $type, ?string $length, ?string $precision, ?string $scale, string $udt, string $ddl, string $resolved): void
39    {
40        $row = ['data_type' => $type, 'character_maximum_length' => $length, 'numeric_precision' => $precision, 'numeric_scale' => $scale, 'udt_name' => $udt];
41        $column = new Subject();
42        self::assertSame($ddl, $column->mapDataType($row));
43        self::assertSame($resolved, $column->resolveType($row));
44    }
45
46    /**
47     * @return list<array{string, ?string, ?string, ?string, string, string, string}>
48     */
49    public static function providerCatalogTypes(): array
50    {
51        return [
52            ['character varying', '40', null, null, 'varchar', 'VARCHAR(40)', 'CHARACTER VARYING'],
53            ['character varying', null, null, null, 'varchar', 'CHARACTER VARYING', 'CHARACTER VARYING'],
54            ['character', '3', null, null, 'bpchar', 'CHAR(3)', 'CHARACTER'],
55            ['character', null, null, null, 'bpchar', 'CHARACTER', 'CHARACTER'],
56            ['numeric', null, null, null, 'numeric', 'NUMERIC', 'NUMERIC'],
57            ['numeric', null, '8', null, 'numeric', 'NUMERIC(8)', 'NUMERIC'],
58            ['numeric', null, '8', '0', 'numeric', 'NUMERIC(8)', 'NUMERIC'],
59            ['numeric', null, '8', '2', 'numeric', 'NUMERIC(8, 2)', 'NUMERIC'],
60            ['array', null, null, null, '_int4', '_INT4', 'INT4_ARRAY'],
61            ['user-defined', null, null, null, 'mood', 'MOOD', 'MOOD'],
62            ['integer', null, '32', '0', 'int4', 'INTEGER', 'INTEGER'],
63        ];
64    }
65
66    #[\PHPUnit\Framework\Attributes\DataProvider('providerCatalogDefaults')]
67    public function testParseDefaultInterpretsCatalogLiterals(?string $input, int|float|bool|string|null $expected): void
68    {
69        self::assertSame($expected, (new Subject())->parseDefault($input));
70    }
71
72    /**
73     * @return list<array{?string, int|float|bool|string|null}>
74     */
75    public static function providerCatalogDefaults(): array
76    {
77        return [
78            [null, null],
79            ['null', null],
80            ['null::', null],
81            ["nextval('orders_id_seq'::regclass)", null],
82            ["'line\nvalue'::text", "line\nvalue"],
83            ["'ready'", 'ready'],
84            ["'line\nvalue'", "line\nvalue"],
85            ['FALSE', false],
86            ['TRUE', true],
87            ['0', 0],
88            ['-12', -12],
89            ['-0.25', -0.25],
90            ['CURRENT_TIMESTAMP', 'CURRENT_TIMESTAMP'],
91        ];
92    }
93}
94