Passed
Push — master ( fbff8a...4b6aad )
by Chito
01:44
created

PaginationResultTest::testIteratorCurrent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 16
c 1
b 0
f 1
dl 0
loc 23
rs 9.7333
cc 1
nc 1
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Lampager\Cake\Test\TestCase;
6
7
use ArrayIterator;
8
use Cake\I18n\Time;
9
use Cake\ORM\Entity;
10
use Generator;
11
use IteratorAggregate;
12
use Lampager\Cake\PaginationResult;
13
use PHPUnit\Framework\Error\Error;
14
use PHPUnit\Framework\MockObject\MockObject;
15
use Traversable;
16
17
class PaginationResultTest extends TestCase
18
{
19
    /**
20
     * @param Entity[]                     $entities
21
     * @param Entity[]|Traversable<Entity> $records
22
     * @param mixed[]                      $meta
23
     * @dataProvider arrayProvider
24
     * @dataProvider iteratorAggregateProvider
25
     */
26
    public function testIteratorCurrent(array $entities, $records, array $meta): void
27
    {
28
        $actual = new PaginationResult($records, $meta);
29
30
        $this->assertEquals($entities[0], $actual->current());
31
32
        $actual->next();
33
        $this->assertTrue($actual->valid());
34
        $this->assertEquals(1, $actual->key());
35
        $this->assertEquals($entities[1], $actual->current());
36
37
        $actual->next();
38
        $this->assertTrue($actual->valid());
39
        $this->assertEquals(2, $actual->key());
40
        $this->assertEquals($entities[2], $actual->current());
41
42
        $actual->next();
43
        $this->assertFalse($actual->valid());
44
45
        $actual->rewind();
46
        $this->assertTrue($actual->valid());
47
        $this->assertEquals(0, $actual->key());
48
        $this->assertEquals($entities[0], $actual->current());
49
    }
50
51
    /**
52
     * @param Entity[]                     $entities
53
     * @param Entity[]|Traversable<Entity> $records
54
     * @param mixed[]                      $meta
55
     * @dataProvider arrayProvider
56
     * @dataProvider iteratorAggregateProvider
57
     */
58
    public function testIteratorKey(array $entities, $records, array $meta): void
59
    {
60
        $actual = new PaginationResult($records, $meta);
61
62
        $this->assertEquals(0, $actual->key());
63
64
        $actual->next();
65
        $this->assertTrue($actual->valid());
66
        $this->assertEquals(1, $actual->key());
67
        $this->assertEquals($entities[1], $actual->current());
68
69
        $actual->next();
70
        $this->assertTrue($actual->valid());
71
        $this->assertEquals(2, $actual->key());
72
        $this->assertEquals($entities[2], $actual->current());
73
74
        $actual->next();
75
        $this->assertFalse($actual->valid());
76
77
        $actual->rewind();
78
        $this->assertTrue($actual->valid());
79
        $this->assertEquals(0, $actual->key());
80
        $this->assertEquals($entities[0], $actual->current());
81
    }
82
83
    /**
84
     * @param Entity[]                     $entities
85
     * @param Entity[]|Traversable<Entity> $records
86
     * @param mixed[]                      $meta
87
     * @dataProvider arrayProvider
88
     * @dataProvider iteratorAggregateProvider
89
     */
90
    public function testIteratorNext(array $entities, $records, array $meta): void
91
    {
92
        $actual = new PaginationResult($records, $meta);
93
94
        $actual->next();
95
        $this->assertTrue($actual->valid());
96
        $this->assertEquals(1, $actual->key());
97
        $this->assertEquals($entities[1], $actual->current());
98
99
        $actual->next();
100
        $this->assertTrue($actual->valid());
101
        $this->assertEquals(2, $actual->key());
102
        $this->assertEquals($entities[2], $actual->current());
103
104
        $actual->next();
105
        $this->assertFalse($actual->valid());
106
107
        $actual->rewind();
108
        $this->assertTrue($actual->valid());
109
        $this->assertEquals(0, $actual->key());
110
        $this->assertEquals($entities[0], $actual->current());
111
    }
112
113
    /**
114
     * @param Entity[]                     $entities
115
     * @param Entity[]|Traversable<Entity> $records
116
     * @param mixed[]                      $meta
117
     * @dataProvider arrayProvider
118
     * @dataProvider iteratorAggregateProvider
119
     */
120
    public function testIteratorValid(array $entities, $records, array $meta): void
121
    {
122
        $actual = new PaginationResult($records, $meta);
123
124
        $this->assertTrue($actual->valid());
125
        $this->assertEquals(0, $actual->key());
126
        $this->assertEquals($entities[0], $actual->current());
127
128
        $actual->next();
129
        $this->assertTrue($actual->valid());
130
        $this->assertEquals(1, $actual->key());
131
        $this->assertEquals($entities[1], $actual->current());
132
133
        $actual->next();
134
        $this->assertTrue($actual->valid());
135
        $this->assertEquals(2, $actual->key());
136
        $this->assertEquals($entities[2], $actual->current());
137
138
        $actual->next();
139
        $this->assertFalse($actual->valid());
140
141
        $actual->rewind();
142
        $this->assertTrue($actual->valid());
143
        $this->assertEquals(0, $actual->key());
144
        $this->assertEquals($entities[0], $actual->current());
145
    }
146
147
    /**
148
     * @param Entity[]                     $entities
149
     * @param Entity[]|Traversable<Entity> $records
150
     * @param mixed[]                      $meta
151
     * @dataProvider arrayProvider
152
     * @dataProvider iteratorAggregateProvider
153
     */
154
    public function testJsonSerialize(array $entities, $records, array $meta, string $expected): void
0 ignored issues
show
Unused Code introduced by
The parameter $entities is not used and could be removed. ( Ignorable by Annotation )

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

154
    public function testJsonSerialize(/** @scrutinizer ignore-unused */ array $entities, $records, array $meta, string $expected): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
155
    {
156
        $actual = json_encode(new PaginationResult($records, $meta));
157
        $this->assertJsonStringEqualsJsonString($expected, $actual);
158
    }
159
160
    /**
161
     * @param Entity[]                     $entities
162
     * @param Entity[]|Traversable<Entity> $records
163
     * @param mixed[]                      $meta
164
     * @dataProvider arrayProvider
165
     * @dataProvider iteratorAggregateProvider
166
     */
167
    public function testSerializeAndUnserialize(array $entities, $records, array $meta): void
0 ignored issues
show
Unused Code introduced by
The parameter $entities is not used and could be removed. ( Ignorable by Annotation )

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

167
    public function testSerializeAndUnserialize(/** @scrutinizer ignore-unused */ array $entities, $records, array $meta): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
168
    {
169
        $actual = unserialize(serialize(new PaginationResult($records, $meta)));
170
        $expected = new PaginationResult($records, $meta);
171
        $this->assertJsonEquals($expected, $actual);
172
    }
173
174
    /**
175
     * @param Entity[]                     $entities
176
     * @param Entity[]|Traversable<Entity> $records
177
     * @param mixed[]                      $meta
178
     * @dataProvider arrayProvider
179
     * @dataProvider iteratorAggregateProvider
180
     */
181
    public function testDebugInfo(array $entities, $records, array $meta): void
182
    {
183
        $actual = (new PaginationResult($records, $meta))->__debugInfo();
184
185
        $this->assertEquals([
186
            '(help)' => 'This is a Lampager Pagination Result object.',
187
            'records' => $entities,
188
            'hasPrevious' => $meta['hasPrevious'],
189
            'previousCursor' => $meta['previousCursor'],
190
            'hasNext' => $meta['hasNext'],
191
            'nextCursor' => $meta['nextCursor'],
192
        ], $actual);
193
    }
194
195
    /**
196
     * @param Entity[]                     $entities
197
     * @param Entity[]|Traversable<Entity> $records
198
     * @param mixed[]                      $meta
199
     * @dataProvider arrayProvider
200
     * @dataProvider iteratorAggregateProvider
201
     */
202
    public function testPublicProperties(array $entities, $records, array $meta): void
0 ignored issues
show
Unused Code introduced by
The parameter $entities is not used and could be removed. ( Ignorable by Annotation )

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

202
    public function testPublicProperties(/** @scrutinizer ignore-unused */ array $entities, $records, array $meta): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
203
    {
204
        $paginationResult = new PaginationResult($records, $meta);
205
206
        $this->assertEquals($meta['hasPrevious'], $paginationResult->hasPrevious);
207
        $this->assertEquals($meta['previousCursor'], $paginationResult->previousCursor);
208
        $this->assertEquals($meta['hasNext'], $paginationResult->hasNext);
209
        $this->assertEquals($meta['nextCursor'], $paginationResult->nextCursor);
210
    }
211
212
    /**
213
     * @param Entity[]                     $entities
214
     * @param Entity[]|Traversable<Entity> $records
215
     * @param mixed[]                      $meta
216
     * @dataProvider arrayProvider
217
     * @dataProvider iteratorAggregateProvider
218
     */
219
    public function testUndefinedProperties(array $entities, $records, array $meta): void
0 ignored issues
show
Unused Code introduced by
The parameter $entities is not used and could be removed. ( Ignorable by Annotation )

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

219
    public function testUndefinedProperties(/** @scrutinizer ignore-unused */ array $entities, $records, array $meta): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
220
    {
221
        $this->expectException(Error::class);
222
        $this->expectExceptionMessageMatches('/^Undefined property via __get\(\): undefinedProperty/');
223
224
        $paginationResult = new PaginationResult($records, $meta);
225
        $paginationResult->undefinedProperty;
0 ignored issues
show
Bug Best Practice introduced by
The property undefinedProperty does not exist on Lampager\Cake\PaginationResult. Since you implemented __get, consider adding a @property annotation.
Loading history...
226
    }
227
228
    public function arrayProvider(): Generator
229
    {
230
        yield 'Array iteration' => [
231
            [
232
                new Entity([
233
                    'id' => 1,
234
                    'modified' => new Time('2017-01-01 10:00:00'),
235
                ]),
236
                new Entity([
237
                    'id' => 3,
238
                    'modified' => new Time('2017-01-01 10:00:00'),
239
                ]),
240
                new Entity([
241
                    'id' => 5,
242
                    'modified' => new Time('2017-01-01 10:00:00'),
243
                ]),
244
            ],
245
            [
246
                new Entity([
247
                    'id' => 1,
248
                    'modified' => new Time('2017-01-01 10:00:00'),
249
                ]),
250
                new Entity([
251
                    'id' => 3,
252
                    'modified' => new Time('2017-01-01 10:00:00'),
253
                ]),
254
                new Entity([
255
                    'id' => 5,
256
                    'modified' => new Time('2017-01-01 10:00:00'),
257
                ]),
258
            ],
259
            [
260
                'hasPrevious' => null,
261
                'previousCursor' => null,
262
                'hasNext' => true,
263
                'nextCursor' => [
264
                    'Posts.id' => 2,
265
                    'Posts.modified' => new Time('2017-01-01 11:00:00'),
266
                ],
267
            ],
268
            '{
269
                "records": [
270
                    {
271
                        "id": 1,
272
                        "modified": "2017-01-01T10:00:00+00:00"
273
                    },
274
                    {
275
                        "id": 3,
276
                        "modified": "2017-01-01T10:00:00+00:00"
277
                    },
278
                    {
279
                        "id": 5,
280
                        "modified": "2017-01-01T10:00:00+00:00"
281
                    }
282
                ],
283
                "hasPrevious": null,
284
                "previousCursor": null,
285
                "hasNext": true,
286
                "nextCursor": {
287
                    "Posts.id": 2,
288
                    "Posts.modified": "2017-01-01T11:00:00+00:00"
289
                }
290
            }',
291
        ];
292
293
        yield 'ArrayIterator iteration' => [
294
            [
295
                new Entity([
296
                    'id' => 1,
297
                    'modified' => new Time('2017-01-01 10:00:00'),
298
                ]),
299
                new Entity([
300
                    'id' => 3,
301
                    'modified' => new Time('2017-01-01 10:00:00'),
302
                ]),
303
                new Entity([
304
                    'id' => 5,
305
                    'modified' => new Time('2017-01-01 10:00:00'),
306
                ]),
307
            ],
308
            new ArrayIterator([
309
                new Entity([
310
                    'id' => 1,
311
                    'modified' => new Time('2017-01-01 10:00:00'),
312
                ]),
313
                new Entity([
314
                    'id' => 3,
315
                    'modified' => new Time('2017-01-01 10:00:00'),
316
                ]),
317
                new Entity([
318
                    'id' => 5,
319
                    'modified' => new Time('2017-01-01 10:00:00'),
320
                ]),
321
            ]),
322
            [
323
                'hasPrevious' => null,
324
                'previousCursor' => null,
325
                'hasNext' => true,
326
                'nextCursor' => [
327
                    'Posts.id' => 2,
328
                    'Posts.modified' => new Time('2017-01-01 11:00:00'),
329
                ],
330
            ],
331
            '{
332
                "records": [
333
                    {
334
                        "id": 1,
335
                        "modified": "2017-01-01T10:00:00+00:00"
336
                    },
337
                    {
338
                        "id": 3,
339
                        "modified": "2017-01-01T10:00:00+00:00"
340
                    },
341
                    {
342
                        "id": 5,
343
                        "modified": "2017-01-01T10:00:00+00:00"
344
                    }
345
                ],
346
                "hasPrevious": null,
347
                "previousCursor": null,
348
                "hasNext": true,
349
                "nextCursor": {
350
                    "Posts.id": 2,
351
                    "Posts.modified": "2017-01-01T11:00:00+00:00"
352
                }
353
            }',
354
        ];
