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