packages/sql-faker/tests/Unit/Generation/Derivation/ConstraintDependenciesTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Generation\Derivation;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Generation\Derivation\CompletionCosts;
11use SqlFaker\Generation\Derivation\CompletionFrontier;
12use SqlFaker\Generation\Derivation\CompletionMemo;
13use SqlFaker\Generation\Derivation\CompletionReduction;
14use SqlFaker\Generation\Derivation\CompletionState;
15use SqlFaker\Generation\Derivation\ConstrainedCompletion;
16use SqlFaker\Generation\Derivation\ConstraintDependencies;
17use SqlFaker\Generation\Plan\GenerationPlan;
18use SqlFaker\Generation\Plan\ProductionPattern;
19use SqlFaker\Grammar\Model\Grammar;
20use SqlFaker\Grammar\Model\NonTerminal;
21use SqlFaker\Grammar\Model\Production;
22use SqlFaker\Grammar\Model\ProductionRule;
23use SqlFaker\Grammar\Model\Terminal;
24
25#[CoversClass(ConstraintDependencies::class)]
26#[UsesClass(CompletionCosts::class)]
27#[UsesClass(CompletionFrontier::class)]
28#[UsesClass(CompletionState::class)]
29#[UsesClass(CompletionMemo::class)]
30#[UsesClass(CompletionReduction::class)]
31#[UsesClass(ConstrainedCompletion::class)]
32#[UsesClass(GenerationPlan::class)]
33#[UsesClass(ProductionPattern::class)]
34#[UsesClass(Grammar::class)]
35#[UsesClass(NonTerminal::class)]
36#[UsesClass(Production::class)]
37#[UsesClass(ProductionRule::class)]
38#[UsesClass(Terminal::class)]
39#[UsesClass(\SqlFaker\Generation\Choice\BytePlanCompiler::class)]
40#[UsesClass(\SqlFaker\Generation\Derivation\Completion\PatternProductions::class)]
41#[UsesClass(\SqlFaker\Generation\Derivation\Completion\CompletionWitness::class)]
42final class ConstraintDependenciesTest extends TestCase
43{
44 public function testAffectedFindsRecursiveAncestorsAndDropsConsumedConstraints(): void
45 {
46 $grammar = new Grammar('root', [
47 'root' => new ProductionRule('root', [new Production([new NonTerminal('child'), new NonTerminal('free')])]),
48 'child' => new ProductionRule('child', [new Production([new NonTerminal('root')]), new Production([new Terminal('T')])]),
49 'free' => new ProductionRule('free', [new Production([new Terminal('T')])]),
50 ]);
51 $dependencies = new ConstraintDependencies($grammar);
52 $plan = GenerationPlan::constrained('root', ['child' => [ProductionPattern::at(1)]]);
53 self::assertSame(['child' => true, 'root' => true], $dependencies->affected($plan, []));
54 self::assertSame(['child' => true, 'root' => true], $dependencies->affected($plan, []));
55 self::assertSame([], $dependencies->affected($plan, ['child' => 1]));
56 self::assertSame(['free' => true, 'root' => true, 'child' => true], $dependencies->affected(GenerationPlan::all()->withPatternForEveryOccurrence('free', ProductionPattern::at(0)), ['free' => 50]));
57 }
58}
59