Passed
Push — master ( cdeeca...9b5c0a )
by William
09:37 queued 10s
created

TestCase   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 34
dl 0
loc 118
rs 10
c 3
b 0
f 0
wmc 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A runParserTest() 0 37 4
A getErrorsAsArray() 0 20 3
A getData() 0 11 1
A setUp() 0 9 1
A getTokensList() 0 5 1
1
<?php
2
/**
3
 * Bootstrap for tests.
4
 */
5
6
declare(strict_types=1);
7
8
namespace PhpMyAdmin\SqlParser\Tests;
9
10
use PhpMyAdmin\SqlParser\Context;
11
use PhpMyAdmin\SqlParser\Exceptions\LexerException;
12
use PhpMyAdmin\SqlParser\Exceptions\ParserException;
13
use PhpMyAdmin\SqlParser\Lexer;
14
use PhpMyAdmin\SqlParser\Parser;
15
use PhpMyAdmin\SqlParser\TokensList;
16
use PHPUnit\Framework\TestCase as BaseTestCase;
17
use function file_get_contents;
18
use function strpos;
19
use function unserialize;
20
21
/**
22
 * Implements useful methods for testing.
23
 */
24
abstract class TestCase extends BaseTestCase
25
{
26
    public function setUp(): void
27
    {
28
        global $lang;
29
        // This line makes sure the test suite uses English so we can assert
30
        // on the error messages, if it is not here you will need to use
31
        // LC_ALL=C ./vendor/bin/phpunit
32
        // Users can have French language as default on their OS
33
        // That would make the assertions fail
34
        $lang = 'en';
35
    }
36
37
    /**
38
     * Gets the token list generated by lexing this query.
39
     *
40
     * @param string $query the query to be lexed
41
     *
42
     * @return TokensList
43
     */
44
    public function getTokensList($query)
45
    {
46
        $lexer = new Lexer($query);
47
48
        return $lexer->list;
49
    }
50
51
    /**
52
     * Gets the errors as an array.
53
     *
54
     * @param Lexer|Parser $obj object containing the errors
55
     *
56
     * @return array
57
     */
58
    public function getErrorsAsArray($obj)
59
    {
60
        $ret = [];
61
        /** @var LexerException|ParserException $err */
62
        foreach ($obj->errors as $err) {
63
            $ret[] = $obj instanceof Lexer
64
                ? [
65
                    $err->getMessage(),
66
                    $err->ch,
67
                    $err->pos,
68
                    $err->getCode(),
69
                ]
70
                : [
71
                    $err->getMessage(),
72
                    $err->token,
73
                    $err->getCode(),
74
                ];
75
        }
76
77
        return $ret;
78
    }
79
80
    /**
81
     * Gets test's input and expected output.
82
     *
83
     * @param string $name the name of the test
84
     *
85
     * @return array
86
     */
87
    public function getData($name)
88
    {
89
        /*
90
         * The unrestricted unserialize() is needed here as we do have
91
         * serialized objects in the tests. There should be no security risk as
92
         * the test data comes with the repository.
93
         */
94
        $data = unserialize(file_get_contents('tests/data/' . $name . '.out'));
95
        $data['query'] = file_get_contents('tests/data/' . $name . '.in');
96
97
        return $data;
98
    }
99
100
    /**
101
     * Runs a test.
102
     *
103
     * @param string $name the name of the test
104
     */
105
    public function runParserTest($name)
106
    {
107
        /**
108
         * Test's data.
109
         *
110
         * @var array
111
         */
112
        $data = $this->getData($name);
113
114
        if (strpos($name, '/ansi/') !== false) {
115
            // set mode if appropriate
116
            Context::setMode('ANSI_QUOTES');
117
        }
118
119
        // Lexer.
120
        $lexer = new Lexer($data['query']);
121
        $lexerErrors = $this->getErrorsAsArray($lexer);
122
        $lexer->errors = [];
123
124
        // Parser.
125
        $parser = empty($data['parser']) ? null : new Parser($lexer->list);
126
        $parserErrors = [];
127
        if ($parser !== null) {
128
            $parserErrors = $this->getErrorsAsArray($parser);
129
            $parser->errors = [];
130
        }
131
132
        // Testing objects.
133
        $this->assertEquals($data['lexer'], $lexer);
134
        $this->assertEquals($data['parser'], $parser);
135
136
        // Testing errors.
137
        $this->assertEquals($data['errors']['parser'], $parserErrors);
138
        $this->assertEquals($data['errors']['lexer'], $lexerErrors);
139
140
        // reset mode after test run
141
        Context::setMode();
142
    }
143
}
144