packages/sql-faker/tests/Unit/PostgreSql/Generation/Rewrite/Column/ConstraintCapabilitiesRuleTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\PostgreSql\Generation\Rewrite\Column;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use SqlFaker\Generation\Token\ProductionOccurrence;
12use SqlFaker\Generation\Token\TerminalOccurrence;
13use SqlFaker\Generation\Token\TerminalSequence;
14use SqlFaker\PostgreSql\Generation\Rewrite\Column\ConstraintCapabilitiesRule;
15
16#[CoversClass(ConstraintCapabilitiesRule::class)]
17#[UsesClass(ProductionOccurrence::class)]
18#[UsesClass(TerminalOccurrence::class)]
19#[UsesClass(TerminalSequence::class)]
20final class ConstraintCapabilitiesRuleTest extends TestCase
21{
22    #[DataProvider('providerCapabilities')]
23    public function testRewriteAttributesRespectTheirOwningConstraint(string $scope, string $kind, string $option, bool $kept): void
24    {
25        $head = new TerminalOccurrence($kind, 10, [0], [$scope]);
26        $words = explode(' ', $option);
27        $attributes = array_map(static fn (int $index, string $name): TerminalOccurrence =>
28            new TerminalOccurrence($name, 11 + $index, [0, 1, 2], [$scope, 'ConstraintAttributeSpec', 'ConstraintAttributeElem']), array_keys($words), $words);
29        $terminals = [$head, ...$attributes];
30        $input = new TerminalSequence($terminals, $terminals, [], [
31            new ProductionOccurrence(0, null, $scope, 0), new ProductionOccurrence(1, 0, 'ConstraintAttributeSpec', 0),
32            new ProductionOccurrence(2, 1, 'ConstraintAttributeElem', 0),
33        ]);
34        $rule = new ConstraintCapabilitiesRule();
35        $result = $rule->rewrite($input);
36        self::assertSame($kept ? $terminals : [$head], $result->terminals);
37        self::assertSame($input->original, $result->original);
38        self::assertSame($result, $rule->rewrite($result));
39    }
40
41    /**
42     * @return iterable<array{string, string, string, bool}>
43     */
44    public static function providerCapabilities(): iterable
45    {
46        foreach (['CHECK', 'UNIQUE', 'PRIMARY', 'FOREIGN', 'EXCLUDE'] as $kind) {
47            yield ['ConstraintElem', $kind, 'DEFERRABLE', $kind !== 'CHECK'];
48            yield ['ConstraintElem', $kind, 'INITIALLY DEFERRED', $kind !== 'CHECK'];
49            yield ['ConstraintElem', $kind, 'NOT VALID', in_array($kind, ['CHECK', 'FOREIGN'], true)];
50            yield ['ConstraintElem', $kind, 'NO INHERIT', $kind === 'CHECK'];
51            yield ['ConstraintElem', $kind, 'NOT DEFERRABLE', true];
52        }
53        yield ['DomainConstraintElem', 'NOT', 'NOT VALID', false];
54        yield ['DomainConstraintElem', 'NOT', 'NO INHERIT', true];
55        yield ['DomainConstraintElem', 'NOT', 'DEFERRABLE', false];
56        yield ['CreateTrigStmt', 'CREATE', 'NOT VALID', false];
57        yield ['CreateTrigStmt', 'CREATE', 'DEFERRABLE', true];
58        yield ['alter_table_cmd', 'ALTER', 'NO INHERIT', false];
59        yield ['unrelated', 'CHECK', 'DEFERRABLE', true];
60    }
61}
62