p$0   A
last analyzed

Complexity

Total Complexity 1

Size/Duplication

Total Lines 15
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 1
c 1
b 0
f 0
dl 0
loc 15
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Lampager\Cake\Test\TestCase;
6
7
use ArrayIterator;
8
use Cake\I18n\DateTime;
0 ignored issues
show
Bug introduced by
The type Cake\I18n\DateTime was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Cake\ORM\Entity;
10
use Generator;
11
use IteratorAggregate;
12
use Lampager\Cake\PaginationResult;
13
use PHPUnit\Framework\Attributes\DataProvider;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Framework\Attributes\DataProvider was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Traversable;
15
16
class PaginationResultTest extends TestCase
17
{
18
    public function setUp(): void
19
    {
20
        parent::setUp();
21
22
        set_error_handler(
23
            static function ($errno, $errstr, $errfile, $errline) {
24
                throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
25
            },
26
            E_ALL
27
        );
28
    }
29
30
    public function tearDown(): void
31
    {
32
        restore_error_handler();
33
34
        parent::tearDown();
35
    }
36
37
    /**
38
     * @param Entity[]                     $entities
39
     * @param Entity[]|Traversable<Entity> $records
40
     * @param mixed[]                      $meta
41
     */
42
    #[DataProvider('arrayProvider')]
43
    #[DataProvider('iteratorAggregateProvider')]
44
    public function testCurrentPage(array $entities, $records, array $meta): void
45
    {
46
        $actual = new PaginationResult($records, $meta);
47
        $this->assertEquals(0, $actual->currentPage());
48
    }
49
50
    /**
51
     * @param Entity[]                     $entities
52
     * @param Entity[]|Traversable<Entity> $records
53
     * @param mixed[]                      $meta
54
     */
55
    #[DataProvider('arrayProvider')]
56
    #[DataProvider('iteratorAggregateProvider')]
57
    public function testPerPage(array $entities, $records, array $meta): void
58
    {
59
        $actual = new PaginationResult($records, $meta);
60
        $this->assertEquals(3, $actual->perPage());
61
    }
62
63
    /**
64
     * @param Entity[]                     $entities
65
     * @param Entity[]|Traversable<Entity> $records
66
     * @param mixed[]                      $meta
67
     */
68
    #[DataProvider('arrayProvider')]
69
    #[DataProvider('iteratorAggregateProvider')]
70
    public function testTotalCount(array $entities, $records, array $meta): void
71
    {
72
        $actual = new PaginationResult($records, $meta);
73
        $this->assertNull($actual->totalCount());
0 ignored issues
show
Bug introduced by
Are you sure the usage of $actual->totalCount() targeting Lampager\Cake\PaginationResult::totalCount() 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...
74
    }
75
76
    /**
77
     * @param Entity[]                     $entities
78
     * @param Entity[]|Traversable<Entity> $records
79
     * @param mixed[]                      $meta
80
     */
81
    #[DataProvider('arrayProvider')]
82
    #[DataProvider('iteratorAggregateProvider')]
83
    public function testPageCount(array $entities, $records, array $meta): void
84
    {
85
        $actual = new PaginationResult($records, $meta);
86
        $this->assertNull($actual->pageCount());
0 ignored issues
show
Bug introduced by
Are you sure the usage of $actual->pageCount() targeting Lampager\Cake\PaginationResult::pageCount() 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...
87
    }
88
89
    /**
90
     * @param Entity[]                     $entities
91
     * @param Entity[]|Traversable<Entity> $records
92
     * @param mixed[]                      $meta
93
     */
94
    #[DataProvider('arrayProvider')]
95
    #[DataProvider('iteratorAggregateProvider')]
96
    public function testHasPrevPage(array $entities, $records, array $meta): void
97
    {
98
        $actual = new PaginationResult($records, $meta);
99
        $this->assertEquals((bool)$meta['hasPrevious'], $actual->hasPrevPage());
100
    }
101
102
    /**
103
     * @param Entity[]                     $entities
104
     * @param Entity[]|Traversable<Entity> $records
105
     * @param mixed[]                      $meta
106
     */
107
    #[DataProvider('arrayProvider')]
108
    #[DataProvider('iteratorAggregateProvider')]
109
    public function testHasNextPage(array $entities, $records, array $meta): void
110
    {
111
        $actual = new PaginationResult($records, $meta);
112
        $this->assertEquals((bool)$meta['hasNext'], $actual->hasNextPage());
113
    }
114
115
    /**
116
     * @param Entity[]                     $entities
117
     * @param Entity[]|Traversable<Entity> $records
118
     * @param mixed[]                      $meta
119
     */
120
    #[DataProvider('arrayProvider')]
121
    #[DataProvider('iteratorAggregateProvider')]
122
    public function testItems(array $entities, $records, array $meta): void
123
    {
124
        $paginationResult = new PaginationResult($records, $meta);
125
        $expected = is_array($records) ? $records : iterator_to_array($records);
126
        $actual = is_array($paginationResult->items()) ? $paginationResult->items() : iterator_to_array($paginationResult->items());
127
        $this->assertEquals($expected, $actual);
128
    }
129
130
    /**
131
     * @param Entity[]                     $entities
132
     * @param Entity[]|Traversable<Entity> $records
133
     * @param mixed[]                      $meta
134
     */
135
    #[DataProvider('arrayProvider')]
136
    #[DataProvider('iteratorAggregateProvider')]
137
    public function testPagingParam(array $entities, $records, array $meta): void
138
    {
139
        $actual = new PaginationResult($records, $meta);
140
        $this->assertEquals(count($entities), $actual->pagingParam('count'));
141
        $this->assertNull($actual->pagingParam('totalCount'));
142
        $this->assertEquals($meta['limit'], $actual->pagingParam('perPage'));
143
        $this->assertNull($actual->pagingParam('pageCount'));
144
        $this->assertEquals(0, $actual->pagingParam('currentPage'));
145
        $this->assertEquals($meta['hasPrevious'], $actual->pagingParam('hasPrevPage'));
146
        $this->assertEquals($meta['hasNext'], $actual->pagingParam('hasNextPage'));
147
    }
148
149
    /**
150
     * @param Entity[]                     $entities
151
     * @param Entity[]|Traversable<Entity> $records
152
     * @param mixed[]                      $meta
153
     */
154
    #[DataProvider('arrayProvider')]
155
    #[DataProvider('iteratorAggregateProvider')]
156
    public function testJsonSerialize(array $entities, $records, array $meta, string $expected): void
157
    {
158
        $actual = json_encode(new PaginationResult($records, $meta));
159
        $this->assertJsonStringEqualsJsonString($expected, $actual);
160
    }
161
162
    /**
163
     * @param Entity[]                     $entities
164
     * @param Entity[]|Traversable<Entity> $records
165
     * @param mixed[]                      $meta
166
     */
167
    #[DataProvider('arrayProvider')]
168
    #[DataProvider('iteratorAggregateProvider')]
169
    public function testDebugInfo(array $entities, $records, array $meta): void
170
    {
171
        $actual = (new PaginationResult($records, $meta))->__debugInfo();
172
173
        $this->assertEquals([
174
            '(help)' => 'This is a Lampager Pagination Result object.',
175
            'records' => $entities,
176
            'hasPrevious' => $meta['hasPrevious'],
177
            'previousCursor' => $meta['previousCursor'],
178
            'hasNext' => $meta['hasNext'],
179
            'nextCursor' => $meta['nextCursor'],
180
        ], $actual);
181
    }
182
183
    /**
184
     * @param Entity[]                     $entities
185
     * @param Entity[]|Traversable<Entity> $records
186
     * @param mixed[]                      $meta
187
     */
188
    #[DataProvider('arrayProvider')]
189
    #[DataProvider('iteratorAggregateProvider')]
190
    public function testPublicProperties(array $entities, $records, array $meta): void
191
    {
192
        $paginationResult = new PaginationResult($records, $meta);
193
194
        $this->assertEquals($meta['hasPrevious'], $paginationResult->hasPrevious);
195
        $this->assertEquals($meta['previousCursor'], $paginationResult->previousCursor);
196
        $this->assertEquals($meta['hasNext'], $paginationResult->hasNext);
197
        $this->assertEquals($meta['nextCursor'], $paginationResult->nextCursor);
198
    }
199
200
    public static function arrayProvider(): Generator
201
    {
202
        yield 'Array iteration' => [
203
            [
204
                new Entity([
205
                    'id' => 1,
206
                    'modified' => new DateTime('2017-01-01 10:00:00'),
207
                ]),
208
                new Entity([
209
                    'id' => 3,
210
                    'modified' => new DateTime('2017-01-01 10:00:00'),
211
                ]),
212
                new Entity([
213
                    'id' => 5,
214
                    'modified' => new DateTime('2017-01-01 10:00:00'),
215
                ]),
216
            ],
217
            [
218
                new Entity([
219
                    'id' => 1,
220
                    'modified' => new DateTime('2017-01-01 10:00:00'),
221
                ]),
222
                new Entity([
223
                    'id' => 3,
224
                    'modified' => new DateTime('2017-01-01 10:00:00'),
225
                ]),
226
                new Entity([
227
                    'id' => 5,
228
                    'modified' => new DateTime('2017-01-01 10:00:00'),
229
                ]),
230
            ],
231
            [
232
                'hasPrevious' => null,
233
                'previousCursor' => null,
234
                'hasNext' => true,
235
                'nextCursor' => [
236
                    'Posts.id' => 2,
237
                    'Posts.modified' => new DateTime('2017-01-01 11:00:00'),
238
                ],
239
                'limit' => 3,
240
            ],
241
            '{
242
                "records": [
243
                    {
244
                        "id": 1,
245
                        "modified": "2017-01-01T10:00:00+00:00"
246
                    },
247
                    {
248
                        "id": 3,
249
                        "modified": "2017-01-01T10:00:00+00:00"
250
                    },
251
                    {
252
                        "id": 5,
253
                        "modified": "2017-01-01T10:00:00+00:00"
254
                    }
255
                ],
256
                "hasPrevious": null,
257
                "previousCursor": null,
258
                "hasNext": true,
259
                "nextCursor": {
260
                    "Posts.id": 2,
261
                    "Posts.modified": "2017-01-01T11:00:00+00:00"
262
                }
263
            }',
264
        ];
265
266
        yield 'ArrayIterator iteration' => [
267
            [
268
                new Entity([
269
                    'id' => 1,
270
                    'modified' => new DateTime('2017-01-01 10:00:00'),
271
                ]),
272
                new Entity([
273
                    'id' => 3,
274
                    'modified' => new DateTime('2017-01-01 10:00:00'),
275
                ]),
276
                new Entity([
277
                    'id' => 5,
278
                    'modified' => new DateTime('2017-01-01 10:00:00'),
279
                ]),
280
            ],
281
            new ArrayIterator([
282
                new Entity([
283
                    'id' => 1,
284
                    'modified' => new DateTime('2017-01-01 10:00:00'),
285
                ]),
286
                new Entity([
287
                    'id' => 3,
288
                    'modified' => new DateTime('2017-01-01 10:00:00'),
289
                ]),
290
                new Entity([
291
                    'id' => 5,
292
                    'modified' => new DateTime('2017-01-01 10:00:00'),
293
                ]),
294
            ]),
295
            [
296
                'hasPrevious' => null,
297
                'previousCursor' => null,
298
                'hasNext' => true,
299
                'nextCursor' => [
300
                    'Posts.id' => 2,
301
                    'Posts.modified' => new DateTime('2017-01-01 11:00:00'),
302
                ],
303
                'limit' => 3,
304
            ],
305
            '{
306
                "records": [
307
                    {
308
                        "id": 1,
309
                        "modified": "2017-01-01T10:00:00+00:00"
310
                    },
311
                    {
312
                        "id": 3,
313
                        "modified": "2017-01-01T10:00:00+00:00"
314
                    },
315
                    {
316
                        "id": 5,
317
                        "modified": "2017-01-01T10:00:00+00:00"
318
                    }
319
                ],
320
                "hasPrevious": null,
321
                "previousCursor": null,
322
                "hasNext": true,
323
                "nextCursor": {
324
                    "Posts.id": 2,
325
                    "Posts.modified": "2017-01-01T11:00:00+00:00"
326
                }
327
            }',
328
        ];
