packages/sql-faker/tests/Unit/Compiler/Bison/Lexer/BisonScannerTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Compiler\Bison\Lexer;
6
7use PHPUnit\Framework\Attributes\CoversNothing;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Compiler\Bison\Lexer\ActionScanner;
11use SqlFaker\Compiler\Bison\Lexer\BisonScanner;
12use SqlFaker\Compiler\Bison\Lexer\DirectiveScanner;
13use SqlFaker\Compiler\Bison\Lexer\IdentifierScanner;
14use SqlFaker\Compiler\Bison\Lexer\NumberScanner;
15use SqlFaker\Compiler\Bison\Lexer\PunctuationScanner;
16use SqlFaker\Compiler\Bison\Lexer\QuotedLiteralScanner;
17use SqlFaker\Compiler\Bison\Lexer\SourceCursor;
18use SqlFaker\Compiler\Bison\Lexer\TypeTagScanner;
19
20#[CoversNothing]
21#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFaker\Generation\Derivation\CompletionCosts::class)]
22#[\PHPUnit\Framework\Attributes\UsesClass(\SqlFaker\Generation\Derivation\DerivationNode::class)]
23final class BisonScannerTest extends TestCase
24{
25 #[DataProvider('providerScanner')]
26 public function testScanConsumesTheLexemeTheScannerClaims(BisonScanner $scanner, string $source): void
27 {
28 $cursor = new SourceCursor($source);
29
30 self::assertTrue($scanner->handles($cursor->current()));
31
32 $scanner->scan($cursor);
33
34 self::assertTrue($cursor->atEnd(), 'the scanner left input behind');
35 }
36
37 #[DataProvider('providerScanner')]
38 public function testHandlesRejectsWhatNoScannerReads(BisonScanner $scanner, string $source): void
39 {
40 unset($source);
41
42 self::assertFalse($scanner->handles('@'));
43 }
44
45 /**
46 * @return iterable<string, array{BisonScanner, string}>
47 */
48 public static function providerScanner(): iterable
49 {
50 yield 'directive' => [new DirectiveScanner(), '%token'];
51 yield 'action' => [new ActionScanner(), '{ x; }'];
52 yield 'type tag' => [new TypeTagScanner(), '<num>'];
53 yield 'quoted literal' => [new QuotedLiteralScanner(), '"alias"'];
54 yield 'number' => [new NumberScanner(), '42'];
55 yield 'identifier' => [new IdentifierScanner(), 'expr'];
56 yield 'punctuation' => [new PunctuationScanner(), ':'];
57 }
58}
59