packages/sql-faker/tests/Unit/Compiler/Bison/Lexer/PunctuationScannerTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Compiler\Bison\Lexer;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use SqlFaker\Compiler\Bison\Lexer\BisonLexeme;
12use SqlFaker\Compiler\Bison\Lexer\BisonToken;
13use SqlFaker\Compiler\Bison\Lexer\PunctuationScanner;
14use SqlFaker\Compiler\Bison\Lexer\SourceCursor;
15
16#[CoversClass(PunctuationScanner::class)]
17#[UsesClass(BisonLexeme::class)]
18#[UsesClass(BisonToken::class)]
19#[UsesClass(SourceCursor::class)]
20final class PunctuationScannerTest extends TestCase
21{
22    public function testHandlesRejectsCharactersItDoesNotOwn(): void
23    {
24        $scanner = new PunctuationScanner();
25
26        self::assertFalse($scanner->handles('@'));
27        self::assertFalse($scanner->handles('a'));
28        self::assertFalse($scanner->handles('%'));
29    }
30
31    #[DataProvider('providerPunctuation')]
32    public function testScanReadsEachPunctuationCharacterAsItsOwnLexeme(string $character, BisonLexeme $expected): void
33    {
34        $scanner = new PunctuationScanner();
35        $cursor = new SourceCursor($character . 'rest');
36
37        self::assertTrue($scanner->handles($character));
38
39        $token = $scanner->scan($cursor);
40
41        self::assertSame($expected, $token->type);
42        self::assertSame($character, $token->value);
43        self::assertSame(0, $token->offset);
44        self::assertSame('rest', $cursor->takeRest());
45    }
46
47    /**
48     * @return iterable<string, array{string, BisonLexeme}>
49     */
50    public static function providerPunctuation(): iterable
51    {
52        yield 'colon opens the alternatives' => [':', BisonLexeme::Colon];
53        yield 'semicolon closes the rule' => [';', BisonLexeme::Semicolon];
54        yield 'pipe separates alternatives' => ['|', BisonLexeme::Pipe];
55        yield 'equals' => ['=', BisonLexeme::CharLiteral];
56        yield 'comma' => [',', BisonLexeme::CharLiteral];
57        yield 'open paren' => ['(', BisonLexeme::CharLiteral];
58        yield 'close paren' => [')', BisonLexeme::CharLiteral];
59        yield 'open bracket' => ['[', BisonLexeme::CharLiteral];
60        yield 'close bracket' => [']', BisonLexeme::CharLiteral];
61    }
62}
63