Passed
Push — master ( 6c31f6...fbff8a )
by Chito
01:43
created

testSerializeAndUnserialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 3
c 1
b 0
f 1
dl 0
loc 5
rs 10
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\MockObject\MockObject;
14
use Traversable;
15
16
class PaginationResultTest extends TestCase
17
{
18
    /**
19
     * @param Entity[]                     $entities
20
     * @param Entity[]|Traversable<Entity> $records
21
     * @param mixed[]                      $meta
22
     * @dataProvider arrayProvider
23
     * @dataProvider iteratorAggregateProvider
24
     */
25
    public function testIteratorCurrent(array $entities, $records, array $meta): void
26
    {
27
        $actual = new PaginationResult($records, $meta);
28
29
        $this->assertEquals($entities[0], $actual->current());
30
31
        $actual->next();
32
        $this->assertTrue($actual->valid());
33
        $this->assertEquals(1, $actual->key());
34
        $this->assertEquals($entities[1], $actual->current());
35
36
        $actual->next();
37
        $this->assertTrue($actual->valid());
38
        $this->assertEquals(2, $actual->key());
39
        $this->assertEquals($entities[2], $actual->current());
40
41
        $actual->next();
42
        $this->assertFalse($actual->valid());
43
44
        $actual->rewind();
45
        $this->assertTrue($actual->valid());
46
        $this->assertEquals(0, $actual->key());
47
        $this->assertEquals($entities[0], $actual->current());
48
    }
49
50
    /**
51
     * @param Entity[]                     $entities
52
     * @param Entity[]|Traversable<Entity> $records
53
     * @param mixed[]                      $meta
54
     * @dataProvider arrayProvider
55
     * @dataProvider iteratorAggregateProvider
56
     */
57
    public function testIteratorKey(array $entities, $records, array $meta): void
58
    {
59
        $actual = new PaginationResult($records, $meta);
60
61
        $this->assertEquals(0, $actual->key());
62
63
        $actual->next();
64
        $this->assertTrue($actual->valid());
65
        $this->assertEquals(1, $actual->key());
66
        $this->assertEquals($entities[1], $actual->current());
67
68
        $actual->next();
69
        $this->assertTrue($actual->valid());
70
        $this->assertEquals(2, $actual->key());
71
        $this->assertEquals($entities[2], $actual->current());
72
73
        $actual->next();
74
        $this->assertFalse($actual->valid());
75
76
        $actual->rewind();
77
        $this->assertTrue($actual->valid());
78
        $this->assertEquals(0, $actual->key());
79
        $this->assertEquals($entities[0], $actual->current());
80
    }
81
82
    /**
83
     * @param Entity[]                     $entities
84
     * @param Entity[]|Traversable<Entity> $records
85
     * @param mixed[]                      $meta
86
     * @dataProvider arrayProvider
87
     * @dataProvider iteratorAggregateProvider
88
     */
89
    public function testIteratorNext(array $entities, $records, array $meta): void
90
    {
91
        $actual = new PaginationResult($records, $meta);
92
93
        $actual->next();
94
        $this->assertTrue($actual->valid());
95
        $this->assertEquals(1, $actual->key());
96
        $this->assertEquals($entities[1], $actual->current());
97
98
        $actual->next();
99
        $this->assertTrue($actual->valid());
100
        $this->assertEquals(2, $actual->key());
101
        $this->assertEquals($entities[2], $actual->current());
102
103
        $actual->next();
104
        $this->assertFalse($actual->valid());
105
106
        $actual->rewind();
107
        $this->assertTrue($actual->valid());
108
        $this->assertEquals(0, $actual->key());
109
        $this->assertEquals($entities[0], $actual->current());
110
    }
111
112
    /**
113
     * @param Entity[]                     $entities
114
     * @param Entity[]|Traversable<Entity> $records
115
     * @param mixed[]                      $meta
116
     * @dataProvider arrayProvider
117
     * @dataProvider iteratorAggregateProvider
118
     */
119
    public function testIteratorValid(array $entities, $records, array $meta): void
120
    {
121
        $actual = new PaginationResult($records, $meta);
122
123
        $this->assertTrue($actual->valid());
124
        $this->assertEquals(0, $actual->key());
125
        $this->assertEquals($entities[0], $actual->current());
126
127
        $actual->next();
128
        $this->assertTrue($actual->valid());
129
        $this->assertEquals(1, $actual->key());
130
        $this->assertEquals($entities[1], $actual->current());
131
132
        $actual->next();
133
        $this->assertTrue($actual->valid());
134
        $this->assertEquals(2, $actual->key());
135
        $this->assertEquals($entities[2], $actual->current());
136
137
        $actual->next();
138
        $this->assertFalse($actual->valid());
139
140
        $actual->rewind();
141
        $this->assertTrue($actual->valid());
142
        $this->assertEquals(0, $actual->key());
143
        $this->assertEquals($entities[0], $actual->current());
144
    }
145
146
    /**
147
     * @param Entity[]                     $entities
148
     * @param Entity[]|Traversable<Entity> $records
149
     * @param mixed[]                      $meta
150
     * @dataProvider arrayProvider
151
     * @dataProvider iteratorAggregateProvider
152
     */
153
    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

153
    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...
154
    {
155
        $actual = json_encode(new PaginationResult($records, $meta));
156
        $this->assertJsonStringEqualsJsonString($expected, $actual);
157
    }
158
159
    /**
160
     * @param Entity[]                     $entities
161
     * @param Entity[]|Traversable<Entity> $records
162
     * @param mixed[]                      $meta
163
     * @dataProvider arrayProvider
164
     * @dataProvider iteratorAggregateProvider
165
     */
166
    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

166
    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...
167
    {
168
        $actual = unserialize(serialize(new PaginationResult($records, $meta)));
169
        $expected = new PaginationResult($records, $meta);
170
        $this->assertJsonEquals($expected, $actual);
171
    }
172
173
    /**
174
     * @param Entity[]                     $entities
175
     * @param Entity[]|Traversable<Entity> $records
176
     * @param mixed[]                      $meta
177
     * @dataProvider arrayProvider
178
     * @dataProvider iteratorAggregateProvider
179
     */
180
    public function testDebugInfo(array $entities, $records, array $meta): void
181
    {
182
        $actual = (new PaginationResult($records, $meta))->__debugInfo();
183
184
        $this->assertEquals([
185
            '(help)' => 'This is a Lampager Pagination Result object.',
186
            'records' => $entities,
187
            'hasPrevious' => $meta['hasPrevious'],
188
            'previousCursor' => $meta['previousCursor'],
189
            'hasNext' => $meta['hasNext'],
190
            'nextCursor' => $meta['nextCursor'],
191
        ], $actual);
192
    }
193
194
    /**
195
     * @param Entity[] $entities
196
     * @param Entity[]|Traversable<Entity> $records
197
     * @param mixed[] $meta
198
     * @dataProvider arrayProvider
199
     * @dataProvider iteratorAggregateProvider
200
     */
201
    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

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