355
    }
356
357
    public function iteratorAggregateProvider(): Generator
358
    {
359
        /** @var IteratorAggregate&MockObject $iteratorAggregate */
360
        $iteratorAggregate = $this->getMockForAbstractClass(IteratorAggregate::class);
361
        $iteratorAggregate->method('getIterator')->willReturn(new ArrayIterator([
362
            new Entity([
363
                'id' => 1,
364
                'modified' => new Time('2017-01-01 10:00:00'),
365
            ]),
366
            new Entity([
367
                'id' => 3,
368
                'modified' => new Time('2017-01-01 10:00:00'),
369
            ]),
370
            new Entity([
371
                'id' => 5,
372
                'modified' => new Time('2017-01-01 10:00:00'),
373
            ]),
374
        ]));
375
376
        yield 'IteratorAggregate iteration' => [
377
            [
378
                new Entity([
379
                    'id' => 1,
380
                    'modified' => new Time('2017-01-01 10:00:00'),
381
                ]),
382
                new Entity([
383
                    'id' => 3,
384
                    'modified' => new Time('2017-01-01 10:00:00'),
385
                ]),
386
                new Entity([
387
                    'id' => 5,
388
                    'modified' => new Time('2017-01-01 10:00:00'),
389
                ]),
390
            ],
391
            $iteratorAggregate,
392
            [
393
                'hasPrevious' => null,
394
                'previousCursor' => null,
395
                'hasNext' => true,
396
                'nextCursor' => [
397
                    'Posts.id' => 2,
398
                    'Posts.modified' => new Time('2017-01-01 11:00:00'),
399
                ],
400
            ],
401
            '{
402
                "records": [
403
                    {
404
                        "id": 1,
405
                        "modified": "2017-01-01T10:00:00+00:00"
406
                    },
407
                    {
408
                        "id": 3,
409
                        "modified": "2017-01-01T10:00:00+00:00"
410
                    },
411
                    {
412
                        "id": 5,
413
                        "modified": "2017-01-01T10:00:00+00:00"
414
                    }
415
                ],
416
                "hasPrevious": null,
417
                "previousCursor": null,
418
                "hasNext": true,
419
                "nextCursor": {
420
                    "Posts.id": 2,
421
                    "Posts.modified": "2017-01-01T11:00:00+00:00"
422
                }
423
            }',
424
        ];
425
    }
426
}
427