Passed
Push — master ( b07f9b...3efcb7 )
by Chito
02:06
created

PaginationResultTest::testPublicProperties()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 8
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\FrozenTime;
9
use Cake\ORM\Entity;
10
use Generator;
11
use IteratorAggregate;
12
use Lampager\Cake\PaginationResult;
13
use Traversable;
14
15
class PaginationResultTest extends TestCase
16
{
17
    public function setUp(): void
18
    {
19
        parent::setUp();
20
21
        set_error_handler(
22
            static function ($errno, $errstr, $errfile, $errline) {
23
                throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
24
            },
25
            E_ALL
26
        );
27
    }
28
29
    public function tearDown(): void
30
    {
31
        restore_error_handler();
32
33
        parent::tearDown();
34
    }
35
36
    /**
37
     * @param Entity[]                     $entities
38
     * @param Entity[]|Traversable<Entity> $records
39
     * @param mixed[]                      $meta
40
     * @dataProvider arrayProvider
41
     * @dataProvider iteratorAggregateProvider
42
     */
43
    public function testIteratorCurrent(array $entities, $records, array $meta): void
44
    {
45
        $actual = new PaginationResult($records, $meta);
46
47
        $this->assertEquals($entities[0], $actual->current());
48
49
        $actual->next();
50
        $this->assertTrue($actual->valid());
51
        $this->assertEquals(1, $actual->key());
52
        $this->assertEquals($entities[1], $actual->current());
53
54
        $actual->next();
55
        $this->assertTrue($actual->valid());
56
        $this->assertEquals(2, $actual->key());
57
        $this->assertEquals($entities[2], $actual->current());
58
59
        $actual->next();
60
        $this->assertFalse($actual->valid());
61
62
        $actual->rewind();
63
        $this->assertTrue($actual->valid());
64
        $this->assertEquals(0, $actual->key());
65
        $this->assertEquals($entities[0], $actual->current());
66
    }
67
68
    /**
69
     * @param Entity[]                     $entities
70
     * @param Entity[]|Traversable<Entity> $records
71
     * @param mixed[]                      $meta
72
     * @dataProvider arrayProvider
73
     * @dataProvider iteratorAggregateProvider
74
     */
75
    public function testIteratorKey(array $entities, $records, array $meta): void
76
    {
77
        $actual = new PaginationResult($records, $meta);
78
79
        $this->assertEquals(0, $actual->key());
80
81
        $actual->next();
82
        $this->assertTrue($actual->valid());
83
        $this->assertEquals(1, $actual->key());
84
        $this->assertEquals($entities[1], $actual->current());
85
86
        $actual->next();
87
        $this->assertTrue($actual->valid());
88
        $this->assertEquals(2, $actual->key());
89
        $this->assertEquals($entities[2], $actual->current());
90
91
        $actual->next();
92
        $this->assertFalse($actual->valid());
93
94
        $actual->rewind();
95
        $this->assertTrue($actual->valid());
96
        $this->assertEquals(0, $actual->key());
97
        $this->assertEquals($entities[0], $actual->current());
98
    }
99
100
    /**
101
     * @param Entity[]                     $entities
102
     * @param Entity[]|Traversable<Entity> $records
103
     * @param mixed[]                      $meta
104
     * @dataProvider arrayProvider
105
     * @dataProvider iteratorAggregateProvider
106
     */
107
    public function testIteratorNext(array $entities, $records, array $meta): void
108
    {
109
        $actual = new PaginationResult($records, $meta);
110
111
        $actual->next();
112
        $this->assertTrue($actual->valid());
113
        $this->assertEquals(1, $actual->key());
114
        $this->assertEquals($entities[1], $actual->current());
115
116
        $actual->next();
117
        $this->assertTrue($actual->valid());
118
        $this->assertEquals(2, $actual->key());
119
        $this->assertEquals($entities[2], $actual->current());
120
121
        $actual->next();
122
        $this->assertFalse($actual->valid());
123
124
        $actual->rewind();
125
        $this->assertTrue($actual->valid());
126
        $this->assertEquals(0, $actual->key());
127
        $this->assertEquals($entities[0], $actual->current());
128
    }
129
130
    /**
131
     * @param Entity[]                     $entities
132
     * @param Entity[]|Traversable<Entity> $records
133
     * @param mixed[]                      $meta
134
     * @dataProvider arrayProvider
135
     * @dataProvider iteratorAggregateProvider
136
     */
137
    public function testIteratorValid(array $entities, $records, array $meta): void
138
    {
139
        $actual = new PaginationResult($records, $meta);
140
141
        $this->assertTrue($actual->valid());
142
        $this->assertEquals(0, $actual->key());
143
        $this->assertEquals($entities[0], $actual->current());
144
145
        $actual->next();
146
        $this->assertTrue($actual->valid());
147
        $this->assertEquals(1, $actual->key());
148
        $this->assertEquals($entities[1], $actual->current());
149
150
        $actual->next();
151
        $this->assertTrue($actual->valid());
152
        $this->assertEquals(2, $actual->key());
153
        $this->assertEquals($entities[2], $actual->current());
154
155
        $actual->next();
156
        $this->assertFalse($actual->valid());
157
158
        $actual->rewind();
159
        $this->assertTrue($actual->valid());
160
        $this->assertEquals(0, $actual->key());
161
        $this->assertEquals($entities[0], $actual->current());
162
    }
163
164
    /**
165
     * @param Entity[]                     $entities
166
     * @param Entity[]|Traversable<Entity> $records
167
     * @param mixed[]                      $meta
168
     * @dataProvider arrayProvider
169
     * @dataProvider iteratorAggregateProvider
170
     */
171
    public function testJsonSerialize(array $entities, $records, array $meta, string $expected): void
172
    {
173
        $actual = json_encode(new PaginationResult($records, $meta));
174
        $this->assertJsonStringEqualsJsonString($expected, $actual);
175
    }
176
177
    /**
178
     * @param Entity[]                     $entities
179
     * @param Entity[]|Traversable<Entity> $records
180
     * @param mixed[]                      $meta
181
     * @dataProvider arrayProvider
182
     * @dataProvider iteratorAggregateProvider
183
     */
184
    public function testSerializeAndUnserialize(array $entities, $records, array $meta): void
185
    {
186
        $actual = unserialize(serialize(new PaginationResult($records, $meta)));
187
        $expected = new PaginationResult($records, $meta);
188
        $this->assertJsonEquals($expected, $actual);
189
    }
190
191
    /**
192
     * @param Entity[]                     $entities
193
     * @param Entity[]|Traversable<Entity> $records
194
     * @param mixed[]                      $meta
195
     * @dataProvider arrayProvider
196
     * @dataProvider iteratorAggregateProvider
197
     */
198
    public function testDebugInfo(array $entities, $records, array $meta): void
199
    {
200
        $actual = (new PaginationResult($records, $meta))->__debugInfo();
201
202
        $this->assertEquals([
203
            '(help)' => 'This is a Lampager Pagination Result object.',
204
            'records' => $entities,
205
            'hasPrevious' => $meta['hasPrevious'],
206
            'previousCursor' => $meta['previousCursor'],
207
            'hasNext' => $meta['hasNext'],
208
            'nextCursor' => $meta['nextCursor'],
209
        ], $actual);
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 testPublicProperties(array $entities, $records, array $meta): void
220
    {
221
        $paginationResult = new PaginationResult($records, $meta);
222
223
        $this->assertEquals($meta['hasPrevious'], $paginationResult->hasPrevious);
224
        $this->assertEquals($meta['previousCursor'], $paginationResult->previousCursor);
225
        $this->assertEquals($meta['hasNext'], $paginationResult->hasNext);
226
        $this->assertEquals($meta['nextCursor'], $paginationResult->nextCursor);
227
    }
228
229
    /**
230
     * @param Entity[]                     $entities
231
     * @param Entity[]|Traversable<Entity> $records
232
     * @param mixed[]                      $meta
233
     * @dataProvider arrayProvider
234
     * @dataProvider iteratorAggregateProvider
235
     */
236
    public function testUndefinedProperties(array $entities, $records, array $meta): void
237
    {
238
        $this->expectException(\ErrorException::class);
239
        $this->expectExceptionMessageMatches('/^Undefined property via __get\(\): undefinedProperty/');
240
241
        $paginationResult = new PaginationResult($records, $meta);
242
        $paginationResult->undefinedProperty;
243
    }
244
245
    public function arrayProvider(): Generator
246
    {
247
        yield 'Array iteration' => [
248
            [
249
                new Entity([
250
                    'id' => 1,
251
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
252
                ]),
253
                new Entity([
254
                    'id' => 3,
255
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
256
                ]),
257
                new Entity([
258
                    'id' => 5,
259
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
260
                ]),
261
            ],
262
            [
263
                new Entity([
264
                    'id' => 1,
265
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
266
                ]),
267
                new Entity([
268
                    'id' => 3,
269
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
270
                ]),
271
                new Entity([
272
                    'id' => 5,
273
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
274
                ]),
275
            ],
276
            [
277
                'hasPrevious' => null,
278
                'previousCursor' => null,
279
                'hasNext' => true,
280
                'nextCursor' => [
281
                    'Posts.id' => 2,
282
                    'Posts.modified' => new FrozenTime('2017-01-01 11:00:00'),
283
                ],
284
            ],
285
            '{
286
                "records": [
287
                    {
288
                        "id": 1,
289
                        "modified": "2017-01-01T10:00:00+00:00"
290
                    },
291
                    {
292
                        "id": 3,
293
                        "modified": "2017-01-01T10:00:00+00:00"
294
                    },
295
                    {
296
                        "id": 5,
297
                        "modified": "2017-01-01T10:00:00+00:00"
298
                    }
299
                ],
300
                "hasPrevious": null,
301
                "previousCursor": null,
302
                "hasNext": true,
303
                "nextCursor": {
304
                    "Posts.id": 2,
305
                    "Posts.modified": "2017-01-01T11:00:00+00:00"
306
                }
307
            }',
308
        ];
309
310
        yield 'ArrayIterator iteration' => [
311
            [
312
                new Entity([
313
                    'id' => 1,
314
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
315
                ]),
316
                new Entity([
317
                    'id' => 3,
318
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
319
                ]),
320
                new Entity([
321
                    'id' => 5,
322
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
323
                ]),
324
            ],
325
            new ArrayIterator([
326
                new Entity([
327
                    'id' => 1,
328
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
329
                ]),
330
                new Entity([
331
                    'id' => 3,
332
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
333
                ]),
334
                new Entity([
335
                    'id' => 5,
336
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
337
                ]),
338
            ]),
339
            [
340
                'hasPrevious' => null,
341
                'previousCursor' => null,
342
                'hasNext' => true,
343
                'nextCursor' => [
344
                    'Posts.id' => 2,
345
                    'Posts.modified' => new FrozenTime('2017-01-01 11:00:00'),
346
                ],
347
            ],
348
            '{
349
                "records": [
350
                    {
351
                        "id": 1,
352
                        "modified": "2017-01-01T10:00:00+00:00"
353
                    },
354
                    {
355
                        "id": 3,
356
                        "modified": "2017-01-01T10:00:00+00:00"
357
                    },
358
                    {
359
                        "id": 5,
360
                        "modified": "2017-01-01T10:00:00+00:00"
361
                    }
362
                ],
363
                "hasPrevious": null,
364
                "previousCursor": null,
365
                "hasNext": true,
366
                "nextCursor": {
367
                    "Posts.id": 2,
368
                    "Posts.modified": "2017-01-01T11:00:00+00:00"
369
                }
370
            }',
371
        ];
372
    }
