Passed
Pull Request — master (#363)
by
unknown
12:34
created

WithStatementTest   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 77
dl 0
loc 128
rs 10
c 1
b 0
f 0
wmc 8

8 Methods

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

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