PaginatorTest   A
last analyzed

Complexity

Total Complexity 34

Size/Duplication

Total Lines 470
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 218
c 2
b 1
f 0
dl 0
loc 470
rs 9.68
wmc 34

31 Methods

Rating   Name   Duplication   Size   Complexity  
A testGetTotalPages() 0 8 1
A testGetResultTotalCountWhenNotPaginated() 0 6 1
A testGetPageNumbersWithUnlimitedOption() 0 17 1
A setUp() 0 14 1
A testGetPageSizeWhenNotPaginated() 0 6 1
A testGetPageNumbers() 0 10 1
A testGetNextPageNumberWhenMaximumPageIsOne() 0 5 1
A testGetPreviousPageNumber() 0 5 1
A testPaginate() 0 31 2
A testGetPreviousPageNumberWhenNotPaginated() 0 6 1
A testGetNextPageNumberWhenPaginateFake() 0 5 1
A testConstruct() 0 23 1
A testGetResultTotalCountWhenPaginateFakeCalled() 0 10 1
A testGetTotalPagesWhenFakePaginate() 0 5 1
A testGetTotalPagesWhenFakePaginateHasNoResult() 0 5 1
A testGetResultTotalCount() 0 5 1
A createPaginator() 0 21 1
A testGetPageSize() 0 5 1
A testGetPageNumbersWhenPaginateFake() 0 11 1
A testGetTotalPagesWhenNotPaginated() 0 6 1
A getTotalPagesData() 0 10 1
A testGetNextPageNumber() 0 5 1
A testGetPageNumbersWhenPaginateFakeWithoutResult() 0 12 1
A testGetNextPageNumberWhenNotPaginated() 0 6 1
A testGetPageNumbersWhenNotPaginated() 0 6 1
A testPaginateFakeWithoutResult() 0 25 1
A testPaginateFake() 0 30 2
A testGetCurrentPageNumbersWhenNotPaginated() 0 6 1
A testGetCurrentPageNumbers() 0 5 1
A testGetPreviousPageNumberWhenCurrentPageIsOne() 0 5 1
A testPaginateWhenCurrentPageIsHigherThanExistingPage() 0 29 2
1
<?php declare(strict_types=1);
2
3
namespace Janisbiz\LightOrm\Tests\Unit\Paginator;
4
5
use Janisbiz\LightOrm\Entity\EntityInterface;
6
use Janisbiz\LightOrm\Paginator\Paginator;
7
use Janisbiz\LightOrm\Paginator\PaginatorException;
8
use Janisbiz\LightOrm\QueryBuilder\QueryBuilderInterface;
9
use Janisbiz\LightOrm\Repository\AbstractRepository;
10
use Janisbiz\LightOrm\Repository\RepositoryInterface;
11
use Janisbiz\LightOrm\Tests\Unit\ReflectionTrait;
12
use PHPUnit\Framework\TestCase;
13
14
class PaginatorTest extends TestCase
15
{
16
    use ReflectionTrait;
17
18
    const PAGE_SIZE = 10;
19
    const PREVIOUS_PAGE_NON_EXISTENT = null;
20
    const NEXT_PAGE_NON_EXISTENT = null;
21
    const CURRENT_PAGE = 4;
22
    const CURRENT_PAGE_LOW = 1;
23
    const RESULT_COUNT = 80;
24
    const RESULT_COUNT_LOW = 10;
25
    const RESULT_COUNT_ODD = 81;
26
27
    /**
28
     * @var EntityInterface|\PHPUnit_Framework_MockObject_MockObject
29
     */
30
    private $entity;
31
32
    /**
33
     * @var QueryBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
34
     */
35
    private $queryBuilder;
36
37
    /**
38
     * @var RepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
39
     */
40
    private $abstractRepository;
41
42
    /**
43
     * @var \Closure
44
     */
45
    private $addPaginateQuery;
46
47
    /**
48
     * @var \Closure
49
     */
50
    private $getPaginateResult;
51
52
    public function setUp()
53
    {
54
        $this->entity = $this->createMock(EntityInterface::class);
55
        $this->queryBuilder = $this->createMock(QueryBuilderInterface::class);
56
        $this->abstractRepository = $this->getMockForAbstractClass(
57
            AbstractRepository::class,
58
            [],
59
            '',
60
            true,
61
            true,
62
            true,
63
            [
64
                'addPaginateQuery',
65
                'getPaginateResult',
66
            ]
67
        );
68
    }
69
70
    public function testConstruct()
71
    {
72
        $paginator = $this->createPaginator();
73
74
        $this->assertEquals(
75
            $this->queryBuilder,
76
            $this->createAccessibleProperty($paginator, 'queryBuilder')->getValue($paginator)
77
        );
78
        $this->assertEquals(
79
            $this->addPaginateQuery,
80
            $this->createAccessibleProperty($paginator, 'addPaginateQuery')->getValue($paginator)
81
        );
82
        $this->assertEquals(
83
            $this->getPaginateResult,
84
            $this->createAccessibleProperty($paginator, 'getPaginateResult')->getValue($paginator)
85
        );
86
        $this->assertEquals(
87
            static::PAGE_SIZE,
88
            $this->createAccessibleProperty($paginator, 'pageSize')->getValue($paginator)
89
        );
90
        $this->assertEquals(
91
            static::CURRENT_PAGE,
92
            $this->createAccessibleProperty($paginator, 'currentPage')->getValue($paginator)
93
        );
94
    }
95
96
    /**
97
     * @return Paginator
98
     */
99
    public function testPaginate()
100
    {
101
        $this->queryBuilder->method('count')->willReturn(static::RESULT_COUNT);
0 ignored issues
show
Bug introduced by
The method method() does not exist on Janisbiz\LightOrm\QueryB...r\QueryBuilderInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

101
        $this->queryBuilder->/** @scrutinizer ignore-call */ 
102
                             method('count')->willReturn(static::RESULT_COUNT);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
102
        $this
103
            ->abstractRepository
104
            ->expects($this->once())
105
            ->method('addPaginateQuery')
106
            ->withConsecutive([$this->queryBuilder, static::PAGE_SIZE, static::CURRENT_PAGE])
107
        ;
108
109
        $resultExpected = [];
110
        for ($i = 1; $i <= static::PAGE_SIZE; $i++) {
111
            $resultExpected[] = $this->entity;
112
        }
113
        $this
114
            ->abstractRepository
115
            ->expects($this->once())
116
            ->method('getPaginateResult')
117
            ->withConsecutive([$this->queryBuilder, false])
118
            ->willReturn($resultExpected)
119
        ;
120
121
        $paginator = $this->createPaginator();
122
        $result = $paginator->paginate();
123
124
        $this->assertCount(\count($resultExpected), $result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type string; however, parameter $haystack of PHPUnit\Framework\Assert::assertCount() does only seem to accept Countable|iterable, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

124
        $this->assertCount(\count($resultExpected), /** @scrutinizer ignore-type */ $result);
Loading history...
125
        $this->assertEquals($resultExpected, $result);
126
127
        $paginator->paginate();
128
129
        return $paginator;
130
    }
131
132
    /**
133
     * @return Paginator
134
     */
135
    public function testPaginateWhenCurrentPageIsHigherThanExistingPage()
136
    {
137
        $this->queryBuilder->method('count')->willReturn(static::RESULT_COUNT_LOW);
138
        $this
139
            ->abstractRepository
140
            ->expects($this->once())
141
            ->method('addPaginateQuery')
142
            ->withConsecutive([$this->queryBuilder, static::PAGE_SIZE, static::CURRENT_PAGE_LOW])
143
        ;
144
145
        $resultExpected = [];
146
        for ($i = 1; $i <= static::PAGE_SIZE; $i++) {
147
            $resultExpected[] = $this->entity;
148
        }
149
        $this
150
            ->abstractRepository
151
            ->expects($this->once())
152
            ->method('getPaginateResult')
153
            ->withConsecutive([$this->queryBuilder, false])
154
            ->willReturn($resultExpected)
155
        ;
156
157
        $paginator = $this->createPaginator();
158
        $result = $paginator->paginate();
159
160
        $this->assertCount(\count($resultExpected), $result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type string; however, parameter $haystack of PHPUnit\Framework\Assert::assertCount() does only seem to accept Countable|iterable, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

160
        $this->assertCount(\count($resultExpected), /** @scrutinizer ignore-type */ $result);
Loading history...
161
        $this->assertEquals($resultExpected, $result);
162
163
        return $paginator;
164
    }
165
166
    /**
167
     * @return Paginator
168
     */
169
    public function testPaginateFake()
170
    {
171
        $this
172
            ->abstractRepository
173
            ->expects($this->once())
174
            ->method('addPaginateQuery')
175
            ->withConsecutive([$this->queryBuilder, static::PAGE_SIZE, static::CURRENT_PAGE])
176
        ;
177
178
        $resultExpected = [];
179
        for ($i = 1; $i <= static::PAGE_SIZE; $i++) {
180
            $resultExpected[] = $this->entity;
181
        }
182
        $this
183
            ->abstractRepository
184
            ->expects($this->once())
185
            ->method('getPaginateResult')
186
            ->withConsecutive([$this->queryBuilder, false])
187
            ->willReturn($resultExpected)
188
        ;
189
190
        $paginator = $this->createPaginator();
191
        $result = $paginator->paginateFake();
192
193
        $this->assertCount(\count($resultExpected), $result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type string; however, parameter $haystack of PHPUnit\Framework\Assert::assertCount() does only seem to accept Countable|iterable, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

193
        $this->assertCount(\count($resultExpected), /** @scrutinizer ignore-type */ $result);
Loading history...
194
        $this->assertEquals($resultExpected, $result);
195
196
        $paginator->paginateFake();
197
198
        return $paginator;
199
    }
200
201
    /**
202
     * @return Paginator
203
     */
204
    public function testPaginateFakeWithoutResult()
205
    {
206
        $this
207
            ->abstractRepository
208
            ->expects($this->once())
209
            ->method('addPaginateQuery')
210
            ->withConsecutive([$this->queryBuilder, static::PAGE_SIZE, static::CURRENT_PAGE])
211
        ;
212
213
        $resultExpected = [];
214
        $this
215
            ->abstractRepository
216
            ->expects($this->once())
217
            ->method('getPaginateResult')
218
            ->withConsecutive([$this->queryBuilder, false])
219
            ->willReturn($resultExpected)
220
        ;
221
222
        $paginator = $this->createPaginator();
223
        $result = $paginator->paginateFake();
224
225
        $this->assertCount(\count($resultExpected), $result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type string; however, parameter $haystack of PHPUnit\Framework\Assert::assertCount() does only seem to accept Countable|iterable, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

225
        $this->assertCount(\count($resultExpected), /** @scrutinizer ignore-type */ $result);
Loading history...
226
        $this->assertEquals($resultExpected, $result);
227
228
        return $paginator;
229
    }
230
231
    public function testGetPageNumbers()
232
    {
233
        $paginator = $this->testPaginate();
234
        $pagesBeforeAfter = $this
235
            ->createAccessibleProperty($paginator, 'options')
236
            ->getValue($paginator)[Paginator::OPTION_SHOW_PAGES_BEFORE_AND_AFTER_CURRENT_PAGE]
237
        ;
238
239
        $pages = \range(static::CURRENT_PAGE - $pagesBeforeAfter, static::CURRENT_PAGE + $pagesBeforeAfter);
240
        $this->assertEquals(\array_combine($pages, $pages), $paginator->getPageNumbers());
241
    }
242
243
    public function testGetPageNumbersWithUnlimitedOption()
244
    {
245
        $paginator = $this->testPaginate();
246
        $this
247
            ->createAccessibleProperty($paginator, 'options')
248
            ->setValue(
249
                $paginator,
250
                [
251
                    Paginator::OPTION_SHOW_PAGES_BEFORE_AND_AFTER_CURRENT_PAGE =>
252
                        Paginator::OPTION_VALUE_SHOW_PAGES_BEFORE_AND_AFTER_CURRENT_PAGE_UNLIMITED,
253
                ]
254
            )
255
        ;
256
257
        $totalPages = static::RESULT_COUNT / static::PAGE_SIZE;
258
        $pages = \range($totalPages - $totalPages + 1, $totalPages);
259
        $this->assertEquals(\array_combine($pages, $pages), $paginator->getPageNumbers());
260
    }
261
262
    public function testGetPageNumbersWhenPaginateFake()
263
    {
264
        $paginator = $this->testPaginateFake();
265
        $pagesBeforeAfter = $this
266
            ->createAccessibleProperty($paginator, 'options')
267
            ->getValue($paginator)[Paginator::OPTION_SHOW_PAGES_BEFORE_AND_AFTER_CURRENT_PAGE]
268
        ;
269
270
        $totalPages = static::CURRENT_PAGE;
271
        $pages = \range($totalPages - $pagesBeforeAfter, $totalPages + 1);
272
        $this->assertEquals(\array_combine($pages, $pages), $paginator->getPageNumbers());
273
    }
274
275
    public function testGetPageNumbersWhenPaginateFakeWithoutResult()
276
    {
277
        $paginator = $this->testPaginateFakeWithoutResult();
278
        $pagesBeforeAfter = $this
279
            ->createAccessibleProperty($paginator, 'options')
280
            ->getValue($paginator)[Paginator::OPTION_SHOW_PAGES_BEFORE_AND_AFTER_CURRENT_PAGE]
281
        ;
282
283
        $totalPages = static::CURRENT_PAGE - 1;
284
        $pages = \range($totalPages - $pagesBeforeAfter, $totalPages);
285
286
        $this->assertEquals(\array_combine($pages, $pages), $paginator->getPageNumbers());
287
    }
288
289
    public function testGetPageNumbersWhenNotPaginated()
290
    {
291
        $this->expectException(PaginatorException::class);
292
        $this->expectExceptionMessage('You must call "paginate" or "paginateFake" before calling this method!');
293
294
        $this->createPaginator()->getPageNumbers();
295
    }
296
297
    /**
298
     * @dataProvider getTotalPagesData
299
     *
300
     * @param int $resultCount
301
     * @param int $expectedTotalPages
302
     */
303
    public function testGetTotalPages(int $resultCount, int $expectedTotalPages)
304
    {
305
        $this->queryBuilder->method('count')->willReturn($resultCount);
306
307
        $paginator = $this->createPaginator();
308
        $paginator->paginate();
309
310
        $this->assertEquals($expectedTotalPages, $paginator->getTotalPages());
311
    }
312
313
    /**
314
     * @return array
315
     */
316
    public function getTotalPagesData()
317
    {
318
        return [
319
            [
320
                static::RESULT_COUNT,
321
                (int) \ceil(static::RESULT_COUNT / static::PAGE_SIZE),
322
            ],
323
            [
324
                static::RESULT_COUNT_ODD,
325
                (int) \ceil(static::RESULT_COUNT_ODD / static::PAGE_SIZE),
326
            ],
327
        ];
328
    }
329
330
    public function testGetTotalPagesWhenFakePaginate()
331
    {
332
        $paginator = $this->testPaginateFake();
333
334
        $this->assertEquals(static::CURRENT_PAGE + 1, $paginator->getTotalPages());
335
    }
336
337
    public function testGetTotalPagesWhenFakePaginateHasNoResult()
338
    {
339
        $paginator = $this->testPaginateFakeWithoutResult();
340
341
        $this->assertEquals(static::CURRENT_PAGE, $paginator->getTotalPages());
342
    }
343
344
    public function testGetTotalPagesWhenNotPaginated()
345
    {
346
        $this->expectException(PaginatorException::class);
347
        $this->expectExceptionMessage('You must call "paginate" or "paginateFake" before calling this method!');
348
349
        $this->createPaginator()->getTotalPages();
350
    }
351
352
    public function testGetCurrentPageNumbers()
353
    {
354
        $paginator = $this->testPaginate();
355
356
        $this->assertEquals(static::CURRENT_PAGE, $paginator->getCurrentPageNumber());
357
    }
358
359
    public function testGetCurrentPageNumbersWhenNotPaginated()
360
    {
361
        $this->expectException(PaginatorException::class);
362
        $this->expectExceptionMessage('You must call "paginate" or "paginateFake" before calling this method!');
363
364
        $this->createPaginator()->getCurrentPageNumber();
365
    }
366
367
    public function testGetNextPageNumber()
368
    {
369
        $paginator = $this->testPaginate();
370
371
        $this->assertEquals(static::CURRENT_PAGE + 1, $paginator->getNextPageNumber());
372
    }
373
374
    public function testGetNextPageNumberWhenPaginateFake()
375
    {
376
        $paginator = $this->testPaginateFake();
377
378
        $this->assertEquals(static::CURRENT_PAGE + 1, $paginator->getNextPageNumber());
379
    }
380
381
    public function testGetNextPageNumberWhenMaximumPageIsOne()
382
    {
383
        $paginator = $this->testPaginateWhenCurrentPageIsHigherThanExistingPage();
384
385
        $this->assertEquals(static::NEXT_PAGE_NON_EXISTENT, $paginator->getNextPageNumber());
386
    }
387
388
    public function testGetNextPageNumberWhenNotPaginated()
389
    {
390
        $this->expectException(PaginatorException::class);
391
        $this->expectExceptionMessage('You must call "paginate" or "paginateFake" before calling this method!');
392
393
        $this->createPaginator()->getNextPageNumber();
394
    }
395
396
    public function testGetPreviousPageNumber()
397
    {
398
        $paginator = $this->testPaginate();
399
400
        $this->assertEquals(static::CURRENT_PAGE - 1, $paginator->getPreviousPageNumber());
401
    }
402
403
    public function testGetPreviousPageNumberWhenCurrentPageIsOne()
404
    {
405
        $paginator = $this->testPaginateWhenCurrentPageIsHigherThanExistingPage();
406
407
        $this->assertEquals(static::PREVIOUS_PAGE_NON_EXISTENT, $paginator->getPreviousPageNumber());
408
    }
409
410
    public function testGetPreviousPageNumberWhenNotPaginated()
411
    {
412
        $this->expectException(PaginatorException::class);
413
        $this->expectExceptionMessage('You must call "paginate" or "paginateFake" before calling this method!');
414
415
        $this->createPaginator()->getPreviousPageNumber();
416
    }
417
418
    public function testGetResultTotalCount()
419
    {
420
        $paginator = $this->testPaginate();
421
422
        $this->assertEquals(static::RESULT_COUNT, $paginator->getResultTotalCount());
423
    }
424
425
    public function testGetResultTotalCountWhenPaginateFakeCalled()
426
    {
427
        $paginator = $this->testPaginateFake();
428
429
        $this->expectException(PaginatorException::class);
430
        $this->expectExceptionMessage(
431
            'When calling "paginateFake", is is not possible to determine result total count!'
432
        );
433
434
        $paginator->getResultTotalCount();
435
    }
436
437
    public function testGetResultTotalCountWhenNotPaginated()
438
    {
439
        $this->expectException(PaginatorException::class);
440
        $this->expectExceptionMessage('You must call "paginate" or "paginateFake" before calling this method!');
441
442
        $this->createPaginator()->getResultTotalCount();
443
    }
444
445
    public function testGetPageSize()
446
    {
447
        $paginator = $this->testPaginate();
448
449
        $this->assertEquals(static::PAGE_SIZE, $paginator->getPageSize());
450
    }
451
452
    public function testGetPageSizeWhenNotPaginated()
453
    {
454
        $this->expectException(PaginatorException::class);
455
        $this->expectExceptionMessage('You must call "paginate" or "paginateFake" before calling this method!');
456
457
        $this->createPaginator()->getPageSize();
458
    }
459
460
    /**
461
     * @return Paginator
462
     */
463
    private function createPaginator()
464
    {
465
        $this->addPaginateQuery = function (QueryBuilderInterface $queryBuilder, $pageSize, $currentPage) {
466
            $this
467
                ->createAccessibleMethod($this->abstractRepository, 'addPaginateQuery')
468
                ->invoke($this->abstractRepository, $queryBuilder, $pageSize, $currentPage)
469
            ;
470
        };
471
        $this->getPaginateResult = function (QueryBuilderInterface $queryBuilder, $toString) {
472
            return $this
473
                ->createAccessibleMethod($this->abstractRepository, 'getPaginateResult')
474
                ->invoke($this->abstractRepository, $queryBuilder, $toString)
475
            ;
476
        };
477
478
        return new Paginator(
479
            $this->queryBuilder,
480
            $this->addPaginateQuery,
481
            $this->getPaginateResult,
482
            static::PAGE_SIZE,
483
            static::CURRENT_PAGE
484
        );
485
    }
486
}
487