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 ( ce4f68...496032 )
by Dušan
53s
created

it_can_convert_the_collection_to_string()   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 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_convert_to_array()
95
    {
96
        $iterator = new \ArrayIterator([
97
            'foo',
98
        ]);
99
100
        $this->beConstructedWith(function () use ($iterator) {
101
            yield 'no key';
102
            yield 'with key' => 'this value is overwritten by the same key';
103
            yield 'nested' => [
104
                'y' => 'z',
105
            ];
106
            yield 'iterator is not converted' => $iterator;
107
            yield 'with key' => 'x';
108
        });
109
110
        $this
111
            ->toArray()
112
            ->shouldReturn([
113
                'no key',
114
                'with key' => 'x',
115
                'nested' => [
116
                    'y' => 'z',
117
                ],
118
                'iterator is not converted' => $iterator,
119
            ]);
120
    }
121
122
    function it_can_filter()
123
    {
124
        $this->beConstructedWith([1, 3, 3, 2,]);
125
126
        $this
127
            ->filter(function ($item) {
128
                return $item > 2;
129
            })
130
            ->toArray()
131
            ->shouldReturn([1 => 3, 2 => 3]);
132
133
        $this
134
            ->filter(function ($item, $key) {
135
                return $key > 2 && $item < 3;
136
            })
137
            ->toArray()
138
            ->shouldReturn([3 => 2]);
139
    }
140
141
    function it_can_filter_falsy_values()
142
    {
143
        $this->beConstructedWith([false, null, '', 0, 0.0, []]);
144
145
        $this->filter()->isEmpty()->shouldReturn(true);
146
    }
147
148
    function it_can_distinct()
149
    {
150
        $this->beConstructedWith([1, 3, 3, 2,]);
151
152
        $this
153
            ->distinct()
154
            ->toArray()
155
            ->shouldReturn([1, 3, 3 => 2]);
156
    }
157
158
    function it_can_concat()
159
    {
160
        $this->beConstructedWith([1, 3, 3, 2,]);
161
162
        $collection = $this->concat([4, 5]);
163
        $collection->toArray()->shouldReturn([4, 5, 3, 2]);
164
        $collection->size()->shouldReturn(6);
165
    }
166
167 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...
168
    {
169
        $this->beConstructedWith([1, 3, 3, 2,]);
170
171
        $this
172
            ->map(function ($item) {
173
                return $item + 1;
174
            })
175
            ->toArray()
176
            ->shouldReturn([2, 4, 4, 3]);
177
    }
178
179
    function it_can_reduce()
180
    {
181
        $this->beConstructedWith([1, 3, 3, 2,]);
182
183
        $this
184
            ->reduce(
185
                function ($temp, $item) {
186
                    $temp[] = $item;
187
188
                    return $temp;
189
                },
190
                ['a' => [1]],
191
                true
192
            )
193
            ->values()
194
            ->toArray()
195
            ->shouldReturn([[1], 1, 3, 3, 2]);
196
197
        $this
198
            ->reduce(
199
                function ($temp, $item) {
200
                    return $temp + $item;
201
                },
202
                0
203
            )
204
            ->shouldReturn(9);
205
206
        $this
207
            ->reduce(
208
                function ($temp, $item, $key) {
209
                    return $temp + $key + $item;
210
                },
211
                0
212
            )
213
            ->shouldReturn(15);
214
215
        $this
216
            ->reduce(
217
                function (Collection $temp, $item) {
218
                    return $temp->append($item);
219
                },
220
                new Collection([])
221
            )
222
            ->toArray()
223
            ->shouldReturn([1, 3, 3, 2]);
224
    }
225
226
    function it_can_flatten()
227
    {
228
        $this->beConstructedWith([1, [2, [3]]]);
229
        $this->flatten()->values()->toArray()->shouldReturn([1, 2, 3]);
230
        $this->flatten(1)->values()->toArray()->shouldReturn([1, 2, [3]]);
231
    }
232
233
    function it_can_sort()
234
    {
235
        $this->beConstructedWith([3, 1, 2]);
236
237
        $this
238
            ->sort(function ($a, $b) {
239
                return $a > $b;
240
            })
241
            ->toArray()
242
            ->shouldReturn([1 => 1, 2 => 2, 0 => 3]);
243
244
        $this
245
            ->sort(function ($v1, $v2, $k1, $k2) {
246
                return $k1 < $k2 || $v1 == $v2;
247
            })
248
            ->toArray()
249
            ->shouldReturn([2 => 2, 1 => 1, 0 => 3]);
250
    }
251
252
    function it_can_slice()
253
    {
254
        $this->beConstructedWith([1, 2, 3, 4, 5]);
255
256
        $this
257
            ->slice(2, 4)
258
            ->toArray()
259
            ->shouldReturn([2 => 3, 3 => 4]);
260
261
        $this
262
            ->slice(4)
263
            ->toArray()
264
            ->shouldReturn([4 => 5]);
265
    }
266
267
    function it_can_group_by()
