packages/sql-faker/tests/Unit/Generation/Output/CombinedSpacingRuleTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Generation\Output;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Generation\Lexeme\Lexeme;
11use SqlFaker\Generation\Lexeme\LexemeBoundary;
12use SqlFaker\Generation\Lexeme\LexemeInput;
13use SqlFaker\Generation\Lexeme\ResolvedOutput;
14use SqlFaker\Generation\Lexeme\SpacingConstraint;
15use SqlFaker\Generation\Lexeme\SpacingRule;
16use SqlFaker\Generation\Output\CombinedSpacingRule;
17use SqlFaker\Generation\Token\TerminalSequence;
18
19#[CoversClass(CombinedSpacingRule::class)]
20#[UsesClass(Lexeme::class)]
21#[UsesClass(LexemeInput::class)]
22#[UsesClass(ResolvedOutput::class)]
23#[UsesClass(LexemeBoundary::class)]
24#[UsesClass(SpacingConstraint::class)]
25#[UsesClass(\SqlFaker\Generation\Token\TerminalOccurrence::class)]
26#[UsesClass(TerminalSequence::class)]
27#[UsesClass(\SqlFaker\Generation\Lexeme\LexemeSequence::class)]
28#[UsesClass(\SqlFaker\Generation\Token\ProductionOccurrence::class)]
29final class CombinedSpacingRuleTest extends TestCase
30{
31    public function testApplyPreservesContradictionsAcrossOrderAndDuplicateRules(): void
32    {
33        $join = $this->createMock(SpacingRule::class);
34        $join->method('apply')->willReturn(new SpacingConstraint(SpacingConstraint::JOIN, ['join']));
35        $space = $this->createMock(SpacingRule::class);
36        $space->method('apply')->willReturn(new SpacingConstraint(SpacingConstraint::SPACE, ['space']));
37        $none = $this->createMock(SpacingRule::class);
38        $none->method('apply')->willReturn(null);
39        $sequence = TerminalSequence::fromNames(['X', 'Y']);
40        $boundary = new LexemeBoundary(new Lexeme('X', 'keyword', $sequence->terminals[0], 'x'), new Lexeme('Y', 'keyword', $sequence->terminals[1], 'y'));
41        $input = new LexemeInput($sequence, 0, new ResolvedOutput());
42        $forward = (new CombinedSpacingRule($join, $space))->apply($boundary, $input);
43        $reverse = (new CombinedSpacingRule($space, $none, $join))->apply($boundary, $input);
44        $duplicate = (new CombinedSpacingRule($join, $join, $space))->apply($boundary, $input);
45        self::assertSame([0, 0, 0], [$forward->allowed, $reverse->allowed, $duplicate->allowed]);
46        self::assertSame([null, null, null], [$forward->separator(), $reverse->separator(), $duplicate->separator()]);
47        self::assertSame(['join', 'space'], $forward->rules);
48        self::assertSame(['space', 'join'], $reverse->rules);
49        self::assertSame($forward->rules, $duplicate->rules);
50        self::assertSame(' ', (new CombinedSpacingRule($none))->apply($boundary, $input)->separator());
51    }
52}
53