Passed
Pull Request — master (#363)
by
unknown
13:37 queued 04:05
created

WithStatementTest::parseWith()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 15
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 17
rs 9.7666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin\SqlParser\Tests\Parser;
6
7
use PhpMyAdmin\SqlParser\Components\WithKeyword;
8
use PhpMyAdmin\SqlParser\Lexer;
9
use PhpMyAdmin\SqlParser\Parser;
10
use PhpMyAdmin\SqlParser\Tests\TestCase;
11
use stdClass;
12
13
class WithStatementTest extends TestCase
14
{
15
    /**
16
     * @dataProvider parseWith
17
     */
18
    public function testParse(string $test): void
19
    {
20
        $this->runParserTest($test);
21
    }
22
23
    /**
24
     * @return array<int,array<int, string>>
25
     */
26
    public function parseWith(): array
27
    {
28
        return [
29
            ['parser/parseWithStatement'],
30
            ['parser/parseWithStatement1'],
31
            ['parser/parseWithStatement2'],
32
            ['parser/parseWithStatement3'],
33
            ['parser/parseWithStatement4'],
34
            ['parser/parseWithStatement5'],
35
            ['parser/parseWithStatement6'],
36
            ['parser/parseWithStatementErr'],
37
            ['parser/parseWithStatementErr1'],
38
            ['parser/parseWithStatementErr2'],
39
            ['parser/parseWithStatementErr3'],
40
            ['parser/parseWithStatementErr4'],
41
            ['parser/parseWithStatementErr5'],
42
            ['parser/parseWithStatementErr6'],
43
        ];
44
    }
45
46
    public function testWith(): void
47
    {
48
        $sql = <<<SQL
49
WITH categories(identifier, name, parent_id) AS (
50
    SELECT c.identifier, c.name, c.parent_id FROM category c WHERE c.identifier = 'a'
51
    UNION ALL
52
    SELECT c.identifier, c.name, c.parent_id FROM categories, category c WHERE c.identifier = categories.parent_id
53
), foo AS ( SELECT * FROM test )
54
SELECT * FROM categories
55
SQL;
56
57
        $lexer = new Lexer($sql);
58
59
        $lexerErrors = $this->getErrorsAsArray($lexer);
60
        $this->assertCount(0, $lexerErrors);
61
        $parser = new Parser($lexer->list);
62
        $parserErrors = $this->getErrorsAsArray($parser);
63
        $this->assertCount(0, $parserErrors);
64
        $this->assertCount(1, $parser->statements);
65
66
        // phpcs:disable Generic.Files.LineLength.TooLong
67
        $expected = <<<SQL
68
WITH categories(identifier, name, parent_id) AS (SELECT c.identifier, c.name, c.parent_id FROM category AS `c` WHERE c.identifier = 'a' UNION ALL SELECT c.identifier, c.name, c.parent_id FROM categories, category AS `c` WHERE c.identifier = categories.parent_id), foo AS (SELECT * FROM test)
69
SQL;
70
        // phpcs:enable
71
        $this->assertEquals($expected, $parser->statements[0]->build());
72
    }
73
74
    public function testWithHasErrors(): void
75
    {
76
        $sql = <<<SQL
77
WITH categories(identifier, name, parent_id) AS (
78
    SOMETHING * FROM foo
79
)
80
SELECT * FROM categories
81
SQL;
82
83
        $lexer = new Lexer($sql);
84
85
        $lexerErrors = $this->getErrorsAsArray($lexer);
86
        $this->assertCount(0, $lexerErrors);
87
        $parser = new Parser($lexer->list);
88
        $parserErrors = $this->getErrorsAsArray($parser);
89
        $this->assertCount(4, $parserErrors);
90
    }
91
92
    public function testWithEmbedParenthesis(): void
93
    {
94
        $sql = <<<SQL
95
WITH categories AS (
96
    SELECT * FROM (SELECT * FROM foo)
97
)
98
SELECT * FROM categories
99
SQL;
100
101
        $lexer = new Lexer($sql);
102
        $lexerErrors = $this->getErrorsAsArray($lexer);
103
        $this->assertCount(0, $lexerErrors);
104
        $parser = new Parser($lexer->list);
105
        $parserErrors = $this->getErrorsAsArray($parser);
106
        $this->assertCount(0, $parserErrors);
107
108
        // phpcs:disable Generic.Files.LineLength.TooLong
109
        $expected = <<<SQL
110
WITH categories AS (SELECT * FROM (SELECT * FROM foo))
111
SQL;
112
        // phpcs:enable
113
        $this->assertEquals($expected, $parser->statements[0]->build());
114
    }
115
116
    public function testWithHasUnclosedParenthesis(): void
117
    {
118
        $sql = <<<SQL
119
WITH categories(identifier, name, parent_id) AS (
120
    SELECT * FROM (SELECT * FROM foo
121
)
122
SELECT * FROM categories
123
SQL;
124
125
        $lexer = new Lexer($sql);
126
127
        $lexerErrors = $this->getErrorsAsArray($lexer);
128
        $this->assertCount(0, $lexerErrors);
129
        $parser = new Parser($lexer->list);
130
        $parserErrors = $this->getErrorsAsArray($parser);
131
        $this->assertEquals($parserErrors[0][0], 'A closing bracket was expected.');
132
    }
133
134
    public function testBuildWrongWithKeyword(): void
135
    {
136
        $this->expectExceptionMessage('Can not build a component that is not a WithKeyword');
137
        WithKeyword::build(new stdClass());
0 ignored issues
show
Bug introduced by
new stdClass() of type stdClass is incompatible with the type PhpMyAdmin\SqlParser\Components\WithKeyword expected by parameter $component of PhpMyAdmin\SqlParser\Com...ts\WithKeyword::build(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

137
        WithKeyword::build(/** @scrutinizer ignore-type */ new stdClass());
Loading history...
138
    }
139
140
    public function testBuildBadWithKeyword(): void
141
    {
142
        $this->expectExceptionMessage('No statement inside WITH');
143
        WithKeyword::build(new WithKeyword('test'));
144
    }
145
}
146