1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Vectorface\Tests\MySQLite; |
4
|
|
|
|
5
|
|
|
use InvalidArgumentException; |
6
|
|
|
use PDO; |
7
|
|
|
use PDOException; |
8
|
|
|
use PHPUnit\Framework\TestCase; |
9
|
|
|
use Vectorface\MySQLite\MySQLite; |
10
|
|
|
use Vectorface\Tests\MySQLite\Util\FakePDO; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Test MySQLite; This could be split up into individual function categories later. |
14
|
|
|
*/ |
15
|
|
|
class MySQLiteTest extends TestCase |
16
|
|
|
{ |
17
|
|
|
/** |
18
|
|
|
* Test miscellaneous compatibility functions. |
19
|
|
|
*/ |
20
|
|
|
public function testCompatibilityFunctions() |
21
|
|
|
{ |
22
|
|
|
/* Aggregate functions */ |
23
|
|
|
$this->assertEquals(1 | 2 | 4, MySQLite::mysql_bit_or(1, 2, 4)); |
24
|
|
|
|
25
|
|
|
/* Comparison functions */ |
26
|
|
|
$this->assertEquals(1, MySQLite::mysql_least(1, 2, 3, 4)); |
27
|
|
|
try { |
28
|
|
|
MySQLite::mysql_least(); |
29
|
|
|
$this->fail("Least with no arguments is not valid"); |
30
|
|
|
} catch (\InvalidArgumentException $e) { |
31
|
|
|
/* Expected */ |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
/* Flow control functions */ |
35
|
|
|
$this->assertEquals("foo", MySQLite::mysql_if(true, "foo", "bar")); |
36
|
|
|
$this->assertEquals("bar", MySQLite::mysql_if(false, "foo", "bar")); |
37
|
|
|
|
38
|
|
|
/* Numeric functions */ |
39
|
|
|
$this->assertEquals(10, MySQLite::mysql_sqrt(100)); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
public function testDateTimeFunctions() |
43
|
|
|
{ |
44
|
|
|
$this->assertEquals(date("Y-m-d H:i:s"), MySQLite::mysql_now()); |
45
|
|
|
$this->assertEquals(365, MySQLite::mysql_to_days("0000-12-31")); |
46
|
|
|
$this->assertEquals(718613, MySQLite::mysql_to_days("1967-07-01")); |
47
|
|
|
$this->assertEquals(735599, MySQLite::mysql_to_days("2014-01-01")); |
48
|
|
|
$this->assertEquals(time(), MySQLite::mysql_unix_timestamp()); |
49
|
|
|
$time = time(); |
50
|
|
|
$this->assertEquals($time, MySQLite::mysql_unix_timestamp(date("Y-m-d H:i:s"))); |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Test that createFunctions hooks the functions into a PDO object. |
55
|
|
|
*/ |
56
|
|
|
public function testCreateFunctions() |
57
|
|
|
{ |
58
|
|
|
$fakepdo = new FakePDO(); |
59
|
|
|
$fakepdo->attributes[PDO::ATTR_DRIVER_NAME] = 'mysql'; |
60
|
|
|
|
61
|
|
|
try { |
62
|
|
|
MySQLite::createFunctions($fakepdo); |
63
|
|
|
$this->fail("Attempt to create functions with a driver other than SQLite should fail."); |
64
|
|
|
} catch (InvalidArgumentException $e) { |
65
|
|
|
/* Expected */ |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
$pdo = new PDO("sqlite::memory:", null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); |
69
|
|
|
try { |
70
|
|
|
$pdo->query("SELECT BIT_OR(1, 2)"); |
71
|
|
|
$this->fail("Attempt to BIT_OR two values is expected to fail before the function is created."); |
72
|
|
|
} catch (PDOException $e) { |
73
|
|
|
/* Expected */ |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
$this->assertSame($pdo, MySQLite::createFunctions($pdo)); |
77
|
|
|
$this->assertEquals(3, $pdo->query("SELECT BIT_OR(1, 2)")->fetch(PDO::FETCH_COLUMN)); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Test that createFunctions is able to create only a limited subset of supported functions. |
82
|
|
|
*/ |
83
|
|
|
public function testSelectiveCreateFunctions() |
84
|
|
|
{ |
85
|
|
|
$pdo = new PDO("sqlite::memory:", null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); |
86
|
|
|
$this->assertSame($pdo, MySQLite::createFunctions($pdo, ['bit_or'])); |
87
|
|
|
$this->assertEquals(3, $pdo->query("SELECT BIT_OR(1, 2)")->fetch(PDO::FETCH_COLUMN)); |
88
|
|
|
try { |
89
|
|
|
$pdo->query("SELECT UNIX_TIMESTAMP()"); |
90
|
|
|
$this->fail("UNIX_TIMESTAMP function is expected not to have been created."); |
91
|
|
|
} catch (PDOException $e) { |
92
|
|
|
/* Expected */ |
93
|
|
|
} |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Test that registered functions are listed and available. |
98
|
|
|
*/ |
99
|
|
|
public function testGetFunctionList() |
100
|
|
|
{ |
101
|
|
|
$this->assertContains("bit_or", MySQLite::getFunctionList()); |
102
|
|
|
$this->assertContains("unix_timestamp", MySQLite::getFunctionList()); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* Test the concat function |
107
|
|
|
*/ |
108
|
|
View Code Duplication |
public function testConcat() |
|
|
|
|
109
|
|
|
{ |
110
|
|
|
$expected = 'test1 test2 test4'; |
111
|
|
|
$test = MySQLite::mysql_concat("test1", " ", "test2", " ", "test4"); |
112
|
|
|
$this->assertEquals($expected, $test); |
113
|
|
|
|
114
|
|
|
$pdo = new PDO("sqlite::memory:", null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); |
115
|
|
|
MySQLite::createFunctions($pdo); |
116
|
|
|
$result = $pdo->query('SELECT CONCAT("test1"," ","test2"," " ,"test4")')->fetch(PDO::FETCH_COLUMN); |
117
|
|
|
$this->assertEquals($expected, $result); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Test the concat_ws function |
122
|
|
|
*/ |
123
|
|
View Code Duplication |
public function testConcatWS() |
|
|
|
|
124
|
|
|
{ |
125
|
|
|
$expected = 'test1|test2|test4'; |
126
|
|
|
$test = MySQLite::mysql_concat_ws("|", "test1", "test2", "test4"); |
127
|
|
|
$this->assertEquals($expected, $test); |
128
|
|
|
|
129
|
|
|
$pdo = new PDO("sqlite::memory:", null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); |
130
|
|
|
MySQLite::createFunctions($pdo); |
131
|
|
|
$result = $pdo->query('SELECT CONCAT_WS("|","test1","test2","test4")')->fetch(PDO::FETCH_COLUMN); |
132
|
|
|
$this->assertEquals($expected, $result); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Test the rand function |
137
|
|
|
*/ |
138
|
|
|
public function testRand() |
139
|
|
|
{ |
140
|
|
|
$pdo = new PDO("sqlite::memory:", null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); |
141
|
|
|
MySQLite::createFunctions($pdo); |
142
|
|
|
|
143
|
|
|
$pdo->exec("CREATE TABLE testing(id INT PRIMARY KEY NOT NULL)"); |
144
|
|
|
$stmt = $pdo->prepare("INSERT INTO testing (id) VALUES (?)"); |
145
|
|
|
for ($x = 0; $x <= 10; $x++) { |
146
|
|
|
$stmt->execute([$x]); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
$results = []; |
150
|
|
|
for ($x = 0; $x < 20; $x++) { |
151
|
|
|
$results[] = $pdo->query('SELECT id FROM testing ORDER BY RAND() LIMIT 1')->fetch(PDO::FETCH_COLUMN); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
$this->assertNotEquals( |
155
|
|
|
array_slice($results, 0, 10), |
156
|
|
|
array_slice($results, 10, 10) |
157
|
|
|
); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
public function testFormat() |
161
|
|
|
{ |
162
|
|
|
$expected = '12,312,312'; |
163
|
|
|
$test = MySQLite::mysql_format("12312312.232", 0); |
164
|
|
|
$this->assertEquals($expected, $test); |
165
|
|
|
|
166
|
|
|
$expected = '12.2'; |
167
|
|
|
$test = MySQLite::mysql_format("12.232", 1); |
168
|
|
|
$this->assertEquals($expected, $test); |
169
|
|
|
} |
170
|
|
|
} |
171
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.