packages/ztd-query-postgres/tests/Unit/Shadow/Mutation/Upsert/Expression/PrecedenceParserTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Shadow\Mutation\Upsert\Expression;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9
10#[CoversClass(\ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\PrecedenceParser::class)]
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\ComparisonOperator::class)]
12#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\ExpressionCursor::class)]
13#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\ExpressionLexeme::class)]
14#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\PrimaryParser::class)]
15#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::class)]
16final class PrecedenceParserTest extends TestCase
17{
18 public function testParseOrPreservesPrecedenceAndConsumesItsTokens(): void
19 {
20 $sql = 'TRUE OR FALSE AND FALSE';
21 $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
22 $cursor = new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\ExpressionCursor($sql, 'users', $tokens);
23 $expression = (new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\PrecedenceParser($cursor))->parseOr();
24 self::assertSame(true, $expression->evaluate([], [], 'users'));
25 self::assertSame(count($tokens), $cursor->index);
26 }
27
28 public function testParseAndPreservesPrecedenceAndConsumesItsTokens(): void
29 {
30 $sql = 'TRUE AND (FALSE OR TRUE)';
31 $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
32 $cursor = new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\ExpressionCursor($sql, 'users', $tokens);
33 $expression = (new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\PrecedenceParser($cursor))->parseAnd();
34 self::assertSame(true, $expression->evaluate([], [], 'users'));
35 self::assertSame(count($tokens), $cursor->index);
36 }
37
38 public function testParseComparisonPreservesPrecedenceAndConsumesItsTokens(): void
39 {
40 $sql = '2 + 3 * 4 >= 14';
41 $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
42 $cursor = new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\ExpressionCursor($sql, 'users', $tokens);
43 $expression = (new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\PrecedenceParser($cursor))->parseComparison();
44 self::assertSame(true, $expression->evaluate([], [], 'users'));
45 self::assertSame(count($tokens), $cursor->index);
46 }
47
48 public function testParseAdditivePreservesPrecedenceAndConsumesItsTokens(): void
49 {
50 $sql = '8 - 3 - 1 * 2';
51 $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
52 $cursor = new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\ExpressionCursor($sql, 'users', $tokens);
53 $expression = (new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\PrecedenceParser($cursor))->parseAdditive();
54 self::assertSame(3, $expression->evaluate([], [], 'users'));
55 self::assertSame(count($tokens), $cursor->index);
56 }
57
58 public function testParseMultiplicativePreservesPrecedenceAndConsumesItsTokens(): void
59 {
60 $sql = '12 / 3 % 3';
61 $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
62 $cursor = new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\ExpressionCursor($sql, 'users', $tokens);
63 $expression = (new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\PrecedenceParser($cursor))->parseMultiplicative();
64 self::assertSame(1, $expression->evaluate([], [], 'users'));
65 self::assertSame(count($tokens), $cursor->index);
66 }
67
68 public function testParseUnaryPreservesPrecedenceAndConsumesItsTokens(): void
69 {
70 $sql = 'NOT -1';
71 $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
72 $cursor = new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\ExpressionCursor($sql, 'users', $tokens);
73 $expression = (new \ZtdQuery\Platform\Postgres\Shadow\Mutation\Upsert\Expression\PrecedenceParser($cursor))->parseUnary();
74 self::assertSame(false, $expression->evaluate([], [], 'users'));
75 self::assertSame(count($tokens), $cursor->index);
76 }
77}
78