packages/sql-faker/tests/Unit/Generation/Token/TerminalOccurrenceTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Generation\Token;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use SqlFaker\Generation\Token\TerminalOccurrence;
10
11#[CoversClass(TerminalOccurrence::class)]
12
13final class TerminalOccurrenceTest extends TestCase
14{
15    public function testWithinRecognizesOnlyDeclaredAncestors(): void
16    {
17        $terminal = new TerminalOccurrence('IDENT', 3, [0, 2], ['stmt', 'name']);
18        self::assertTrue($terminal->within('stmt'));
19        self::assertFalse($terminal->within('IDENT'));
20    }
21
22    public function testAncestorSelectsTheNearestRecursiveOccurrence(): void
23    {
24        $terminal = new TerminalOccurrence('IDENT', 5, [0, 1, 2], ['expr', 'name', 'expr']);
25        self::assertSame(2, $terminal->ancestor('expr'));
26        self::assertSame(1, $terminal->ancestor('name'));
27        self::assertNull($terminal->ancestor('stmt'));
28    }
29
30    public function testReplacedPreservesIdentityAndScopeWithoutMutatingItsSource(): void
31    {
32        $terminal = new TerminalOccurrence('IDENT', 3, [0, 2], ['stmt', 'name']);
33        $result = $terminal->replaced('MODE', 'source:mode');
34        self::assertSame('IDENT', $terminal->name);
35        self::assertSame('MODE', $result->name);
36        self::assertSame($terminal->id, $result->id);
37        self::assertSame($terminal->ancestors, $result->ancestors);
38        self::assertSame($terminal->rules, $result->rules);
39        self::assertSame('source:mode', $result->rewrite);
40    }
41}
42