5
5
namespace Vimeo \MysqlEngine \Tests ;
6
6
7
7
use PHPUnit \Framework \TestCase ;
8
- use Vimeo \MysqlEngine \FakePdoInterface ;
9
- use Vimeo \MysqlEngine \Processor \Expression \FunctionEvaluator ;
10
- use Vimeo \MysqlEngine \Processor \QueryResult ;
11
- use Vimeo \MysqlEngine \Processor \Scope ;
12
- use Vimeo \MysqlEngine \Query \Expression \ColumnExpression ;
13
- use Vimeo \MysqlEngine \Query \Expression \FunctionExpression ;
14
8
15
9
class FunctionEvaluatorTest extends TestCase
16
10
{
17
11
18
- public function dataFunction (): array
12
+ public function tearDown () : void
19
13
{
20
- return [
21
- 'numeric ' => ['SELECT ? ' , 1 ],
22
- ':field ' => ['SELECT :field ' , ':field ' ],
23
- 'field ' => ['SELECT :field ' , 'field ' ],
24
- ];
14
+ \Vimeo \MysqlEngine \Server::reset ();
25
15
}
26
16
27
17
/**
28
18
* @dataProvider maxValueProvider
29
19
*/
30
- public function testSqlMax (array $ rows , ?int $ expected ) : void
31
- {
32
- $ conn = $ this ->createMock (FakePdoInterface::class);
33
- $ scope = $ this ->createMock (Scope::class);
34
- $ queryResult = $ this ->createMock (QueryResult::class);
35
- /** @var array<int, non-empty-array<string, mixed>> $rows */
36
- $ queryResult ->rows = $ rows ;
37
-
38
- $ token = new \Vimeo \MysqlEngine \Parser \Token (
39
- \Vimeo \MysqlEngine \TokenType::SQLFUNCTION ,
40
- 'MAX ' ,
41
- 'MAX ' ,
42
- 0
43
- );
44
-
45
- $ exp = new ColumnExpression (
46
- new \Vimeo \MysqlEngine \Parser \Token (\Vimeo \MysqlEngine \TokenType::IDENTIFIER , "value " , '' , 0 )
47
- );
48
-
49
- $ functionExpr = new FunctionExpression (
50
- $ token ,
51
- [$ exp ],
52
- false
53
- );
54
-
55
- $ refMethod = new \ReflectionMethod (FunctionEvaluator::class, 'sqlMax ' );
56
- $ refMethod ->setAccessible (true );
57
-
58
- if ($ expected === -1 ) {
59
- $ this ->expectException (\TypeError::class);
60
- $ this ->expectExceptionMessage ('Bad max value ' );
61
- }
62
-
63
- /** @var int|null $actual */
64
- $ actual = $ refMethod ->invoke (null , $ conn , $ scope , $ functionExpr , $ queryResult );
65
-
66
- if ($ expected !== -1 ) {
67
- $ this ->assertSame ($ expected , $ actual );
68
- }
69
- }
70
-
71
- /**
72
- * @dataProvider minValueProvider
73
- */
74
- public function testSqlMin (array $ rows , ?int $ expected ) : void
20
+ public function testSqlMax (string $ sql , ?string $ expected , bool $ is_db_number ) : void
75
21
{
76
- $ conn = $ this ->createMock (FakePdoInterface::class);
77
- $ scope = $ this ->createMock (Scope::class);
78
- $ queryResult = $ this ->createMock (QueryResult::class);
79
- /** @var array<int, non-empty-array<string, mixed>> $rows */
80
- $ queryResult ->rows = $ rows ;
81
-
82
- $ token = new \Vimeo \MysqlEngine \Parser \Token (
83
- \Vimeo \MysqlEngine \TokenType::SQLFUNCTION ,
84
- 'MIN ' ,
85
- 'MIN ' ,
86
- 0
87
- );
88
-
89
- $ exp = new ColumnExpression (
90
- new \Vimeo \MysqlEngine \Parser \Token (\Vimeo \MysqlEngine \TokenType::IDENTIFIER , "value " , '' , 0 )
91
- );
92
-
93
- $ functionExpr = new FunctionExpression (
94
- $ token ,
95
- [$ exp ],
96
- false
97
- );
98
-
99
- $ refMethod = new \ReflectionMethod (FunctionEvaluator::class, 'sqlMin ' );
100
- $ refMethod ->setAccessible (true );
101
-
102
- if ($ expected === -1 ) {
103
- $ this ->expectException (\TypeError::class);
104
- $ this ->expectExceptionMessage ('Bad min value ' );
105
- }
106
-
107
- /** @var int|null $actual */
108
- $ actual = $ refMethod ->invoke (null , $ conn , $ scope , $ functionExpr , $ queryResult );
109
-
110
- if ($ expected !== -1 ) {
111
- $ this ->assertSame ($ expected , $ actual );
22
+ $ query = self ::getConnectionToFullDB ()->prepare ($ sql );
23
+ $ query ->execute ();
24
+ /** @var array<array<string, string|null>> $result */
25
+ $ result = $ query ->fetchAll (\PDO ::FETCH_ASSOC );
26
+
27
+ if ($ is_db_number ) {
28
+ $ this ->assertNotEmpty ($ result );
29
+ $ this ->assertNotNull ($ result [0 ]['max ' ]);
30
+ } else {
31
+ $ this ->assertSame ([['max ' => $ expected ]], $ result );
112
32
}
113
33
}
114
34
115
-
116
35
public static function maxValueProvider (): array
117
36
{
118
37
return [
119
38
'null when no rows ' => [
120
- 'rows ' => [] ,
39
+ 'sql ' => ' SELECT MAX(null) as `max` FROM `video_game_characters` ' ,
121
40
'expected ' => null ,
41
+ 'is_db_number ' => false ,
122
42
],
123
43
'max of scalar values ' => [
124
- 'rows ' => [
125
- ['value ' => 10 ],
126
- ['value ' => 25 ],
127
- ['value ' => 5 ],
128
- ],
129
- 'expected ' => 25 ,
130
- ],
131
- 'null values mixed in ' => [
132
- 'rows ' => [
133
- ['value ' => null ],
134
- ['value ' => 7 ],
135
- ['value ' => null ],
136
- ],
137
- 'expected ' => 7 ,
44
+ 'sql ' => 'SELECT MAX(10) as `max` FROM `video_game_characters` ' ,
45
+ 'expected ' => '10 ' ,
46
+ 'is_db_number ' => false ,
138
47
],
139
- 'non scalar values ' => [
140
- 'rows ' => [
141
- ['value ' => ['test ' ]],
142
- ],
143
- 'expected ' => -1 ,
48
+ 'max in DB values ' => [
49
+ 'sql ' => 'SELECT MAX(id) as `max` FROM `video_game_characters` ' ,
50
+ 'expected ' => '' ,
51
+ 'is_db_number ' => true ,
144
52
],
145
53
];
146
54
}
147
55
56
+ /**
57
+ * @dataProvider minValueProvider
58
+ */
59
+ public function testSqlMin (string $ sql , ?string $ expected , bool $ is_db_number ) : void
60
+ {
61
+ $ query = self ::getConnectionToFullDB ()->prepare ($ sql );
62
+ $ query ->execute ();
63
+ /** @var array<array<string, string|null>> $result */
64
+ $ result = $ query ->fetchAll (\PDO ::FETCH_ASSOC );
65
+
66
+ if ($ is_db_number ) {
67
+ $ this ->assertNotEmpty ($ result );
68
+ $ this ->assertNotNull ($ result [0 ]['min ' ]);
69
+ } else {
70
+ $ this ->assertSame ([['min ' => $ expected ]], $ result );
71
+ }
72
+ }
73
+
148
74
public static function minValueProvider (): array
149
75
{
150
76
return [
151
77
'null when no rows ' => [
152
- 'rows ' => [] ,
78
+ 'sql ' => ' SELECT MIN(null) as `min` FROM `video_game_characters` ' ,
153
79
'expected ' => null ,
80
+ 'is_db_number ' => false ,
154
81
],
155
82
'min of scalar values ' => [
156
- 'rows ' => [
157
- ['value ' => 10 ],
158
- ['value ' => 25 ],
159
- ['value ' => 5 ],
160
- ],
161
- 'expected ' => 5 ,
162
- ],
163
- 'null values mixed in ' => [
164
- 'rows ' => [
165
- ['value ' => null ],
166
- ['value ' => 7 ],
167
- ['value ' => null ],
168
- ],
169
- 'expected ' => null ,
83
+ 'sql ' => 'SELECT MIN(10) as `min` FROM `video_game_characters` ' ,
84
+ 'expected ' => '10 ' ,
85
+ 'is_db_number ' => false ,
170
86
],
171
- 'non scalar values ' => [
172
- 'rows ' => [
173
- ['value ' => ['test ' ]],
174
- ],
175
- 'expected ' => -1 ,
87
+ 'min in DB values ' => [
88
+ 'sql ' => 'SELECT MIN(id) as `min` FROM `video_game_characters` ' ,
89
+ 'expected ' => '' ,
90
+ 'is_db_number ' => true ,
176
91
],
177
92
];
178
93
}
94
+
95
+ private static function getPdo (string $ connection_string , bool $ strict_mode = false ) : \PDO
96
+ {
97
+ $ options = $ strict_mode ? [\PDO ::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode="STRICT_ALL_TABLES" ' ] : [];
98
+
99
+ if (\PHP_MAJOR_VERSION === 8 ) {
100
+ return new \Vimeo \MysqlEngine \Php8 \FakePdo ($ connection_string , '' , '' , $ options );
101
+ }
102
+
103
+ return new \Vimeo \MysqlEngine \Php7 \FakePdo ($ connection_string , '' , '' , $ options );
104
+ }
105
+
106
+ private static function getConnectionToFullDB (bool $ emulate_prepares = true , bool $ strict_mode = false ) : \PDO
107
+ {
108
+ $ pdo = self ::getPdo ('mysql:foo;dbname=test; ' , $ strict_mode );
109
+
110
+ $ pdo ->setAttribute (\PDO ::ATTR_EMULATE_PREPARES , $ emulate_prepares );
111
+
112
+ // create table
113
+ $ pdo ->prepare (file_get_contents (__DIR__ . '/fixtures/create_table.sql ' ))->execute ();
114
+
115
+ // insertData
116
+ $ pdo ->prepare (file_get_contents (__DIR__ . '/fixtures/bulk_character_insert.sql ' ))->execute ();
117
+ $ pdo ->prepare (file_get_contents (__DIR__ . '/fixtures/bulk_enemy_insert.sql ' ))->execute ();
118
+ $ pdo ->prepare (file_get_contents (__DIR__ . '/fixtures/bulk_tag_insert.sql ' ))->execute ();
119
+
120
+ return $ pdo ;
121
+ }
179
122
}
0 commit comments