Passed
Pull Request — master (#480)
by
unknown
03:22
created

ContextTest::testModeWithCombinedModes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 13
nc 1
nop 0
dl 0
loc 19
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin\SqlParser\Tests\Lexer;
6
7
use PhpMyAdmin\SqlParser\Context;
8
use PhpMyAdmin\SqlParser\Tests\TestCase;
9
10
use function class_exists;
11
12
class ContextTest extends TestCase
13
{
14
    public function testLoad(): void
15
    {
16
        // Default context is 5.7.0.
17
        $this->assertEquals('\\PhpMyAdmin\\SqlParser\\Contexts\\ContextMySql50700', Context::$loadedContext);
18
        $this->assertArrayHasKey('STORED', Context::$keywords);
19
        $this->assertArrayNotHasKey('AUTHORS', Context::$keywords);
20
21
        // Restoring context.
22
        Context::load('');
23
        $this->assertEquals('\\PhpMyAdmin\\SqlParser\\Contexts\\ContextMySql50700', Context::$defaultContext);
24
        $this->assertArrayHasKey('STORED', Context::$keywords);
25
        $this->assertArrayNotHasKey('AUTHORS', Context::$keywords);
26
    }
27
28
    /**
29
     * Test for loading closest SQL context
30
     *
31
     * @dataProvider contextLoadingProvider
32
     */
33
    public function testLoadClosest(string $context, string|null $expected): void
34
    {
35
        $this->assertEquals($expected, Context::loadClosest($context));
36
        if ($expected !== null) {
37
            $this->assertEquals('\\PhpMyAdmin\\SqlParser\\Contexts\\Context' . $expected, Context::$loadedContext);
38
            $this->assertTrue(class_exists(Context::$loadedContext));
39
        }
40
41
        // Restoring context.
42
        Context::load('');
43
    }
44
45
    /**
46
     * @return array<string, array<int, string|null>>
47
     * @psalm-return array<string, array{string, (string|null)}>
48
     */
49
    public static function contextLoadingProvider(): array
50
    {
51
        return [
52
            'MySQL match' => [
53
                'MySql50500',
54
                'MySql50500',
55
            ],
56
            'MySQL strip' => [
57
                'MySql50712',
58
                'MySql50700',
59
            ],
60
            'MySQL fallback' => [
61
                'MySql99999',
62
                'MySql50700',
63
            ],
64
            'MariaDB match' => [
65
                'MariaDb100000',
66
                'MariaDb100000',
67
            ],
68
            'MariaDB stripg' => [
69
                'MariaDb109900',
70
                'MariaDb100000',
71
            ],
72
            'MariaDB fallback' => [
73
                'MariaDb990000',
74
                'MariaDb100300',
75
            ],
76
            'Invalid' => [
77
                'Sql',
78
                null,
79
            ],
80
        ];
81
    }
82
83
    /**
84
     * @dataProvider contextNamesProvider
85
     */
86
    public function testLoadAll(string $context): void
87
    {
88
        Context::load($context);
89
        $this->assertEquals('\\PhpMyAdmin\\SqlParser\\Contexts\\Context' . $context, Context::$loadedContext);
90
91
        // Restoring context.
92
        Context::load('');
93
    }
94
95
    /**
96
     * @return string[][]
97
     */
98
    public static function contextNamesProvider(): array
99
    {
100
        return [
101
            ['MySql50000'],
102
            ['MySql50100'],
103
            ['MySql50500'],
104
            ['MySql50600'],
105
            ['MySql50700'],
106
            ['MySql80000'],
107
            ['MariaDb100000'],
108
            ['MariaDb100100'],
109
            ['MariaDb100200'],
110
            ['MariaDb100300'],
111
        ];
112
    }
113
114
    public function testLoadError(): void
115
    {
116
        $this->assertFalse(Context::load('Foo'));
117
    }
118
119
    /**
120
     * @param int|string $mode
121
     *
122
     * @dataProvider providerForTestMode
123
     */
124
    public function testMode($mode, int $expected): void
125
    {
126
        Context::setMode($mode);
127
        $this->assertSame($expected, Context::getMode());
128
    }
129
130
    /**
131
     * @return array<int, array<int, int|string>>
132
     * @psalm-return list<array{int|string, int}>
133
     */
134
    public static function providerForTestMode(): array
135
    {
136
        return [
137
            [0, Context::SQL_MODE_NONE],
138
            [1, 1],
139
            ['', Context::SQL_MODE_NONE],
140
            ['invalid', Context::SQL_MODE_NONE],
141
            ['ALLOW_INVALID_DATES', Context::SQL_MODE_ALLOW_INVALID_DATES],
142
            ['ANSI_QUOTES', Context::SQL_MODE_ANSI_QUOTES],
143
            ['COMPAT_MYSQL', Context::SQL_MODE_COMPAT_MYSQL],
144
            ['ERROR_FOR_DIVISION_BY_ZERO', Context::SQL_MODE_ERROR_FOR_DIVISION_BY_ZERO],
145
            ['HIGH_NOT_PRECEDENCE', Context::SQL_MODE_HIGH_NOT_PRECEDENCE],
146
            ['IGNORE_SPACE', Context::SQL_MODE_IGNORE_SPACE],
147
            ['NO_AUTO_CREATE_USER', Context::SQL_MODE_NO_AUTO_CREATE_USER],
148
            ['NO_AUTO_VALUE_ON_ZERO', Context::SQL_MODE_NO_AUTO_VALUE_ON_ZERO],
149
            ['NO_BACKSLASH_ESCAPES', Context::SQL_MODE_NO_BACKSLASH_ESCAPES],
150
            ['NO_DIR_IN_CREATE', Context::SQL_MODE_NO_DIR_IN_CREATE],
151
            ['NO_ENGINE_SUBSTITUTION', Context::SQL_MODE_NO_ENGINE_SUBSTITUTION],
152
            ['NO_FIELD_OPTIONS', Context::SQL_MODE_NO_FIELD_OPTIONS],
153
            ['NO_KEY_OPTIONS', Context::SQL_MODE_NO_KEY_OPTIONS],
154
            ['NO_TABLE_OPTIONS', Context::SQL_MODE_NO_TABLE_OPTIONS],
155
            ['NO_UNSIGNED_SUBTRACTION', Context::SQL_MODE_NO_UNSIGNED_SUBTRACTION],
156
            ['NO_ZERO_DATE', Context::SQL_MODE_NO_ZERO_DATE],
157
            ['NO_ZERO_IN_DATE', Context::SQL_MODE_NO_ZERO_IN_DATE],
158
            ['ONLY_FULL_GROUP_BY', Context::SQL_MODE_ONLY_FULL_GROUP_BY],
159
            ['PIPES_AS_CONCAT', Context::SQL_MODE_PIPES_AS_CONCAT],
160
            ['REAL_AS_FLOAT', Context::SQL_MODE_REAL_AS_FLOAT],
161
            ['STRICT_ALL_TABLES', Context::SQL_MODE_STRICT_ALL_TABLES],
162
            ['STRICT_TRANS_TABLES', Context::SQL_MODE_STRICT_TRANS_TABLES],
163
            ['NO_ENCLOSING_QUOTES', Context::SQL_MODE_NO_ENCLOSING_QUOTES],
164
            ['ANSI', Context::SQL_MODE_ANSI],
165
            ['DB2', Context::SQL_MODE_DB2],
166
            ['MAXDB', Context::SQL_MODE_MAXDB],
167
            ['MSSQL', Context::SQL_MODE_MSSQL],
168
            ['ORACLE', Context::SQL_MODE_ORACLE],
169
            ['POSTGRESQL', Context::SQL_MODE_POSTGRESQL],
170
            ['TRADITIONAL', Context::SQL_MODE_TRADITIONAL],
171
        ];
172
    }
173
174
    public function testModeWithCombinedModes(): void
175
    {
176
        Context::setMode(
177
            Context::SQL_MODE_REAL_AS_FLOAT | Context::SQL_MODE_ANSI_QUOTES | Context::SQL_MODE_IGNORE_SPACE
178
        );
179
        $this->assertSame(
180
            Context::SQL_MODE_REAL_AS_FLOAT | Context::SQL_MODE_ANSI_QUOTES | Context::SQL_MODE_IGNORE_SPACE,
181
            Context::getMode()
182
        );
183
        $this->assertTrue(Context::hasMode(Context::SQL_MODE_REAL_AS_FLOAT | Context::SQL_MODE_IGNORE_SPACE));
184
        $this->assertTrue(Context::hasMode(Context::SQL_MODE_ANSI_QUOTES));
185
        $this->assertFalse(Context::hasMode(Context::SQL_MODE_REAL_AS_FLOAT | Context::SQL_MODE_ALLOW_INVALID_DATES));
186
        $this->assertFalse(Context::hasMode(Context::SQL_MODE_ALLOW_INVALID_DATES));
187
188
        Context::setMode(Context::SQL_MODE_TRADITIONAL);
189
        $this->assertSame(Context::SQL_MODE_TRADITIONAL, Context::getMode());
190
191
        Context::setMode();
192
        $this->assertSame(Context::SQL_MODE_NONE, Context::getMode());
193
    }
194
195
    public function testModeWithString(): void
196
    {
197
        Context::setMode('REAL_AS_FLOAT,ANSI_QUOTES,IGNORE_SPACE');
198
        $this->assertSame(
199
            Context::SQL_MODE_REAL_AS_FLOAT | Context::SQL_MODE_ANSI_QUOTES | Context::SQL_MODE_IGNORE_SPACE,
200
            Context::getMode()
201
        );
202
        $this->assertTrue(Context::hasMode(Context::SQL_MODE_REAL_AS_FLOAT | Context::SQL_MODE_IGNORE_SPACE));
203
        $this->assertTrue(Context::hasMode(Context::SQL_MODE_ANSI_QUOTES));
204
        $this->assertFalse(Context::hasMode(Context::SQL_MODE_REAL_AS_FLOAT | Context::SQL_MODE_ALLOW_INVALID_DATES));
205
        $this->assertFalse(Context::hasMode(Context::SQL_MODE_ALLOW_INVALID_DATES));
206
207
        Context::setMode('TRADITIONAL');
208
        $this->assertSame(Context::SQL_MODE_TRADITIONAL, Context::getMode());
209
210
        Context::setMode('');
211
        $this->assertSame(Context::SQL_MODE_NONE, Context::getMode());
212
    }
213
214
    public function testEscape(): void
215
    {
216
        Context::setMode(Context::SQL_MODE_NO_ENCLOSING_QUOTES);
217
        $this->assertEquals('test', Context::escape('test'));
218
219
        Context::setMode(Context::SQL_MODE_ANSI_QUOTES);
220
        $this->assertEquals('"test"', Context::escape('test'));
221
222
        Context::setMode();
223
        $this->assertEquals('`test`', Context::escape('test'));
224
225
        $this->assertEquals(['`a`', '`b`'], Context::escapeAll(['a', 'b']));
226
    }
227
228
    public function testEscapeAll(): void
229
    {
230
        Context::setMode();
231
        $this->assertEquals(['`a`', '`b`'], Context::escapeAll(['a', 'b']));
232
    }
233
}
234