268
    {
269
        $this->beConstructedWith([1, 2, 3, 4, 5]);
270
271
        $collection = $this->groupBy(function ($i) {
272
            return $i % 2;
273
        });
274
275
        $collection->get(0)->toArray()->shouldReturn([2, 4]);
276
        $collection->get(1)->toArray()->shouldReturn([1, 3, 5]);
277
278
        $collection = $this->groupBy(function ($k, $i) {
279
            return ($k + $i) % 3;
280
        });
281
        $collection->get(0)->toArray()->shouldReturn([2, 5]);
282
        $collection->get(1)->toArray()->shouldReturn([1, 4]);
283
        $collection->get(2)->toArray()->shouldReturn([3]);
284
    }
285
286
    function it_can_group_by_key()
287
    {
288
        $this->beConstructedWith([
289
            'some' => 'thing',
290
            ['letter' => 'A', 'type' => 'caps'],
291
            ['letter' => 'a', 'type' => 'small'],
292
            ['letter' => 'B', 'type' => 'caps'],
293
            ['letter' => 'Z'],
294
        ]);
295
296
        $collection = $this->groupByKey('type');
297
        $collection->get('small')->toArray()->shouldReturn([
298
            ['letter' => 'a', 'type' => 'small'],
299
        ]);
300
        $collection->get('caps')->toArray()->shouldReturn([
301
            ['letter' => 'A', 'type' => 'caps'],
302
            ['letter' => 'B', 'type' => 'caps'],
303
        ]);
304
305
        $collection = $this->groupByKey('types');
306
        $collection->shouldThrow(new ItemNotFound)->during('get', ['caps']);
307
    }
308
309
    function it_can_execute_callback_for_each_item(DOMXPath $a)
310
    {
311
        $a->query('asd')->shouldBeCalled();
312
        $this->beConstructedWith([$a]);
313
314
        $this
315
            ->each(function (DOMXPath $i) {
316
                $i->query('asd');
317
            })
318
            ->toArray()
319
            ->shouldReturn([$a]);
320
    }
321
322
    function it_can_get_size()
323
    {
324
        $this->beConstructedWith([1, 3, 3, 2,]);
325
        $this->size()->shouldReturn(4);
326
    }
327
328
    function it_can_get_item_by_key()
329
    {
330
        $this->beConstructedWith([1, [2], 3]);
331
        $this->get(0)->shouldReturn(1);
332
        $this->get(1, true)->first()->shouldReturn(2);
333
        $this->get(1)->shouldReturn([2]);
334
        $this->shouldThrow(new ItemNotFound)->during('get', [5]);
335
    }
336
337
    function it_can_get_item_by_key_or_return_default()
338
    {
339
        $this->beConstructedWith([1, [2], 3]);
340
        $this->getOrDefault(0)->shouldReturn(1);
341
        $this->getOrDefault(1, null, true)->first()->shouldReturn(2);
342
        $this->getOrDefault(1, null)->shouldReturn([2]);
343
        $this->getOrDefault(5)->shouldReturn(null);
344
        $this->getOrDefault(5, 'not found')->shouldReturn('not found');
345
    }
346
347
    function it_can_find()
348
    {
349
        $this->beConstructedWith([1, 3, 3, 2, [5]]);
350
351
        $this
352
            ->find(function ($v) {
353
                return $v < 3;
354
            })
355
            ->shouldReturn(1);
356
357
        $this
358
            ->find(function ($v, $k) {
359
                return $v < 3 && $k > 1;
360
            })
361
            ->shouldReturn(2);
362
363
        $this
364
            ->find(function ($v) {
365
                return $v < 0;
366
            })
367
            ->shouldReturn(null);
368
369
        $this
370
            ->find(
371
                function ($v) {
372
                    return $v < 0;
373
                },
374
                'not found'
375
            )
376
            ->shouldReturn('not found');
377
378
        $this->find('\DusanKasan\Knapsack\isCollection', null, true)->first()->shouldReturn(5);
379
        $this->find('\DusanKasan\Knapsack\isCollection')->shouldReturn([5]);
380
    }
381
382
    function it_can_count_by()
383
    {
384
        $this->beConstructedWith([1, 3, 3, 2,]);
385
386
        $this
387
            ->countBy(function ($v) {
388
                return $v % 2 == 0 ? 'even' : 'odd';
389
            })
390
            ->toArray()
391
            ->shouldReturn(['odd' => 3, 'even' => 1]);
392
393
        $this
394
            ->countBy(function ($k, $v) {
395
                return ($k + $v) % 2 == 0 ? 'even' : 'odd';
396
            })
397
            ->toArray()
398
            ->shouldReturn(['odd' => 3, 'even' => 1]);
399
    }
400
401
    function it_can_index_by()
402
    {
403
        $this->beConstructedWith([1, 3, 3, 2,]);
404
405
        $this
406
            ->indexBy(function ($v) {
407
                return $v;
408
            })
409
            ->toArray()
410
            ->shouldReturn([1 => 1, 3 => 3, 2 => 2]);
411
412
        $this
413
            ->indexBy(function ($v, $k) {
414
                return $k . $v;
415
            })
416
            ->toArray()
417
            ->shouldReturn(['01' => 1, '13' => 3, '23' => 3, '32' => 2]);
418
    }
419
420
    function it_can_check_if_every_item_passes_predicament_test()
