1
+ <?php
2
+
3
+ declare (strict_types=1 );
4
+
5
+ namespace Vimeo \MysqlEngine \Tests ;
6
+
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
+
15
+ class FunctionEvaluatorTest extends TestCase
16
+ {
17
+
18
+ public function dataFunction (): array
19
+ {
20
+ return [
21
+ 'numeric ' => ['SELECT ? ' , 1 ],
22
+ ':field ' => ['SELECT :field ' , ':field ' ],
23
+ 'field ' => ['SELECT :field ' , 'field ' ],
24
+ ];
25
+ }
26
+
27
+ /**
28
+ * @dataProvider maxValueProvider
29
+ */
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
75
+ {
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 );
112
+ }
113
+ }
114
+
115
+
116
+ public static function maxValueProvider (): array
117
+ {
118
+ return [
119
+ 'null when no rows ' => [
120
+ 'rows ' => [],
121
+ 'expected ' => null ,
122
+ ],
123
+ '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 ,
138
+ ],
139
+ 'non scalar values ' => [
140
+ 'rows ' => [
141
+ ['value ' => ['test ' ]],
142
+ ],
143
+ 'expected ' => -1 ,
144
+ ],
145
+ ];
146
+ }
147
+
148
+ public static function minValueProvider (): array
149
+ {
150
+ return [
151
+ 'null when no rows ' => [
152
+ 'rows ' => [],
153
+ 'expected ' => null ,
154
+ ],
155
+ '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 ,
170
+ ],
171
+ 'non scalar values ' => [
172
+ 'rows ' => [
173
+ ['value ' => ['test ' ]],
174
+ ],
175
+ 'expected ' => -1 ,
176
+ ],
177
+ ];
178
+ }
179
+ }
0 commit comments