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
Branch master (878646)
by Dušan
02:50
created

CollectionSpec::it_can_replace_by_key()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace spec\DusanKasan\Knapsack;
4
5
use ArrayIterator;
6
use DOMXPath;
7
use DusanKasan\Knapsack\Collection;
8
use DusanKasan\Knapsack\Exceptions\InvalidArgument;
9
use DusanKasan\Knapsack\Exceptions\InvalidReturnValue;
10
use DusanKasan\Knapsack\Exceptions\ItemNotFound;
11
use DusanKasan\Knapsack\Exceptions\NoMoreItems;
12
use DusanKasan\Knapsack\Tests\Helpers\PlusOneAdder;
13
use function DusanKasan\Knapsack\reverse;
14
use Iterator;
15
use IteratorAggregate;
16
use PhpSpec\ObjectBehavior;
17
use Serializable;
18
19
/**
20
 * @mixin Collection
21
 */
22
class CollectionSpec extends ObjectBehavior
23
{
24
    function it_is_initializable()
25
    {
26
        $this->beConstructedWith([1, 2, 3]);
27
        $this->shouldHaveType(Collection::class);
28
        $this->shouldHaveType(Iterator::class);
29
    }
30
31
    function it_can_be_instantiated_from_iterator()
32
    {
33
        $iterator = new ArrayIterator([1, 2]);
34
        $this->beConstructedWith($iterator);
35
        $this->toArray()->shouldReturn([1, 2]);
36
    }
37
38
    function it_can_be_instantiated_from_iterator_aggregate(IteratorAggregate $iteratorAggregate)
39
    {
40
        $iterator = new ArrayIterator([1, 2]);
41
        $iteratorAggregate->getIterator()->willReturn($iterator);
42
        $this->beConstructedWith($iteratorAggregate);
43
        $this->toArray()->shouldReturn([1, 2]);
44
    }
45
46
    function it_can_be_instantiated_from_array()
47
    {
48
        $this->beConstructedWith([1, 2, 3]);
49
        $this->toArray()->shouldReturn([1, 2, 3]);
50
    }
51
52
    function it_will_throw_when_passed_something_other_than_array_or_traversable()
53
    {
54
        $this->beConstructedWith(1);
55
        $this->shouldThrow(InvalidArgument::class)->duringInstantiation();
56
    }
57
58
    function it_can_be_created_statically()
59
    {
60
        $this->beConstructedThrough('from', [[1, 2]]);
61
        $this->toArray()->shouldReturn([1, 2]);
62
    }
63
64
    function it_can_be_created_to_iterate_over_function_infinitely()
65
    {
66
        $this->beConstructedThrough('iterate', [1, function ($i) {return $i + 1;}]);
67
        $this->take(2)->toArray()->shouldReturn([1, 2]);
68
    }
69
70
    function it_can_be_created_to_iterate_over_function_non_infinitely()
71
    {
72
        $this->beConstructedThrough(
73
            'iterate',
74
            [
75
                1,
76
                function ($i) {
77
                    if ($i > 3) {
78
                        throw new NoMoreItems;
79
                    }
80
81
                    return $i + 1;
82
                },
83
            ]
84
        );
85
        $this->toArray()->shouldReturn([1, 2, 3, 4]);
86
    }
87
88
    function it_can_be_created_to_repeat_a_value_infinite_times()
89
    {
90
        $this->beConstructedThrough('repeat', [1]);
91
        $this->take(2)->toArray()->shouldReturn([1, 1]);
92
    }
93
94
    function it_can_filter()
95
    {
96
        $this->beConstructedWith([1, 3, 3, 2,]);
97
98
        $this
99
            ->filter(function ($item) {
100
                return $item > 2;
101
            })
102
            ->toArray()
103
            ->shouldReturn([1 => 3, 2 => 3]);
104
105
        $this
106
            ->filter(function ($item, $key) {
107
                return $key > 2 && $item < 3;
108
            })
109
            ->toArray()
110
            ->shouldReturn([3 => 2]);
111
    }
112
113
    function it_can_filter_falsy_values()
114
    {
115
        $this->beConstructedWith([false, null, '', 0, 0.0, []]);
116
117
        $this->filter()->isEmpty()->shouldReturn(true);
118
119
    }
120
121
    function it_can_distinct()
122
    {
123
        $this->beConstructedWith([1, 3, 3, 2,]);
124
125
        $this
126
            ->distinct()
127
            ->toArray()
128
            ->shouldReturn([1, 3, 3 => 2]);
129
    }
130
131
    function it_can_concat()
132
    {
133
        $this->beConstructedWith([1, 3, 3, 2,]);
134
135
        $collection = $this->concat([4, 5]);
136
        $collection->toArray()->shouldReturn([4, 5, 3, 2]);
137
        $collection->size()->shouldReturn(6);
138
    }
139
140 View Code Duplication
    function it_can_map()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
141
    {
142
        $this->beConstructedWith([1, 3, 3, 2,]);
143
144
        $this
145
            ->map(function ($item) {
146
                return $item + 1;
147
            })
148
            ->toArray()
149
            ->shouldReturn([2, 4, 4, 3]);
150
    }
151
152
    function it_can_reduce()
153
    {
154
        $this->beConstructedWith([1, 3, 3, 2,]);
155
156
        $this
157
            ->reduce(
158
                function ($temp, $item) {
159
                    $temp[] = $item;
160
161
                    return $temp;
162
                },
163
                ['a' => [1]],
164
                true
165
            )
166
            ->values()
167
            ->toArray()
168
            ->shouldReturn([[1], 1, 3, 3, 2]);
169
170
        $this
171
            ->reduce(
172
                function ($temp, $item) {
173
                    return $temp + $item;
174
                },
175
                0
176
            )
177
            ->shouldReturn(9);
178
179
        $this
180
            ->reduce(
181
                function ($temp, $item, $key) {
182
                    return $temp + $key + $item;
183
                },
184
                0
185
            )
186
            ->shouldReturn(15);
187
188
        $this
189
            ->reduce(
190
                function (Collection $temp, $item) {
191
                    return $temp->append($item);
192
                },
193
                new Collection([])
194
            )
195
            ->toArray()
196
            ->shouldReturn([1, 3, 3, 2]);
197
    }
198
199
    function it_can_flatten()
200
    {
201
        $this->beConstructedWith([1, [2, [3]]]);
202
        $this->flatten()->values()->toArray()->shouldReturn([1, 2, 3]);
203
        $this->flatten(1)->values()->toArray()->shouldReturn([1, 2, [3]]);
204
    }
205
206
    function it_can_sort()
207
    {
208
        $this->beConstructedWith([3, 1, 2]);
209
210
        $this
211
            ->sort(function ($a, $b) {
212
                return $a > $b;
213
            })
214
            ->toArray()
215
            ->shouldReturn([1 => 1, 2 => 2, 0 => 3]);
216
217
        $this
218
            ->sort(function ($v1, $v2, $k1, $k2) {
219
                return $k1 < $k2 || $v1 == $v2;
220
            })
221
            ->toArray()
222
            ->shouldReturn([2 => 2, 1 => 1, 0 => 3]);
223
    }
224
225
    function it_can_slice()
226
    {
227
        $this->beConstructedWith([1, 2, 3, 4, 5]);
228
229
        $this
230
            ->slice(2, 4)
231
            ->toArray()
232
            ->shouldReturn([2 => 3, 3 => 4]);
233
234
        $this
235
            ->slice(4)
236
            ->toArray()
237
            ->shouldReturn([4 => 5]);
238
    }
239
240
    function it_can_group_by()
241
    {
242
        $this->beConstructedWith([1, 2, 3, 4, 5]);
243
244
        $collection = $this->groupBy(function ($i) {
245
            return $i % 2;
246
        });
247
248
        $collection->get(0)->toArray()->shouldReturn([2, 4]);
249
        $collection->get(1)->toArray()->shouldReturn([1, 3, 5]);
250
251
        $collection = $this->groupBy(function ($k, $i) {
252
            return ($k + $i) % 3;
253
        });
254
        $collection->get(0)->toArray()->shouldReturn([2, 5]);
255
        $collection->get(1)->toArray()->shouldReturn([1, 4]);
256
        $collection->get(2)->toArray()->shouldReturn([3]);
257
    }
258
259
    function it_can_group_by_key()
260
    {
261
        $this->beConstructedWith([
262
            'some' => 'thing',
263
            ['letter' => 'A', 'type' => 'caps'],
264
            ['letter' => 'a', 'type' => 'small'],
265
            ['letter' => 'B', 'type' => 'caps'],
266
            ['letter' => 'Z'],
267
        ]);
268
269
        $collection = $this->groupByKey('type');
270
        $collection->get('small')->toArray()->shouldReturn([
271
            ['letter' => 'a', 'type' => 'small'],
272
        ]);
273
        $collection->get('caps')->toArray()->shouldReturn([
274
            ['letter' => 'A', 'type' => 'caps'],
275
            ['letter' => 'B', 'type' => 'caps'],
276
        ]);
277
278
        $collection = $this->groupByKey('types');
279
        $collection->shouldThrow(new ItemNotFound)->during('get', ['caps']);
280
    }
281
282
    function it_can_execute_callback_for_each_item(DOMXPath $a)
283
    {
284
        $a->query('asd')->shouldBeCalled();
285
        $this->beConstructedWith([$a]);
286
287
        $this
288
            ->each(function (DOMXPath $i) {
289
                $i->query('asd');
290
            })
291
            ->toArray()
292
            ->shouldReturn([$a]);
293
    }
294
295
    function it_can_get_size()
296
    {
297
        $this->beConstructedWith([1, 3, 3, 2,]);
298
        $this->size()->shouldReturn(4);
299
    }
300
301
    function it_can_get_item_by_key()
302
    {
303
        $this->beConstructedWith([1, [2], 3]);
304
        $this->get(0)->shouldReturn(1);
305
        $this->get(1, true)->first()->shouldReturn(2);
306
        $this->get(1)->shouldReturn([2]);
307
        $this->shouldThrow(new ItemNotFound)->during('get', [5]);
308
    }
309
310
    function it_can_get_item_by_key_or_return_default()
311
    {
312
        $this->beConstructedWith([1, [2], 3]);
313
        $this->getOrDefault(0)->shouldReturn(1);
314
        $this->getOrDefault(1, null, true)->first()->shouldReturn(2);
315
        $this->getOrDefault(1, null)->shouldReturn([2]);
316
        $this->getOrDefault(5)->shouldReturn(null);
317
        $this->getOrDefault(5, 'not found')->shouldReturn('not found');
318
    }
319
320
    function it_can_find()
321
    {
322
        $this->beConstructedWith([1, 3, 3, 2, [5]]);
323
324
        $this
325
            ->find(function ($v) {
326
                return $v < 3;
327
            })
328
            ->shouldReturn(1);
329
330
        $this
331
            ->find(function ($v, $k) {
332
                return $v < 3 && $k > 1;
333
            })
334
            ->shouldReturn(2);
335
336
        $this
337
            ->find(function ($v) {
338
                return $v < 0;
339
            })
340
            ->shouldReturn(null);
341
342
        $this
343
            ->find(
344
                function ($v) {
345
                    return $v < 0;
346
                },
347
                'not found'
348
            )
349
            ->shouldReturn('not found');
350
351
        $this->find('\DusanKasan\Knapsack\isCollection', null, true)->first()->shouldReturn(5);
352
        $this->find('\DusanKasan\Knapsack\isCollection')->shouldReturn([5]);
353
    }
354
355
    function it_can_count_by()
356
    {
357
        $this->beConstructedWith([1, 3, 3, 2,]);
358
359
        $this
360
            ->countBy(function ($v) {
361
                return $v % 2 == 0 ? 'even' : 'odd';
362
            })
363
            ->toArray()
364
            ->shouldReturn(['odd' => 3, 'even' => 1]);
365
366
        $this
367
            ->countBy(function ($k, $v) {
368
                return ($k + $v) % 2 == 0 ? 'even' : 'odd';
369
            })
370
            ->toArray()
371
            ->shouldReturn(['odd' => 3, 'even' => 1]);
372
    }
373
374
    function it_can_index_by()
375
    {
376
        $this->beConstructedWith([1, 3, 3, 2,]);
377
378
        $this
379
            ->indexBy(function ($v) {
380
                return $v;
381
            })
382
            ->toArray()
383
            ->shouldReturn([1 => 1, 3 => 3, 2 => 2]);
384
385
        $this
386
            ->indexBy(function ($v, $k) {
387
                return $k . $v;
388
            })
389
            ->toArray()
390
            ->shouldReturn(['01' => 1, '13' => 3, '23' => 3, '32' => 2]);
391
    }
392
393
    function it_can_check_if_every_item_passes_predicament_test()
394
    {
395
        $this->beConstructedWith([1, 3, 3, 2,]);
396
397
        $this
398
            ->every(function ($v) {
399
                return $v > 0;
400
            })
401
            ->shouldReturn(true);
402
403
        $this
404
            ->every(function ($v) {
405
                return $v > 1;
406
            })
407
            ->shouldReturn(false);
408
409
        $this
410
            ->every(function ($v, $k) {
411
                return $v > 0 && $k >= 0;
412
            })
413
            ->shouldReturn(true);
414
415
        $this
416
            ->every(function ($v, $k) {
417
                return $v > 0 && $k > 0;
418
            })
419
            ->shouldReturn(false);
420
    }
421
422
    function it_can_check_if_some_items_pass_predicament_test()
423
    {
424
        $this->beConstructedWith([1, 3, 3, 2,]);
425
426
        $this
427
            ->some(function ($v) {
428
                return $v < -1;
429
            })
430
            ->shouldReturn(false);
431
432
        $this
433
            ->some(function ($v, $k) {
434
                return $v > 0 && $k < -1;
435
            })
436
            ->shouldReturn(false);
437
438
        $this
439
            ->some(function ($v) {
440
                return $v < 2;
441
            })
442
            ->shouldReturn(true);
443
444
        $this
445
            ->some(function ($v, $k) {
446
                return $v > 0 && $k > 0;
447
            })
448
            ->shouldReturn(true);
449
    }
450
451 View Code Duplication
    function it_can_check_if_it_contains_a_value()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
452
    {
453
        $this->beConstructedWith([1, 3, 3, 2,]);
454
455
        $this
456
            ->contains(3)
457
            ->shouldReturn(true);
458
459
        $this
460
            ->contains(true)
461
            ->shouldReturn(false);
462
    }
463
464
    function it_can_reverse()
465
    {
466
        $this->beConstructedWith([1, 3, 3, 2,]);
467
468
        $collection = $this->reverse();
469
470
        $collection->rewind();
471
        $collection->valid()->shouldReturn(true);
472
        $collection->key()->shouldReturn(3);
473
        $collection->current()->shouldReturn(2);
474
        $collection->next();
475
        $collection->valid()->shouldReturn(true);
476
        $collection->key()->shouldReturn(2);
477
        $collection->current()->shouldReturn(3);
478
        $collection->next();
479
        $collection->valid()->shouldReturn(true);
480
        $collection->key()->shouldReturn(1);
481
        $collection->current()->shouldReturn(3);
482
        $collection->next();
483
        $collection->valid()->shouldReturn(true);
484
        $collection->key()->shouldReturn(0);
485
        $collection->current()->shouldReturn(1);
486
        $collection->next();
487
        $collection->valid()->shouldReturn(false);
488
    }
489
490
    function it_can_reduce_from_right()
491
    {
492
        $this->beConstructedWith([1, 3, 3, 2,]);
493
494
        $this
495
            ->reduceRight(
496
                function ($temp, $e) {
497
                    return $temp . $e;
498
                },
499
                0
500
            )
501
            ->shouldReturn('02331');
502
503
        $this
504
            ->reduceRight(
505
                function ($temp, $key, $item) {
506
                    return $temp + $key + $item;
507
                },
508
                0
509
            )
510
            ->shouldReturn(15);
511
512
        $this
513
            ->reduceRight(
514
                function (Collection $temp, $item) {
515
                    return $temp->append($item);
516
                },
517
                new Collection([])
518
            )
519
            ->toArray()
520
            ->shouldReturn([2, 3, 3, 1]);
521
    }
522
523
    function it_can_return_only_first_x_elements()
524
    {
525
        $this->beConstructedWith([1, 3, 3, 2,]);
526
527
        $this->take(2)
528
            ->toArray()
529
            ->shouldReturn([1, 3]);
530
    }
531
532
    function it_can_skip_first_x_elements()
533
    {
534
        $this->beConstructedWith([1, 3, 3, 2,]);
535
536
        $this->drop(2)
537
            ->toArray()
538
            ->shouldReturn([2 => 3, 3 => 2]);
539
    }
540
541
    function it_can_return_values()
542
    {
543
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
544
        $this->values()->toArray()->shouldReturn([1, 2]);
545
    }
546
547
    function it_can_reject_elements_from_collection()
548
    {
549
        $this->beConstructedWith([1, 3, 3, 2,]);
550
551
        $this
552
            ->reject(function ($v) {
553
                return $v == 3;
554
            })
555
            ->toArray()
556
            ->shouldReturn([1, 3 => 2]);
557
558
        $this
559
            ->reject(function ($v, $k) {
560
                return $k == 2 && $v == 3;
561
            })
562
            ->toArray()
563
            ->shouldReturn([1, 3, 3 => 2]);
564
    }
565
566
    function it_can_get_keys()
567
    {
568
        $this->beConstructedWith([1, 3, 3, 2,]);
569
570
        $this
571
            ->keys()
572
            ->toArray()
573
            ->shouldReturn([0, 1, 2, 3]);
574
    }
575
576 View Code Duplication
    function it_can_interpose()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
577
    {
578
        $this->beConstructedWith([1, 3, 3, 2,]);
579
580
        $this
581
            ->interpose('a')
582
            ->values()
583
            ->toArray()
584
            ->shouldReturn([1, 'a', 3, 'a', 3, 'a', 2]);
585
    }
586
587
    function it_can_drop_elements_from_end_of_the_collection()
588
    {
589
        $this->beConstructedWith([1, 3, 3, 2,]);
590
591
        $this
592
            ->dropLast()
593
            ->toArray()
594
            ->shouldReturn([1, 3, 3]);
595
596
        $this
597
            ->dropLast(2)
598
            ->toArray()
599
            ->shouldReturn([1, 3]);
600
    }
601
602
    function it_can_interleave_elements()
603
    {
604
        $this->beConstructedWith([1, 3, 3, 2,]);
605
606
        $this
607
            ->interleave(['a', 'b', 'c', 'd', 'e'])
608
            ->values()
609
            ->toArray()
610
            ->shouldReturn([1, 'a', 3, 'b', 3, 'c', 2, 'd', 'e']);
611
    }
612
613 View Code Duplication
    function it_can_repeat_items_of_collection_infinitely()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
614
    {
615
        $this->beConstructedWith([1, 3, 3, 2,]);
616
617
        $this
618
            ->cycle()
619
            ->take(8)
620
            ->values()
621
            ->toArray()
622
            ->shouldReturn([1, 3, 3, 2, 1, 3, 3, 2]);
623
    }
624
625 View Code Duplication
    function it_can_prepend_item()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
626
    {
627
        $this->beConstructedWith([1, 3, 3, 2,]);
628
629
        $this
630
            ->prepend(1)
631
            ->values()
632
            ->toArray()
633
            ->shouldReturn([1, 1, 3, 3, 2]);
634
    }
635
636
    function it_can_prepend_item_with_key()
637
    {
638
        $this->beConstructedWith([1, 3, 3, 2,]);
639
640
        $this
641
            ->prepend(1, 'a')
642
            ->toArray()
643
            ->shouldReturn(['a' => 1, 0 => 1, 1 => 3, 2 => 3, 3 => 2]);
644
    }
645
646 View Code Duplication
    function it_can_append_item()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
647
    {
648
        $this->beConstructedWith([1, 3, 3, 2,]);
649
650
        $this
651
            ->append(1)
652
            ->values()
653
            ->toArray()
654
            ->shouldReturn([1, 3, 3, 2, 1]);
655
    }
656
657
    function it_can_append_item_with_key()
658
    {
659
        $this->beConstructedWith([1, 3, 3, 2,]);
660
661
        $this
662
            ->append(1, 'a')
663
            ->toArray()
664
            ->shouldReturn([1, 3, 3, 2, 'a' => 1]);
665
    }
666
667
    function it_can_drop_items_while_predicament_is_true()
668
    {
669
        $this->beConstructedWith([1, 3, 3, 2,]);
670
671
        $this
672
            ->dropWhile(function ($v) {
673
                return $v < 3;
674
            })
675
            ->toArray()
676
            ->shouldReturn([1 => 3, 2 => 3, 3 => 2]);
677
678
        $this
679
            ->dropWhile(function ($v, $k) {
680
                return $k < 2 && $v < 3;
681
            })
682
            ->toArray()
683
            ->shouldReturn([1 => 3, 2 => 3, 3 => 2]);
684
    }
685
686
    function it_can_map_and_then_concatenate_a_collection()
687
    {
688
        $this->beConstructedWith([1, 3, 3, 2,]);
689
690
        $this
691
            ->mapcat(function ($v) {
692
                return [[$v]];
693
            })
694
            ->values()
695
            ->toArray()
696
            ->shouldReturn([[1], [3], [3], [2]]);
697
698
        $this
699
            ->mapcat(function ($v, $k) {
700
                return [[$k + $v]];
701
            })
702
            ->values()
703
            ->toArray()
704
            ->shouldReturn([[1], [4], [5], [5]]);
705
    }
706
707
    function it_can_take_items_while_predicament_is_true()
708
    {
709
        $this->beConstructedWith([1, 3, 3, 2,]);
710
711
        $this
712
            ->takeWhile(function ($v) {
713
                return $v < 3;
714
            })
715
            ->toArray()
716
            ->shouldReturn([1]);
717
718
        $this
719
            ->takeWhile(function ($v, $k) {
720
                return $k < 2 && $v < 3;
721
            })
722
            ->toArray()
723
            ->shouldReturn([1]);
724
    }
725
726
    function it_can_split_the_collection_at_nth_item()
727
    {
728
        $this->beConstructedWith([1, 3, 3, 2,]);
729
730
        $this->splitAt(2)->size()->shouldBe(2);
731
        $this->splitAt(2)->first()->toArray()->shouldBeLike([1, 3]);
732
        $this->splitAt(2)->second()->toArray()->shouldBeLike([2 => 3, 3 => 2]);
733
    }
734
735
    function it_can_split_the_collection_with_predicament()
736
    {
737
        $this->beConstructedWith([1, 3, 3, 2,]);
738
739
        $s1 = $this->splitWith(function ($v) {
740
            return $v < 3;
741
        });
742
743
        $s1->size()->shouldBe(2);
744
        $s1->first()->toArray()->shouldBe([1]);
745
        $s1->second()->toArray()->shouldBe([1 => 3, 2 => 3, 3 => 2]);
746
747
        $s2 = $this->splitWith(function ($v, $k) {
748
            return $v < 2 && $k < 3;
749
        });
750
751
        $s2->size()->shouldBe(2);
752
        $s2->first()->toArray()->shouldBe([1]);
753
        $s2->second()->toArray()->shouldBe([1 => 3, 2 => 3, 3 => 2]);
754
    }
755
756 View Code Duplication
    function it_can_replace_items_by_items_from_another_collection()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
757
    {
758
        $this->beConstructedWith([1, 3, 3, 2,]);
759
760
        $this
761
            ->replace([3 => 'a'])
762
            ->toArray()
763
            ->shouldReturn([1, 'a', 'a', 2]);
764
    }
765
766 View Code Duplication
    function it_can_get_reduction_steps()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
767
    {
768
        $this->beConstructedWith([1, 3, 3, 2,]);
769
770
        $this
771
            ->reductions(
772
                function ($tmp, $i) {
773
                    return $tmp + $i;
774
                },
775
                0
776
            )
777
            ->toArray()
778
            ->shouldReturn([0, 1, 4, 7, 9]);
779
    }
780
781
    function it_can_return_every_nth_item()
782
    {
783
        $this->beConstructedWith([1, 3, 3, 2,]);
784
785
        $this->takeNth(2)
786
            ->toArray()
787
            ->shouldReturn([1, 2 => 3]);
788
    }
789
790
    function it_can_shuffle_itself()
791
    {
792
        $this->beConstructedWith([1, 3, 3, 2,]);
793
794
        $this
795
            ->shuffle()
796
            ->reduce(
797
                function ($tmp, $i) {
798
                    return $tmp + $i;
799
                },
800
                0
801
            )
802
            ->shouldReturn(9);
803
    }
804
805
    function it_can_partition()
806
    {
807
        $this->beConstructedWith([1, 3, 3, 2,]);
808
809
        $s1 = $this->partition(3, 2, [0, 1]);
810
        $s1->size()->shouldBe(2);
811
        $s1->first()->toArray()->shouldBe([1, 3, 3]);
812
        $s1->second()->toArray()->shouldBe([2 => 3, 3 => 2, 0 => 0]);
813
814
        $s2 = $this->partition(3, 2);
815
        $s2->size()->shouldBe(2);
816
        $s2->first()->toArray()->shouldBe([1, 3, 3]);
817
        $s2->second()->toArray()->shouldBe([2 => 3, 3 => 2]);
818
819
        $s3 = $this->partition(3);
820
        $s3->size()->shouldBe(2);
821
        $s3->first()->toArray()->shouldBe([1, 3, 3]);
822
        $s3->second()->toArray()->shouldBe([3 => 2]);
823
824
        $s4 = $this->partition(1, 3);
825
        $s4->size()->shouldBe(2);
826
        $s4->first()->toArray()->shouldBe([1,]);
827
        $s4->second()->toArray()->shouldBe([3 => 2]);
828
    }
829
830
    function it_can_partition_by()
831
    {
832
        $this->beConstructedWith([1, 3, 3, 2]);
833
834
        $s1 = $this->partitionBy(function ($v) {
835
            return $v % 3 == 0;
836
        });
837
        $s1->size()->shouldBe(3);
838
        $s1->first()->toArray()->shouldBe([1]);
839
        $s1->second()->toArray()->shouldBe([1 => 3, 2 => 3]);
840
        $s1->values()->get(2)->toArray()->shouldBe([3 => 2]);
841
842
        $s2 = $this->partitionBy(function ($v, $k) {
843
            return $k - $v;
844
        });
845
        $s2->size()->shouldBe(4);
846
        $s2->first()->toArray()->shouldBe([1]);
847
        $s2->values()->get(1)->toArray()->shouldBe([1 => 3]);
848
        $s2->values()->get(2)->toArray()->shouldBe([2 => 3]);
849
        $s2->values()->get(3)->toArray()->shouldBe([3 => 2]);
850
    }
851
852
    function it_can_get_nth_value()
853
    {
854
        $this->beConstructedWith([1, 3, 3, 2,]);
855
856
        $this->first(0)->shouldReturn(1);
857
        $this->values()->get(3)->shouldReturn(2);
858
    }
859
860
    function it_can_create_infinite_collection_of_repeated_values()
861
    {
862
        $this->beConstructedThrough('repeat', [1]);
863
        $this->take(3)->toArray()->shouldReturn([1, 1, 1]);
864
    }
865
866
    function it_can_create_finite_collection_of_repeated_values()
867
    {
868
        $this->beConstructedThrough('repeat', [1, 1]);
869
        $this->toArray()->shouldReturn([1]);
870
    }
871
872
    function it_can_create_range_from_value_to_infinity()
873
    {
874
        $this->beConstructedThrough('range', [5]);
875
        $this->take(2)->toArray()->shouldReturn([5, 6]);
876
    }
877
878
    function it_can_create_range_from_value_to_another_value()
879
    {
880
        $this->beConstructedThrough('range', [5, 6]);
881
        $this->take(4)->toArray()->shouldReturn([5, 6]);
882
    }
883
884
    function it_can_check_if_it_is_not_empty()
885
    {
886
        $this->beConstructedWith([1, 3, 3, 2,]);
887
888
        $this->isEmpty()->shouldReturn(false);
889
        $this->isNotEmpty()->shouldReturn(true);
890
    }
891
892
    function it_can_check_if_it_is_empty()
893
    {
894
        $this->beConstructedWith([]);
895
896
        $this->isEmpty()->shouldReturn(true);
897
        $this->isNotEmpty()->shouldReturn(false);
898
    }
899
900
    function it_can_check_frequency_of_distinct_items()
901
    {
902
        $this->beConstructedWith([1, 3, 3, 2,]);
903
904
        $this
905
            ->frequencies()
906
            ->toArray()
907
            ->shouldReturn([1 => 1, 3 => 2, 2 => 1]);
908
    }
909
910 View Code Duplication
    function it_can_get_first_item()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
911
    {
912
        $this->beConstructedWith([1, [2], 3]);
913
        $this->first()->shouldReturn(1);
914
        $this->drop(1)->first()->shouldReturn([2]);
915
        $this->drop(1)->first(true)->toArray()->shouldReturn([2]);
916
    }
917
918
    function it_will_throw_when_trying_to_get_first_item_of_empty_collection()
919
    {
920
        $this->beConstructedWith([]);
921
        $this->shouldThrow(ItemNotFound::class)->during('first');
922
    }
923
924 View Code Duplication
    function it_can_get_last_item()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
925
    {
926
        $this->beConstructedWith([1, [2], 3]);
927
        $this->last()->shouldReturn(3);
928
        $this->take(2)->last()->shouldReturn([2]);
929
        $this->take(2)->last(true)->toArray()->shouldReturn([2]);
930
    }
931
932
    function it_will_throw_when_trying_to_get_last_item_of_empty_collection()
933
    {
934
        $this->beConstructedWith([]);
935
        $this->shouldThrow(ItemNotFound::class)->during('last');
936
    }
937
938
    function it_can_realize_the_collection(PlusOneAdder $adder)
939
    {
940
        $adder->dynamicMethod(1)->willReturn(2);
941
        $adder->dynamicMethod(2)->willReturn(3);
942
943
        $this->beConstructedWith(function () use ($adder) {
944
            yield $adder->dynamicMethod(1);
945
            yield $adder->dynamicMethod(2);
946
        });
947
948
        $this->realize();
949
    }
950
951
    function it_can_combine_the_collection()
952
    {
953
        $this->beConstructedWith(['a', 'b']);
954
        $this->combine([1, 2])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
955
        $this->combine([1])->toArray()->shouldReturn(['a' => 1]);
956
        $this->combine([1, 2, 3])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
957
    }
958
959
    function it_can_get_second_item()
960
    {
961
        $this->beConstructedWith([1, 2]);
962
        $this->second()->shouldReturn(2);
963
    }
964
965
    function it_throws_when_trying_to_get_non_existent_second_item()
966
    {
967
        $this->beConstructedWith([1]);
968
        $this->shouldThrow(ItemNotFound::class)->during('second');
969
    }
970
971
    function it_can_drop_item_by_key()
972
    {
973
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
974
        $this->except(['a', 'b'])->toArray()->shouldReturn([]);
975
    }
976
977
    function it_can_get_the_difference_between_collections()
978
    {
979
        $this->beConstructedWith([1, 2, 3, 4]);
980
        $this->diff([1, 2])->toArray()->shouldReturn([2 => 3, 3 => 4]);
981
        $this->diff([1, 2], [3])->toArray()->shouldReturn([3 => 4]);
982
    }
983
984
    function it_can_flip_the_collection()
985
    {
986
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
987
        $this->flip()->toArray()->shouldReturn([1 => 'a', 2 => 'b']);
988
    }
989
990
    function it_can_check_if_key_exits()
991
    {
992
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
993
        $this->has('a')->shouldReturn(true);
994
        $this->has('x')->shouldReturn(false);
995
    }
996
997
    function it_filters_by_keys()
998
    {
999
        $this->beConstructedWith(['a' => 1, 'b' => 2, 'c' => 3]);
1000
        $this->only(['a', 'b'])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
1001
        $this->only(['a', 'b', 'x'])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
1002
    }
1003
1004
    function it_can_serialize_and_unserialize()
1005
    {
1006
        $original = Collection::from([1, 2, 3])->take(2);
1007
        $this->beConstructedWith([1, 2, 3, 4]);
1008
        $this->shouldHaveType(Serializable::class);
1009
        $this->unserialize($original->serialize());
1010
        $this->toArray()->shouldReturn([1, 2]);
1011
    }
1012
1013
    function it_can_zip()
1014
    {
1015
        $this->beConstructedWith([1, 2, 3]);
1016
        $this->zip(['a' => 1, 'b' => 2, 'c' => 4])
1017
            ->map('\DusanKasan\Knapsack\toArray')
1018
            ->toArray()
1019
            ->shouldReturn([[1, 'a' => 1], [1 => 2, 'b' => 2], [2 => 3, 'c' => 4]]);
1020
1021
        $this->zip([4, 5, 6], [7, 8, 9])
1022
            ->map('\DusanKasan\Knapsack\values')
1023
            ->map('\DusanKasan\Knapsack\toArray')
1024
            ->toArray()
1025
            ->shouldReturn([[1, 4, 7], [2, 5, 8], [3, 6, 9]]);
1026
1027
        $this->zip([4, 5])
1028
            ->map('\DusanKasan\Knapsack\values')
1029
            ->map('\DusanKasan\Knapsack\toArray')
1030
            ->toArray()
1031
            ->shouldReturn([[1, 4], [2, 5]]);
1032
    }
1033
1034
    function it_can_use_callable_as_transformer()
1035
    {
1036
        $this->beConstructedWith([1, 2, 3]);
1037
        $this
1038
            ->transform(function (Collection $collection) {
1039
                return $collection->map('\DusanKasan\Knapsack\increment');
1040
            })
1041
            ->toArray()
1042
            ->shouldReturn([2, 3, 4]);
1043
1044
        $this
1045
            ->shouldThrow(InvalidReturnValue::class)
1046
            ->during(
1047
                'transform',
1048
                [
1049
                    function (Collection $collection) {
1050
                        return $collection->first();
1051
                    },
1052
                ]
1053
            );
1054
    }
1055
1056
    function it_can_extract_data_from_nested_collections()
1057
    {
1058
        $input = [
1059
                    [
1060
                        'a' => [
1061
                            'b' => 1
1062
                        ]
1063
                    ],
1064
                    [
1065
                        'a' => [
1066
                            'b' => 2
1067
                        ]
1068
                    ],
1069
                    [
1070
                        '*' => [
1071
                            'b' => 3
1072
                        ]
1073
                    ],
1074
                    [
1075
                        '.' => [
1076
                            'b' => 4
1077
                        ],
1078
                        'c' => [
1079
                            'b' => 5
1080
                        ],
1081
                        [
1082
                            'a'
1083
                        ]
1084
                    ]
1085
                ];
1086
                $this->beConstructedWith($input);
1087
1088
                $this->extract('')->toArray()->shouldReturn($input);
1089
                $this->extract('a.b')->toArray()->shouldReturn([1, 2]);
1090
                $this->extract('*.b')->toArray()->shouldReturn([1, 2, 3, 4, 5]);
1091
                $this->extract('\*.b')->toArray()->shouldReturn([3]);
1092
                $this->extract('\..b')->toArray()->shouldReturn([4]);
1093
    }
1094
1095
    function it_can_get_the_intersect_of_collections()
1096
    {
1097
        $this->beConstructedWith([1, 2, 3]);
1098
        $this->intersect([1, 2])->values()->toArray()->shouldReturn([1, 2]);
1099
        $this->intersect([1], [3])->values()->toArray()->shouldReturn([1, 3]);
1100
    }
1101
1102 View Code Duplication
    function it_can_check_if_size_is_exactly_n()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1103
    {
1104
        $this->beConstructedWith([1, 2]);
1105
        $this->sizeIs(2)->shouldReturn(true);
1106
        $this->sizeIs(3)->shouldReturn(false);
1107
        $this->sizeIs(0)->shouldReturn(false);
1108
    }
1109
1110 View Code Duplication
    function it_can_check_if_size_is_less_than_n()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1111
    {
1112
        $this->beConstructedWith([1, 2]);
1113
        $this->sizeIsLessThan(0)->shouldReturn(false);
1114
        $this->sizeIsLessThan(2)->shouldReturn(false);
1115
        $this->sizeIsLessThan(3)->shouldReturn(true);
1116
    }
1117
1118 View Code Duplication
    function it_can_check_if_size_is_greater_than_n()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1119
    {
1120
        $this->beConstructedWith([1, 2]);
1121
        $this->sizeIsGreaterThan(2)->shouldReturn(false);
1122
        $this->sizeIsGreaterThan(1)->shouldReturn(true);
1123
        $this->sizeIsGreaterThan(0)->shouldReturn(true);
1124
    }
1125
1126
    function it_can_check_if_size_is_between_n_and_m()
1127
    {
1128
        $this->beConstructedWith([1, 2]);
1129
        $this->sizeIsBetween(1, 3)->shouldReturn(true);
1130
        $this->sizeIsBetween(3, 4)->shouldReturn(false);
1131
        $this->sizeIsBetween(0, 0)->shouldReturn(false);
1132
        $this->sizeIsBetween(3, 1)->shouldReturn(true);
1133
    }
1134
1135
    function it_can_sum_the_collection()
1136
    {
1137
        $this->beConstructedWith([1, 2, 3, 4]);
1138
        $this->sum()->shouldReturn(10);
1139
        $this->append(1.5)->sum()->shouldReturn(11.5);
1140
    }
1141
1142
    function it_can_get_average_of_the_collection()
1143
    {
1144
        $this->beConstructedWith([1, 2, 2, 3]);
1145
        $this->average()->shouldReturn(2);
1146
        $this->append(3)->average()->shouldReturn(2.2);
1147
    }
1148
1149
    function it_will_return_zero_when_average_is_called_on_empty_collection()
1150
    {
1151
        $this->beConstructedWith([]);
1152
        $this->average()->shouldReturn(0);
1153
    }
1154
1155
    function it_can_get_maximal_value_in_the_colleciton()
1156
    {
1157
        $this->beConstructedWith([1, 2, 3, 2]);
1158
        $this->max()->shouldReturn(3);
1159
    }
1160
1161
    function it_will_return_null_when_max_is_called_on_empty_collection()
1162
    {
1163
        $this->beConstructedWith([]);
1164
        $this->max()->shouldReturn(null);
1165
    }
1166
1167
    function it_can_get_min_value_in_the_colleciton()
1168
    {
1169
        $this->beConstructedWith([2, 1, 3, 2]);
1170
        $this->min()->shouldReturn(1);
1171
    }
1172
1173
    function it_will_return_null_when_min_is_called_on_empty_collection()
1174
    {
1175
        $this->beConstructedWith([]);
1176
        $this->min()->shouldReturn(null);
1177
    }
1178
1179
    function it_can_convert_the_collection_to_string()
1180
    {
1181
        $this->beConstructedWith([2, 'a', 3, null]);
1182
        $this->toString()->shouldReturn('2a3');
1183
    }
1184
1185
    function it_can_replace_by_key()
1186
    {
1187
        $this->beConstructedWith(['a' => 1, 'b' => 2, 'c' => 3]);
1188
        $this->replaceByKeys(['b' => 3])->toArray()->shouldReturn(['a' => 1, 'b' => 3, 'c' => 3]);
1189
    }
1190
1191
    function it_can_transpose_collections_of_collections()
1192
    {
1193
        $this->beConstructedWith([
1194
            new Collection([1, 2, 3]),
1195
            new Collection([4, 5, new Collection(['foo', 'bar'])]),
1196
            new Collection([7, 8, 9]),
1197
        ]);
1198
1199
        $this->transpose()->toArray()->shouldBeLike([
1200
            new Collection([1, 4, 7]),
1201
            new Collection([2, 5, 8]),
1202
            new Collection([3, new Collection(['foo', 'bar']), 9]),
1203
        ]);
1204
    }
1205
1206
    function it_can_transpose_arrays_of_different_lengths()
1207
    {
1208
        $this->beConstructedWith([
1209
            new Collection(['a', 'b', 'c', 'd']),
1210
            new Collection(['apple', 'box', 'car']),
1211
        ]);
1212
1213
        $this->transpose()->toArray()->shouldBeLike([
1214
            new Collection(['a', 'apple']),
1215
            new Collection(['b', 'box']),
1216
            new Collection(['c', 'car']),
1217
            new Collection(['d', null]),
1218
        ]);
1219
    }
1220
1221
    function it_should_throw_an_invalid_argument_if_collection_items_are_not_collection()
1222
    {
1223
        $this->beConstructedWith([
1224
            [1, 2, 3],
1225
            [4, 5, 6],
1226
            [7, 8, 9],
1227
        ]);
1228
1229
        $this->shouldThrow(InvalidArgument::class)->during('transpose');
1230
    }
1231
1232
    function it_can_use_the_utility_methods()
1233
    {
1234
        $this->beConstructedWith([1, 3, 2]);
1235
1236
        $this
1237
            ->sort('\DusanKasan\Knapsack\compare')
1238
            ->values()
1239
            ->toArray()
1240
            ->shouldReturn([1, 2, 3]);
1241
1242
        $this
1243
            ->map('\DusanKasan\Knapsack\compare')
1244
            ->toArray()
1245
            ->shouldReturn([1, 1, 0]);
1246
1247
        $this
1248
            ->map('\DusanKasan\Knapsack\decrement')
1249
            ->toArray()
1250
            ->shouldReturn([0, 2, 1]);
1251
    }
1252
1253
    function it_can_dump_the_collection()
1254
    {
1255
        $this->beConstructedWith(
1256
            [
1257
                [
1258
                    [1, [2], 3],
1259
                    ['a' => 'b'],
1260
                    new ArrayIterator([1, 2, 3])
1261
                ],
1262
                [1, 2, 3],
1263
                new ArrayIterator(['a', 'b', 'c']),
1264
                true,
1265
                new \DusanKasan\Knapsack\Tests\Helpers\Car('sedan', 5),
1266
                \DusanKasan\Knapsack\concat([1], [1]),
1267
            ]
1268
        );
1269
1270
        $this->dump()->shouldReturn(
1271
            [
1272
                [
1273
                    [1, [2], 3],
1274
                    ['a' => 'b'],
1275
                    [1, 2, 3]
1276
                ],
1277
                [1, 2, 3],
1278
                ['a', 'b', 'c'],
1279
                true,
1280
                [
1281
                    'DusanKasan\Knapsack\Tests\Helpers\Car' => [
1282
                        'numberOfSeats' => 5,
1283
                     ],
1284
1285
                ],
1286
                [1, '0//1' => 1]
1287
            ]
1288
        );
1289
1290
        $this->dump(2)->shouldReturn(
1291
            [
1292
                [
1293
                    [1, [2], '>>>'],
1294
                    ['a' => 'b'],
1295
                    '>>>'
1296
                ],
1297
                [1, 2, '>>>'],
1298
                '>>>'
1299
            ]
1300
        );
1301
1302
        $this->dump(null, 3)->shouldReturn(
1303
            [
1304
                [
1305
                    [1, '^^^', 3],
1306
                    ['a' => 'b'],
1307
                    [1, 2, 3]
1308
                ],
1309
                [1, 2, 3],
1310
                ['a', 'b', 'c'],
1311
                true,
1312
                [
1313
                    'DusanKasan\Knapsack\Tests\Helpers\Car' => [
1314
                        'numberOfSeats' => 5,
1315
                    ],
1316
                ],
1317
                [1, '0//1' => 1]
1318
            ]
1319
        );
1320
1321
        $this->dump(2, 3)->shouldReturn(
1322
            [
1323
                [
1324
                    [1, '^^^', '>>>'],
1325
                    ['a' => 'b'],
1326
                    '>>>'
1327
                ],
1328
                [1, 2, '>>>'],
1329
                '>>>'
1330
            ]
1331
        );
1332
    }
1333
1334
    function it_can_print_dump()
1335
    {
1336
        $this->beConstructedWith([1, [2], 3]);
1337
1338
        ob_start();
1339
        $this->printDump()->shouldReturn($this);
1340
        $this->printDump(2)->shouldReturn($this);
1341
        $this->printDump(2, 2)->shouldReturn($this);
1342
        ob_clean();
1343
    }
1344
}
1345