421
    {
422
        $this->beConstructedWith([1, 3, 3, 2,]);
423
424
        $this
425
            ->every(function ($v) {
426
                return $v > 0;
427
            })
428
            ->shouldReturn(true);
429
430
        $this
431
            ->every(function ($v) {
432
                return $v > 1;
433
            })
434
            ->shouldReturn(false);
435
436
        $this
437
            ->every(function ($v, $k) {
438
                return $v > 0 && $k >= 0;
439
            })
440
            ->shouldReturn(true);
441
442
        $this
443
            ->every(function ($v, $k) {
444
                return $v > 0 && $k > 0;
445
            })
446
            ->shouldReturn(false);
447
    }
448
449
    function it_can_check_if_some_items_pass_predicament_test()
450
    {
451
        $this->beConstructedWith([1, 3, 3, 2,]);
452
453
        $this
454
            ->some(function ($v) {
455
                return $v < -1;
456
            })
457
            ->shouldReturn(false);
458
459
        $this
460
            ->some(function ($v, $k) {
461
                return $v > 0 && $k < -1;
462
            })
463
            ->shouldReturn(false);
464
465
        $this
466
            ->some(function ($v) {
467
                return $v < 2;
468
            })
469
            ->shouldReturn(true);
470
471
        $this
472
            ->some(function ($v, $k) {
473
                return $v > 0 && $k > 0;
474
            })
475
            ->shouldReturn(true);
476
    }
477
478 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...
479
    {
480
        $this->beConstructedWith([1, 3, 3, 2,]);
481
482
        $this
483
            ->contains(3)
484
            ->shouldReturn(true);
485
486
        $this
487
            ->contains(true)
488
            ->shouldReturn(false);
489
    }
490
491 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...
492
    {
493
        $this->beConstructedWith([1, 3, 3, 2,]);
494
495
        $this
496
            ->reverse()
497
            ->toArray()
498
            ->shouldReturn([
499
                3 => 2,
500
                2 => 3,
501
                1 => 3,
502
                0 => 1,
503
            ])
504
        ;
505
    }
506
507
    function it_can_reduce_from_right()
508
    {
509
        $this->beConstructedWith([1, 3, 3, 2,]);
510
511
        $this
512
            ->reduceRight(
513
                function ($temp, $e) {
514
                    return $temp . $e;
515
                },
516
                0
517
            )
518
            ->shouldReturn('02331');
519
520
        $this
521
            ->reduceRight(
522
                function ($temp, $key, $item) {
523
                    return $temp + $key + $item;
524
                },
525
                0
526
            )
527
            ->shouldReturn(15);
528
529
        $this
530
            ->reduceRight(
531
                function (Collection $temp, $item) {
532
                    return $temp->append($item);
533
                },
534
                new Collection([])
535
            )
536
            ->toArray()
537
            ->shouldReturn([2, 3, 3, 1]);
538
    }
539
540
    function it_can_return_only_first_x_elements()
541
    {
542
        $this->beConstructedWith([1, 3, 3, 2,]);
543
544
        $this->take(2)
545
            ->toArray()
546
            ->shouldReturn([1, 3]);
547
    }
548
549
    function it_can_skip_first_x_elements()
550
    {
551
        $this->beConstructedWith([1, 3, 3, 2,]);
552
553
        $this->drop(2)
554
            ->toArray()
555
            ->shouldReturn([2 => 3, 3 => 2]);
556
    }
557
558
    function it_can_return_values()
559
    {
560
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
561
        $this->values()->toArray()->shouldReturn([1, 2]);
562
    }
563
564
    function it_can_reject_elements_from_collection()
565
    {
566
        $this->beConstructedWith([1, 3, 3, 2,]);
567
568
        $this
569
            ->reject(function ($v) {
570
                return $v == 3;
571
            })
572
            ->toArray()
573
            ->shouldReturn([1, 3 => 2]);
574
575
        $this
576
            ->reject(function ($v, $k) {
577
                return $k == 2 && $v == 3;
578
            })
579
            ->toArray()
580
            ->shouldReturn([1, 3, 3 => 2]);
581
    }
582
583
    function it_can_get_keys()
584
    {
585
        $this->beConstructedWith([1, 3, 3, 2,]);
586
587
        $this
588
            ->keys()
589
            ->toArray()
590
            ->shouldReturn([0, 1, 2, 3]);
591
    }
592
593 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...
594
    {
595
        $this->beConstructedWith([1, 3, 3, 2,]);
596
597
        $this
598
            ->interpose('a')
599
            ->values()
600
            ->toArray()
601
            ->shouldReturn([1, 'a', 3, 'a', 3, 'a', 2]);
602
    }
603
604
    function it_can_drop_elements_from_end_of_the_collection()
605
    {
606
        $this->beConstructedWith([1, 3, 3, 2,]);
607
608
        $this
609
            ->dropLast()
610
            ->toArray()
611
            ->shouldReturn([1, 3, 3]);
612
613
        $this
614
            ->dropLast(2)
615
            ->toArray()
616
            ->shouldReturn([1, 3]);
617
    }
618
619
    function it_can_interleave_elements()
620
    {
621
        $this->beConstructedWith([1, 3, 3, 2,]);
622
623
        $this
624
            ->interleave(['a', 'b', 'c', 'd', 'e'])
625
            ->values()
626
            ->toArray()
627
            ->shouldReturn([1, 'a', 3, 'b', 3, 'c', 2, 'd', 'e']);
628
    }