329
    }
330
331
    public static function iteratorAggregateProvider(): Generator
332
    {
333
        yield 'IteratorAggregate iteration' => [
334
            [
335
                new Entity([
336
                    'id' => 1,
337
                    'modified' => new DateTime('2017-01-01 10:00:00'),
338
                ]),
339
                new Entity([
340
                    'id' => 3,
341
                    'modified' => new DateTime('2017-01-01 10:00:00'),
342
                ]),
343
                new Entity([
344
                    'id' => 5,
345
                    'modified' => new DateTime('2017-01-01 10:00:00'),
346
                ]),
347
            ],
348
            new class implements IteratorAggregate {
349
                public function getIterator(): Traversable
350
                {
351
                    return new ArrayIterator([
352
                        new Entity([
353
                            'id' => 1,
354
                            'modified' => new DateTime('2017-01-01 10:00:00'),
355
                        ]),
356
                        new Entity([
357
                            'id' => 3,
358
                            'modified' => new DateTime('2017-01-01 10:00:00'),
359
                        ]),
360
                        new Entity([
361
                            'id' => 5,
362
                            'modified' => new DateTime('2017-01-01 10:00:00'),
363
                        ]),
364
                    ]);
365
                }
366
            },
367
            [
368
                'hasPrevious' => null,
369
                'previousCursor' => null,
370
                'hasNext' => true,
371
                'nextCursor' => [
372
                    'Posts.id' => 2,
373
                    'Posts.modified' => new DateTime('2017-01-01 11:00:00'),
374
                ],
375
                'limit' => 3,
376
            ],
377
            '{
378
                "records": [
379
                    {
380
                        "id": 1,
381
                        "modified": "2017-01-01T10:00:00+00:00"
382
                    },
383
                    {
384
                        "id": 3,
385
                        "modified": "2017-01-01T10:00:00+00:00"
386
                    },
387
                    {
388
                        "id": 5,
389
                        "modified": "2017-01-01T10:00:00+00:00"
390
                    }
391
                ],
392
                "hasPrevious": null,
393
                "previousCursor": null,
394
                "hasNext": true,
395
                "nextCursor": {
396
                    "Posts.id": 2,
397
                    "Posts.modified": "2017-01-01T11:00:00+00:00"
398
                }
399
            }',
400
        ];
401
    }
402
}
403