Passed
Pull Request — 4 (#8209)
by Ingo
09:07
created

ArrayListTest   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 1200
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1200
rs 7.2
c 0
b 0
f 0
wmc 50

49 Methods

Rating   Name   Duplication   Size   Complexity  
A testReverse() 0 19 1
A testArrayAccessUnset() 0 11 1
A testPushPop() 0 16 1
A testPushOperator() 0 15 1
A testSimpleExclude() 0 17 1
A testSimpleExcludeWithArray() 0 13 1
A testByIDs() 0 15 2
A testLimit() 0 11 1
A testMultipleFilter() 0 14 1
A testFind() 0 13 1
A testMultipleFilterNoMatch() 0 11 1
A testMultipleWithArrayFilterAdvanced() 0 22 1
A testMap() 0 20 1
A testSimpleFilter() 0 11 1
B testSortSimpleASCOrder() 0 61 1
A testSortNumeric() 0 42 1
A testMultipleExclude() 0 24 1
A testArrayAccessExists() 0 12 1
A testArrayAccessSet() 0 6 1
A testExists() 0 6 1
A testMultipleExcludeThreeArguments() 0 30 1
A testCanFilterByEmpty() 0 6 1
A testByIDEmpty() 0 6 1
A testCount() 0 6 1
A testMultiSort() 0 17 1
A testMerge() 0 18 1
A testSortWithCircularDependencies() 0 20 1
A testToNestedArray() 0 16 1
B testSortSimpleDefaultIsSortedASC() 0 92 1
A testEach() 0 16 1
A testMultipleExcludeNoMatch() 0 27 1
A testRemoveDuplicates() 0 20 1
A testSimpleFilterWithMultiple() 0 16 1
A testSimpleExcludeNoMatch() 0 17 1
A testMixedCaseSort() 0 41 1
A testReplace() 0 19 1
A testAddRemove() 0 21 1
A testByID() 0 18 1
A testMultipleWithArrayFilter() 0 19 1
A testSimpleMultiSort() 0 17 1
A testFirstLast() 0 9 1
A testFilterByCallback() 0 22 1
A testSimpleFilterWithMultipleNoMatch() 0 11 1
B testSortSimpleDESCOrder() 0 61 1
A testColumn() 0 13 1
A testShiftUnshift() 0 16 1
B testFilterAny() 0 67 1
A testExcludeWithTwoArrays() 0 19 1
A testCanFilterBy() 0 12 1

How to fix   Complexity   

Complex Class

Complex classes like ArrayListTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ArrayListTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace SilverStripe\ORM\Tests;
4
5
use SilverStripe\ORM\ArrayList;
6
use SilverStripe\ORM\DataObject;
7
use SilverStripe\ORM\Filterable;
8
use SilverStripe\Dev\SapphireTest;
9
use SilverStripe\View\ArrayData;
10
use stdClass;
11
12
class ArrayListTest extends SapphireTest
13
{
14
15
    public function testPushOperator()
16
    {
17
        $list = new ArrayList(
18
            array(
19
            array('Num' => 1)
20
            )
21
        );
22
23
        $list[] = array('Num' => 2);
24
        $this->assertEquals(2, count($list));
25
        $this->assertEquals(array('Num' => 2), $list->last());
26
27
        $list[] = array('Num' => 3);
28
        $this->assertEquals(3, count($list));
29
        $this->assertEquals(array('Num' => 3), $list->last());
30
    }
31
32
    public function testArrayAccessExists()
33
    {
34
        $list = new ArrayList(
35
            array(
36
            $one = new DataObject(array('Title' => 'one')),
37
            $two = new DataObject(array('Title' => 'two')),
0 ignored issues
show
Unused Code introduced by
The assignment to $two is dead and can be removed.
Loading history...
38
            $three = new DataObject(array('Title' => 'three'))
0 ignored issues
show
Unused Code introduced by
The assignment to $three is dead and can be removed.
Loading history...
39
            )
40
        );
41
        $this->assertEquals(count($list), 3);
42
        $this->assertTrue(isset($list[0]), 'First item in the set is set');
43
        $this->assertEquals($one, $list[0], 'First item in the set is accessible by array notation');
44
    }
45
46
    public function testArrayAccessUnset()
47
    {
48
        $list = new ArrayList(
49
            array(
50
            $one = new DataObject(array('Title' => 'one')),
0 ignored issues
show
Unused Code introduced by
The assignment to $one is dead and can be removed.
Loading history...
51
            $two = new DataObject(array('Title' => 'two')),
0 ignored issues
show
Unused Code introduced by
The assignment to $two is dead and can be removed.
Loading history...
52
            $three = new DataObject(array('Title' => 'three'))
0 ignored issues
show
Unused Code introduced by
The assignment to $three is dead and can be removed.
Loading history...
53
            )
54
        );
55
        unset($list[0]);
56
        $this->assertEquals(count($list), 2);
57
    }
58
59
    public function testArrayAccessSet()
60
    {
61
        $list = new ArrayList();
62
        $this->assertEquals(0, count($list));
63
        $list['testing!'] = $test = new DataObject(array('Title' => 'I\'m testing!'));
64
        $this->assertEquals($test, $list['testing!'], 'Set item is accessible by the key we set it as');
65
    }
66
67
    public function testCount()
68
    {
69
        $list = new ArrayList();
70
        $this->assertEquals(0, $list->count());
71
        $list = new ArrayList(array(1, 2, 3));
72
        $this->assertEquals(3, $list->count());
73
    }
74
75
    public function testExists()
76
    {
77
        $list = new ArrayList();
78
        $this->assertFalse($list->exists());
79
        $list = new ArrayList(array(1, 2, 3));
80
        $this->assertTrue($list->exists());
81
    }
82
83
    public function testToNestedArray()
84
    {
85
        $list = new ArrayList(
86
            array(
87
            array('First' => 'FirstFirst', 'Second' => 'FirstSecond'),
88
            (object) array('First' => 'SecondFirst', 'Second' => 'SecondSecond'),
89
            new ArrayListTest\TestObject('ThirdFirst', 'ThirdSecond')
90
            )
91
        );
92
93
        $this->assertEquals(
94
            $list->toNestedArray(),
95
            array(
96
            array('First' => 'FirstFirst', 'Second' => 'FirstSecond'),
97
            array('First' => 'SecondFirst', 'Second' => 'SecondSecond'),
98
            array('First' => 'ThirdFirst', 'Second' => 'ThirdSecond')
99
            )
100
        );
101
    }
102
103
    public function testEach()
104
    {
105
        $list = new ArrayList(array(1, 2, 3));
106
107
        $count = 0;
108
        $test = $this;
109
110
        $list->each(
111
            function ($item) use (&$count, $test) {
112
                $count++;
113
114
                $test->assertTrue(is_int($item));
115
            }
116
        );
117
118
        $this->assertEquals($list->Count(), $count);
119
    }
120
121
    public function testLimit()
122
    {
123
        $list = new ArrayList(
124
            array(
125
            array('Key' => 1), array('Key' => 2), array('Key' => 3)
126
            )
127
        );
128
        $this->assertEquals(
129
            $list->limit(2, 1)->toArray(),
130
            array(
131
            array('Key' => 2), array('Key' => 3)
132
            )
133
        );
134
    }
135
136
    public function testAddRemove()
137
    {
138
        $list = new ArrayList(
139
            array(
140
            array('Key' => 1), array('Key' => 2)
141
            )
142
        );
143
144
        $list->add(array('Key' => 3));
145
        $this->assertEquals(
146
            $list->toArray(),
147
            array(
148
            array('Key' => 1), array('Key' => 2), array('Key' => 3)
149
            )
150
        );
151
152
        $list->remove(array('Key' => 2));
153
        $this->assertEquals(
154
            array_values($list->toArray()),
155
            array(
156
            array('Key' => 1), array('Key' => 3)
157
            )
158
        );
159
    }
160
161
    public function testReplace()
162
    {
163
        $list = new ArrayList(
164
            array(
165
            array('Key' => 1),
166
            $two = (object) array('Key' => 2),
167
            (object) array('Key' => 3)
168
            )
169
        );
170
171
        $this->assertEquals(array('Key' => 1), $list[0]);
172
        $list->replace(array('Key' => 1), array('Replaced' => 1));
173
        $this->assertEquals(3, count($list));
174
        $this->assertEquals(array('Replaced' => 1), $list[0]);
175
176
        $this->assertEquals($two, $list[1]);
177
        $list->replace($two, array('Replaced' => 2));
178
        $this->assertEquals(3, count($list));
179
        $this->assertEquals(array('Replaced' => 2), $list[1]);
180
    }
181
182
    public function testMerge()
183
    {
184
        $list = new ArrayList(
185
            array(
186
            array('Num' => 1), array('Num' => 2)
187
            )
188
        );
189
        $list->merge(
190
            array(
191
            array('Num' => 3), array('Num' => 4)
192
            )
193
        );
194
195
        $this->assertEquals(4, count($list));
196
        $this->assertEquals(
197
            $list->toArray(),
198
            array(
199
            array('Num' => 1), array('Num' => 2), array('Num' => 3), array('Num' => 4)
200
            )
201
        );
202
    }
203
204
    public function testRemoveDuplicates()
205
    {
206
        $list = new ArrayList(
207
            array(
208
            array('ID' => 1, 'Field' => 1),
209
            array('ID' => 2, 'Field' => 2),
210
            array('ID' => 3, 'Field' => 3),
211
            array('ID' => 4, 'Field' => 1),
212
            (object) array('ID' => 5, 'Field' => 2)
213
            )
214
        );
215
216
        $this->assertEquals(5, count($list));
217
        $list->removeDuplicates();
218
        $this->assertEquals(5, count($list));
219
220
        $list->removeDuplicates('Field');
221
        $this->assertEquals(3, count($list));
222
        $this->assertEquals(array(1, 2, 3), $list->column('Field'));
223
        $this->assertEquals(array(1, 2, 3), $list->column('ID'));
224
    }
225
226
    public function testPushPop()
227
    {
228
        $list = new ArrayList(array('Num' => 1));
229
        $this->assertEquals(1, count($list));
230
231
        $list->push(array('Num' => 2));
232
        $this->assertEquals(2, count($list));
233
        $this->assertEquals(array('Num' => 2), $list->last());
234
235
        $list->push(array('Num' => 3));
236
        $this->assertEquals(3, count($list));
237
        $this->assertEquals(array('Num' => 3), $list->last());
238
239
        $this->assertEquals(array('Num' => 3), $list->pop());
240
        $this->assertEquals(2, count($list));
241
        $this->assertEquals(array('Num' => 2), $list->last());
242
    }
243
244
    public function testShiftUnshift()
245
    {
246
        $list = new ArrayList(array('Num' => 1));
247
        $this->assertEquals(1, count($list));
248
249
        $list->unshift(array('Num' => 2));
250
        $this->assertEquals(2, count($list));
251
        $this->assertEquals(array('Num' => 2), $list->first());
252
253
        $list->unshift(array('Num' => 3));
254
        $this->assertEquals(3, count($list));
255
        $this->assertEquals(array('Num' => 3), $list->first());
256
257
        $this->assertEquals(array('Num' => 3), $list->shift());
258
        $this->assertEquals(2, count($list));
259
        $this->assertEquals(array('Num' => 2), $list->first());
260
    }
261
262
    public function testFirstLast()
263
    {
264
        $list = new ArrayList(
265
            array(
266
            array('Key' => 1), array('Key' => 2), array('Key' => 3)
267
            )
268
        );
269
        $this->assertEquals($list->first(), array('Key' => 1));
270
        $this->assertEquals($list->last(), array('Key' => 3));
271
    }
272
273
    public function testMap()
274
    {
275
        $list = new ArrayList(
276
            array(
277
            array('ID' => 1, 'Name' => 'Steve',),
278
            (object) array('ID' => 3, 'Name' => 'Bob'),
279
            array('ID' => 5, 'Name' => 'John')
280
            )
281
        );
282
        $map = $list->map('ID', 'Name');
283
        // Items added after calling map should not be included retroactively
284
        $list->add(array('ID' => 7, 'Name' => 'Andrew'));
285
        $this->assertInstanceOf('SilverStripe\\ORM\\Map', $map);
286
        $this->assertEquals(
287
            array(
288
            1 => 'Steve',
289
            3 => 'Bob',
290
            5 => 'John'
291
            ),
292
            $map->toArray()
293
        );
294
    }
295
296
    public function testFind()
297
    {
298
        $list = new ArrayList(
299
            array(
300
            array('Name' => 'Steve'),
301
            (object) array('Name' => 'Bob'),
302
            array('Name' => 'John')
303
            )
304
        );
305
        $this->assertEquals(
306
            $list->find('Name', 'Bob'),
307
            (object) array(
308
            'Name' => 'Bob'
309
            )
310
        );
311
    }
312
313
    public function testColumn()
314
    {
315
        $list = new ArrayList(
316
            array(
317
            array('Name' => 'Steve'),
318
            (object) array('Name' => 'Bob'),
319
            array('Name' => 'John')
320
            )
321
        );
322
        $this->assertEquals(
323
            $list->column('Name'),
324
            array(
325
            'Steve', 'Bob', 'John'
326
            )
327
        );
328
    }
329
330
    public function testSortSimpleDefaultIsSortedASC()
331
    {
332
        $list = new ArrayList(
333
            array(
334
            array('Name' => 'Steve'),
335
            (object) array('Name' => 'Bob'),
336
            array('Name' => 'John'),
337
            array('Name' => 'bonny'),
338
            )
339
        );
340
341
        // Unquoted name
342
        $list1 = $list->sort('Name');
343
        $this->assertEquals(
344
            array(
345
            (object) array('Name' => 'Bob'),
346
            array('Name' => 'bonny'),
347
            array('Name' => 'John'),
348
            array('Name' => 'Steve'),
349
            ),
350
            $list1->toArray()
351
        );
352
353
        // Quoted name name
354
        $list2 = $list->sort('"Name"');
355
        $this->assertEquals(
356
            array(
357
            (object) array('Name' => 'Bob'),
358
            array('Name' => 'bonny'),
359
            array('Name' => 'John'),
360
            array('Name' => 'Steve'),
361
            ),
362
            $list2->toArray()
363
        );
364
365
        // Array (non-associative)
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
366
        $list3 = $list->sort(array('"Name"'));
367
        $this->assertEquals(
368
            array(
369
            (object) array('Name' => 'Bob'),
370
            array('Name' => 'bonny'),
371
            array('Name' => 'John'),
372
            array('Name' => 'Steve'),
373
            ),
374
            $list3->toArray()
375
        );
376
377
        // Quoted name name with table
378
        $list4 = $list->sort('"Record"."Name"');
379
        $this->assertEquals(
380
            array(
381
            (object) array('Name' => 'Bob'),
382
            array('Name' => 'bonny'),
383
            array('Name' => 'John'),
384
            array('Name' => 'Steve')
385
            ),
386
            $list4->toArray()
387
        );
388
389
        // Quoted name name with table (desc)
390
        $list5 = $list->sort('"Record"."Name" DESC');
391
        $this->assertEquals(
392
            array(
393
            array('Name' => 'Steve'),
394
            array('Name' => 'John'),
395
            array('Name' => 'bonny'),
396
            (object) array('Name' => 'Bob')
397
            ),
398
            $list5->toArray()
399
        );
400
401
        // Table without quotes
402
        $list6 = $list->sort('Record.Name');
403
        $this->assertEquals(
404
            array(
405
            (object) array('Name' => 'Bob'),
406
            array('Name' => 'bonny'),
407
            array('Name' => 'John'),
408
            array('Name' => 'Steve')
409
            ),
410
            $list6->toArray()
411
        );
412
413
        // Check original list isn't altered
414
        $this->assertEquals(
415
            array(
416
            array('Name' => 'Steve'),
417
            (object) array('Name' => 'Bob'),
418
            array('Name' => 'John'),
419
            array('Name' => 'bonny'),
420
            ),
421
            $list->toArray()
422
        );
423
    }
424
425
    public function testMixedCaseSort()
426
    {
427
        // Note: Natural sorting is not expected, so if 'bonny10' were included
428
        // below we would expect it to appear between bonny1 and bonny2. That's
429
        // undesirable though so we're not enforcing it in tests.
430
        $original = array(
431
            array('Name' => 'Steve'),
432
            (object) array('Name' => 'Bob'),
433
            array('Name' => 'John'),
434
            array('Name' => 'bonny'),
435
            array('Name' => 'bonny1'),
436
            //array('Name' => 'bonny10'),
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
437
            array('Name' => 'bonny2'),
438
        );
439
440
        $list = new ArrayList($original);
441
442
        $expected = array(
443
            (object) array('Name' => 'Bob'),
444
            array('Name' => 'bonny'),
445
            array('Name' => 'bonny1'),
446
            //array('Name' => 'bonny10'),
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
447
            array('Name' => 'bonny2'),
448
            array('Name' => 'John'),
449
            array('Name' => 'Steve'),
450
        );
451
452
        // Unquoted name
453
        $list1 = $list->sort('Name');
454
        $this->assertEquals($expected, $list1->toArray());
455
456
        // Quoted name name
457
        $list2 = $list->sort('"Name"');
458
        $this->assertEquals($expected, $list2->toArray());
459
460
        // Array (non-associative)
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
461
        $list3 = $list->sort(array('"Name"'));
462
        $this->assertEquals($expected, $list3->toArray());
463
464
        // Check original list isn't altered
465
        $this->assertEquals($original, $list->toArray());
466
    }
467
468
    public function testSortSimpleASCOrder()
469
    {
470
        $list = new ArrayList(
471
            array(
472
            array('Name' => 'Steve'),
473
            (object) array('Name' => 'Bob'),
474
            array('Name' => 'John')
475
            )
476
        );
477
478
        // Sort two arguments
479
        $list1 = $list->sort('Name', 'ASC');
480
        $this->assertEquals(
481
            $list1->toArray(),
482
            array(
483
            (object) array('Name' => 'Bob'),
484
            array('Name' => 'John'),
485
            array('Name' => 'Steve')
486
            )
487
        );
488
489
        // Sort single string
490
        $list2 = $list->sort('Name asc');
491
        $this->assertEquals(
492
            $list2->toArray(),
493
            array(
494
            (object) array('Name' => 'Bob'),
495
            array('Name' => 'John'),
496
            array('Name' => 'Steve')
497
            )
498
        );
499
500
        // Sort quoted string
501
        $list3 = $list->sort('"Name" ASCENDING');
502
        $this->assertEquals(
503
            $list3->toArray(),
504
            array(
505
            (object) array('Name' => 'Bob'),
506
            array('Name' => 'John'),
507
            array('Name' => 'Steve')
508
            )
509
        );
510
511
        // Sort array specifier
512
        $list4 = $list->sort(array('Name' => 'ascending'));
513
        $this->assertEquals(
514
            $list4->toArray(),
515
            array(
516
            (object) array('Name' => 'Bob'),
517
            array('Name' => 'John'),
518
            array('Name' => 'Steve')
519
            )
520
        );
521
522
        // Check original list isn't altered
523
        $this->assertEquals(
524
            $list->toArray(),
525
            array(
526
            array('Name' => 'Steve'),
527
            (object) array('Name' => 'Bob'),
528
            array('Name' => 'John')
529
            )
530
        );
531
    }
532
533
    public function testSortSimpleDESCOrder()
534
    {
535
        $list = new ArrayList(
536
            array(
537
            array('Name' => 'Steve'),
538
            (object) array('Name' => 'Bob'),
539
            array('Name' => 'John')
540
            )
541
        );
542
543
        // Sort two arguments
544
        $list1 = $list->sort('Name', 'DESC');
545
        $this->assertEquals(
546
            $list1->toArray(),
547
            array(
548
            array('Name' => 'Steve'),
549
            array('Name' => 'John'),
550
            (object) array('Name' => 'Bob')
551
            )
552
        );
553
554
        // Sort single string
555
        $list2 = $list->sort('Name desc');
556
        $this->assertEquals(
557
            $list2->toArray(),
558
            array(
559
            array('Name' => 'Steve'),
560
            array('Name' => 'John'),
561
            (object) array('Name' => 'Bob')
562
            )
563
        );
564
565
        // Sort quoted string
566
        $list3 = $list->sort('"Name" DESCENDING');
567
        $this->assertEquals(
568
            $list3->toArray(),
569
            array(
570
            array('Name' => 'Steve'),
571
            array('Name' => 'John'),
572
            (object) array('Name' => 'Bob')
573
            )
574
        );
575
576
        // Sort array specifier
577
        $list4 = $list->sort(array('Name' => 'descending'));
578
        $this->assertEquals(
579
            $list4->toArray(),
580
            array(
581
            array('Name' => 'Steve'),
582
            array('Name' => 'John'),
583
            (object) array('Name' => 'Bob')
584
            )
585
        );
586
587
        // Check original list isn't altered
588
        $this->assertEquals(
589
            $list->toArray(),
590
            array(
591
            array('Name' => 'Steve'),
592
            (object) array('Name' => 'Bob'),
593
            array('Name' => 'John')
594
            )
595
        );
596
    }
597
598
    public function testSortNumeric()
599
    {
600
        $list = new ArrayList(
601
            array(
602
            array('Sort' => 0),
603
            array('Sort' => -1),
604
            array('Sort' => 1),
605
            array('Sort' => -2),
606
            array('Sort' => 2),
607
            array('Sort' => -10),
608
            array('Sort' => 10)
609
            )
610
        );
611
612
        // Sort descending
613
        $list1 = $list->sort('Sort', 'DESC');
614
        $this->assertEquals(
615
            array(
616
            array('Sort' => 10),
617
            array('Sort' => 2),
618
            array('Sort' => 1),
619
            array('Sort' => 0),
620
            array('Sort' => -1),
621
            array('Sort' => -2),
622
            array('Sort' => -10)
623
            ),
624
            $list1->toArray()
625
        );
626
627
        // Sort ascending
628
        $list1 = $list->sort('Sort', 'ASC');
629
        $this->assertEquals(
630
            array(
631
            array('Sort' => -10),
632
            array('Sort' => -2),
633
            array('Sort' => -1),
634
            array('Sort' => 0),
635
            array('Sort' => 1),
636
            array('Sort' => 2),
637
            array('Sort' => 10)
638
            ),
639
            $list1->toArray()
640
        );
641
    }
642
643
    public function testReverse()
644
    {
645
        $list = new ArrayList(
646
            array(
647
            array('Name' => 'John'),
648
            array('Name' => 'Bob'),
649
            array('Name' => 'Steve')
650
            )
651
        );
652
653
        $list = $list->sort('Name', 'ASC');
654
        $list = $list->reverse();
655
656
        $this->assertEquals(
657
            $list->toArray(),
658
            array(
659
            array('Name' => 'Steve'),
660
            array('Name' => 'John'),
661
            array('Name' => 'Bob')
662
            )
663
        );
664
    }
665
666
    public function testSimpleMultiSort()
667
    {
668
        $list = new ArrayList(
669
            array(
670
            (object) array('Name'=>'Object1', 'F1'=>1, 'F2'=>2, 'F3'=>3),
671
            (object) array('Name'=>'Object2', 'F1'=>2, 'F2'=>1, 'F3'=>4),
672
            (object) array('Name'=>'Object3', 'F1'=>5, 'F2'=>2, 'F3'=>2),
673
            )
674
        );
675
676
        $list = $list->sort('F3', 'ASC');
677
        $this->assertEquals($list->first()->Name, 'Object3', 'Object3 should be first in the list');
678
        $this->assertEquals($list->last()->Name, 'Object2', 'Object2 should be last in the list');
679
680
        $list = $list->sort('F3', 'DESC');
681
        $this->assertEquals($list->first()->Name, 'Object2', 'Object2 should be first in the list');
682
        $this->assertEquals($list->last()->Name, 'Object3', 'Object3 should be last in the list');
683
    }
684
685
    public function testMultiSort()
686
    {
687
        $list = new ArrayList(
688
            array(
689
            (object) array('ID'=>3, 'Name'=>'Bert', 'Importance'=>1),
690
            (object) array('ID'=>1, 'Name'=>'Aron', 'Importance'=>2),
691
            (object) array('ID'=>2, 'Name'=>'Aron', 'Importance'=>1),
692
            )
693
        );
694
695
        $list = $list->sort(array('Name'=>'ASC', 'Importance'=>'ASC'));
696
        $this->assertEquals($list->first()->ID, 2, 'Aron.2 should be first in the list');
697
        $this->assertEquals($list->last()->ID, 3, 'Bert.3 should be last in the list');
698
699
        $list = $list->sort(array('Name'=>'ASC', 'Importance'=>'DESC'));
700
        $this->assertEquals($list->first()->ID, 1, 'Aron.2 should be first in the list');
701
        $this->assertEquals($list->last()->ID, 3, 'Bert.3 should be last in the list');
702
    }
703
704
    /**
705
     * Check that we don't cause recursion errors with array_multisort() and circular dependencies
706
     */
707
    public function testSortWithCircularDependencies()
708
    {
709
        $itemA = new stdClass;
710
        $childA = new stdClass;
711
        $itemA->child = $childA;
712
        $childA->parent = $itemA;
713
        $itemA->Sort = 1;
714
715
        $itemB = new stdClass;
716
        $childB = new stdClass;
717
        $itemB->child = $childB;
718
        $childB->parent = $itemB;
719
        $itemB->Sort = 1;
720
721
        $items = new ArrayList;
722
        $items->add($itemA);
723
        $items->add($itemB);
724
725
        // This call will trigger a fatal error if there are issues with circular dependencies
726
        $items->sort('Sort');
727
    }
728
    /**
729
     * $list->filter('Name', 'bob'); // only bob in the list
730
     */
731
    public function testSimpleFilter()
732
    {
733
        $list = new ArrayList(
734
            array(
735
            array('Name' => 'Steve'),
736
            (object) array('Name' => 'Bob'),
737
            array('Name' => 'John')
738
            )
739
        );
740
        $list = $list->filter('Name', 'Bob');
741
        $this->assertEquals(array((object)array('Name'=>'Bob')), $list->toArray(), 'List should only contain Bob');
742
    }
743
744
    /**
745
     * $list->filter('Name', array('Steve', 'John'); // Steve and John in list
746
     */
747
    public function testSimpleFilterWithMultiple()
748
    {
749
        $list = new ArrayList(
750
            array(
751
            array('Name' => 'Steve'),
752
            (object) array('Name' => 'Bob'),
753
            array('Name' => 'John')
754
            )
755
        );
756
757
        $expected = array(
758
            array('Name' => 'Steve'),
759
            array('Name' => 'John')
760
        );
761
        $list = $list->filter('Name', array('Steve','John'));
762
        $this->assertEquals($expected, $list->toArray(), 'List should only contain Steve and John');
763
    }
764
765
    /**
766
     * $list->filter('Name', array('Steve', 'John'); // negative version
767
     */
768
    public function testSimpleFilterWithMultipleNoMatch()
769
    {
770
        $list = new ArrayList(
771
            array(
772
            array('Name' => 'Steve', 'ID' => 1),
773
            (object) array('Name' => 'Steve', 'ID' => 2),
774
            array('Name' => 'John', 'ID' => 2)
775
            )
776
        );
777
        $list = $list->filter(array('Name'=>'Clair'));
778
        $this->assertEquals(array(), $list->toArray(), 'List should be empty');
779
    }
780
781
    /**
782
     * $list->filter(array('Name'=>'bob, 'Age'=>21)); // bob with the Age 21 in list
783
     */
784
    public function testMultipleFilter()
785
    {
786
        $list = new ArrayList(
787
            array(
788
            array('Name' => 'Steve', 'ID' => 1),
789
            (object) array('Name' => 'Steve', 'ID' => 2),
790
            array('Name' => 'John', 'ID' => 2)
791
            )
792
        );
793
        $list = $list->filter(array('Name'=>'Steve', 'ID'=>2));
794
        $this->assertEquals(
795
            array((object)array('Name'=>'Steve', 'ID'=>2)),
796
            $list->toArray(),
797
            'List should only contain object Steve'
798
        );
799
    }
800
801
    /**
802
     * $list->filter(array('Name'=>'bob, 'Age'=>21)); // negative version
803
     */
804
    public function testMultipleFilterNoMatch()
805
    {
806
        $list = new ArrayList(
807
            array(
808
            array('Name' => 'Steve', 'ID' => 1),
809
            (object) array('Name' => 'Steve', 'ID' => 2),
810
            array('Name' => 'John', 'ID' => 2)
811
            )
812
        );
813
        $list = $list->filter(array('Name'=>'Steve', 'ID'=>4));
814
        $this->assertEquals(array(), $list->toArray(), 'List should be empty');
815
    }
816
817
    /**
818
     * $list->filter(array('Name'=>'Steve', 'Age'=>array(21, 43))); // Steve with the Age 21 or 43
819
     */
820
    public function testMultipleWithArrayFilter()
821
    {
822
        $list = new ArrayList(
823
            array(
824
            array('Name' => 'Steve', 'ID' => 1, 'Age'=>21),
825
            array('Name' => 'Steve', 'ID' => 2, 'Age'=>18),
826
            array('Name' => 'Clair', 'ID' => 2, 'Age'=>21),
827
            array('Name' => 'Steve', 'ID' => 3, 'Age'=>43)
828
            )
829
        );
830
831
        $list = $list->filter(array('Name'=>'Steve','Age'=>array(21, 43)));
832
833
        $expected = array(
834
            array('Name' => 'Steve', 'ID' => 1, 'Age'=>21),
835
            array('Name' => 'Steve', 'ID' => 3, 'Age'=>43)
836
        );
837
        $this->assertEquals(2, $list->count());
838
        $this->assertEquals($expected, $list->toArray(), 'List should only contain Steve and Steve');
839
    }
840
841
    /**
842
     * $list->filter(array('Name'=>array('aziz','bob'), 'Age'=>array(21, 43)));
843
     */
844
    public function testMultipleWithArrayFilterAdvanced()
845
    {
846
        $list = new ArrayList(
847
            array(
848
            array('Name' => 'Steve', 'ID' => 1, 'Age'=>21),
849
            array('Name' => 'Steve', 'ID' => 2, 'Age'=>18),
850
            array('Name' => 'Clair', 'ID' => 2, 'Age'=>21),
851
            array('Name' => 'Clair', 'ID' => 2, 'Age'=>52),
852
            array('Name' => 'Steve', 'ID' => 3, 'Age'=>43)
853
            )
854
        );
855
856
        $list = $list->filter(array('Name'=>array('Steve','Clair'),'Age'=>array(21, 43)));
857
858
        $expected = array(
859
            array('Name' => 'Steve', 'ID' => 1, 'Age'=>21),
860
            array('Name' => 'Clair', 'ID' => 2, 'Age'=>21),
861
            array('Name' => 'Steve', 'ID' => 3, 'Age'=>43)
862
        );
863
864
        $this->assertEquals(3, $list->count());
865
        $this->assertEquals($expected, $list->toArray(), 'List should only contain Steve and Steve and Clair');
866
    }
867
868
    public function testFilterAny()
869
    {
870
871
        $list = new ArrayList(
872
            array(
873
            $steve = array('Name' => 'Steve', 'ID' => 1, 'Age' => 21),
874
            $bob = array('Name' => 'Bob', 'ID' => 2, 'Age' => 18),
875
            $clair = array('Name' => 'Clair', 'ID' => 3, 'Age' => 21),
876
            $phil = array('Name' => 'Phil', 'ID' => 4, 'Age' => 21),
877
            $oscar = array('Name' => 'Oscar', 'ID' => 5, 'Age' => 52),
0 ignored issues
show
Unused Code introduced by
The assignment to $oscar is dead and can be removed.
Loading history...
878
            $mike = array('Name' => 'Mike', 'ID' => 6, 'Age' => 43),
879
            )
880
        );
881
882
        // only bob in the list
883
        //$list = $list->filterAny('Name', 'bob');
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
884
        $filteredList = $list->filterAny('Name', 'Bob')->toArray();
885
        $this->assertCount(1, $filteredList);
886
        $this->assertContains($bob, $filteredList);
887
888
        // azis or bob in the list
889
        //$list = $list->filterAny('Name', array('aziz', 'bob');
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
890
        $filteredList = $list->filterAny('Name', array('Aziz', 'Bob'))->toArray();
891
        $this->assertCount(1, $filteredList);
892
        $this->assertContains($bob, $filteredList);
893
894
        $filteredList = $list->filterAny('Name', array('Steve', 'Bob'))->toArray();
895
        $this->assertCount(2, $filteredList);
896
        $this->assertContains($steve, $filteredList);
897
        $this->assertContains($bob, $filteredList);
898
899
        // bob or anyone aged 21 in the list
900
        //$list = $list->filterAny(array('Name'=>'bob, 'Age'=>21));
901
        $filteredList = $list->filterAny(array('Name' => 'Bob', 'Age' => 21))->toArray();
902
        $this->assertCount(4, $filteredList);
903
        $this->assertContains($bob, $filteredList);
904
        $this->assertContains($steve, $filteredList);
905
        $this->assertContains($clair, $filteredList);
906
        $this->assertContains($phil, $filteredList);
907
908
        // bob or anyone aged 21 or 43 in the list
909
        // $list = $list->filterAny(array('Name'=>'bob, 'Age'=>array(21, 43)));
910
        $filteredList = $list->filterAny(array('Name' => 'Bob', 'Age' => array(21, 43)))->toArray();
911
        $this->assertCount(5, $filteredList);
912
        $this->assertContains($bob, $filteredList);
913
        $this->assertContains($steve, $filteredList);
914
        $this->assertContains($clair, $filteredList);
915
        $this->assertContains($mike, $filteredList);
916
        $this->assertContains($phil, $filteredList);
917
918
        // all bobs, phils or anyone aged 21 or 43 in the list
919
        //$list = $list->filterAny(array('Name'=>array('bob','phil'), 'Age'=>array(21, 43)));
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
920
        $filteredList = $list->filterAny(array('Name' => array('Bob', 'Phil'), 'Age' => array(21, 43)))->toArray();
921
        $this->assertCount(5, $filteredList);
922
        $this->assertContains($bob, $filteredList);
923
        $this->assertContains($steve, $filteredList);
924
        $this->assertContains($clair, $filteredList);
925
        $this->assertContains($mike, $filteredList);
926
        $this->assertContains($phil, $filteredList);
927
928
        $filteredList = $list->filterAny(array('Name' => array('Bob', 'Nobody'), 'Age' => array(21, 43)))->toArray();
929
        $this->assertCount(5, $filteredList);
930
        $this->assertContains($bob, $filteredList);
931
        $this->assertContains($steve, $filteredList);
932
        $this->assertContains($clair, $filteredList);
933
        $this->assertContains($mike, $filteredList);
934
        $this->assertContains($phil, $filteredList);
935
    }
936
937
    /**
938
     * $list = $list->filterByCallback(function($item, $list) { return $item->Age == 21; })
939
     */
940
    public function testFilterByCallback()
941
    {
942
        $list = new ArrayList(
943
            array(
944
            $steve = array('Name' => 'Steve', 'ID' => 1, 'Age' => 21),
945
            array('Name' => 'Bob', 'ID' => 2, 'Age' => 18),
946
            $clair = array('Name' => 'Clair', 'ID' => 2, 'Age' => 21),
947
            array('Name' => 'Oscar', 'ID' => 2, 'Age' => 52),
948
            array('Name' => 'Mike', 'ID' => 3, 'Age' => 43)
949
            )
950
        );
951
952
        $list = $list->filterByCallback(
953
            function ($item, $list) {
0 ignored issues
show
Unused Code introduced by
The parameter $list is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

953
            function ($item, /** @scrutinizer ignore-unused */ $list) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
954
                return $item->Age == 21;
955
            }
956
        );
957
958
        $this->assertEquals(2, $list->count());
959
        $this->assertEquals($steve, $list[0]->toMap(), 'List should only contain Steve and Clair');
960
        $this->assertEquals($clair, $list[1]->toMap(), 'List should only contain Steve and Clair');
961
        $this->assertTrue($list instanceof Filterable, 'The List should be of type SS_Filterable');
962
    }
963
964
    /**
965
     * $list->exclude('Name', 'bob'); // exclude bob from list
966
     */
967
    public function testSimpleExclude()
968
    {
969
        $list = new ArrayList(
970
            array(
971
            array('Name' => 'Steve'),
972
            array('Name' => 'Bob'),
973
            array('Name' => 'John')
974
            )
975
        );
976
977
        $list = $list->exclude('Name', 'Bob');
978
        $expected = array(
979
            array('Name' => 'Steve'),
980
            array('Name' => 'John')
981
        );
982
        $this->assertEquals(2, $list->count());
983
        $this->assertEquals($expected, $list->toArray(), 'List should not contain Bob');
984
    }
985
986
    /**
987
     * $list->exclude('Name', 'bob'); // No exclusion version
988
     */
989
    public function testSimpleExcludeNoMatch()
990
    {
991
        $list = new ArrayList(
992
            array(
993
            array('Name' => 'Steve'),
994
            array('Name' => 'Bob'),
995
            array('Name' => 'John')
996
            )
997
        );
998
999
        $list = $list->exclude('Name', 'Clair');
1000
        $expected = array(
1001
            array('Name' => 'Steve'),
1002
            array('Name' => 'Bob'),
1003
            array('Name' => 'John')
1004
        );
1005
        $this->assertEquals($expected, $list->toArray(), 'List should be unchanged');
1006
    }
1007
1008
    /**
1009
     * $list->exclude('Name', array('Steve','John'));
1010
     */
1011
    public function testSimpleExcludeWithArray()
1012
    {
1013
        $list = new ArrayList(
1014
            array(
1015
            array('Name' => 'Steve'),
1016
            array('Name' => 'Bob'),
1017
            array('Name' => 'John')
1018
            )
1019
        );
1020
        $list = $list->exclude('Name', array('Steve','John'));
1021
        $expected = array(array('Name' => 'Bob'));
1022
        $this->assertEquals(1, $list->count());
1023
        $this->assertEquals($expected, $list->toArray(), 'List should only contain Bob');
1024
    }
1025
1026
    /**
1027
     * $list->exclude(array('Name'=>'bob, 'Age'=>21)); // exclude all Bob that has Age 21
1028
     */
1029
    public function testExcludeWithTwoArrays()
1030
    {
1031
        $list = new ArrayList(
1032
            array(
1033
            array('Name' => 'Bob' , 'Age' => 21),
1034
            array('Name' => 'Bob' , 'Age' => 32),
1035
            array('Name' => 'John', 'Age' => 21)
1036
            )
1037
        );
1038
1039
        $list = $list->exclude(array('Name' => 'Bob', 'Age' => 21));
1040
1041
        $expected = array(
1042
            array('Name' => 'Bob', 'Age' => 32),
1043
            array('Name' => 'John', 'Age' => 21)
1044
        );
1045
1046
        $this->assertEquals(2, $list->count());
1047
        $this->assertEquals($expected, $list->toArray(), 'List should only contain John and Bob');
1048
    }
1049
1050
    /**
1051
     * $list->exclude(array('Name'=>array('bob','phil'), 'Age'=>array(10, 16)));
1052
     */
1053
    public function testMultipleExclude()
1054
    {
1055
        $list = new ArrayList(
1056
            array(
1057
            array('Name' => 'bob', 'Age' => 10),
1058
            array('Name' => 'phil', 'Age' => 11),
1059
            array('Name' => 'bob', 'Age' => 12),
1060
            array('Name' => 'phil', 'Age' => 12),
1061
            array('Name' => 'bob', 'Age' => 14),
1062
            array('Name' => 'phil', 'Age' => 14),
1063
            array('Name' => 'bob', 'Age' => 16),
1064
            array('Name' => 'phil', 'Age' => 16)
1065
            )
1066
        );
1067
1068
        $list = $list->exclude(array('Name'=>array('bob','phil'),'Age'=>array(10, 16)));
1069
        $expected = array(
1070
            array('Name' => 'phil', 'Age' => 11),
1071
            array('Name' => 'bob', 'Age' => 12),
1072
            array('Name' => 'phil', 'Age' => 12),
1073
            array('Name' => 'bob', 'Age' => 14),
1074
            array('Name' => 'phil', 'Age' => 14),
1075
        );
1076
        $this->assertEquals($expected, $list->toArray());
1077
    }
1078
1079
    /**
1080
     * $list->exclude(array('Name'=>array('bob','phil'), 'Age'=>array(10, 16), 'Bananas'=>true));
1081
     */
1082
    public function testMultipleExcludeNoMatch()
1083
    {
1084
        $list = new ArrayList(
1085
            array(
1086
            array('Name' => 'bob', 'Age' => 10),
1087
            array('Name' => 'phil', 'Age' => 11),
1088
            array('Name' => 'bob', 'Age' => 12),
1089
            array('Name' => 'phil', 'Age' => 12),
1090
            array('Name' => 'bob', 'Age' => 14),
1091
            array('Name' => 'phil', 'Age' => 14),
1092
            array('Name' => 'bob', 'Age' => 16),
1093
            array('Name' => 'phil', 'Age' => 16)
1094
            )
1095
        );
1096
1097
        $list = $list->exclude(array('Name'=>array('bob','phil'),'Age'=>array(10, 16),'Bananas'=>true));
1098
        $expected = array(
1099
            array('Name' => 'bob', 'Age' => 10),
1100
            array('Name' => 'phil', 'Age' => 11),
1101
            array('Name' => 'bob', 'Age' => 12),
1102
            array('Name' => 'phil', 'Age' => 12),
1103
            array('Name' => 'bob', 'Age' => 14),
1104
            array('Name' => 'phil', 'Age' => 14),
1105
            array('Name' => 'bob', 'Age' => 16),
1106
            array('Name' => 'phil', 'Age' => 16)
1107
        );
1108
        $this->assertEquals($expected, $list->toArray());
1109
    }
1110
1111
    /**
1112
     * $list->exclude(array('Name'=>array('bob','phil'), 'Age'=>array(10, 16), 'HasBananas'=>true));
1113
     */
1114
    public function testMultipleExcludeThreeArguments()
1115
    {
1116
        $list = new ArrayList(
1117
            array(
1118
            array('Name' => 'bob', 'Age' => 10, 'HasBananas'=>false),
1119
            array('Name' => 'phil','Age' => 11, 'HasBananas'=>true),
1120
            array('Name' => 'bob', 'Age' => 12, 'HasBananas'=>true),
1121
            array('Name' => 'phil','Age' => 12, 'HasBananas'=>true),
1122
            array('Name' => 'bob', 'Age' => 14, 'HasBananas'=>false),
1123
            array('Name' => 'ann', 'Age' => 14, 'HasBananas'=>true),
1124
            array('Name' => 'phil','Age' => 14, 'HasBananas'=>false),
1125
            array('Name' => 'bob', 'Age' => 16, 'HasBananas'=>false),
1126
            array('Name' => 'phil','Age' => 16, 'HasBananas'=>true),
1127
            array('Name' => 'clair','Age' => 16, 'HasBananas'=>true)
1128
            )
1129
        );
1130
1131
        $list = $list->exclude(array('Name'=>array('bob','phil'),'Age'=>array(10, 16),'HasBananas'=>true));
1132
        $expected = array(
1133
            array('Name' => 'bob', 'Age' => 10, 'HasBananas'=>false),
1134
            array('Name' => 'phil','Age' => 11, 'HasBananas'=>true),
1135
            array('Name' => 'bob', 'Age' => 12, 'HasBananas'=>true),
1136
            array('Name' => 'phil','Age' => 12, 'HasBananas'=>true),
1137
            array('Name' => 'bob', 'Age' => 14, 'HasBananas'=>false),
1138
            array('Name' => 'ann', 'Age' => 14, 'HasBananas'=>true),
1139
            array('Name' => 'phil','Age' => 14, 'HasBananas'=>false),
1140
            array('Name' => 'bob', 'Age' => 16, 'HasBananas'=>false),
1141
            array('Name' => 'clair','Age' => 16, 'HasBananas'=>true)
1142
        );
1143
        $this->assertEquals($expected, $list->toArray());
1144
    }
1145
1146
    public function testCanFilterBy()
1147
    {
1148
        $list = new ArrayList(
1149
            array(
1150
            array('Name' => 'Steve'),
1151
            array('Name' => 'Bob'),
1152
            array('Name' => 'John')
1153
            )
1154
        );
1155
1156
        $this->assertTrue($list->canFilterBy('Name'));
1157
        $this->assertFalse($list->canFilterBy('Age'));
1158
    }
1159
1160
    public function testCanFilterByEmpty()
1161
    {
1162
        $list = new ArrayList();
1163
1164
        $this->assertFalse($list->canFilterBy('Name'));
1165
        $this->assertFalse($list->canFilterBy('Age'));
1166
    }
1167
1168
    public function testByID()
1169
    {
1170
        $list = new ArrayList(
1171
            array(
1172
            array('ID' => 1, 'Name' => 'Steve'),
1173
            array('ID' => 2, 'Name' => 'Bob'),
1174
            array('ID' => 3, 'Name' => 'John')
1175
            )
1176
        );
1177
1178
        $element = $list->byID(1);
1179
        $this->assertEquals($element['Name'], 'Steve');
1180
1181
        $element = $list->byID(2);
1182
        $this->assertEquals($element['Name'], 'Bob');
1183
1184
        $element = $list->byID(4);
1185
        $this->assertNull($element);
1186
    }
1187
1188
    public function testByIDs()
1189
    {
1190
        $list = new ArrayList(
1191
            array(
1192
            array('ID' => 1, 'Name' => 'Steve'),
1193
            array('ID' => 2, 'Name' => 'Bob'),
1194
            array('ID' => 3, 'Name' => 'John')
1195
            )
1196
        );
1197
        $knownIDs = $list->column('ID');
1198
        $removedID = array_pop($knownIDs);
1199
        $filteredItems = $list->byIDs($knownIDs);
1200
        foreach ($filteredItems as $item) {
1201
            $this->assertContains($item->ID, $knownIDs);
1202
            $this->assertNotEquals($removedID, $item->ID);
1203
        }
1204
    }
1205
1206
    public function testByIDEmpty()
1207
    {
1208
        $list = new ArrayList();
1209
1210
        $element = $list->byID(1);
1211
        $this->assertNull($element);
1212
    }
1213
}
1214