629
630 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...
631
    {
632
        $this->beConstructedWith([1, 3, 3, 2,]);
633
634
        $this
635
            ->cycle()
636
            ->take(8)
637
            ->values()
638
            ->toArray()
639
            ->shouldReturn([1, 3, 3, 2, 1, 3, 3, 2]);
640
    }
641
642 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...
643
    {
644
        $this->beConstructedWith([1, 3, 3, 2,]);
645
646
        $this
647
            ->prepend(1)
648
            ->values()
649
            ->toArray()
650
            ->shouldReturn([1, 1, 3, 3, 2]);
651
    }
652
653
    function it_can_prepend_item_with_key()
654
    {
655
        $this->beConstructedWith([1, 3, 3, 2,]);
656
657
        $this
658
            ->prepend(1, 'a')
659
            ->toArray()
660
            ->shouldReturn(['a' => 1, 0 => 1, 1 => 3, 2 => 3, 3 => 2]);
661
    }
662
663 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...
664
    {
665
        $this->beConstructedWith([1, 3, 3, 2,]);
666
667
        $this
668
            ->append(1)
669
            ->values()
670
            ->toArray()
671
            ->shouldReturn([1, 3, 3, 2, 1]);
672
    }
673
674
    function it_can_append_item_with_key()
675
    {
676
        $this->beConstructedWith([1, 3, 3, 2,]);
677
678
        $this
679
            ->append(1, 'a')
680
            ->toArray()
681
            ->shouldReturn([1, 3, 3, 2, 'a' => 1]);
682
    }
683
684
    function it_can_drop_items_while_predicament_is_true()
685
    {
686
        $this->beConstructedWith([1, 3, 3, 2,]);
687
688
        $this
689
            ->dropWhile(function ($v) {
690
                return $v < 3;
691
            })
692
            ->toArray()
693
            ->shouldReturn([1 => 3, 2 => 3, 3 => 2]);
694
695
        $this
696
            ->dropWhile(function ($v, $k) {
697
                return $k < 2 && $v < 3;
698
            })
699
            ->toArray()
700
            ->shouldReturn([1 => 3, 2 => 3, 3 => 2]);
701
    }
702
703
    function it_can_map_and_then_concatenate_a_collection()
704
    {
705
        $this->beConstructedWith([1, 3, 3, 2,]);
706
707
        $this
708
            ->mapcat(function ($v) {
709
                return [[$v]];
710
            })
711
            ->values()
712
            ->toArray()
713
            ->shouldReturn([[1], [3], [3], [2]]);
714
715
        $this
716
            ->mapcat(function ($v, $k) {
717
                return [[$k + $v]];
718
            })
719
            ->values()
720
            ->toArray()
721
            ->shouldReturn([[1], [4], [5], [5]]);
722
    }
723
724
    function it_can_take_items_while_predicament_is_true()
725
    {
726
        $this->beConstructedWith([1, 3, 3, 2,]);
727
728
        $this
729
            ->takeWhile(function ($v) {
730
                return $v < 3;
731
            })
732
            ->toArray()
733
            ->shouldReturn([1]);
734
735
        $this
736
            ->takeWhile(function ($v, $k) {
737
                return $k < 2 && $v < 3;
738
            })
739
            ->toArray()
740
            ->shouldReturn([1]);
741
    }
742
743
    function it_can_split_the_collection_at_nth_item()
744
    {
745
        $this->beConstructedWith([1, 3, 3, 2,]);
746
747
        $this->splitAt(2)->size()->shouldBe(2);
748
        $this->splitAt(2)->first()->toArray()->shouldBeLike([1, 3]);
749
        $this->splitAt(2)->second()->toArray()->shouldBeLike([2 => 3, 3 => 2]);
750
    }
751
752
    function it_can_split_the_collection_with_predicament()
753
    {
754
        $this->beConstructedWith([1, 3, 3, 2,]);
755
756
        $s1 = $this->splitWith(function ($v) {
757
            return $v < 3;
758
        });
759
760
        $s1->size()->shouldBe(2);
761
        $s1->first()->toArray()->shouldBe([1]);
762
        $s1->second()->toArray()->shouldBe([1 => 3, 2 => 3, 3 => 2]);
763
764
        $s2 = $this->splitWith(function ($v, $k) {
765
            return $v < 2 && $k < 3;
766
        });
767
768
        $s2->size()->shouldBe(2);
769
        $s2->first()->toArray()->shouldBe([1]);
770
        $s2->second()->toArray()->shouldBe([1 => 3, 2 => 3, 3 => 2]);
771
    }
772
773 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...
774
    {
775
        $this->beConstructedWith([1, 3, 3, 2,]);
776
777
        $this
778
            ->replace([3 => 'a'])
779
            ->toArray()
780
            ->shouldReturn([1, 'a', 'a', 2]);
781
    }
782
783 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...
784
    {
785
        $this->beConstructedWith([1, 3, 3, 2,]);
786
787
        $this
788
            ->reductions(
789
                function ($tmp, $i) {
790
                    return $tmp + $i;
791
                },
792
                0
793
            )
794
            ->toArray()
795
            ->shouldReturn([0, 1, 4, 7, 9]);
796
    }
