GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — develop ( ebf010...27e4a8 )
by Baptiste
02:14
created

DeferTest::testThrowWhenYieldingInvalidType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
4
namespace Tests\Innmind\Immutable\Sequence;
5
6
use Innmind\Immutable\{
7
    Sequence\Defer,
0 ignored issues
show
Bug introduced by
The type Innmind\Immutable\Sequence\Defer 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...
8
    Sequence\Implementation,
9
    Map,
10
    Sequence,
11
    Str,
12
    Set,
13
    Exception\OutOfBoundException,
14
    Exception\CannotGroupEmptyStructure,
15
    Exception\ElementNotFound,
16
};
17
use function Innmind\Immutable\unwrap;
18
use PHPUnit\Framework\TestCase;
19
20
class DeferTest extends TestCase
21
{
22
    public function testInterface()
23
    {
24
        $this->assertInstanceOf(
25
            Implementation::class,
26
            new Defer('mixed', (fn() => yield)()),
27
        );
28
    }
29
30
    public function testGeneratorNotLoadedAtInstanciation()
31
    {
32
        $loaded = false;
33
        $sequence = new Defer('int', (function() use (&$loaded) {
0 ignored issues
show
Unused Code introduced by
The assignment to $sequence is dead and can be removed.
Loading history...
34
            yield 1;
35
            $loaded = true;
36
        })());
37
38
        $this->assertFalse($loaded);
39
    }
40
41
    public function testThrowWhenYieldingInvalidType()
42
    {
43
        $this->expectException(\TypeError::class);
44
        $this->expectExceptionMessage('Argument 1 must be of type int, string given');
45
46
        $sequence = new Defer('int', (function() {
47
            yield '1';
48
        })());
49
        \iterator_to_array($sequence->iterator());
50
    }
51
52
    public function testType()
53
    {
54
        $this->assertSame('int', (new Defer('int', (fn() => yield)()))->type());
55
    }
56
57
    public function testSize()
58
    {
59
        $sequence = new Defer('int', (function() {
60
            yield 1;
61
            yield 1;
62
        })());
63
64
        $this->assertSame(2, $sequence->size());
65
        $this->assertSame(2, $sequence->count());
66
    }
67
68
    public function testIterator()
69
    {
70
        $sequence = new Defer('int', (function() {
71
            yield 1;
72
            yield 2;
73
            yield 3;
74
        })());
75
76
        $this->assertSame(
77
            [1, 2, 3],
78
            \iterator_to_array($sequence->iterator()),
79
        );
80
    }
81
82
    public function testGet()
83
    {
84
        $sequence = new Defer('int', (function() {
85
            yield 1;
86
            yield 42;
87
            yield 3;
88
        })());
89
90
        $this->assertSame(42, $sequence->get(1));
91
    }
92
93
    public function testThrowWhenIndexNotFound()
94
    {
95
        $this->expectException(OutOfBoundException::class);
96
97
        $sequence = new Defer('int', (function() {
98
            if (false) {
99
                yield 1;
100
            }
101
        })());
102
103
        $sequence->get(0);
104
    }
105
106
    public function testDiff()
107
    {
108
        $aLoaded = false;
109
        $bLoaded = false;
110
        $a = new Defer('int', (function() use (&$aLoaded) {
111
            yield 1;
112
            yield 2;
113
            $aLoaded = true;
114
        })());
115
        $b = new Defer('int', (function() use (&$bLoaded) {
116
            yield 2;
117
            yield 3;
118
            $bLoaded = true;
119
        })());
120
        $c = $a->diff($b);
121
122
        $this->assertFalse($aLoaded);
123
        $this->assertFalse($bLoaded);
124
        $this->assertSame([1, 2], \iterator_to_array($a->iterator()));
125
        $this->assertSame([2, 3], \iterator_to_array($b->iterator()));
126
        $this->assertInstanceOf(Defer::class, $c);
127
        $this->assertSame([1], \iterator_to_array($c->iterator()));
128
        $this->assertTrue($aLoaded);
129
        $this->assertTrue($bLoaded);
130
    }
131
132
    public function testDistinct()
133
    {
134
        $loaded = false;
135
        $a = new Defer('int', (function() use (&$loaded) {
136
            yield 1;
137
            yield 2;
138
            yield 1;
139
            $loaded = true;
140
        })());
141
        $b = $a->distinct();
142
143
        $this->assertFalse($loaded);
144
        $this->assertSame([1, 2, 1], \iterator_to_array($a->iterator()));
145
        $this->assertInstanceOf(Defer::class, $b);
146
        $this->assertSame([1, 2], \iterator_to_array($b->iterator()));
147
        $this->assertTrue($loaded);
148
    }
149
150
    public function testDrop()
151
    {
152
        $loaded = false;
153
        $a = new Defer('int', (function() use (&$loaded) {
154
            yield 1;
155
            yield 2;
156
            yield 3;
157
            yield 4;
158
            $loaded = true;
159
        })());
160
        $b = $a->drop(2);
161
162
        $this->assertFalse($loaded);
163
        $this->assertSame([1, 2, 3, 4], \iterator_to_array($a->iterator()));
164
        $this->assertInstanceOf(Defer::class, $b);
165
        $this->assertSame([3, 4], \iterator_to_array($b->iterator()));
166
        $this->assertTrue($loaded);
167
    }
168
169
    public function testDropEnd()
170
    {
171
        $a = new Defer('int', (function() {
172
            yield 1;
173
            yield 2;
174
            yield 3;
175
            yield 4;
176
        })());
177
        $b = $a->dropEnd(2);
178
179
        $this->assertSame([1, 2, 3, 4], \iterator_to_array($a->iterator()));
180
        $this->assertInstanceOf(Implementation::class, $b);
181
        $this->assertSame([1, 2], \iterator_to_array($b->iterator()));
182
    }
183
184
    public function testEquals()
185
    {
186
        $a = new Defer('int', (function() {
187
            yield 1;
188
            yield 2;
189
        })());
190
        $b = new Defer('int', (function() {
191
            yield 1;
192
            yield 2;
193
            yield 3;
194
        })());
195
        $this->assertTrue($a->equals($a));
196
        $this->assertFalse($a->equals($b));
197
    }
198
199
    public function testFilter()
200
    {
201
        $loaded = false;
202
        $a = new Defer('int', (function() use (&$loaded) {
203
            yield 1;
204
            yield 2;
205
            yield 3;
206
            yield 4;
207
            $loaded = true;
208
        })());
209
        $b = $a->filter(fn($i) => $i % 2 === 0);
210
211
        $this->assertFalse($loaded);
212
        $this->assertSame([1, 2, 3, 4], \iterator_to_array($a->iterator()));
213
        $this->assertInstanceOf(Defer::class, $b);
214
        $this->assertSame([2, 4], \iterator_to_array($b->iterator()));
215
        $this->assertTrue($loaded);
216
    }
217
218
    public function testForeach()
219
    {
220
        $sequence = new Defer('int', (function() {
221
            yield 1;
222
            yield 2;
223
            yield 3;
224
            yield 4;
225
        })());
226
        $calls = 0;
227
        $sum = 0;
228
229
        $this->assertNull($sequence->foreach(function($i) use (&$calls, &$sum) {
230
            ++$calls;
231
            $sum += $i;
232
        }));
233
        $this->assertSame(4, $calls);
234
        $this->assertSame(10, $sum);
235
    }
236
237
    public function testThrowWhenTryingToGroupEmptySequence()
238
    {
239
        $this->expectException(CannotGroupEmptyStructure::class);
240
241
        $sequence = new Defer('int', (function() {
242
            if (false) {
243
                yield 1;
244
            }
245
        })());
246
247
        $sequence->groupBy(fn($i) => $i);
248
    }
249
250
    public function testGroupBy()
251
    {
252
        $sequence = new Defer('int', (function() {
253
            yield 1;
254
            yield 2;
255
            yield 3;
256
            yield 4;
257
        })());
258
        $groups = $sequence->groupBy(fn($i) => $i % 2);
259
260
        $this->assertSame([1, 2, 3, 4], \iterator_to_array($sequence->iterator()));
261
        $this->assertInstanceOf(Map::class, $groups);
262
        $this->assertTrue($groups->isOfType('int', Sequence::class));
263
        $this->assertCount(2, $groups);
264
        $this->assertTrue($groups->get(0)->isOfType('int'));
265
        $this->assertTrue($groups->get(1)->isOfType('int'));
266
        $this->assertSame([2, 4], unwrap($groups->get(0)));
267
        $this->assertSame([1, 3], unwrap($groups->get(1)));
268
    }
269
270
    public function testThrowWhenTryingToAccessFirstElementOnEmptySequence()
271
    {
272
        $this->expectException(OutOfBoundException::class);
273
274
        $sequence = new Defer('int', (function() {
275
            if (false) {
276
                yield 1;
277
            }
278
        })());
279
280
        $sequence->first();
281
    }
282
283
    public function testThrowWhenTryingToAccessLastElementOnEmptySequence()
284
    {
285
        $this->expectException(OutOfBoundException::class);
286
287
        $sequence = new Defer('int', (function() {
288
            if (false) {
289
                yield 1;
290
            }
291
        })());
292
293
        $sequence->last();
294
    }
295
296
    public function testFirst()
297
    {
298
        $sequence = new Defer('int', (function() {
299
            yield 2;
300
            yield 3;
301
            yield 4;
302
        })());
303
304
        $this->assertSame(2, $sequence->first());
305
    }
306
307
    public function testLast()
308
    {
309
        $sequence = new Defer('int', (function() {
310
            yield 1;
311
            yield 2;
312
            yield 3;
313
        })());
314
315
        $this->assertSame(3, $sequence->last());
316
    }
317
318
    public function testContains()
319
    {
320
        $sequence = new Defer('int', (function() {
321
            yield 1;
322
            yield 2;
323
            yield 3;
324
        })());
325
326
        $this->assertTrue($sequence->contains(2));
327
        $this->assertFalse($sequence->contains(4));
328
    }
329
330
    public function testIndexOf()
331
    {
332
        $sequence = new Defer('int', (function() {
333
            yield 1;
334
            yield 2;
335
            yield 4;
336
        })());
337
338
        $this->assertSame(1, $sequence->indexOf(2));
339
        $this->assertSame(2, $sequence->indexOf(4));
340
    }
341
342
    public function testThrowWhenTryingToAccessIndexOfUnknownValue()
343
    {
344
        $this->expectException(ElementNotFound::class);
345
346
        $sequence = new Defer('int', (function() {
347
            if (false) {
348
                yield 1;
349
            }
350
        })());
351
352
        $sequence->indexOf(1);
353
    }
354
355
    public function testIndices()
356
    {
357
        $loaded = false;
358
        $a = new Defer('string', (function() use (&$loaded) {
359
            yield '1';
360
            yield '2';
361
            $loaded = true;
362
        })());
363
        $b = $a->indices();
364
365
        $this->assertFalse($loaded);
366
        $this->assertSame(['1', '2'], \iterator_to_array($a->iterator()));
367
        $this->assertInstanceOf(Defer::class, $b);
368
        $this->assertSame('int', $b->type());
369
        $this->assertSame([0, 1], \iterator_to_array($b->iterator()));
370
        $this->assertTrue($loaded);
371
    }
372
373
    public function testIndicesOnEmptySequence()
374
    {
375
        $a = new Defer('string', (function() {
376
            if (false) {
377
                yield 1;
378
            }
379
        })());
380
        $b = $a->indices();
381
382
        $this->assertSame([], \iterator_to_array($a->iterator()));
383
        $this->assertInstanceOf(Defer::class, $b);
384
        $this->assertSame('int', $b->type());
385
        $this->assertSame([], \iterator_to_array($b->iterator()));
386
    }
387
388
    public function testMap()
389
    {
390
        $loaded = false;
391
        $a = new Defer('int', (function() use (&$loaded) {
392
            yield 1;
393
            yield 2;
394
            yield 3;
395
            $loaded = true;
396
        })());
397
        $b = $a->map(fn($i) => $i * 2);
398
399
        $this->assertFalse($loaded);
400
        $this->assertSame([1, 2, 3], \iterator_to_array($a->iterator()));
401
        $this->assertInstanceOf(Defer::class, $b);
402
        $this->assertSame([2, 4, 6], \iterator_to_array($b->iterator()));
403
        $this->assertTrue($loaded);
404
    }
405
406
    public function testThrowWhenTryingToModifyTheTypeWhenMapping()
407
    {
408
        $this->expectException(\TypeError::class);
409
        $this->expectExceptionMessage('Argument 1 must be of type int, string given');
410
411
        $sequence = new Defer('int', (function() {
412
            yield 1;
413
            yield 2;
414
            yield 3;
415
        })());
416
417
        \iterator_to_array($sequence->map(fn($i) => (string) $i)->iterator());
418
    }
419
420
    public function testPad()
421
    {
422
        $loaded = false;
423
        $a = new Defer('int', (function() use (&$loaded) {
424
            yield 1;
425
            yield 2;
426
            $loaded = true;
427
        })());
428
        $b = $a->pad(4, 0);
429
        $c = $a->pad(1, 0);
430
431
        $this->assertFalse($loaded);
432
        $this->assertSame([1, 2], \iterator_to_array($a->iterator()));
433
        $this->assertInstanceOf(Defer::class, $b);
434
        $this->assertInstanceOf(Defer::class, $c);
435
        $this->assertSame([1, 2, 0, 0], \iterator_to_array($b->iterator()));
436
        $this->assertSame([1, 2], \iterator_to_array($c->iterator()));
437
        $this->assertTrue($loaded);
438
    }
439
440
    public function testPartition()
441
    {
442
        $sequence = new Defer('int', (function() {
443
            yield 1;
444
            yield 2;
445
            yield 3;
446
            yield 4;
447
        })());
448
        $partition = $sequence->partition(fn($i) => $i % 2 === 0);
449
450
        $this->assertSame([1, 2, 3, 4], \iterator_to_array($sequence->iterator()));
451
        $this->assertInstanceOf(Map::class, $partition);
452
        $this->assertTrue($partition->isOfType('bool', Sequence::class));
453
        $this->assertCount(2, $partition);
454
        $this->assertTrue($partition->get(true)->isOfType('int'));
455
        $this->assertTrue($partition->get(false)->isOfType('int'));
456
        $this->assertSame([2, 4], unwrap($partition->get(true)));
457
        $this->assertSame([1, 3], unwrap($partition->get(false)));
458
    }
459
460
    public function testSlice()
461
    {
462
        $loaded = false;
463
        $a = new Defer('int', (function() use (&$loaded) {
464
            yield 2;
465
            yield 3;
466
            yield 4;
467
            yield 5;
468
            $loaded = true;
469
        })());
470
        $b = $a->slice(1, 3);
471
472
        $this->assertFalse($loaded);
473
        $this->assertSame([2, 3, 4, 5], \iterator_to_array($a->iterator()));
474
        $this->assertInstanceOf(Defer::class, $b);
475
        $this->assertSame([3, 4], \iterator_to_array($b->iterator()));
476
        $this->assertTrue($loaded);
477
    }
478
479
    public function testSplitAt()
480
    {
481
        $sequence = new Defer('int', (function() {
482
            yield 2;
483
            yield 3;
484
            yield 4;
485
            yield 5;
486
        })());
487
        $parts = $sequence->splitAt(2);
488
489
        $this->assertSame([2, 3, 4, 5], \iterator_to_array($sequence->iterator()));
490
        $this->assertInstanceOf(Sequence::class, $parts);
491
        $this->assertTrue($parts->isOfType(Sequence::class));
492
        $this->assertCount(2, $parts);
493
        $this->assertTrue($parts->first()->isOfType('int'));
494
        $this->assertTrue($parts->last()->isOfType('int'));
495
        $this->assertSame([2, 3], unwrap($parts->first()));
496
        $this->assertSame([4, 5], unwrap($parts->last()));
497
    }
498
499
    public function testTake()
500
    {
501
        $loaded = false;
502
        $a = new Defer('int', (function() use (&$loaded) {
503
            yield 2;
504
            yield 3;
505
            yield 4;
506
            $loaded = true;
507
        })());
508
        $b = $a->take(2);
509
510
        $this->assertFalse($loaded);
511
        $this->assertSame([2, 3, 4], \iterator_to_array($a->iterator()));
512
        $this->assertInstanceOf(Defer::class, $b);
513
        $this->assertSame([2, 3], \iterator_to_array($b->iterator()));
514
        $this->assertTrue($loaded);
515
    }
516
517
    public function testTakeEnd()
518
    {
519
        $a = new Defer('int', (function() {
520
            yield 2;
521
            yield 3;
522
            yield 4;
523
        })());
524
        $b = $a->takeEnd(2);
525
526
        $this->assertSame([2, 3, 4], \iterator_to_array($a->iterator()));
527
        $this->assertInstanceOf(Implementation::class, $b);
528
        $this->assertSame([3, 4], \iterator_to_array($b->iterator()));
529
    }
530
531
    public function testAppend()
532
    {
533
        $aLoaded = false;
534
        $bLoaded = false;
535
        $a = new Defer('int', (function() use (&$aLoaded) {
536
            yield 1;
537
            yield 2;
538
            $aLoaded = true;
539
        })());
540
        $b = new Defer('int', (function() use (&$bLoaded) {
541
            yield 3;
542
            yield 4;
543
            $bLoaded = true;
544
        })());
545
        $c = $a->append($b);
546
547
        $this->assertFalse($aLoaded);
548
        $this->assertFalse($bLoaded);
549
        $this->assertSame([1, 2], \iterator_to_array($a->iterator()));
550
        $this->assertSame([3, 4], \iterator_to_array($b->iterator()));
551
        $this->assertInstanceOf(Defer::class, $c);
552
        $this->assertSame([1, 2, 3, 4], \iterator_to_array($c->iterator()));
553
        $this->assertTrue($aLoaded);
554
        $this->assertTrue($bLoaded);
555
    }
556
557
    public function testIntersect()
558
    {
559
        $aLoaded = false;
560
        $bLoaded = false;
561
        $a = new Defer('int', (function() use (&$aLoaded) {
562
            yield 1;
563
            yield 2;
564
            $aLoaded = true;
565
        })());
566
        $b = new Defer('int', (function() use (&$bLoaded) {
567
            yield 2;
568
            yield 3;
569
            $bLoaded = true;
570
        })());
571
        $c = $a->intersect($b);
572
573
        $this->assertFalse($aLoaded);
574
        $this->assertFalse($bLoaded);
575
        $this->assertSame([1, 2], \iterator_to_array($a->iterator()));
576
        $this->assertSame([2, 3], \iterator_to_array($b->iterator()));
577
        $this->assertInstanceOf(Defer::class, $c);
578
        $this->assertSame([2], \iterator_to_array($c->iterator()));
579
        $this->assertTrue($aLoaded);
580
        $this->assertTrue($bLoaded);
581
    }
582
583
    public function testAdd()
584
    {
585
        $loaded = false;
586
        $a = new Defer('int', (function() use (&$loaded) {
587
            yield 1;
588
            $loaded = true;
589
        })());
590
        $b = ($a)(2);
591
592
        $this->assertFalse($loaded);
593
        $this->assertSame([1], \iterator_to_array($a->iterator()));
594
        $this->assertInstanceOf(Defer::class, $b);
595
        $this->assertSame([1, 2], \iterator_to_array($b->iterator()));
596
        $this->assertTrue($loaded);
597
    }
598
599
    public function testSort()
600
    {
601
        $a = new Defer('int', (function() {
602
            yield 1;
603
            yield 4;
604
            yield 3;
605
            yield 2;
606
        })());
607
        $b = $a->sort(fn($a, $b) => $a > $b);
608
609
        $this->assertSame([1, 4, 3, 2], \iterator_to_array($a->iterator()));
610
        $this->assertInstanceOf(Defer::class, $b);
611
        $this->assertSame([1, 2, 3, 4], \iterator_to_array($b->iterator()));
612
    }
613
614
    public function testReduce()
615
    {
616
        $sequence = new Defer('int', (function() {
617
            yield 1;
618
            yield 2;
619
            yield 3;
620
            yield 4;
621
        })());
622
623
        $this->assertSame(10, $sequence->reduce(0, fn($sum, $i) => $sum + $i));
624
    }
625
626
    public function testClear()
627
    {
628
        $loaded = false;
629
        $a = new Defer('int', (function() use (&$loaded) {
630
            yield 1;
631
            yield 2;
632
           $loaded = true;
633
        })());
634
        $b = $a->clear();
635
636
        $this->assertFalse($loaded);
637
        $this->assertInstanceOf(Implementation::class, $b);
638
        $this->assertSame([], \iterator_to_array($b->iterator()));
639
        $this->assertFalse($loaded);
640
        $this->assertSame([1, 2], \iterator_to_array($a->iterator()));
641
    }
642
643
    public function testReverse()
644
    {
645
        $loaded = false;
646
        $a = new Defer('int', (function() use (&$loaded) {
647
            yield 1;
648
            yield 2;
649
            yield 3;
650
            yield 4;
651
            $loaded = true;
652
        })());
653
        $b = $a->reverse();
654
655
        $this->assertFalse($loaded);
656
        $this->assertSame([1, 2, 3, 4], \iterator_to_array($a->iterator()));
657
        $this->assertInstanceOf(Defer::class, $b);
658
        $this->assertSame([4, 3, 2, 1], \iterator_to_array($b->iterator()));
659
        $this->assertTrue($loaded);
660
    }
661
662
    public function testEmpty()
663
    {
664
        $aLoaded = false;
665
        $bLoaded = false;
666
        $a = new Defer('int', (function() use (&$aLoaded) {
667
            yield 1;
668
            $aLoaded = true;
669
        })());
670
        $b = new Defer('int', (function() use (&$bLoaded) {
671
            if (false) {
672
                yield 1;
673
            }
674
            $bLoaded = true;
675
        })());
676
677
        $this->assertFalse($aLoaded);
678
        $this->assertFalse($bLoaded);
679
        $this->assertTrue($b->empty());
680
        $this->assertFalse($a->empty());
681
        $this->assertFalse($aLoaded); // still false as we don't need to load the full iterator to know if it's empty
682
        $this->assertTrue($bLoaded);
683
    }
684
685
    public function testToSequenceOf()
686
    {
687
        $loaded = false;
688
        $sequence = new Defer('int', (function() use (&$loaded) {
689
            yield 1;
690
            yield 2;
691
            yield 3;
692
            $loaded = true;
693
        })());
694
        $sequence = $sequence->toSequenceOf('string|int', function($i) {
695
            yield (string) $i;
696
            yield $i;
697
        });
698
699
        $this->assertFalse($loaded);
700
        $this->assertInstanceOf(Sequence::class, $sequence);
701
        $this->assertSame(
702
            ['1', 1, '2', 2, '3', 3],
703
            unwrap($sequence),
704
        );
705
        $this->assertTrue($loaded);
706
    }
707
708
    public function testToSetOf()
709
    {
710
        $sequence = new Defer('int', (function() {
711
            yield 1;
712
            yield 2;
713
            yield 3;
714
        })());
715
        $set = $sequence->toSetOf('string|int', function($i) {
716
            yield (string) $i;
717
            yield $i;
718
        });
719
720
        $this->assertInstanceOf(Set::class, $set);
721
        $this->assertSame(
722
            ['1', 1, '2', 2, '3', 3],
723
            unwrap($set),
724
        );
725
    }
726
727
    public function testToMapOf()
728
    {
729
        $sequence = new Defer('int', (function() {
730
            yield 1;
731
            yield 2;
732
            yield 3;
733
        })());
734
        $map = $sequence->toMapOf('string', 'int', fn($i) => yield (string) $i => $i);
735
736
        $this->assertInstanceOf(Map::class, $map);
737
        $this->assertCount(3, $map);
738
        $this->assertSame(1, $map->get('1'));
739
        $this->assertSame(2, $map->get('2'));
740
        $this->assertSame(3, $map->get('3'));
741
    }
742
}
743