MySQLiteTest::testSelectiveCreateFunctions()   A
last analyzed

Complexity

Conditions 2
Paths 3

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 7
c 2
b 0
f 0
dl 0
loc 9
rs 10
cc 2
nc 3
nop 0
1
<?php
2
3
namespace Vectorface\Tests\MySQLite;
4
5
use InvalidArgumentException;
6
use PDO;
7
use Pdo\Sqlite;
0 ignored issues
show
Bug introduced by
The type Pdo\Sqlite was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use PDOException;
9
use PHPUnit\Framework\TestCase;
10
use Vectorface\MySQLite\MySQLite;
11
use Vectorface\Tests\MySQLite\Util\FakePDO;
12
13
/**
14
 * Test MySQLite; This could be split up into individual function categories later.
15
 */
16
class MySQLiteTest extends TestCase
17
{
18
    private function getPdo(mixed ...$args): PDO
19
    {
20
        return class_exists(Pdo\Sqlite::class, false)
0 ignored issues
show
Bug introduced by
The type PDO\Sqlite was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
            ? new Pdo\Sqlite(...$args)
22
            : new PDO(...$args);
0 ignored issues
show
Bug introduced by
$args is expanded, but the parameter $dsn of PDO::__construct() does not expect variable arguments. ( Ignorable by Annotation )

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

22
            : new PDO(/** @scrutinizer ignore-type */ ...$args);
Loading history...
23
    }
24
25
    /**
26
     * Test miscellaneous compatibility functions.
27
     */
28
    public function testCompatibilityFunctions()
29
    {
30
        /* Aggregate functions */
31
        $this->assertEquals(1 | 2 | 4, MySQLite::mysql_bit_or(1, 2, 4));
32
33
        /* Comparison functions */
34
        $this->assertEquals(1, MySQLite::mysql_least(1, 2, 3, 4));
35
        try {
36
            MySQLite::mysql_least();
37
            $this->fail("Least with no arguments is not valid");
38
        } catch (\InvalidArgumentException $e) {
39
            /* Expected */
40
        }
41
42
        /* Flow control functions */
43
        $this->assertEquals("foo", MySQLite::mysql_if(true, "foo", "bar"));
44
        $this->assertEquals("bar", MySQLite::mysql_if(false, "foo", "bar"));
45
46
        /* Numeric functions */
47
        $this->assertEquals(10, MySQLite::mysql_sqrt(100));
48
    }
49
50
    public function testDateTimeFunctions()
51
    {
52
        $this->assertEquals(date("Y-m-d H:i:s"), MySQLite::mysql_now());
53
        $this->assertEquals(365, MySQLite::mysql_to_days("0000-12-31"));
54
        $this->assertEquals(718613, MySQLite::mysql_to_days("1967-07-01"));
55
        $this->assertEquals(735599, MySQLite::mysql_to_days("2014-01-01"));
56
        $this->assertEquals(time(), MySQLite::mysql_unix_timestamp());
57
        $this->assertEquals(0, MySQLite::mysql_unix_timestamp("0000-00-00 00:00:00"));
58
        $this->assertEquals(0, MySQLite::mysql_unix_timestamp("0000-00-00"));
59
        $time = time();
60
        $this->assertEquals($time, MySQLite::mysql_unix_timestamp(date("Y-m-d H:i:s")));
61
    }
62
63
    /**
64
     * Test that createFunctions hooks the functions into a PDO object.
65
     */
66
    public function testCreateFunctions()
67
    {
68
        $fakepdo = new FakePDO();
69
        $fakepdo->attributes[PDO::ATTR_DRIVER_NAME] = 'mysql';
70
71
        try {
72
            MySQLite::createFunctions($fakepdo);
73
            $this->fail("Attempt to create functions with a driver other than SQLite should fail.");
74
        } catch (InvalidArgumentException $e) {
75
            /* Expected */
76
        }
77
78
        $pdo = $this->getPdo("sqlite::memory:", null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
79
        try {
80
            $pdo->query("SELECT BIT_OR(1, 2)");
81
            $this->fail("Attempt to BIT_OR two values is expected to fail before the function is created.");
82
        } catch (PDOException $e) {
83
            /* Expected */
84
        }
85
86
        $this->assertSame($pdo, MySQLite::createFunctions($pdo));
87
        $this->assertEquals(3, $pdo->query("SELECT BIT_OR(1, 2)")->fetch(PDO::FETCH_COLUMN));
88
    }
89
90
    /**
91
     * Test that createFunctions is able to create only a limited subset of supported functions.
92
     */
93
    public function testSelectiveCreateFunctions()
94
    {
95
        $pdo = $this->getPdo("sqlite::memory:", null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
96
        $this->assertSame($pdo, MySQLite::createFunctions($pdo, ['bit_or']));
97
        $this->assertEquals(3, $pdo->query("SELECT BIT_OR(1, 2)")->fetch(PDO::FETCH_COLUMN));
98
        try {
99
            $pdo->query("SELECT UNIX_TIMESTAMP()");
100
            $this->fail("UNIX_TIMESTAMP function is expected not to have been created.");
101
        } catch (PDOException $e) {
102
            /* Expected */
103
        }
104
    }
105
106
    /**
107
     * Test that registered functions are listed and available.
108
     */
109
    public function testGetFunctionList()
110
    {
111
        $this->assertContains("bit_or", MySQLite::getFunctionList());
112
        $this->assertContains("unix_timestamp", MySQLite::getFunctionList());
113
    }
114
115
    /**
116
     * Test the concat function
117
     */
118
    public function testConcat()
119
    {
120
        $expected = 'test1 test2 test4';
121
        $test = MySQLite::mysql_concat("test1", " ", "test2", " ", "test4");
122
        $this->assertEquals($expected, $test);
123
124
        $pdo = $this->getPdo("sqlite::memory:", null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
125
        MySQLite::createFunctions($pdo);
126
        $result = $pdo->query('SELECT CONCAT("test1"," ","test2"," " ,"test4")')->fetch(PDO::FETCH_COLUMN);
127
        $this->assertEquals($expected, $result);
128
    }
129
130
    /**
131
     * Test the concat_ws function
132
     */
133
    public function testConcatWS()
134
    {
135
        $expected = 'test1|test2|test4';
136
        $test = MySQLite::mysql_concat_ws("|", "test1", "test2", "test4");
137
        $this->assertEquals($expected, $test);
138
139
        $pdo = $this->getPdo("sqlite::memory:", null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
140
        MySQLite::createFunctions($pdo);
141
        $result = $pdo->query('SELECT CONCAT_WS("|","test1","test2","test4")')->fetch(PDO::FETCH_COLUMN);
142
        $this->assertEquals($expected, $result);
143
    }
144
145
     /**
146
     * Test the rand function
147
     */
148
    public function testRand()
149
    {
150
        $pdo = $this->getPdo("sqlite::memory:", null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
151
        MySQLite::createFunctions($pdo);
152
153
        $pdo->exec("CREATE TABLE testing(id INT PRIMARY KEY NOT NULL)");
154
        $stmt = $pdo->prepare("INSERT INTO testing (id) VALUES (?)");
155
        for ($x = 0; $x <= 10; $x++) {
156
            $stmt->execute([$x]);
157
        }
158
159
        $results = [];
160
        for ($x = 0; $x < 20; $x++) {
161
            $results[] = $pdo->query('SELECT id FROM testing ORDER BY RAND() LIMIT 1')->fetch(PDO::FETCH_COLUMN);
162
        }
163
164
        $this->assertNotEquals(
165
            array_slice($results, 0, 10),
166
            array_slice($results, 10, 10)
167
        );
168
    }
169
170
    public function testFormat()
171
    {
172
        $expected = '12,312,312';
173
        $test = MySQLite::mysql_format("12312312.232", 0);
174
        $this->assertEquals($expected, $test);
175
176
        $expected = '12.2';
177
        $test = MySQLite::mysql_format("12.232", 1);
178
        $this->assertEquals($expected, $test);
179
    }
180
181
    public function testSoundex()
182
    {
183
        $this->assertEquals("F000", MySQLite::mysql_soundex("foo"));
184
    }
185
}
186