797
798
    function it_can_return_every_nth_item()
799
    {
800
        $this->beConstructedWith([1, 3, 3, 2,]);
801
802
        $this->takeNth(2)
803
            ->toArray()
804
            ->shouldReturn([1, 2 => 3]);
805
    }
806
807
    function it_can_shuffle_itself()
808
    {
809
        $this->beConstructedWith([1, 3, 3, 2,]);
810
811
        $this
812
            ->shuffle()
813
            ->reduce(
814
                function ($tmp, $i) {
815
                    return $tmp + $i;
816
                },
817
                0
818
            )
819
            ->shouldReturn(9);
820
    }
821
822
    function it_can_partition()
823
    {
824
        $this->beConstructedWith([1, 3, 3, 2,]);
825
826
        $s1 = $this->partition(3, 2, [0, 1]);
827
        $s1->size()->shouldBe(2);
828
        $s1->first()->toArray()->shouldBe([1, 3, 3]);
829
        $s1->second()->toArray()->shouldBe([2 => 3, 3 => 2, 0 => 0]);
830
831
        $s2 = $this->partition(3, 2);
832
        $s2->size()->shouldBe(2);
833
        $s2->first()->toArray()->shouldBe([1, 3, 3]);
834
        $s2->second()->toArray()->shouldBe([2 => 3, 3 => 2]);
835
836
        $s3 = $this->partition(3);
837
        $s3->size()->shouldBe(2);
838
        $s3->first()->toArray()->shouldBe([1, 3, 3]);
839
        $s3->second()->toArray()->shouldBe([3 => 2]);
840
841
        $s4 = $this->partition(1, 3);
842
        $s4->size()->shouldBe(2);
843
        $s4->first()->toArray()->shouldBe([1,]);
844
        $s4->second()->toArray()->shouldBe([3 => 2]);
845
    }
846
847
    function it_can_partition_by()
848
    {
849
        $this->beConstructedWith([1, 3, 3, 2]);
850
851
        $s1 = $this->partitionBy(function ($v) {
852
            return $v % 3 == 0;
853
        });
854
        $s1->size()->shouldBe(3);
855
        $s1->first()->toArray()->shouldBe([1]);
856
        $s1->second()->toArray()->shouldBe([1 => 3, 2 => 3]);
857
        $s1->values()->get(2)->toArray()->shouldBe([3 => 2]);
858
859
        $s2 = $this->partitionBy(function ($v, $k) {
860
            return $k - $v;
861
        });
862
        $s2->size()->shouldBe(4);
863
        $s2->first()->toArray()->shouldBe([1]);
864
        $s2->values()->get(1)->toArray()->shouldBe([1 => 3]);
865
        $s2->values()->get(2)->toArray()->shouldBe([2 => 3]);
866
        $s2->values()->get(3)->toArray()->shouldBe([3 => 2]);
867
    }
868
869
    function it_can_get_nth_value()
870
    {
871
        $this->beConstructedWith([1, 3, 3, 2,]);
872
873
        $this->first(0)->shouldReturn(1);
874
        $this->values()->get(3)->shouldReturn(2);
875
    }
876
877
    function it_can_create_infinite_collection_of_repeated_values()
878
    {
879
        $this->beConstructedThrough('repeat', [1]);
880
        $this->take(3)->toArray()->shouldReturn([1, 1, 1]);
881
    }
882
883
    function it_can_create_finite_collection_of_repeated_values()
884
    {
885
        $this->beConstructedThrough('repeat', [1, 1]);
886
        $this->toArray()->shouldReturn([1]);
887
    }
888
889
    function it_can_create_range_from_value_to_infinity()
890
    {
891
        $this->beConstructedThrough('range', [5]);
892
        $this->take(2)->toArray()->shouldReturn([5, 6]);
893
    }
894
895
    function it_can_create_range_from_value_to_another_value()
896
    {
897
        $this->beConstructedThrough('range', [5, 6]);
898
        $this->take(4)->toArray()->shouldReturn([5, 6]);
899
    }
900
901
    function it_can_check_if_it_is_not_empty()
902
    {
903
        $this->beConstructedWith([1, 3, 3, 2,]);
904
905
        $this->isEmpty()->shouldReturn(false);
906
        $this->isNotEmpty()->shouldReturn(true);
907
    }
908
909
    function it_can_check_if_it_is_empty()
910
    {
911
        $this->beConstructedWith([]);
912
913
        $this->isEmpty()->shouldReturn(true);
914
        $this->isNotEmpty()->shouldReturn(false);
915
    }
916
917
    function it_can_check_frequency_of_distinct_items()
918
    {
919
        $this->beConstructedWith([1, 3, 3, 2,]);
920
921
        $this
922
            ->frequencies()
923
            ->toArray()
924
            ->shouldReturn([1 => 1, 3 => 2, 2 => 1]);
925
    }
926
927 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...
928
    {
929
        $this->beConstructedWith([1, [2], 3]);
930
        $this->first()->shouldReturn(1);
931
        $this->drop(1)->first()->shouldReturn([2]);
932
        $this->drop(1)->first(true)->toArray()->shouldReturn([2]);
933
    }
