Completed
Pull Request — master (#6747)
by Gabriel
09:15
created

ExprTest::testModExpr()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Query;
6
7
use Doctrine\ORM\Query\Expr;
8
use Doctrine\Tests\Models\Company\CompanyEmployee;
9
use Doctrine\Tests\OrmTestCase;
10
use InvalidArgumentException;
11
12
/**
13
 * Test case for the DQL Expr class used for generating DQL snippets through
14
 * a programmatic interface
15
 */
16
class ExprTest extends OrmTestCase
17
{
18
    private $em;
19
20
    /** @var Expr */
21
    private $expr;
22
23
    protected function setUp() : void
24
    {
25
        $this->em   = $this->getTestEntityManager();
26
        $this->expr = new Expr();
27
    }
28
29
    public function testAvgExpr() : void
30
    {
31
        self::assertEquals('AVG(u.id)', (string) $this->expr->avg('u.id'));
32
    }
33
34
    public function testMaxExpr() : void
35
    {
36
        self::assertEquals('MAX(u.id)', (string) $this->expr->max('u.id'));
37
    }
38
39
    public function testMinExpr() : void
40
    {
41
        self::assertEquals('MIN(u.id)', (string) $this->expr->min('u.id'));
42
    }
43
44
    public function testCountExpr() : void
45
    {
46
        self::assertEquals('MAX(u.id)', (string) $this->expr->max('u.id'));
47
    }
48
49
    public function testCountDistinctExpr() : void
50
    {
51
        self::assertEquals('COUNT(DISTINCT u.id)', (string) $this->expr->countDistinct('u.id'));
52
    }
53
54
    public function testCountDistinctExprMulti() : void
55
    {
56
        self::assertEquals('COUNT(DISTINCT u.id, u.name)', (string) $this->expr->countDistinct('u.id', 'u.name'));
57
    }
58
59
    public function testExistsExpr() : void
60
    {
61
        $qb = $this->em->createQueryBuilder();
62
        $qb->select('u')->from('User', 'u')->where('u.name = ?1');
63
64
        self::assertEquals('EXISTS(SELECT u FROM User u WHERE u.name = ?1)', (string) $this->expr->exists($qb));
65
    }
66
67
    public function testAllExpr() : void
68
    {
69
        $qb = $this->em->createQueryBuilder();
70
        $qb->select('u')->from('User', 'u')->where('u.name = ?1');
71
72
        self::assertEquals('ALL(SELECT u FROM User u WHERE u.name = ?1)', (string) $this->expr->all($qb));
73
    }
74
75
    public function testSomeExpr() : void
76
    {
77
        $qb = $this->em->createQueryBuilder();
78
        $qb->select('u')->from('User', 'u')->where('u.name = ?1');
79
80
        self::assertEquals('SOME(SELECT u FROM User u WHERE u.name = ?1)', (string) $this->expr->some($qb));
81
    }
82
83
    public function testAnyExpr() : void
84
    {
85
        $qb = $this->em->createQueryBuilder();
86
        $qb->select('u')->from('User', 'u')->where('u.name = ?1');
87
88
        self::assertEquals('ANY(SELECT u FROM User u WHERE u.name = ?1)', (string) $this->expr->any($qb));
89
    }
90
91
    public function testNotExpr() : void
92
    {
93
        $qb = $this->em->createQueryBuilder();
94
        $qb->select('u')->from('User', 'u')->where('u.name = ?1');
95
96
        self::assertEquals('NOT(SELECT u FROM User u WHERE u.name = ?1)', (string) $this->expr->not($qb));
97
    }
98
99
    public function testAndExpr() : void
100
    {
101
        self::assertEquals('1 = 1 AND 2 = 2', (string) $this->expr->andX((string) $this->expr->eq(1, 1), (string) $this->expr->eq(2, 2)));
102
    }
103
104
    public function testIntelligentParenthesisPreventionAndExpr() : void
105
    {
106
        self::assertEquals(
107
            '1 = 1 AND 2 = 2',
108
            (string) $this->expr->andX($this->expr->orX($this->expr->andX($this->expr->eq(1, 1))), (string) $this->expr->eq(2, 2))
109
        );
110
    }
111
112
    public function testOrExpr() : void
113
    {
114
        self::assertEquals('1 = 1 OR 2 = 2', (string) $this->expr->orX((string) $this->expr->eq(1, 1), (string) $this->expr->eq(2, 2)));
115
    }
116
117
    public function testAbsExpr() : void
118
    {
119
        self::assertEquals('ABS(1)', (string) $this->expr->abs(1));
120
    }
121
122
    public function testModExpr() : void
123
    {
124
        self::assertEquals('MOD(10, 1)', (string) $this->expr->mod(10, 1));
125
    }
126
127
    public function testProdExpr() : void
128
    {
129
        self::assertEquals('1 * 2', (string) $this->expr->prod(1, 2));
130
    }
131
132
    public function testDiffExpr() : void
133
    {
134
        self::assertEquals('1 - 2', (string) $this->expr->diff(1, 2));
135
    }
136
137
    public function testSumExpr() : void
138
    {
139
        self::assertEquals('1 + 2', (string) $this->expr->sum(1, 2));
140
    }
141
142
    public function testQuotientExpr() : void
143
    {
144
        self::assertEquals('10 / 2', (string) $this->expr->quot(10, 2));
145
    }
146
147
    public function testScopeInArithmeticExpr() : void
148
    {
149
        self::assertEquals('(100 - 20) / 2', (string) $this->expr->quot($this->expr->diff(100, 20), 2));
150
        self::assertEquals('100 - (20 / 2)', (string) $this->expr->diff(100, $this->expr->quot(20, 2)));
151
    }
152
153
    public function testSquareRootExpr() : void
154
    {
155
        self::assertEquals('SQRT(1)', (string) $this->expr->sqrt(1));
156
    }
157
158
    public function testEqualExpr() : void
159
    {
160
        self::assertEquals('1 = 1', (string) $this->expr->eq(1, 1));
161
    }
162
163
    public function testLikeExpr() : void
164
    {
165
        self::assertEquals('a.description LIKE :description', (string) $this->expr->like('a.description', ':description'));
166
    }
167
168
    public function testNotLikeExpr() : void
169
    {
170
        self::assertEquals('a.description NOT LIKE :description', (string) $this->expr->notLike('a.description', ':description'));
171
    }
172
173
    public function testConcatExpr() : void
174
    {
175
        self::assertEquals('CONCAT(u.first_name, u.last_name)', (string) $this->expr->concat('u.first_name', 'u.last_name'));
176
        self::assertEquals('CONCAT(u.first_name, u.middle_name, u.last_name)', (string) $this->expr->concat('u.first_name', 'u.middle_name', 'u.last_name'));
177
    }
178
179
    public function testSubstringExpr() : void
180
    {
181
        self::assertEquals('SUBSTRING(a.title, 0, 25)', (string) $this->expr->substring('a.title', 0, 25));
182
    }
183
184
    /**
185
     * @group regression
186
     * @group DDC-612
187
     */
188
    public function testSubstringExprAcceptsTwoArguments() : void
189
    {
190
        self::assertEquals('SUBSTRING(a.title, 5)', (string) $this->expr->substring('a.title', 5));
191
    }
192
193
    public function testLowerExpr() : void
194
    {
195
        self::assertEquals('LOWER(u.first_name)', (string) $this->expr->lower('u.first_name'));
196
    }
197
198
    public function testUpperExpr() : void
199
    {
200
        self::assertEquals('UPPER(u.first_name)', (string) $this->expr->upper('u.first_name'));
201
    }
202
203
    public function testLengthExpr() : void
204
    {
205
        self::assertEquals('LENGTH(u.first_name)', (string) $this->expr->length('u.first_name'));
206
    }
207
208
    public function testGreaterThanExpr() : void
209
    {
210
        self::assertEquals('5 > 2', (string) $this->expr->gt(5, 2));
211
    }
212
213
    public function testLessThanExpr() : void
214
    {
215
        self::assertEquals('2 < 5', (string) $this->expr->lt(2, 5));
216
    }
217
218
    public function testStringLiteralExpr() : void
219
    {
220
        self::assertEquals("'word'", (string) $this->expr->literal('word'));
221
    }
222
223
    public function testNumericLiteralExpr() : void
224
    {
225
        self::assertEquals(5, (string) $this->expr->literal(5));
226
    }
227
228
    /**
229
     * @group regression
230
     * @group DDC-610
231
     */
232
    public function testLiteralExprProperlyQuotesStrings() : void
233
    {
234
        self::assertEquals("'00010001'", (string) $this->expr->literal('00010001'));
235
    }
236
237
    public function testGreaterThanOrEqualToExpr() : void
238
    {
239
        self::assertEquals('5 >= 2', (string) $this->expr->gte(5, 2));
240
    }
241
242
    public function testLessThanOrEqualTo() : void
243
    {
244
        self::assertEquals('2 <= 5', (string) $this->expr->lte(2, 5));
245
    }
246
247
    public function testBetweenExpr() : void
248
    {
249
        self::assertEquals('u.id BETWEEN 3 AND 6', (string) $this->expr->between('u.id', 3, 6));
250
    }
251
252
    public function testTrimExpr() : void
253
    {
254
        self::assertEquals('TRIM(u.id)', (string) $this->expr->trim('u.id'));
255
    }
256
257
    public function testIsNullExpr() : void
258
    {
259
        self::assertEquals('u.id IS NULL', (string) $this->expr->isNull('u.id'));
260
    }
261
262
    public function testIsNotNullExpr() : void
263
    {
264
        self::assertEquals('u.id IS NOT NULL', (string) $this->expr->isNotNull('u.id'));
265
    }
266
267
    public function testIsInstanceOfExpr() : void
268
    {
269
        self::assertEquals('u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee', (string) $this->expr->isInstanceOf('u', CompanyEmployee::class));
270
    }
271
272
    public function testIsMemberOfExpr() : void
273
    {
274
        self::assertEquals(':groupId MEMBER OF u.groups', (string) $this->expr->isMemberOf(':groupId', 'u.groups'));
275
    }
276
277
    public function testInExpr() : void
278
    {
279
        self::assertEquals('u.id IN(1, 2, 3)', (string) $this->expr->in('u.id', [1, 2, 3]));
280
    }
281
282
    public function testInLiteralExpr() : void
283
    {
284
        self::assertEquals("u.type IN('foo', 'bar')", (string) $this->expr->in('u.type', ['foo', 'bar']));
285
    }
286
287
    public function testNotInExpr() : void
288
    {
289
        self::assertEquals('u.id NOT IN(1, 2, 3)', (string) $this->expr->notIn('u.id', [1, 2, 3]));
290
    }
291
292
    public function testNotInLiteralExpr() : void
293
    {
294
        self::assertEquals("u.type NOT IN('foo', 'bar')", (string) $this->expr->notIn('u.type', ['foo', 'bar']));
295
    }
296
297
    public function testAndxOrxExpr() : void
298
    {
299
        $andExpr = $this->expr->andX();
300
        $andExpr->add($this->expr->eq(1, 1));
301
        $andExpr->add($this->expr->lt(1, 5));
302
303
        $orExpr = $this->expr->orX();
304
        $orExpr->add($andExpr);
305
        $orExpr->add($this->expr->eq(1, 1));
306
307
        self::assertEquals('(1 = 1 AND 1 < 5) OR 1 = 1', (string) $orExpr);
308
    }
309
310
    public function testOrxExpr() : void
311
    {
312
        $orExpr = $this->expr->orX();
313
        $orExpr->add($this->expr->eq(1, 1));
314
        $orExpr->add($this->expr->lt(1, 5));
315
316
        self::assertEquals('1 = 1 OR 1 < 5', (string) $orExpr);
317
    }
318
319
    public function testOrderByCountExpr() : void
320
    {
321
        $orderExpr = $this->expr->desc('u.username');
322
323
        self::assertEquals($orderExpr->count(), 1);
324
        self::assertEquals('u.username DESC', (string) $orderExpr);
325
    }
326
327
    public function testOrderByOrder() : void
328
    {
329
        $orderExpr = $this->expr->desc('u.username');
330
        self::assertEquals('u.username DESC', (string) $orderExpr);
331
    }
332
333
    public function testOrderByAsc() : void
334
    {
335
        $orderExpr = $this->expr->asc('u.username');
336
        self::assertEquals('u.username ASC', (string) $orderExpr);
337
    }
338
339
    /**
340
     * @expectedException InvalidArgumentException
341
     */
342
    public function testAddThrowsException() : void
343
    {
344
        $orExpr = $this->expr->orX();
345
        $orExpr->add($this->expr->quot(5, 2));
346
    }
347
348
    /**
349
     * @group DDC-1683
350
     */
351
    public function testBooleanLiteral() : void
352
    {
353
        self::assertEquals('true', $this->expr->literal(true));
354
        self::assertEquals('false', $this->expr->literal(false));
355
    }
356
357
    /**
358
     * @group DDC-1686
359
     */
360
    public function testExpressionGetter() : void
361
    {
362
        // Andx
363
        $andx = new Expr\Andx(['1 = 1', '2 = 2']);
364
        self::assertEquals(['1 = 1', '2 = 2'], $andx->getParts());
365
366
        // Comparison
367
        $comparison = new Expr\Comparison('foo', Expr\Comparison::EQ, 'bar');
368
        self::assertEquals('foo', $comparison->getLeftExpr());
369
        self::assertEquals('bar', $comparison->getRightExpr());
370
        self::assertEquals(Expr\Comparison::EQ, $comparison->getOperator());
371
372
        // From
373
        $from = new Expr\From('Foo', 'f', 'f.id');
374
        self::assertEquals('f', $from->getAlias());
375
        self::assertEquals('Foo', $from->getFrom());
376
        self::assertEquals('f.id', $from->getIndexBy());
377
378
        // Func
379
        $func = new Expr\Func('MAX', ['f.id']);
380
        self::assertEquals('MAX', $func->getName());
381
        self::assertEquals(['f.id'], $func->getArguments());
382
383
        // GroupBy
384
        $group = new Expr\GroupBy(['foo DESC', 'bar ASC']);
385
        self::assertEquals(['foo DESC', 'bar ASC'], $group->getParts());
386
387
        // Join
388
        $join = new Expr\Join(Expr\Join::INNER_JOIN, 'f.bar', 'b', Expr\Join::ON, 'b.bar_id = 1', 'b.bar_id');
389
        self::assertEquals(Expr\Join::INNER_JOIN, $join->getJoinType());
390
        self::assertEquals(Expr\Join::ON, $join->getConditionType());
391
        self::assertEquals('b.bar_id = 1', $join->getCondition());
392
        self::assertEquals('b.bar_id', $join->getIndexBy());
393
        self::assertEquals('f.bar', $join->getJoin());
394
        self::assertEquals('b', $join->getAlias());
395
396
        // Literal
397
        $literal = new Expr\Literal(['foo']);
398
        self::assertEquals(['foo'], $literal->getParts());
399
400
        // Math
401
        $math = new Expr\Math(10, '+', 20);
402
        self::assertEquals(10, $math->getLeftExpr());
403
        self::assertEquals(20, $math->getRightExpr());
404
        self::assertEquals('+', $math->getOperator());
405
406
        // OrderBy
407
        $order = new Expr\OrderBy('foo', 'DESC');
408
        self::assertEquals(['foo DESC'], $order->getParts());
409
410
        // Andx
411
        $orx = new Expr\Orx(['foo = 1', 'bar = 2']);
412
        self::assertEquals(['foo = 1', 'bar = 2'], $orx->getParts());
413
414
        // Select
415
        $select = new Expr\Select(['foo', 'bar']);
416
        self::assertEquals(['foo', 'bar'], $select->getParts());
417
    }
418
419
    public function testAddEmpty() : void
420
    {
421
        $andExpr = $this->expr->andX();
422
        $andExpr->add($this->expr->andX());
423
424
        self::assertEquals(0, $andExpr->count());
425
    }
426
427
    public function testAddNull() : void
428
    {
429
        $andExpr = $this->expr->andX();
430
        $andExpr->add(null);
431
432
        self::assertEquals(0, $andExpr->count());
433
    }
434
}
435