Passed
Pull Request — master (#380)
by Wilmer
04:47 queued 01:51
created

AbstractQueryTest   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 556
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 275
dl 0
loc 556
rs 10
c 1
b 0
f 0
wmc 20

20 Methods

Rating   Name   Duplication   Size   Complexity  
A testFilterHavingWithOperatorFormat() 0 45 1
A testHaving() 0 17 1
A testFilterWhereWithHashFormat() 0 16 1
A testFilterHavingWithHashFormat() 0 16 1
A testColumn() 0 10 1
A testOne() 0 10 1
A testGroup() 0 16 1
A testOrder() 0 36 1
A testFromTableIsArrayWithExpression() 0 11 1
A testAndFilterCompare() 0 33 1
A testFilterRecursively() 0 10 1
A testEmulateExecution() 0 42 1
A testLimitOffset() 0 9 1
A testLimitOffsetWithExpression() 0 13 1
A testExists() 0 10 1
A testCount() 0 10 1
A testFilterWhereWithOperatorFormat() 0 45 1
A testFrom() 0 8 1
A testWhere() 0 19 1
B testSelect() 0 133 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Tests;
6
7
use PHPUnit\Framework\TestCase;
8
use Yiisoft\Db\Exception\NotSupportedException;
9
use Yiisoft\Db\Expression\Expression;
10
use Yiisoft\Db\Expression\ExpressionInterface;
11
use Yiisoft\Db\Query\Query;
12
use Yiisoft\Db\Query\QueryInterface;
13
use Yiisoft\Db\Tests\Support\TestTrait;
14
15
abstract class AbstractQueryTest extends TestCase
16
{
17
    use TestTrait;
18
19
    /**
20
     * @depends testFilterWhereWithHashFormat
21
     * @depends testFilterWhereWithOperatorFormat
22
     */
23
    public function testAndFilterCompare(): void
24
    {
25
        $db = $this->getConnection();
26
27
        $query = new Query($db);
28
        $result = $query->andFilterCompare('name', null);
29
30
        $this->assertInstanceOf(QueryInterface::class, $result);
31
        $this->assertNull($query->getWhere());
32
33
        $query->andFilterCompare('name', '');
34
35
        $this->assertNull($query->getWhere());
36
37
        $query->andFilterCompare('name', 'John Doe');
38
        $condition = ['=', 'name', 'John Doe'];
39
40
        $this->assertSame($condition, $query->getWhere());
41
42
        $condition = ['and', $condition, ['like', 'name', 'Doe']];
43
        $query->andFilterCompare('name', 'Doe', 'like');
44
45
        $this->assertSame($condition, $query->getWhere());
46
47
        $condition[] = ['>', 'rating', '9'];
48
        $query->andFilterCompare('rating', '>9');
49
50
        $this->assertSame($condition, $query->getWhere());
51
52
        $condition[] = ['<=', 'value', '100'];
53
        $query->andFilterCompare('value', '<=100');
54
55
        $this->assertSame($condition, $query->getWhere());
56
    }
57
58
    public function testColumn(): void
59
    {
60
        $db = $this->getConnectionWithData();
61
62
        $this->expectException(NotSupportedException::class);
63
        $this->expectExceptionMessage(
64
            'Yiisoft\Db\Tests\Support\Stubs\Command does not support internalExecute() by core-db.'
65
        );
66
67
        (new Query($db))->select('name')->from('customer')->orderBy(['id' => SORT_DESC])->column();
68
    }
69
70
    public function testCount(): void
71
    {
72
        $db = $this->getConnectionWithData();
73
74
        $this->expectException(NotSupportedException::class);
75
        $this->expectExceptionMessage(
76
            'Yiisoft\Db\Tests\Support\Stubs\Command does not support internalExecute() by core-db.'
77
        );
78
79
        (new Query($db))->from('customer')->count();
80
    }
81
82
    public function testEmulateExecution(): void
83
    {
84
        $db = $this->getConnectionWithData();
85
86
        $rows = (new Query($db))->from('customer')->emulateExecution()->all();
87
88
        $this->assertSame([], $rows);
89
90
        $row = (new Query($db))->from('customer')->emulateExecution()->one();
91
92
        $this->assertNull($row);
93
94
        $exists = (new Query($db))->from('customer')->emulateExecution()->exists();
95
96
        $this->assertFalse($exists);
97
98
        $count = (new Query($db))->from('customer')->emulateExecution()->count();
99
100
        $this->assertSame(0, $count);
101
102
        $sum = (new Query($db))->from('customer')->emulateExecution()->sum('id');
103
104
        $this->assertNull($sum);
105
106
        $sum = (new Query($db))->from('customer')->emulateExecution()->average('id');
107
108
        $this->assertNull($sum);
109
110
        $max = (new Query($db))->from('customer')->emulateExecution()->max('id');
111
112
        $this->assertNull($max);
113
114
        $min = (new Query($db))->from('customer')->emulateExecution()->min('id');
115
116
        $this->assertNull($min);
117
118
        $scalar = (new Query($db))->select(['id'])->from('customer')->emulateExecution()->scalar();
119
120
        $this->assertNull($scalar);
121
122
        $column = (new Query($db))->select(['id'])->from('customer')->emulateExecution()->column();
123
        $this->assertSame([], $column);
124
    }
125
126
    public function testExists(): void
127
    {
128
        $db = $this->getConnectionWithData();
129
130
        $this->expectException(NotSupportedException::class);
131
        $this->expectExceptionMessage(
132
            'Yiisoft\Db\Tests\Support\Stubs\Command does not support internalExecute() by core-db.'
133
        );
134
135
        (new Query($db))->from('customer')->where(['status' => 2])->exists();
136
    }
137
138
    public function testFilterHavingWithHashFormat(): void
139
    {
140
        $db = $this->getConnection();
141
142
        $query = new Query($db);
143
        $query->filterHaving(['id' => 0, 'title' => '   ', 'author_ids' => [],]);
144
145
        $this->assertSame(['id' => 0], $query->getHaving());
146
147
        $query->andFilterHaving(['status' => null]);
148
149
        $this->assertSame(['id' => 0], $query->getHaving());
150
151
        $query->orFilterHaving(['name' => '']);
152
153
        $this->assertSame(['id' => 0], $query->getHaving());
154
    }
155
156
    public function testFilterHavingWithOperatorFormat(): void
157
    {
158
        $db = $this->getConnection();
159
160
        $query = new Query($db);
161
        $condition = ['like', 'name', 'Alex'];
162
        $query->filterHaving($condition);
163
164
        $this->assertSame($condition, $query->getHaving());
165
166
        $query->andFilterHaving(['between', 'id', null, null]);
167
168
        $this->assertSame($condition, $query->getHaving());
169
170
        $query->orFilterHaving(['not between', 'id', null, null]);
171
172
        $this->assertSame($condition, $query->getHaving());
173
174
        $query->andFilterHaving(['in', 'id', []]);
175
176
        $this->assertSame($condition, $query->getHaving());
177
178
        $query->andFilterHaving(['not in', 'id', []]);
179
180
        $this->assertSame($condition, $query->getHaving());
181
182
        $query->andFilterHaving(['like', 'id', '']);
183
184
        $this->assertSame($condition, $query->getHaving());
185
186
        $query->andFilterHaving(['or like', 'id', '']);
187
188
        $this->assertSame($condition, $query->getHaving());
189
190
        $query->andFilterHaving(['not like', 'id', '   ']);
191
192
        $this->assertSame($condition, $query->getHaving());
193
194
        $query->andFilterHaving(['or not like', 'id', null]);
195
196
        $this->assertSame($condition, $query->getHaving());
197
198
        $query->andFilterHaving(['or', ['eq', 'id', null], ['eq', 'id', []]]);
199
200
        $this->assertSame($condition, $query->getHaving());
201
    }
202
203
    public function testFilterRecursively(): void
204
    {
205
        $db = $this->getConnection();
206
207
        $query = new Query($db);
208
        $query->filterWhere(
209
            ['and', ['like', 'name', ''], ['like', 'title', ''], ['id' => 1], ['not', ['like', 'name', '']]]
210
        );
211
212
        $this->assertSame(['and', ['id' => 1]], $query->getWhere());
213
    }
214
215
    public function testFilterWhereWithHashFormat(): void
216
    {
217
        $db = $this->getConnection();
218
219
        $query = new Query($db);
220
        $query->filterWhere(['id' => 0, 'title' => '   ', 'author_ids' => []]);
221
222
        $this->assertSame(['id' => 0], $query->getWhere());
223
224
        $query->andFilterWhere(['status' => null]);
225
226
        $this->assertSame(['id' => 0], $query->getWhere());
227
228
        $query->orFilterWhere(['name' => '']);
229
230
        $this->assertSame(['id' => 0], $query->getWhere());
231
    }
232
233
    public function testFilterWhereWithOperatorFormat(): void
234
    {
235
        $db = $this->getConnection();
236
237
        $query = new Query($db);
238
        $condition = ['like', 'name', 'Alex'];
239
        $query->filterWhere($condition);
240
241
        $this->assertSame($condition, $query->getWhere());
242
243
        $query->andFilterWhere(['between', 'id', null, null]);
244
245
        $this->assertSame($condition, $query->getWhere());
246
247
        $query->orFilterWhere(['not between', 'id', null, null]);
248
249
        $this->assertSame($condition, $query->getWhere());
250
251
        $query->andFilterWhere(['in', 'id', []]);
252
253
        $this->assertSame($condition, $query->getWhere());
254
255
        $query->andFilterWhere(['not in', 'id', []]);
256
257
        $this->assertSame($condition, $query->getWhere());
258
259
        $query->andFilterWhere(['like', 'id', '']);
260
261
        $this->assertSame($condition, $query->getWhere());
262
263
        $query->andFilterWhere(['or like', 'id', '']);
264
265
        $this->assertSame($condition, $query->getWhere());
266
267
        $query->andFilterWhere(['not like', 'id', '   ']);
268
269
        $this->assertSame($condition, $query->getWhere());
270
271
        $query->andFilterWhere(['or not like', 'id', null]);
272
273
        $this->assertSame($condition, $query->getWhere());
274
275
        $query->andFilterWhere(['or', ['eq', 'id', null], ['eq', 'id', []]]);
276
277
        $this->assertSame($condition, $query->getWhere());
278
    }
279
280
    public function testFrom(): void
281
    {
282
        $db = $this->getConnection();
283
284
        $query = new Query($db);
285
        $query->from('user');
286
287
        $this->assertSame(['user'], $query->getFrom());
288
    }
289
290
    public function testFromTableIsArrayWithExpression(): void
291
    {
292
        $db = $this->getConnection();
293
294
        $query = new Query($db);
295
        $tables = new Expression('(SELECT id,name FROM user) u');
296
        $query->from($tables);
297
        $from = $query->getFrom();
298
299
        $this->assertIsArray($from);
300
        $this->assertInstanceOf(ExpressionInterface::class, $from[0]);
301
    }
302
303
    public function testGroup(): void
304
    {
305
        $db = $this->getConnection();
306
307
        $query = new Query($db);
308
        $query->groupBy('team');
309
310
        $this->assertSame(['team'], $query->getGroupBy());
311
312
        $query->addGroupBy('company');
313
314
        $this->assertSame(['team', 'company'], $query->getGroupBy());
315
316
        $query->addGroupBy('age');
317
318
        $this->assertSame(['team', 'company', 'age'], $query->getGroupBy());
319
    }
320
321
    public function testHaving(): void
322
    {
323
        $db = $this->getConnection();
324
325
        $query = new Query($db);
326
        $query->having('id = :id', [':id' => 1]);
327
328
        $this->assertSame('id = :id', $query->getHaving());
329
        $this->assertSame([':id' => 1], $query->getParams());
330
331
        $query->andHaving('name = :name', [':name' => 'something']);
332
        $this->assertSame(['and', 'id = :id', 'name = :name'], $query->getHaving());
333
        $this->assertSame([':id' => 1, ':name' => 'something'], $query->getParams());
334
335
        $query->orHaving('age = :age', [':age' => '30']);
336
        $this->assertSame(['or', ['and', 'id = :id', 'name = :name'], 'age = :age'], $query->getHaving());
337
        $this->assertSame([':id' => 1, ':name' => 'something', ':age' => '30'], $query->getParams());
338
    }
339
340
    public function testLimitOffset(): void
341
    {
342
        $db = $this->getConnection();
343
344
        $query = new Query($db);
345
        $query->limit(10)->offset(5);
346
347
        $this->assertSame(10, $query->getLimit());
348
        $this->assertSame(5, $query->getOffset());
349
    }
350
351
    public function testLimitOffsetWithExpression(): void
352
    {
353
        $db = $this->getConnectionWithData();
354
355
        $query = (new Query($db))->from('customer')->select('id')->orderBy('id');
356
        $query->limit(new Expression('1 + 1'))->offset(new Expression('1 + 0'));
357
358
        $this->expectException(NotSupportedException::class);
359
        $this->expectExceptionMessage(
360
            'Yiisoft\Db\Tests\Support\Stubs\Command does not support internalExecute() by core-db.'
361
        );
362
363
        $query->column();
364
    }
365
366
    public function testOne(): void
367
    {
368
        $db = $this->getConnectionWithData();
369
370
        $this->expectException(NotSupportedException::class);
371
        $this->expectExceptionMessage(
372
            'Yiisoft\Db\Tests\Support\Stubs\Command does not support internalExecute() by core-db.'
373
        );
374
375
        (new Query($db))->from('customer')->where(['status' => 2])->one();
376
    }
377
378
    public function testOrder(): void
379
    {
380
        $db = $this->getConnection();
381
382
        $query = new Query($db);
383
        $query->orderBy('team');
384
385
        $this->assertSame(['team' => SORT_ASC], $query->getOrderBy());
386
387
        $query->addOrderBy('company');
388
389
        $this->assertSame(['team' => SORT_ASC, 'company' => SORT_ASC], $query->getOrderBy());
390
391
        $query->addOrderBy('age');
392
393
        $this->assertSame(['team' => SORT_ASC, 'company' => SORT_ASC, 'age' => SORT_ASC], $query->getOrderBy());
394
395
        $query->addOrderBy(['age' => SORT_DESC]);
396
397
        $this->assertSame(['team' => SORT_ASC, 'company' => SORT_ASC, 'age' => SORT_DESC], $query->getOrderBy());
398
399
        $query->addOrderBy('age ASC, company DESC');
400
401
        $this->assertSame(['team' => SORT_ASC, 'company' => SORT_DESC, 'age' => SORT_ASC], $query->getOrderBy());
402
403
        $expression1 = new Expression('SUBSTR(name, 3, 4) DESC, x ASC');
404
405
        $query->orderBy($expression1);
406
407
        $this->assertSame([$expression1], $query->getOrderBy());
408
409
        $expression2 = new Expression('SUBSTR(name, 3, 4) DESC, x ASC');
410
411
        $query->addOrderBy($expression2);
412
413
        $this->assertSame([$expression1, $expression2], $query->getOrderBy());
414
    }
415
416
    public function testSelect(): void
417
    {
418
        $db = $this->getConnection();
419
420
        /* default */
421
        $query = new Query($db);
422
        $query->select('*');
423
424
        $this->assertSame(['*' => '*'], $query->getSelect());
425
        $this->assertNull($query->getDistinct());
426
        $this->assertNull($query->getSelectOption());
0 ignored issues
show
Bug introduced by
Are you sure the usage of $query->getSelectOption() targeting Yiisoft\Db\Query\Query::getSelectOption() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
427
428
        $query = new Query($db);
429
        $query->select('id, name', 'something')->distinct(true);
430
431
        $this->assertSame(['id' => 'id', 'name' => 'name'], $query->getSelect());
432
        $this->assertTrue($query->getDistinct());
433
        $this->assertSame('something', $query->getSelectOption());
434
435
        $query = new Query($db);
436
        $query->addSelect('email');
437
438
        $this->assertSame(['email' => 'email'], $query->getSelect());
439
440
        $query = new Query($db);
441
        $query->select('id, name');
442
        $query->addSelect('email');
443
444
        $this->assertSame(['id' => 'id', 'name' => 'name', 'email' => 'email'], $query->getSelect());
445
446
        $query = new Query($db);
447
        $query->select('name, lastname');
448
        $query->addSelect('name');
449
450
        $this->assertSame(['name' => 'name', 'lastname' => 'lastname'], $query->getSelect());
451
452
        $query = new Query($db);
453
        $query->addSelect(['*', 'abc']);
454
        $query->addSelect(['*', 'bca']);
455
456
        $this->assertSame(['*' => '*', 'abc' => 'abc', 'bca' => 'bca'], $query->getSelect());
457
458
        $query = new Query($db);
459
        $query->addSelect(['field1 as a', 'field 1 as b']);
460
461
        $this->assertSame(['a' => 'field1', 'b' => 'field 1'], $query->getSelect());
462
463
        $query = new Query($db);
464
        $query->addSelect(['field1 a', 'field 1 b']);
465
466
        $this->assertSame(['a' => 'field1', 'b' => 'field 1'], $query->getSelect());
467
468
        $query = new Query($db);
469
        $query->select(['name' => 'firstname', 'lastname']);
470
        $query->addSelect(['firstname', 'surname' => 'lastname']);
471
        $query->addSelect(['firstname', 'lastname']);
472
473
        $this->assertSame(
474
            ['name' => 'firstname', 'lastname' => 'lastname', 'firstname' => 'firstname', 'surname' => 'lastname'],
475
            $query->getSelect(),
476
        );
477
478
        $query = new Query($db);
479
        $query->select('name, name, name as X, name as X');
480
481
        $this->assertSame(['name' => 'name', 'X' => 'name'], $query->getSelect());
482
483
        /**
484
         * {@see https://github.com/yiisoft/yii2/issues/15676}
485
         */
486
        $query = (new Query($db))->select('id');
487
488
        $this->assertSame(['id' => 'id'], $query->getSelect());
489
490
        $query->select(['id', 'brand_id']);
491
492
        $this->assertSame(['id' => 'id', 'brand_id' => 'brand_id'], $query->getSelect());
493
494
        /**
495
         * {@see https://github.com/yiisoft/yii2/issues/15676}
496
         */
497
        $query = (new Query($db))->select(['prefix' => 'LEFT(name, 7)', 'prefix_key' => 'LEFT(name, 7)']);
498
499
        $this->assertSame(['prefix' => 'LEFT(name, 7)', 'prefix_key' => 'LEFT(name, 7)'], $query->getSelect());
500
501
        $query->addSelect(['LEFT(name,7) as test']);
502
503
        $this->assertSame(
504
            ['prefix' => 'LEFT(name, 7)', 'prefix_key' => 'LEFT(name, 7)', 'test' => 'LEFT(name,7)'],
505
            $query->getSelect()
506
        );
507
508
        $query->addSelect(['LEFT(name,7) as test']);
509
510
        $this->assertSame(
511
            ['prefix' => 'LEFT(name, 7)', 'prefix_key' => 'LEFT(name, 7)', 'test' => 'LEFT(name,7)'],
512
            $query->getSelect()
513
        );
514
515
        $query->addSelect(['test' => 'LEFT(name,7)']);
516
517
        $this->assertSame(
518
            ['prefix' => 'LEFT(name, 7)', 'prefix_key' => 'LEFT(name, 7)', 'test' => 'LEFT(name,7)'],
519
            $query->getSelect()
520
        );
521
522
        /**
523
         * {@see https://github.com/yiisoft/yii2/issues/15731}
524
         */
525
        $selectedCols = [
526
            'total_sum' => 'SUM(f.amount)',
527
            'in_sum' => 'SUM(IF(f.type = :type_in, f.amount, 0))',
528
            'out_sum' => 'SUM(IF(f.type = :type_out, f.amount, 0))',
529
        ];
530
        $query = (new Query($db))
531
            ->select($selectedCols)
532
            ->addParams([':type_in' => 'in', ':type_out' => 'out', ':type_partner' => 'partner']);
533
534
        $this->assertSame($selectedCols, $query->getSelect());
535
536
        $query->select($selectedCols);
537
538
        $this->assertSame($selectedCols, $query->getSelect());
539
540
        /**
541
         * {@see https://github.com/yiisoft/yii2/issues/17384}
542
         */
543
        $query = new Query($db);
544
        $query->select('DISTINCT ON(tour_dates.date_from) tour_dates.date_from, tour_dates.id');
545
546
        $this->assertSame(
547
            ['DISTINCT ON(tour_dates.date_from) tour_dates.date_from', 'tour_dates.id' => 'tour_dates.id'],
548
            $query->getSelect()
549
        );
550
    }
551
552
    public function testWhere(): void
553
    {
554
        $db = $this->getConnection();
555
556
        $query = new Query($db);
557
        $query->where('id = :id', [':id' => 1]);
558
559
        $this->assertSame('id = :id', $query->getWhere());
560
        $this->assertSame([':id' => 1], $query->getParams());
561
562
        $query->andWhere('name = :name', [':name' => 'something']);
563
564
        $this->assertSame(['and', 'id = :id', 'name = :name'], $query->getWhere());
565
        $this->assertSame([':id' => 1, ':name' => 'something'], $query->getParams());
566
567
        $query->orWhere('age = :age', [':age' => '30']);
568
569
        $this->assertSame(['or', ['and', 'id = :id', 'name = :name'], 'age = :age'], $query->getWhere());
570
        $this->assertSame([':id' => 1, ':name' => 'something', ':age' => '30'], $query->getParams());
571
    }
572
}
573