934
935
    function it_will_throw_when_trying_to_get_first_item_of_empty_collection()
936
    {
937
        $this->beConstructedWith([]);
938
        $this->shouldThrow(ItemNotFound::class)->during('first');
939
    }
940
941 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...
942
    {
943
        $this->beConstructedWith([1, [2], 3]);
944
        $this->last()->shouldReturn(3);
945
        $this->take(2)->last()->shouldReturn([2]);
946
        $this->take(2)->last(true)->toArray()->shouldReturn([2]);
947
    }
948
949
    function it_will_throw_when_trying_to_get_last_item_of_empty_collection()
950
    {
951
        $this->beConstructedWith([]);
952
        $this->shouldThrow(ItemNotFound::class)->during('last');
953
    }
954
955
    function it_can_realize_the_collection(PlusOneAdder $adder)
956
    {
957
        $adder->dynamicMethod(1)->willReturn(2);
958
        $adder->dynamicMethod(2)->willReturn(3);
959
960
        $this->beConstructedWith(function () use ($adder) {
961
            yield $adder->dynamicMethod(1);
962
            yield $adder->dynamicMethod(2);
963
        });
964
965
        $this->realize();
966
    }
967
968
    function it_can_combine_the_collection()
969
    {
970
        $this->beConstructedWith(['a', 'b']);
971
        $this->combine([1, 2])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
972
        $this->combine([1])->toArray()->shouldReturn(['a' => 1]);
973
        $this->combine([1, 2, 3])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
974
    }
975
976
    function it_can_get_second_item()
977
    {
978
        $this->beConstructedWith([1, 2]);
979
        $this->second()->shouldReturn(2);
980
    }
981
982
    function it_throws_when_trying_to_get_non_existent_second_item()
983
    {
984
        $this->beConstructedWith([1]);
985
        $this->shouldThrow(ItemNotFound::class)->during('second');
986
    }
987
988
    function it_can_drop_item_by_key()
989
    {
990
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
991
        $this->except(['a', 'b'])->toArray()->shouldReturn([]);
992
    }
993
994
    function it_can_get_the_difference_between_collections()
995
    {
996
        $this->beConstructedWith([1, 2, 3, 4]);
997
        $this->diff([1, 2])->toArray()->shouldReturn([2 => 3, 3 => 4]);
998
        $this->diff([1, 2], [3])->toArray()->shouldReturn([3 => 4]);
999
    }
1000
1001
    function it_can_flip_the_collection()
1002
    {
1003
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
1004
        $this->flip()->toArray()->shouldReturn([1 => 'a', 2 => 'b']);
1005
    }
1006
1007
    function it_can_check_if_key_exits()
1008
    {
1009
        $this->beConstructedWith(['a' => 1, 'b' => 2]);
1010
        $this->has('a')->shouldReturn(true);
1011
        $this->has('x')->shouldReturn(false);
1012
    }
1013
1014
    function it_filters_by_keys()
1015
    {
1016
        $this->beConstructedWith(['a' => 1, 'b' => 2, 'c' => 3]);
1017
        $this->only(['a', 'b'])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
1018
        $this->only(['a', 'b', 'x'])->toArray()->shouldReturn(['a' => 1, 'b' => 2]);
1019
    }
1020
1021
    function it_can_serialize_and_unserialize()
1022
    {
1023
        $original = Collection::from([1, 2, 3])->take(2);
1024
        $this->beConstructedWith([1, 2, 3, 4]);
1025
        $this->shouldHaveType(Serializable::class);
1026
        $this->unserialize($original->serialize());
1027
        $this->toArray()->shouldReturn([1, 2]);
1028
    }
1029
1030
    function it_can_zip()
1031
    {
1032
        $this->beConstructedWith([1, 2, 3]);
1033
        $this->zip(['a' => 1, 'b' => 2, 'c' => 4])
1034
            ->map('\DusanKasan\Knapsack\toArray')
1035
            ->toArray()
1036
            ->shouldReturn([[1, 'a' => 1], [1 => 2, 'b' => 2], [2 => 3, 'c' => 4]]);
1037
1038
        $this->zip([4, 5, 6], [7, 8, 9])
1039
            ->map('\DusanKasan\Knapsack\values')
1040
            ->map('\DusanKasan\Knapsack\toArray')
1041
            ->toArray()
1042
            ->shouldReturn([[1, 4, 7], [2, 5, 8], [3, 6, 9]]);
1043
1044
        $this->zip([4, 5])
1045
            ->map('\DusanKasan\Knapsack\values')
1046
            ->map('\DusanKasan\Knapsack\toArray')
1047
            ->toArray()
1048
            ->shouldReturn([[1, 4], [2, 5]]);
1049
    }
1050
1051
    function it_can_use_callable_as_transformer()
1052
    {
1053
        $this->beConstructedWith([1, 2, 3]);
1054
        $this
1055
            ->transform(function (Collection $collection) {
1056
                return $collection->map('\DusanKasan\Knapsack\increment');
1057
            })
1058
            ->toArray()
1059
            ->shouldReturn([2, 3, 4]);
1060
1061
        $this
1062
            ->shouldThrow(InvalidReturnValue::class)
1063
            ->during(
1064
                'transform',
1065
                [
1066
                    function (Collection $collection) {
1067
                        return $collection->first();
1068
                    },
1069
                ]
1070
            );
1071
    }
