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