Passed
Push — master ( dbc80d...403e38 )
by Maurício
03:07 queued 11s
created

WithStatementTest::testWith()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 19
nc 1
nop 0
dl 0
loc 26
rs 9.6333
c 1
b 0
f 0
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/parseWithStatement7'],
37
            ['parser/parseWithStatementErr'],
38
            ['parser/parseWithStatementErr1'],
39
            ['parser/parseWithStatementErr2'],
40
            ['parser/parseWithStatementErr3'],
41
            ['parser/parseWithStatementErr4'],
42
            ['parser/parseWithStatementErr5'],
43
            ['parser/parseWithStatementErr6'],
44
            ['parser/parseWithStatementErr7'],
45
            ['parser/parseWithStatementErr8'],
46
        ];
47
    }
48
49
    public function testWith(): void
50
    {
51
        $sql = <<<SQL
52
WITH categories(identifier, name, parent_id) AS (
53
    SELECT c.identifier, c.name, c.parent_id FROM category c WHERE c.identifier = 'a'
54
    UNION ALL
55
    SELECT c.identifier, c.name, c.parent_id FROM categories, category c WHERE c.identifier = categories.parent_id
56
), foo AS ( SELECT * FROM test )
57
SELECT * FROM categories
58
SQL;
59
60
        $lexer = new Lexer($sql);
61
62
        $lexerErrors = $this->getErrorsAsArray($lexer);
63
        $this->assertCount(0, $lexerErrors);
64
        $parser = new Parser($lexer->list);
65
        $parserErrors = $this->getErrorsAsArray($parser);
66
        $this->assertCount(0, $parserErrors);
67
        $this->assertCount(1, $parser->statements);
68
69
        // phpcs:disable Generic.Files.LineLength.TooLong
70
        $expected = <<<SQL
71
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) SELECT * FROM categories
72
SQL;
73
        // phpcs:enable
74
        $this->assertEquals($expected, $parser->statements[0]->build());
75
    }
76
77
    public function testWithHasErrors(): void
78
    {
79
        $sql = <<<SQL
80
WITH categories(identifier, name, parent_id) AS (
81
    SOMETHING * FROM foo
82
)
83
SELECT * FROM categories
84
SQL;
85
86
        $lexer = new Lexer($sql);
87
88
        $lexerErrors = $this->getErrorsAsArray($lexer);
89
        $this->assertCount(0, $lexerErrors);
90
        $parser = new Parser($lexer->list);
91
        $parserErrors = $this->getErrorsAsArray($parser);
92
        $this->assertCount(4, $parserErrors);
93
    }
94
95
    public function testWithEmbedParenthesis(): void
96
    {
97
        $sql = <<<SQL
98
WITH categories AS (
99
    SELECT * FROM (SELECT * FROM foo)
100
)
101
SELECT * FROM categories
102
SQL;
103
104
        $lexer = new Lexer($sql);
105
        $lexerErrors = $this->getErrorsAsArray($lexer);
106
        $this->assertCount(0, $lexerErrors);
107
        $parser = new Parser($lexer->list);
108
        $parserErrors = $this->getErrorsAsArray($parser);
109
        $this->assertCount(0, $parserErrors);
110
111
        // phpcs:disable Generic.Files.LineLength.TooLong
112
        $expected = <<<SQL
113
WITH categories AS (SELECT * FROM (SELECT * FROM foo)) SELECT * FROM categories
114
SQL;
115
        // phpcs:enable
116
        $this->assertEquals($expected, $parser->statements[0]->build());
117
    }
118
119
    public function testWithHasUnclosedParenthesis(): void
120
    {
121
        $sql = <<<SQL
122
WITH categories(identifier, name, parent_id) AS (
123
    SELECT * FROM (SELECT * FROM foo
124
)
125
SELECT * FROM categories
126
SQL;
127
128
        $lexer = new Lexer($sql);
129
130
        $lexerErrors = $this->getErrorsAsArray($lexer);
131
        $this->assertCount(0, $lexerErrors);
132
        $parser = new Parser($lexer->list);
133
        $parserErrors = $this->getErrorsAsArray($parser);
134
        $this->assertEquals($parserErrors[0][0], 'A closing bracket was expected.');
135
    }
136
137
    public function testBuildWrongWithKeyword(): void
138
    {
139
        $this->expectExceptionMessage('Can not build a component that is not a WithKeyword');
140
        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

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