1072
1073
    function it_can_extract_data_from_nested_collections()
1074
    {
1075
        $input = [
1076
                    [
1077
                        'a' => [
1078
                            'b' => 1
1079
                        ]
1080
                    ],
1081
                    [
1082
                        'a' => [
1083
                            'b' => 2
1084
                        ]
1085
                    ],
1086
                    [
1087
                        '*' => [
1088
                            'b' => 3
1089
                        ]
1090
                    ],
1091
                    [
1092
                        '.' => [
1093
                            'b' => 4
1094
                        ],
1095
                        'c' => [
1096
                            'b' => 5
1097
                        ],
1098
                        [
1099
                            'a'
1100
                        ]
1101
                    ]
1102
                ];
1103
                $this->beConstructedWith($input);
1104
1105
                $this->extract('')->toArray()->shouldReturn($input);
1106
                $this->extract('a.b')->toArray()->shouldReturn([1, 2]);
1107
                $this->extract('*.b')->toArray()->shouldReturn([1, 2, 3, 4, 5]);
1108
                $this->extract('\*.b')->toArray()->shouldReturn([3]);
1109
                $this->extract('\..b')->toArray()->shouldReturn([4]);
1110
    }
1111
1112
    function it_can_get_the_intersect_of_collections()
1113
    {
1114
        $this->beConstructedWith([1, 2, 3]);
1115
        $this->intersect([1, 2])->values()->toArray()->shouldReturn([1, 2]);
1116
        $this->intersect([1], [3])->values()->toArray()->shouldReturn([1, 3]);
1117
    }
1118
1119 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...
1120
    {
1121
        $this->beConstructedWith([1, 2]);
1122
        $this->sizeIs(2)->shouldReturn(true);
1123
        $this->sizeIs(3)->shouldReturn(false);
1124
        $this->sizeIs(0)->shouldReturn(false);
1125
    }
1126
1127 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...
1128
    {
1129
        $this->beConstructedWith([1, 2]);
1130
        $this->sizeIsLessThan(0)->shouldReturn(false);
1131
        $this->sizeIsLessThan(2)->shouldReturn(false);
1132
        $this->sizeIsLessThan(3)->shouldReturn(true);
1133
    }
1134
1135 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...
1136
    {
1137
        $this->beConstructedWith([1, 2]);
1138
        $this->sizeIsGreaterThan(2)->shouldReturn(false);
1139
        $this->sizeIsGreaterThan(1)->shouldReturn(true);
1140
        $this->sizeIsGreaterThan(0)->shouldReturn(true);
1141
    }
1142
1143
    function it_can_check_if_size_is_between_n_and_m()
1144
    {
1145
        $this->beConstructedWith([1, 2]);
1146
        $this->sizeIsBetween(1, 3)->shouldReturn(true);
1147
        $this->sizeIsBetween(3, 4)->shouldReturn(false);
1148
        $this->sizeIsBetween(0, 0)->shouldReturn(false);
1149
        $this->sizeIsBetween(3, 1)->shouldReturn(true);
1150
    }
1151
1152
    function it_can_sum_the_collection()
1153
    {
1154
        $this->beConstructedWith([1, 2, 3, 4]);
1155
        $this->sum()->shouldReturn(10);
1156
        $this->append(1.5)->sum()->shouldReturn(11.5);
1157
    }
1158
1159
    function it_can_get_average_of_the_collection()
1160
    {
1161
        $this->beConstructedWith([1, 2, 2, 3]);
1162
        $this->average()->shouldReturn(2);
1163
        $this->append(3)->average()->shouldReturn(2.2);
1164
    }
1165
1166
    function it_will_return_zero_when_average_is_called_on_empty_collection()
1167
    {
1168
        $this->beConstructedWith([]);
1169
        $this->average()->shouldReturn(0);
1170
    }
1171
1172
    function it_can_get_maximal_value_in_the_colleciton()
1173
    {
1174
        $this->beConstructedWith([1, 2, 3, 2]);
1175
        $this->max()->shouldReturn(3);
1176
    }
1177
1178
    function it_will_return_null_when_max_is_called_on_empty_collection()
1179
    {
1180
        $this->beConstructedWith([]);
1181
        $this->max()->shouldReturn(null);
1182
    }
1183
1184
    function it_can_get_min_value_in_the_colleciton()
1185
    {
1186
        $this->beConstructedWith([2, 1, 3, 2]);
1187
        $this->min()->shouldReturn(1);
1188
    }
1189
1190
    function it_will_return_null_when_min_is_called_on_empty_collection()
1191
    {
1192
        $this->beConstructedWith([]);
1193
        $this->min()->shouldReturn(null);
1194
    }
1195
1196
    function it_can_convert_the_collection_to_string()
1197
    {
1198
        $this->beConstructedWith([2, 'a', 3, null]);
1199
        $this->toString()->shouldReturn('2a3');
1200
    }
1201
1202
    function it_can_replace_by_key()
1203
    {
1204
        $this->beConstructedWith(['a' => 1, 'b' => 2, 'c' => 3]);
1205
        $this->replaceByKeys(['b' => 3])->toArray()->shouldReturn(['a' => 1, 'b' => 3, 'c' => 3]);
1206
    }