373
374
    public function iteratorAggregateProvider(): Generator
375
    {
376
        yield 'IteratorAggregate iteration' => [
377
            [
378
                new Entity([
379
                    'id' => 1,
380
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
381
                ]),
382
                new Entity([
383
                    'id' => 3,
384
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
385
                ]),
386
                new Entity([
387
                    'id' => 5,
388
                    'modified' => new FrozenTime('2017-01-01 10:00:00'),
389
                ]),
390
            ],
391
            new class implements IteratorAggregate {
392
                public function getIterator(): Traversable
393
                {
394
                    return new ArrayIterator([
395
                        new Entity([
396
                            'id' => 1,
397
                            'modified' => new FrozenTime('2017-01-01 10:00:00'),
398
                        ]),
399
                        new Entity([
400
                            'id' => 3,
401
                            'modified' => new FrozenTime('2017-01-01 10:00:00'),
402
                        ]),
403
                        new Entity([
404
                            'id' => 5,
405
                            'modified' => new FrozenTime('2017-01-01 10:00:00'),
406
                        ]),
407
                    ]);
408
                }
409
            },
410
            [
411
                'hasPrevious' => null,
412
                'previousCursor' => null,
413
                'hasNext' => true,
414
                'nextCursor' => [
415
                    'Posts.id' => 2,
416
                    'Posts.modified' => new FrozenTime('2017-01-01 11:00:00'),
417
                ],
418
            ],
419
            '{
420
                "records": [
421
                    {
422
                        "id": 1,
423
                        "modified": "2017-01-01T10:00:00+00:00"
424
                    },
425
                    {
426
                        "id": 3,
427
                        "modified": "2017-01-01T10:00:00+00:00"
428
                    },
429
                    {
430
                        "id": 5,
431
                        "modified": "2017-01-01T10:00:00+00:00"
432
                    }
433
                ],
434
                "hasPrevious": null,
435
                "previousCursor": null,
436
                "hasNext": true,
437
                "nextCursor": {
438
                    "Posts.id": 2,
439
                    "Posts.modified": "2017-01-01T11:00:00+00:00"
440
                }
441
            }',
442
        ];
443
    }
444
}
445