[TASK] Add more fixers for php-cs-fixer
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Database / Query / Expression / ExpressionBuilderTest.php
1 <?php
2 declare(strict_types=1);
3 namespace TYPO3\CMS\Core\Tests\Unit\Database\Query;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use Prophecy\Argument;
19 use Prophecy\Prophecy\ObjectProphecy;
20 use TYPO3\CMS\Core\Database\Connection;
21 use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;
22 use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
23 use TYPO3\CMS\Core\Tests\Unit\Database\Mocks\MockPlatform;
24 use TYPO3\CMS\Core\Tests\UnitTestCase;
25
26 class ExpressionBuilderTest extends UnitTestCase
27 {
28 /**
29 * @var Connection
30 */
31 protected $connectionProphet;
32
33 /**
34 * @var ExpressionBuilder
35 */
36 protected $subject;
37
38 /**
39 * @var string
40 */
41 protected $testTable = 'testTable';
42
43 /**
44 * Create a new database connection mock object for every test.
45 *
46 * @return void
47 */
48 protected function setUp()
49 {
50 parent::setUp();
51
52 /** @var Connection|ObjectProphecy $connectionProphet */
53 $this->connectionProphet = $this->prophesize(Connection::class);
54 $this->connectionProphet->quoteIdentifier(Argument::cetera())->willReturnArgument(0);
55
56 $this->subject = new ExpressionBuilder($this->connectionProphet->reveal());
57 }
58
59 /**
60 * @test
61 */
62 public function andXReturnType()
63 {
64 $result = $this->subject->andX('"uid" = 1', '"pid" = 0');
65
66 $this->assertInstanceOf(CompositeExpression::class, $result);
67 $this->assertSame(CompositeExpression::TYPE_AND, $result->getType());
68 }
69
70 /**
71 * @test
72 */
73 public function orXReturnType()
74 {
75 $result = $this->subject->orX('"uid" = 1', '"uid" = 7');
76
77 $this->assertInstanceOf(CompositeExpression::class, $result);
78 $this->assertSame(CompositeExpression::TYPE_OR, $result->getType());
79 }
80
81 /**
82 * @test
83 */
84 public function eqQuotesIdentifier()
85 {
86 $result = $this->subject->eq('aField', 1);
87
88 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
89 $this->assertSame('aField = 1', $result);
90 }
91
92 /**
93 * @test
94 */
95 public function neqQuotesIdentifier()
96 {
97 $result = $this->subject->neq('aField', 1);
98
99 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
100 $this->assertSame('aField <> 1', $result);
101 }
102
103 /**
104 * @test
105 */
106 public function ltQuotesIdentifier()
107 {
108 $result = $this->subject->lt('aField', 1);
109
110 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
111 $this->assertSame('aField < 1', $result);
112 }
113
114 /**
115 * @test
116 */
117 public function lteQuotesIdentifier()
118 {
119 $result = $this->subject->lte('aField', 1);
120
121 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
122 $this->assertSame('aField <= 1', $result);
123 }
124
125 /**
126 * @test
127 */
128 public function gtQuotesIdentifier()
129 {
130 $result = $this->subject->gt('aField', 1);
131
132 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
133 $this->assertSame('aField > 1', $result);
134 }
135
136 /**
137 * @test
138 */
139 public function gteQuotesIdentifier()
140 {
141 $result = $this->subject->gte('aField', 1);
142
143 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
144 $this->assertSame('aField >= 1', $result);
145 }
146
147 /**
148 * @test
149 */
150 public function isNullQuotesIdentifier()
151 {
152 $result = $this->subject->isNull('aField');
153
154 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
155 $this->assertSame('aField IS NULL', $result);
156 }
157
158 /**
159 * @test
160 */
161 public function isNotNullQuotesIdentifier()
162 {
163 $result = $this->subject->isNotNull('aField');
164
165 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
166 $this->assertSame('aField IS NOT NULL', $result);
167 }
168
169 /**
170 * @test
171 */
172 public function likeQuotesIdentifier()
173 {
174 $result = $this->subject->like('aField', "'aValue%'");
175
176 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
177 $this->assertSame("aField LIKE 'aValue%'", $result);
178 }
179
180 /**
181 * @test
182 */
183 public function notLikeQuotesIdentifier()
184 {
185 $result = $this->subject->notLike('aField', "'aValue%'");
186
187 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
188 $this->assertSame("aField NOT LIKE 'aValue%'", $result);
189 }
190
191 /**
192 * @test
193 */
194 public function inWithStringQuotesIdentifier()
195 {
196 $result = $this->subject->in('aField', '1,2,3');
197
198 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
199 $this->assertSame('aField IN (1,2,3)', $result);
200 }
201
202 /**
203 * @test
204 */
205 public function inWithArrayQuotesIdentifier()
206 {
207 $result = $this->subject->in('aField', [1, 2, 3]);
208
209 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
210 $this->assertSame('aField IN (1, 2, 3)', $result);
211 }
212
213 /**
214 * @test
215 */
216 public function notInWithStringQuotesIdentifier()
217 {
218 $result = $this->subject->notIn('aField', '1,2,3');
219
220 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
221 $this->assertSame('aField NOT IN (1,2,3)', $result);
222 }
223
224 /**
225 * @test
226 */
227 public function notInWithArrayQuotesIdentifier()
228 {
229 $result = $this->subject->notIn('aField', [1, 2, 3]);
230
231 $this->connectionProphet->quoteIdentifier('aField')->shouldHaveBeenCalled();
232 $this->assertSame('aField NOT IN (1, 2, 3)', $result);
233 }
234
235 /**
236 * @test
237 */
238 public function inSetForMySQL()
239 {
240 $databasePlatform = $this->prophesize(MockPlatform::class);
241 $databasePlatform->getName()->willReturn('mysql');
242
243 $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
244 return '`' . $args[0] . '`';
245 });
246
247 $this->connectionProphet->getDatabasePlatform()->willReturn($databasePlatform->reveal());
248
249 $result = $this->subject->inSet('aField', "'1'");
250
251 $this->assertSame('FIND_IN_SET(\'1\', `aField`)', $result);
252 }
253
254 /**
255 * @test
256 */
257 public function inSetForPostgreSQL()
258 {
259 $databasePlatform = $this->prophesize(MockPlatform::class);
260 $databasePlatform->getName()->willReturn('postgresql');
261
262 $this->connectionProphet->quote(',', Argument::cetera())->shouldBeCalled()->willReturn("','");
263 $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
264 return '"' . $args[0] . '"';
265 });
266
267 $this->connectionProphet->getDatabasePlatform()->willReturn($databasePlatform->reveal());
268
269 $result = $this->subject->inSet('aField', "'1'");
270
271 $this->assertSame('any(string_to_array("aField", \',\')) = \'1\'', $result);
272 }
273
274 /**
275 * @test
276 */
277 public function defaultBitwiseAnd()
278 {
279 $databasePlatform = $this->prophesize(MockPlatform::class);
280
281 $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
282 return '"' . $args[0] . '"';
283 });
284
285 $this->connectionProphet->getDatabasePlatform()->willReturn($databasePlatform->reveal());
286
287 $this->assertSame('"aField" & 1', $this->subject->bitAnd('aField', 1));
288 }
289
290 /**
291 * @test
292 */
293 public function bitwiseAndForOracle()
294 {
295 $databasePlatform = $this->prophesize(MockPlatform::class);
296 $databasePlatform->getName()->willReturn('pdo_oracle');
297
298 $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
299 return '"' . $args[0] . '"';
300 });
301
302 $this->connectionProphet->getDatabasePlatform()->willReturn($databasePlatform->reveal());
303
304 $this->assertSame('BITAND("aField", 1)', $this->subject->bitAnd('aField', 1));
305 }
306
307 /**
308 * @test
309 */
310 public function maxQuotesIdentifier()
311 {
312 $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
313 $platform = new MockPlatform();
314 return $platform->quoteIdentifier($args[0]);
315 });
316
317 $this->assertSame('MAX("tableName"."fieldName")', $this->subject->max('tableName.fieldName'));
318 $this->assertSame(
319 'MAX("tableName"."fieldName") AS "anAlias"',
320 $this->subject->max('tableName.fieldName', 'anAlias')
321 );
322 }
323
324 /**
325 * @test
326 */
327 public function minQuotesIdentifier()
328 {
329 $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
330 $platform = new MockPlatform();
331 return $platform->quoteIdentifier($args[0]);
332 });
333
334 $this->assertSame('MIN("tableName"."fieldName")', $this->subject->min('tableName.fieldName'));
335 $this->assertSame(
336 'MIN("tableName"."fieldName") AS "anAlias"',
337 $this->subject->min('tableName.fieldName', 'anAlias')
338 );
339 }
340
341 /**
342 * @test
343 */
344 public function sumQuotesIdentifier()
345 {
346 $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
347 $platform = new MockPlatform();
348 return $platform->quoteIdentifier($args[0]);
349 });
350
351 $this->assertSame('SUM("tableName"."fieldName")', $this->subject->sum('tableName.fieldName'));
352 $this->assertSame(
353 'SUM("tableName"."fieldName") AS "anAlias"',
354 $this->subject->sum('tableName.fieldName', 'anAlias')
355 );
356 }
357
358 /**
359 * @test
360 */
361 public function avgQuotesIdentifier()
362 {
363 $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
364 $platform = new MockPlatform();
365 return $platform->quoteIdentifier($args[0]);
366 });
367
368 $this->assertSame('AVG("tableName"."fieldName")', $this->subject->avg('tableName.fieldName'));
369 $this->assertSame(
370 'AVG("tableName"."fieldName") AS "anAlias"',
371 $this->subject->avg('tableName.fieldName', 'anAlias')
372 );
373 }
374
375 /**
376 * @test
377 */
378 public function countQuotesIdentifier()
379 {
380 $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
381 $platform = new MockPlatform();
382 return $platform->quoteIdentifier($args[0]);
383 });
384
385 $this->assertSame('COUNT("tableName"."fieldName")', $this->subject->count('tableName.fieldName'));
386 $this->assertSame(
387 'COUNT("tableName"."fieldName") AS "anAlias"',
388 $this->subject->count('tableName.fieldName', 'anAlias')
389 );
390 }
391
392 /**
393 * @test
394 */
395 public function literalQuotesValue()
396 {
397 $this->connectionProphet->quote('aField', 'Doctrine\DBAL\Types\StringType')
398 ->shouldBeCalled()
399 ->willReturn('"aField"');
400 $result = $this->subject->literal('aField', 'Doctrine\DBAL\Types\StringType');
401
402 $this->assertSame('"aField"', $result);
403 }
404 }