1207
1208
    function it_can_transpose_collections_of_collections()
1209
    {
1210
        $this->beConstructedWith([
1211
            new Collection([1, 2, 3]),
1212
            new Collection([4, 5, new Collection(['foo', 'bar'])]),
1213
            new Collection([7, 8, 9]),
1214
        ]);
1215
1216
        $this->transpose()->toArray()->shouldBeLike([
1217
            new Collection([1, 4, 7]),
1218
            new Collection([2, 5, 8]),
1219
            new Collection([3, new Collection(['foo', 'bar']), 9]),
1220
        ]);
1221
    }
1222
1223
    function it_can_transpose_arrays_of_different_lengths()
1224
    {
1225
        $this->beConstructedWith([
1226
            new Collection(['a', 'b', 'c', 'd']),
1227
            new Collection(['apple', 'box', 'car']),
1228
        ]);
1229
1230
        $this->transpose()->toArray()->shouldBeLike([
1231
            new Collection(['a', 'apple']),
1232
            new Collection(['b', 'box']),
1233
            new Collection(['c', 'car']),
1234
            new Collection(['d', null]),
1235
        ]);
1236
    }
1237
1238
    function it_should_throw_an_invalid_argument_if_collection_items_are_not_collection()
1239
    {
1240
        $this->beConstructedWith([
1241
            [1, 2, 3],
1242
            [4, 5, 6],
1243
            [7, 8, 9],
1244
        ]);
1245
1246
        $this->shouldThrow(InvalidArgument::class)->during('transpose');
1247
    }
1248
1249
    function it_can_use_the_utility_methods()
1250
    {
1251
        $this->beConstructedWith([1, 3, 2]);
1252
1253
        $this
1254
            ->sort('\DusanKasan\Knapsack\compare')
1255
            ->values()
1256
            ->toArray()
1257
            ->shouldReturn([1, 2, 3]);
1258
1259
        $this
1260
            ->map('\DusanKasan\Knapsack\compare')
1261
            ->toArray()
1262
            ->shouldReturn([1, 1, 0]);
1263
1264
        $this
1265
            ->map('\DusanKasan\Knapsack\decrement')
1266
            ->toArray()
1267
            ->shouldReturn([0, 2, 1]);
1268
    }
1269
1270
    function it_can_dump_the_collection()
1271
    {
1272
        $this->beConstructedWith(
1273
            [
1274
                [
1275
                    [1, [2], 3],
1276
                    ['a' => 'b'],
1277
                    new ArrayIterator([1, 2, 3])
1278
                ],
1279
                [1, 2, 3],
1280
                new ArrayIterator(['a', 'b', 'c']),
1281
                true,
1282
                new \DusanKasan\Knapsack\Tests\Helpers\Car('sedan', 5),
1283
                \DusanKasan\Knapsack\concat([1], [1]),
1284
            ]
1285
        );
1286
1287
        $this->dump()->shouldReturn(
1288
            [
1289
                [
1290
                    [1, [2], 3],
1291
                    ['a' => 'b'],
1292
                    [1, 2, 3]
1293
                ],
1294
                [1, 2, 3],
1295
                ['a', 'b', 'c'],
1296
                true,
1297
                [
1298
                    'DusanKasan\Knapsack\Tests\Helpers\Car' => [
1299
                        'numberOfSeats' => 5,
1300
                     ],
1301
1302
                ],
1303
                [1, '0//1' => 1]
1304
            ]
1305
        );
1306
1307
        $this->dump(2)->shouldReturn(
1308
            [
1309
                [
1310
                    [1, [2], '>>>'],
1311
                    ['a' => 'b'],
1312
                    '>>>'
1313
                ],
1314
                [1, 2, '>>>'],
1315
                '>>>'
1316
            ]
1317
        );
1318
1319
        $this->dump(null, 3)->shouldReturn(
1320
            [
1321
                [
1322
                    [1, '^^^', 3],
1323
                    ['a' => 'b'],
1324
                    [1, 2, 3]
1325
                ],
1326
                [1, 2, 3],
1327
                ['a', 'b', 'c'],
1328
                true,
1329
                [
1330
                    'DusanKasan\Knapsack\Tests\Helpers\Car' => [
1331
                        'numberOfSeats' => 5,
1332
                    ],
1333
                ],
1334
                [1, '0//1' => 1]
1335
            ]
1336
        );
1337
1338
        $this->dump(2, 3)->shouldReturn(
1339
            [
1340
                [
1341
                    [1, '^^^', '>>>'],
1342
                    ['a' => 'b'],
1343
                    '>>>'
1344
                ],
1345
                [1, 2, '>>>'],
1346
                '>>>'
1347
            ]
1348
        );
1349
    }
1350
1351
    function it_can_print_dump()
1352
    {
1353
        $this->beConstructedWith([1, [2], 3]);
1354
1355
        ob_start();
1356
        $this->printDump()->shouldReturn($this);
1357
        $this->printDump(2)->shouldReturn($this);
1358
        $this->printDump(2, 2)->shouldReturn($this);
1359
        ob_clean();
1360
    }
1361
}
1362