packages/sql-faker/tests/Unit/Compiler/Bison/Directive/ParamDirectiveReaderTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Compiler\Bison\Directive;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Compiler\Bison\Ast\BisonParamDeclaration;
11use SqlFaker\Compiler\Bison\Directive\BisonDeclarationBoundary;
12use SqlFaker\Compiler\Bison\Directive\ParamDirectiveReader;
13use SqlFaker\Compiler\Bison\Lexer\ActionScanner;
14use SqlFaker\Compiler\Bison\Lexer\BisonLexeme;
15use SqlFaker\Compiler\Bison\Lexer\BisonLexer;
16use SqlFaker\Compiler\Bison\Lexer\BisonScannerChain;
17use SqlFaker\Compiler\Bison\Lexer\BisonToken;
18use SqlFaker\Compiler\Bison\Lexer\BisonTokenStream;
19use SqlFaker\Compiler\Bison\Lexer\BisonTrivia;
20use SqlFaker\Compiler\Bison\Lexer\DirectiveScanner;
21use SqlFaker\Compiler\Bison\Lexer\IdentifierScanner;
22use SqlFaker\Compiler\Bison\Lexer\NumberScanner;
23use SqlFaker\Compiler\Bison\Lexer\QuotedLiteralScanner;
24use SqlFaker\Compiler\Bison\Lexer\SourceCursor;
25use SqlFaker\Compiler\Bison\Lexer\TypeTagScanner;
26
27#[CoversClass(ParamDirectiveReader::class)]
28#[UsesClass(BisonDeclarationBoundary::class)]
29#[UsesClass(BisonLexeme::class)]
30#[UsesClass(BisonLexer::class)]
31#[UsesClass(BisonScannerChain::class)]
32#[UsesClass(BisonToken::class)]
33#[UsesClass(BisonTokenStream::class)]
34#[UsesClass(BisonTrivia::class)]
35#[UsesClass(SourceCursor::class)]
36#[UsesClass(ActionScanner::class)]
37#[UsesClass(BisonParamDeclaration::class)]
38#[UsesClass(DirectiveScanner::class)]
39#[UsesClass(IdentifierScanner::class)]
40#[UsesClass(NumberScanner::class)]
41#[UsesClass(QuotedLiteralScanner::class)]
42#[UsesClass(TypeTagScanner::class)]
43#[UsesClass(\SqlFaker\Compiler\Bison\Lexer\PunctuationScanner::class)]
44#[UsesClass(\SqlFaker\Compiler\GrammarParseException::class)]
45final class ParamDirectiveReaderTest extends TestCase
46{
47    public function testHandlesClaimsBothParameterDirectives(): void
48    {
49        $reader = new ParamDirectiveReader();
50
51        self::assertTrue($reader->handles('%parse-param'));
52        self::assertTrue($reader->handles('%lex-param'));
53        self::assertFalse($reader->handles('%token'));
54    }
55
56    public function testReadTakesTheBracedArgumentAndTheDirectiveKind(): void
57    {
58        $declaration = (new ParamDirectiveReader())
59            ->read(BisonTokenStream::over('{ THD *thd }'), '%parse-param');
60
61        self::assertInstanceOf(BisonParamDeclaration::class, $declaration);
62        self::assertSame('parse-param', $declaration->kind);
63        self::assertSame(' THD *thd ', $declaration->code);
64    }
65
66    public function testReadDistinguishesTheScannerDirective(): void
67    {
68        $declaration = (new ParamDirectiveReader())
69            ->read(BisonTokenStream::over('{ yyscan_t s }'), '%lex-param');
70
71        self::assertInstanceOf(BisonParamDeclaration::class, $declaration);
72        self::assertSame('lex-param', $declaration->kind);
73    }
74
75    public function testReadDeclaresNothingWhenNoBracedCodeFollows(): void
76    {
77        self::assertNull((new ParamDirectiveReader())->read(BisonTokenStream::over('thd'), '%parse-param'));
78    }
79}
80