packages/sql-faker/tests/Unit/Compiler/Bison/Directive/BisonDirectiveReaderTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Compiler\Bison\Directive;
6
7use PHPUnit\Framework\Attributes\CoversNothing;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Compiler\Bison\Directive\BisonDirectiveReader;
11use SqlFaker\Compiler\Bison\Directive\DefineDirectiveReader;
12use SqlFaker\Compiler\Bison\Directive\ExpectDirectiveReader;
13use SqlFaker\Compiler\Bison\Directive\ParamDirectiveReader;
14use SqlFaker\Compiler\Bison\Directive\PrecedenceDirectiveReader;
15use SqlFaker\Compiler\Bison\Directive\StartDirectiveReader;
16use SqlFaker\Compiler\Bison\Directive\TokenDirectiveReader;
17use SqlFaker\Compiler\Bison\Directive\TypeDirectiveReader;
18use SqlFaker\Compiler\Bison\Lexer\BisonTokenStream;
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 BisonDirectiveReaderTest extends TestCase
24{
25 #[DataProvider('providerReader')]
26 public function testHandlesClaimsTheDirectiveTheReaderIsNamedFor(
27 BisonDirectiveReader $reader,
28 string $directive,
29 string $arguments,
30 ): void {
31 unset($arguments);
32
33 self::assertTrue($reader->handles($directive));
34 }
35
36 #[DataProvider('providerReader')]
37 public function testHandlesRejectsADirectiveThatIsNotItsOwn(
38 BisonDirectiveReader $reader,
39 string $directive,
40 string $arguments,
41 ): void {
42 unset($directive, $arguments);
43
44 self::assertFalse($reader->handles('%no-such-directive'));
45 }
46
47 #[DataProvider('providerReader')]
48 public function testReadConsumesTheArgumentsUpToTheNextDeclaration(
49 BisonDirectiveReader $reader,
50 string $directive,
51 string $arguments,
52 ): void {
53 $stream = BisonTokenStream::over($arguments . ' %%');
54
55 $reader->read($stream, $directive);
56
57 self::assertSame('%%', $stream->next()->value);
58 }
59
60 /**
61 * @return iterable<string, array{BisonDirectiveReader, string, string}>
62 */
63 public static function providerReader(): iterable
64 {
65 yield 'start' => [new StartDirectiveReader(), '%start', 'statement'];
66 yield 'token' => [new TokenDirectiveReader(), '%token', 'IDENT'];
67 yield 'type' => [new TypeDirectiveReader(), '%type', '<num> expr'];
68 yield 'precedence' => [new PrecedenceDirectiveReader(), '%left', 'OR_SYM'];
69 yield 'param' => [new ParamDirectiveReader(), '%parse-param', '{ THD *thd }'];
70 yield 'expect' => [new ExpectDirectiveReader(), '%expect', '3'];
71 yield 'define' => [new DefineDirectiveReader(), '%define', 'api.pure'];
72 }
73}
74