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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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
|
|
|
|
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.