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 — master ( d64c76...2b8c72 )
by Dušan
49s
created

CollectionSpec::it_can_reverse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 15
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 0
dl 15
loc 15
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 IteratorAggregate;
14
use PhpSpec\ObjectBehavior;
15
use Serializable;
16
use Traversable;
17
18
/**
19
 * @mixin Collection
20
 */
21
class CollectionSpec extends ObjectBehavior
22
{
23
    function it_is_initializable()
24
    {
25
        $this->beConstructedWith([1, 2, 3]);
26
        $this->shouldHaveType(Collection::class);
27
        $this->shouldHaveType(Traversable::class);
28
        $this->shouldHaveType(Serializable::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 View Code Duplication
    function it_can_reverse()
0 ignored issues
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...
465
    {
466
        $this->beConstructedWith([1, 3, 3, 2,]);
467
468
        $this
469
            ->reverse()
470
            ->toArray()
471
            ->shouldReturn([
472
                3 => 2,
473
                2 => 3,
474
                1 => 3,
475
                0 => 1,
476
            ])
477
        ;
478
    }
479
480
    function it_can_reduce_from_right()
481
    {
482
        $this->beConstructedWith([1, 3, 3, 2,]);
483
484
        $this
485
            ->reduceRight(
486
                function ($temp, $e) {
487
                    return $temp . $e;
488
                },
489
                0
490
            )
491
            ->shouldReturn('02331');
492
493
        $this
494
            ->reduceRight(
495
                function ($temp, $key, $item) {
496
                    return $temp + $key + $item;
497
                },
498
                0
499
            )
500
            ->shouldReturn(15);
501
502
        $this
503
            ->reduceRight(
504
                function (Collection $temp, $item) {
505
                    return $temp->append($item);
506
                },
507
                new Collection([])
508
            )
509
            ->toArray()
510
            ->shouldReturn([2, 3, 3, 1]);
511
    }
512
513
    function it_can_return_only_first_x_elements()
514
    {
515
        $this->beConstructedWith([1, 3, 3, 2,]);
516
517
        $this->take(2)
518
            ->toArray()
519
            ->shouldReturn([1, 3]);
520
    }
521
522
    function it_can_skip_first_x_elements()
523
    {
524
        $this->beConstructedWith([1, 3, 3, 2,]);
525
526
        $this->drop(2)
527
            ->toArray()
528
            ->shouldReturn([2 => 3, 3 => 2]);
529
    }
530
531
    function it_can_return_values()
532
    {
533
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
534
        $this->values()->toArray()->shouldReturn([1, 2]);
535
    }
536
537
    function it_can_reject_elements_from_collection()
538
    {
539
        $this->beConstructedWith([1, 3, 3, 2,]);
540
541
        $this
542
            ->reject(function ($v) {
543
                return $v == 3;
544
            })
545
            ->toArray()
546
            ->shouldReturn([1, 3 => 2]);
547
548
        $this
549
            ->reject(function ($v, $k) {
550
                return $k == 2 && $v == 3;
551
            })
552
            ->toArray()
553
            ->shouldReturn([1, 3, 3 => 2]);
554
    }
555
556
    function it_can_get_keys()
557
    {
558
        $this->beConstructedWith([1, 3, 3, 2,]);
559
560
        $this
561
            ->keys()
562
            ->toArray()
563
            ->shouldReturn([0, 1, 2, 3]);
564
    }
565
566 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...
567
    {
568
        $this->beConstructedWith([1, 3, 3, 2,]);
569
570
        $this
571
            ->interpose('a')
572
            ->values()
573
            ->toArray()
574
            ->shouldReturn([1, 'a', 3, 'a', 3, 'a', 2]);
575
    }
576
577
    function it_can_drop_elements_from_end_of_the_collection()
578
    {
579
        $this->beConstructedWith([1, 3, 3, 2,]);
580
581
        $this
582
            ->dropLast()
583
            ->toArray()
584
            ->shouldReturn([1, 3, 3]);
585
586
        $this
587
            ->dropLast(2)
588
            ->toArray()
589
            ->shouldReturn([1, 3]);
590
    }
591
592
    function it_can_interleave_elements()
593
    {
594
        $this->beConstructedWith([1, 3, 3, 2,]);
595
596
        $this
597
            ->interleave(['a', 'b', 'c', 'd', 'e'])
598
            ->values()
599
            ->toArray()
600
            ->shouldReturn([1, 'a', 3, 'b', 3, 'c', 2, 'd', 'e']);
601
    }
602
603 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...
604
    {
605
        $this->beConstructedWith([1, 3, 3, 2,]);
606
607
        $this
608
            ->cycle()
609
            ->take(8)
610
            ->values()
611
            ->toArray()
612
            ->shouldReturn([1, 3, 3, 2, 1, 3, 3, 2]);
613
    }
614
615 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...
616
    {
617
        $this->beConstructedWith([1, 3, 3, 2,]);
618
619
        $this
620
            ->prepend(1)
621
            ->values()
622
            ->toArray()
623
            ->shouldReturn([1, 1, 3, 3, 2]);
624
    }
625
626
    function it_can_prepend_item_with_key()
627
    {
628
        $this->beConstructedWith([1, 3, 3, 2,]);
629
630
        $this
631
            ->prepend(1, 'a')
632
            ->toArray()
633
            ->shouldReturn(['a' => 1, 0 => 1, 1 => 3, 2 => 3, 3 => 2]);
634
    }
635
636 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...
637
    {
638
        $this->beConstructedWith([1, 3, 3, 2,]);
639
640
        $this
641
            ->append(1)
642
            ->values()
643
            ->toArray()
644
            ->shouldReturn([1, 3, 3, 2, 1]);
645
    }
646
647
    function it_can_append_item_with_key()
648
    {
649
        $this->beConstructedWith([1, 3, 3, 2,]);
650
651
        $this
652
            ->append(1, 'a')
653
            ->toArray()
654
            ->shouldReturn([1, 3, 3, 2, 'a' => 1]);
655
    }
656
657
    function it_can_drop_items_while_predicament_is_true()
658
    {
659
        $this->beConstructedWith([1, 3, 3, 2,]);
660
661
        $this
662
            ->dropWhile(function ($v) {
663
                return $v < 3;
664
            })
665
            ->toArray()
666
            ->shouldReturn([1 => 3, 2 => 3, 3 => 2]);
667
668
        $this
669
            ->dropWhile(function ($v, $k) {
670
                return $k < 2 && $v < 3;
671
            })
672
            ->toArray()
673
            ->shouldReturn([1 => 3, 2 => 3, 3 => 2]);
674
    }
675
676
    function it_can_map_and_then_concatenate_a_collection()
677
    {
678
        $this->beConstructedWith([1, 3, 3, 2,]);
679
680
        $this
681
            ->mapcat(function ($v) {
682
                return [[$v]];
683
            })
684
            ->values()
685
            ->toArray()
686
            ->shouldReturn([[1], [3], [3], [2]]);
687
688
        $this
689
            ->mapcat(function ($v, $k) {
690
                return [[$k + $v]];
691
            })
692
            ->values()
693
            ->toArray()
694
            ->shouldReturn([[1], [4], [5], [5]]);
695
    }
696
697
    function it_can_take_items_while_predicament_is_true()
698
    {
699
        $this->beConstructedWith([1, 3, 3, 2,]);
700
701
        $this
702
            ->takeWhile(function ($v) {
703
                return $v < 3;
704
            })
705
            ->toArray()
706
            ->shouldReturn([1]);
707
708
        $this
709
            ->takeWhile(function ($v, $k) {
710
                return $k < 2 && $v < 3;
711
            })
712
            ->toArray()
713
            ->shouldReturn([1]);
714
    }
715
716
    function it_can_split_the_collection_at_nth_item()
717
    {
718
        $this->beConstructedWith([1, 3, 3, 2,]);
719
720
        $this->splitAt(2)->size()->shouldBe(2);
721
        $this->splitAt(2)->first()->toArray()->shouldBeLike([1, 3]);
722
        $this->splitAt(2)->second()->toArray()->shouldBeLike([2 => 3, 3 => 2]);
723
    }
724
725
    function it_can_split_the_collection_with_predicament()
726
    {
727
        $this->beConstructedWith([1, 3, 3, 2,]);
728
729
        $s1 = $this->splitWith(function ($v) {
730
            return $v < 3;
731
        });
732
733
        $s1->size()->shouldBe(2);
734
        $s1->first()->toArray()->shouldBe([1]);
735
        $s1->second()->toArray()->shouldBe([1 => 3, 2 => 3, 3 => 2]);
736
737
        $s2 = $this->splitWith(function ($v, $k) {
738
            return $v < 2 && $k < 3;
739
        });
740
741
        $s2->size()->shouldBe(2);
742
        $s2->first()->toArray()->shouldBe([1]);
743
        $s2->second()->toArray()->shouldBe([1 => 3, 2 => 3, 3 => 2]);
744
    }
745
746 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...
747
    {
748
        $this->beConstructedWith([1, 3, 3, 2,]);
749
750
        $this
751
            ->replace([3 => 'a'])
752
            ->toArray()
753
            ->shouldReturn([1, 'a', 'a', 2]);
754
    }
755
756 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...
757
    {
758
        $this->beConstructedWith([1, 3, 3, 2,]);
759
760
        $this
761
            ->reductions(
762
                function ($tmp, $i) {
763
                    return $tmp + $i;
764
                },
765
                0
766
            )
767
            ->toArray()
768
            ->shouldReturn([0, 1, 4, 7, 9]);
769
    }
770
771
    function it_can_return_every_nth_item()
772
    {
773
        $this->beConstructedWith([1, 3, 3, 2,]);
774
775
        $this->takeNth(2)
776
            ->toArray()
777
            ->shouldReturn([1, 2 => 3]);
778
    }
779
780
    function it_can_shuffle_itself()
781
    {
782
        $this->beConstructedWith([1, 3, 3, 2,]);
783
784
        $this
785
            ->shuffle()
786
            ->reduce(
787
                function ($tmp, $i) {
788
                    return $tmp + $i;
789
                },
790
                0
791
            )
792
            ->shouldReturn(9);
793
    }
794
795
    function it_can_partition()
796
    {
797
        $this->beConstructedWith([1, 3, 3, 2,]);
798
799
        $s1 = $this->partition(3, 2, [0, 1]);
800
        $s1->size()->shouldBe(2);
801
        $s1->first()->toArray()->shouldBe([1, 3, 3]);
802
        $s1->second()->toArray()->shouldBe([2 => 3, 3 => 2, 0 => 0]);
803
804
        $s2 = $this->partition(3, 2);
805
        $s2->size()->shouldBe(2);
806
        $s2->first()->toArray()->shouldBe([1, 3, 3]);
807
        $s2->second()->toArray()->shouldBe([2 => 3, 3 => 2]);
808
809
        $s3 = $this->partition(3);
810
        $s3->size()->shouldBe(2);
811
        $s3->first()->toArray()->shouldBe([1, 3, 3]);
812
        $s3->second()->toArray()->shouldBe([3 => 2]);
813
814
        $s4 = $this->partition(1, 3);
815
        $s4->size()->shouldBe(2);
816
        $s4->first()->toArray()->shouldBe([1,]);
817
        $s4->second()->toArray()->shouldBe([3 => 2]);
818
    }
819
820
    function it_can_partition_by()
821
    {
822
        $this->beConstructedWith([1, 3, 3, 2]);
823
824
        $s1 = $this->partitionBy(function ($v) {
825
            return $v % 3 == 0;
826
        });
827
        $s1->size()->shouldBe(3);
828
        $s1->first()->toArray()->shouldBe([1]);
829
        $s1->second()->toArray()->shouldBe([1 => 3, 2 => 3]);
830
        $s1->values()->get(2)->toArray()->shouldBe([3 => 2]);
831
832
        $s2 = $this->partitionBy(function ($v, $k) {
833
            return $k - $v;
834
        });
835
        $s2->size()->shouldBe(4);
836
        $s2->first()->toArray()->shouldBe([1]);
837
        $s2->values()->get(1)->toArray()->shouldBe([1 => 3]);
838
        $s2->values()->get(2)->toArray()->shouldBe([2 => 3]);
839
        $s2->values()->get(3)->toArray()->shouldBe([3 => 2]);
840
    }
841
842
    function it_can_get_nth_value()
843
    {
844
        $this->beConstructedWith([1, 3, 3, 2,]);
845
846
        $this->first(0)->shouldReturn(1);
847
        $this->values()->get(3)->shouldReturn(2);
848
    }
849
850
    function it_can_create_infinite_collection_of_repeated_values()
851
    {
852
        $this->beConstructedThrough('repeat', [1]);
853
        $this->take(3)->toArray()->shouldReturn([1, 1, 1]);
854
    }
855
856
    function it_can_create_finite_collection_of_repeated_values()
857
    {
858
        $this->beConstructedThrough('repeat', [1, 1]);
859
        $this->toArray()->shouldReturn([1]);
860
    }
861
862
    function it_can_create_range_from_value_to_infinity()
863
    {
864
        $this->beConstructedThrough('range', [5]);
865
        $this->take(2)->toArray()->shouldReturn([5, 6]);
866
    }
867
868
    function it_can_create_range_from_value_to_another_value()
869
    {
870
        $this->beConstructedThrough('range', [5, 6]);
871
        $this->take(4)->toArray()->shouldReturn([5, 6]);
872
    }
873
874
    function it_can_check_if_it_is_not_empty()
875
    {
876
        $this->beConstructedWith([1, 3, 3, 2,]);
877
878
        $this->isEmpty()->shouldReturn(false);
879
        $this->isNotEmpty()->shouldReturn(true);
880
    }
881
882
    function it_can_check_if_it_is_empty()
883
    {
884
        $this->beConstructedWith([]);
885
886
        $this->isEmpty()->shouldReturn(true);
887
        $this->isNotEmpty()->shouldReturn(false);
888
    }
889
890
    function it_can_check_frequency_of_distinct_items()
891
    {
892
        $this->beConstructedWith([1, 3, 3, 2,]);
893
894
        $this
895
            ->frequencies()
896
            ->toArray()
897
            ->shouldReturn([1 => 1, 3 => 2, 2 => 1]);
898
    }
899
900 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...
901
    {
902
        $this->beConstructedWith([1, [2], 3]);
903
        $this->first()->shouldReturn(1);
904
        $this->drop(1)->first()->shouldReturn([2]);
905
        $this->drop(1)->first(true)->toArray()->shouldReturn([2]);
906
    }
907
908
    function it_will_throw_when_trying_to_get_first_item_of_empty_collection()
909
    {
910
        $this->beConstructedWith([]);
911
        $this->shouldThrow(ItemNotFound::class)->during('first');
912
    }
913
914 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...
915
    {
916
        $this->beConstructedWith([1, [2], 3]);
917
        $this->last()->shouldReturn(3);
918
        $this->take(2)->last()->shouldReturn([2]);
919
        $this->take(2)->last(true)->toArray()->shouldReturn([2]);
920
    }
921
922
    function it_will_throw_when_trying_to_get_last_item_of_empty_collection()
923
    {
924
        $this->beConstructedWith([]);
925
        $this->shouldThrow(ItemNotFound::class)->during('last');
926
    }
927
928
    function it_can_realize_the_collection(PlusOneAdder $adder)
929
    {
930
        $adder->dynamicMethod(1)->willReturn(2);
931
        $adder->dynamicMethod(2)->willReturn(3);
932
933
        $this->beConstructedWith(function () use ($adder) {
934
            yield $adder->dynamicMethod(1);
935
            yield $adder->dynamicMethod(2);
936
        });
937
938
        $this->realize();
939
    }
940
941
    function it_can_combine_the_collection()
942
    {
943
        $this->beConstructedWith(['a', 'b']);
944
        $this->combine([1, 2])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
945
        $this->combine([1])->toArray()->shouldReturn(['a' => 1]);
946
        $this->combine([1, 2, 3])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
947
    }
948
949
    function it_can_get_second_item()
950
    {
951
        $this->beConstructedWith([1, 2]);
952
        $this->second()->shouldReturn(2);
953
    }
954
955
    function it_throws_when_trying_to_get_non_existent_second_item()
956
    {
957
        $this->beConstructedWith([1]);
958
        $this->shouldThrow(ItemNotFound::class)->during('second');
959
    }
960
961
    function it_can_drop_item_by_key()
962
    {
963
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
964
        $this->except(['a', 'b'])->toArray()->shouldReturn([]);
965
    }
966
967
    function it_can_get_the_difference_between_collections()
968
    {
969
        $this->beConstructedWith([1, 2, 3, 4]);
970
        $this->diff([1, 2])->toArray()->shouldReturn([2 => 3, 3 => 4]);
971
        $this->diff([1, 2], [3])->toArray()->shouldReturn([3 => 4]);
972
    }
973
974
    function it_can_flip_the_collection()
975
    {
976
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
977
        $this->flip()->toArray()->shouldReturn([1 => 'a', 2 => 'b']);
978
    }
979
980
    function it_can_check_if_key_exits()
981
    {
982
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
983
        $this->has('a')->shouldReturn(true);
984
        $this->has('x')->shouldReturn(false);
985
    }
986
987
    function it_filters_by_keys()
988
    {
989
        $this->beConstructedWith(['a' => 1, 'b' => 2, 'c' => 3]);
990
        $this->only(['a', 'b'])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
991
        $this->only(['a', 'b', 'x'])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
992
    }
993
994
    function it_can_serialize_and_unserialize()
995
    {
996
        $original = Collection::from([1, 2, 3])->take(2);
997
        $this->beConstructedWith([1, 2, 3, 4]);
998
        $this->shouldHaveType(Serializable::class);
999
        $this->unserialize($original->serialize());
1000
        $this->toArray()->shouldReturn([1, 2]);
1001
    }
1002
1003
    function it_can_zip()
1004
    {
1005
        $this->beConstructedWith([1, 2, 3]);
1006
        $this->zip(['a' => 1, 'b' => 2, 'c' => 4])
1007
            ->map('\DusanKasan\Knapsack\toArray')
1008
            ->toArray()
1009
            ->shouldReturn([[1, 'a' => 1], [1 => 2, 'b' => 2], [2 => 3, 'c' => 4]]);
1010
1011
        $this->zip([4, 5, 6], [7, 8, 9])
1012
            ->map('\DusanKasan\Knapsack\values')
1013
            ->map('\DusanKasan\Knapsack\toArray')
1014
            ->toArray()
1015
            ->shouldReturn([[1, 4, 7], [2, 5, 8], [3, 6, 9]]);
1016
1017
        $this->zip([4, 5])
1018
            ->map('\DusanKasan\Knapsack\values')
1019
            ->map('\DusanKasan\Knapsack\toArray')
1020
            ->toArray()
1021
            ->shouldReturn([[1, 4], [2, 5]]);
1022
    }
1023
1024
    function it_can_use_callable_as_transformer()
1025
    {
1026
        $this->beConstructedWith([1, 2, 3]);
1027
        $this
1028
            ->transform(function (Collection $collection) {
1029
                return $collection->map('\DusanKasan\Knapsack\increment');
1030
            })
1031
            ->toArray()
1032
            ->shouldReturn([2, 3, 4]);
1033
1034
        $this
1035
            ->shouldThrow(InvalidReturnValue::class)
1036
            ->during(
1037
                'transform',
1038
                [
1039
                    function (Collection $collection) {
1040
                        return $collection->first();
1041
                    },
1042
                ]
1043
            );
1044
    }
1045
1046
    function it_can_extract_data_from_nested_collections()
1047
    {
1048
        $input = [
1049
                    [
1050
                        'a' => [
1051
                            'b' => 1
1052
                        ]
1053
                    ],
1054
                    [
1055
                        'a' => [
1056
                            'b' => 2
1057
                        ]
1058
                    ],
1059
                    [
1060
                        '*' => [
1061
                            'b' => 3
1062
                        ]
1063
                    ],
1064
                    [
1065
                        '.' => [
1066
                            'b' => 4
1067
                        ],
1068
                        'c' => [
1069
                            'b' => 5
1070
                        ],
1071
                        [
1072
                            'a'
1073
                        ]
1074
                    ]
1075
                ];
1076
                $this->beConstructedWith($input);
1077
1078
                $this->extract('')->toArray()->shouldReturn($input);
1079
                $this->extract('a.b')->toArray()->shouldReturn([1, 2]);
1080
                $this->extract('*.b')->toArray()->shouldReturn([1, 2, 3, 4, 5]);
1081
                $this->extract('\*.b')->toArray()->shouldReturn([3]);
1082
                $this->extract('\..b')->toArray()->shouldReturn([4]);
1083
    }
1084
1085
    function it_can_get_the_intersect_of_collections()
1086
    {
1087
        $this->beConstructedWith([1, 2, 3]);
1088
        $this->intersect([1, 2])->values()->toArray()->shouldReturn([1, 2]);
1089
        $this->intersect([1], [3])->values()->toArray()->shouldReturn([1, 3]);
1090
    }
1091
1092 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...
1093
    {
1094
        $this->beConstructedWith([1, 2]);
1095
        $this->sizeIs(2)->shouldReturn(true);
1096
        $this->sizeIs(3)->shouldReturn(false);
1097
        $this->sizeIs(0)->shouldReturn(false);
1098
    }
1099
1100 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...
1101
    {
1102
        $this->beConstructedWith([1, 2]);
1103
        $this->sizeIsLessThan(0)->shouldReturn(false);
1104
        $this->sizeIsLessThan(2)->shouldReturn(false);
1105
        $this->sizeIsLessThan(3)->shouldReturn(true);
1106
    }
1107
1108 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...
1109
    {
1110
        $this->beConstructedWith([1, 2]);
1111
        $this->sizeIsGreaterThan(2)->shouldReturn(false);
1112
        $this->sizeIsGreaterThan(1)->shouldReturn(true);
1113
        $this->sizeIsGreaterThan(0)->shouldReturn(true);
1114
    }
1115
1116
    function it_can_check_if_size_is_between_n_and_m()
1117
    {
1118
        $this->beConstructedWith([1, 2]);
1119
        $this->sizeIsBetween(1, 3)->shouldReturn(true);
1120
        $this->sizeIsBetween(3, 4)->shouldReturn(false);
1121
        $this->sizeIsBetween(0, 0)->shouldReturn(false);
1122
        $this->sizeIsBetween(3, 1)->shouldReturn(true);
1123
    }
1124
1125
    function it_can_sum_the_collection()
1126
    {
1127
        $this->beConstructedWith([1, 2, 3, 4]);
1128
        $this->sum()->shouldReturn(10);
1129
        $this->append(1.5)->sum()->shouldReturn(11.5);
1130
    }
1131
1132
    function it_can_get_average_of_the_collection()
1133
    {
1134
        $this->beConstructedWith([1, 2, 2, 3]);
1135
        $this->average()->shouldReturn(2);
1136
        $this->append(3)->average()->shouldReturn(2.2);
1137
    }
1138
1139
    function it_will_return_zero_when_average_is_called_on_empty_collection()
1140
    {
1141
        $this->beConstructedWith([]);
1142
        $this->average()->shouldReturn(0);
1143
    }
1144
1145
    function it_can_get_maximal_value_in_the_colleciton()
1146
    {
1147
        $this->beConstructedWith([1, 2, 3, 2]);
1148
        $this->max()->shouldReturn(3);
1149
    }
1150
1151
    function it_will_return_null_when_max_is_called_on_empty_collection()
1152
    {
1153
        $this->beConstructedWith([]);
1154
        $this->max()->shouldReturn(null);
1155
    }
1156
1157
    function it_can_get_min_value_in_the_colleciton()
1158
    {
1159
        $this->beConstructedWith([2, 1, 3, 2]);
1160
        $this->min()->shouldReturn(1);
1161
    }
1162
1163
    function it_will_return_null_when_min_is_called_on_empty_collection()
1164
    {
1165
        $this->beConstructedWith([]);
1166
        $this->min()->shouldReturn(null);
1167
    }
1168
1169
    function it_can_convert_the_collection_to_string()
1170
    {
1171
        $this->beConstructedWith([2, 'a', 3, null]);
1172
        $this->toString()->shouldReturn('2a3');
1173
    }
1174
1175
    function it_can_replace_by_key()
1176
    {
1177
        $this->beConstructedWith(['a' => 1, 'b' => 2, 'c' => 3]);
1178
        $this->replaceByKeys(['b' => 3])->toArray()->shouldReturn(['a' => 1, 'b' => 3, 'c' => 3]);
1179
    }
1180
1181
    function it_can_transpose_collections_of_collections()
1182
    {
1183
        $this->beConstructedWith([
1184
            new Collection([1, 2, 3]),
1185
            new Collection([4, 5, new Collection(['foo', 'bar'])]),
1186
            new Collection([7, 8, 9]),
1187
        ]);
1188
1189
        $this->transpose()->toArray()->shouldBeLike([
1190
            new Collection([1, 4, 7]),
1191
            new Collection([2, 5, 8]),
1192
            new Collection([3, new Collection(['foo', 'bar']), 9]),
1193
        ]);
1194
    }
1195
1196
    function it_can_transpose_arrays_of_different_lengths()
1197
    {
1198
        $this->beConstructedWith([
1199
            new Collection(['a', 'b', 'c', 'd']),
1200
            new Collection(['apple', 'box', 'car']),
1201
        ]);
1202
1203
        $this->transpose()->toArray()->shouldBeLike([
1204
            new Collection(['a', 'apple']),
1205
            new Collection(['b', 'box']),
1206
            new Collection(['c', 'car']),
1207
            new Collection(['d', null]),
1208
        ]);
1209
    }
1210
1211
    function it_should_throw_an_invalid_argument_if_collection_items_are_not_collection()
1212
    {
1213
        $this->beConstructedWith([
1214
            [1, 2, 3],
1215
            [4, 5, 6],
1216
            [7, 8, 9],
1217
        ]);
1218
1219
        $this->shouldThrow(InvalidArgument::class)->during('transpose');
1220
    }
1221
1222
    function it_can_use_the_utility_methods()
1223
    {
1224
        $this->beConstructedWith([1, 3, 2]);
1225
1226
        $this
1227
            ->sort('\DusanKasan\Knapsack\compare')
1228
            ->values()
1229
            ->toArray()
1230
            ->shouldReturn([1, 2, 3]);
1231
1232
        $this
1233
            ->map('\DusanKasan\Knapsack\compare')
1234
            ->toArray()
1235
            ->shouldReturn([1, 1, 0]);
1236
1237
        $this
1238
            ->map('\DusanKasan\Knapsack\decrement')
1239
            ->toArray()
1240
            ->shouldReturn([0, 2, 1]);
1241
    }
1242
1243
    function it_can_dump_the_collection()
1244
    {
1245
        $this->beConstructedWith(
1246
            [
1247
                [
1248
                    [1, [2], 3],
1249
                    ['a' => 'b'],
1250
                    new ArrayIterator([1, 2, 3])
1251
                ],
1252
                [1, 2, 3],
1253
                new ArrayIterator(['a', 'b', 'c']),
1254
                true,
1255
                new \DusanKasan\Knapsack\Tests\Helpers\Car('sedan', 5),
1256
                \DusanKasan\Knapsack\concat([1], [1]),
1257
            ]
1258
        );
1259
1260
        $this->dump()->shouldReturn(
1261
            [
1262
                [
1263
                    [1, [2], 3],
1264
                    ['a' => 'b'],
1265
                    [1, 2, 3]
1266
                ],
1267
                [1, 2, 3],
1268
                ['a', 'b', 'c'],
1269
                true,
1270
                [
1271
                    'DusanKasan\Knapsack\Tests\Helpers\Car' => [
1272
                        'numberOfSeats' => 5,
1273
                     ],
1274
1275
                ],
1276
                [1, '0//1' => 1]
1277
            ]
1278
        );
1279
1280
        $this->dump(2)->shouldReturn(
1281
            [
1282
                [
1283
                    [1, [2], '>>>'],
1284
                    ['a' => 'b'],
1285
                    '>>>'
1286
                ],
1287
                [1, 2, '>>>'],
1288
                '>>>'
1289
            ]
1290
        );
1291
1292
        $this->dump(null, 3)->shouldReturn(
1293
            [
1294
                [
1295
                    [1, '^^^', 3],
1296
                    ['a' => 'b'],
1297
                    [1, 2, 3]
1298
                ],
1299
                [1, 2, 3],
1300
                ['a', 'b', 'c'],
1301
                true,
1302
                [
1303
                    'DusanKasan\Knapsack\Tests\Helpers\Car' => [
1304
                        'numberOfSeats' => 5,
1305
                    ],
1306
                ],
1307
                [1, '0//1' => 1]
1308
            ]
1309
        );
1310
1311
        $this->dump(2, 3)->shouldReturn(
1312
            [
1313
                [
1314
                    [1, '^^^', '>>>'],
1315
                    ['a' => 'b'],
1316
                    '>>>'
1317
                ],
1318
                [1, 2, '>>>'],
1319
                '>>>'
1320
            ]
1321
        );
1322
    }
1323
1324
    function it_can_print_dump()
1325
    {
1326
        $this->beConstructedWith([1, [2], 3]);
1327
1328
        ob_start();
1329
        $this->printDump()->shouldReturn($this);
1330
        $this->printDump(2)->shouldReturn($this);
1331
        $this->printDump(2, 2)->shouldReturn($this);
1332
        ob_clean();
1333
    }
1334
}
1335