packages/sql-faker/tests/Unit/Generation/Coverage/SequenceObservationTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Generation\Coverage;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Generation\Coverage\SequenceObservation;
11use SqlFaker\Generation\Token\ProductionOccurrence;
12use SqlFaker\Generation\Token\TerminalOccurrence;
13use SqlFaker\Generation\Token\TerminalSequence;
14
15#[CoversClass(SequenceObservation::class)]
16#[UsesClass(ProductionOccurrence::class)]
17#[UsesClass(TerminalOccurrence::class)]
18#[UsesClass(TerminalSequence::class)]
19final class SequenceObservationTest extends TestCase
20{
21 public function testLeavesGroupsCompleteIdentitiesUnderEveryAncestor(): void
22 {
23 $leaf = new TerminalOccurrence('A', 2, [0, 1], ['root', 'child']);
24 self::assertSame([0 => [[2, 'A']], 1 => [[2, 'A']]], (new SequenceObservation())->leaves([$leaf]));
25 self::assertSame([], (new SequenceObservation())->leaves([]));
26 }
27
28 public function testPreservedCreditsUnmodifiedSiblingsAndTheirEmptyChildren(): void
29 {
30 $a = new TerminalOccurrence('A', 4, [0, 1], ['root', 'a']);
31 $b = new TerminalOccurrence('B', 5, [0, 2], ['root', 'b']);
32 $input = new TerminalSequence([$a, $b], [$a, $b], [], [
33 new ProductionOccurrence(0, null, 'root', 0), new ProductionOccurrence(1, 0, 'a', 0),
34 new ProductionOccurrence(2, 0, 'b', 0), new ProductionOccurrence(3, 2, 'empty', 0),
35 ]);
36 $observer = new SequenceObservation();
37 self::assertSame([0, 1, 2, 3], $observer->preserved($input));
38 self::assertSame([2, 3], $observer->preserved($input->replace(0, 1, [$a->replaced('OTHER', 'source')], 'source')));
39 self::assertSame([2, 3], $observer->preserved($input->replace(0, 1, [], 'source')));
40 }
41
42 public function testPreservedDistinguishesEmptyGrammarFromInsertedOutput(): void
43 {
44 $input = new TerminalSequence([], [], [], [new ProductionOccurrence(0, null, 'root', 0), new ProductionOccurrence(1, 0, 'empty', 0)]);
45 $observer = new SequenceObservation();
46 self::assertSame([0, 1], $observer->preserved($input));
47 self::assertSame([], $observer->preserved($input->replace(0, 0, [$input->insertedFor('X', 1, 'source')], 'source')));
48 }
49}
50