packages/sql-parser/tests/Unit/Lexer/CursorTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Lexer;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\Small;
9use PHPUnit\Framework\TestCase;
10use SqlParser\Lexer\Cursor;
11
12#[CoversClass(Cursor::class)]
13#[Small]
14final class CursorTest extends TestCase
15{
16 public function testEof(): void
17 {
18 $cursor = new Cursor('ab');
19 $cursor->take(2);
20
21 self::assertTrue($cursor->eof());
22 self::assertFalse((new Cursor('a'))->eof());
23 }
24
25 public function testPeek(): void
26 {
27 $cursor = new Cursor('abc');
28
29 self::assertSame('a', $cursor->peek());
30 self::assertSame('c', $cursor->peek(2));
31 self::assertSame('', $cursor->peek(3));
32 }
33
34 public function testOffset(): void
35 {
36 $cursor = new Cursor('abc');
37 $cursor->take(2);
38
39 self::assertSame(2, $cursor->offset());
40 }
41
42 public function testSeek(): void
43 {
44 $cursor = new Cursor('abc');
45 $cursor->seek(1);
46
47 self::assertSame('b', $cursor->peek());
48 }
49
50 public function testStartsWith(): void
51 {
52 $cursor = new Cursor('SELECT');
53 $cursor->take(2);
54
55 self::assertTrue($cursor->startsWith('LE'));
56 self::assertFalse($cursor->startsWith('le'));
57 }
58
59 public function testStartsWithIgnoringCase(): void
60 {
61 self::assertTrue((new Cursor('Select'))->startsWithIgnoringCase('SEL'));
62 self::assertFalse((new Cursor('Select'))->startsWithIgnoringCase('SET'));
63 }
64
65 public function testTake(): void
66 {
67 $cursor = new Cursor('abc');
68
69 self::assertSame('ab', $cursor->take(2));
70 self::assertSame('c', $cursor->take(5));
71 self::assertSame(3, $cursor->offset());
72 }
73
74 public function testMatch(): void
75 {
76 $cursor = new Cursor('abc123');
77
78 self::assertSame('abc', $cursor->match('[a-z]+'));
79 self::assertNull($cursor->match('[a-z]+'));
80 self::assertSame('123', $cursor->match('[0-9~]+'));
81 }
82
83 public function testLookingAt(): void
84 {
85 $cursor = new Cursor('abc');
86
87 self::assertTrue($cursor->lookingAt('ab'));
88 self::assertFalse($cursor->lookingAt('bc'));
89 self::assertSame(0, $cursor->offset());
90 }
91
92 public function testSkipPastOrEnd(): void
93 {
94 $cursor = new Cursor('a*/b');
95
96 self::assertTrue($cursor->skipPastOrEnd('*/'));
97 self::assertSame(3, $cursor->offset());
98 self::assertFalse($cursor->skipPastOrEnd('*/'));
99 self::assertTrue($cursor->eof());
100 }
101
102 public function testTakeQuoted(): void
103 {
104 $cursor = new Cursor("'it''s' rest");
105
106 self::assertSame("'it''s'", $cursor->takeQuoted("'"));
107 self::assertSame(' rest', $cursor->take(5));
108 }
109
110 public function testTakeQuotedWithBackslashEscapes(): void
111 {
112 $cursor = new Cursor("'a\\'b' x");
113
114 self::assertSame("'a\\'b'", $cursor->takeQuoted("'", true));
115 self::assertNull((new Cursor("'open"))->takeQuoted("'"));
116 self::assertNull((new Cursor("'open\\'"))->takeQuoted("'", true));
117 }
118}
119