Passed
Push — less-original ( 3c06b4...67fe41 )
by Sam
07:41 queued 24s
created

ArrayListTest::testSimpleExcludeWithArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 13
rs 9.9666
c 0
b 0
f 0
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 SilverStripe\Dev\Deprecation;
11
use stdClass;
12
13
class ArrayListTest extends SapphireTest
14
{
15
16
    public function testPushOperator()
17
    {
18
        $list = new ArrayList(
19
            array(
20
            array('Num' => 1)
21
            )
22
        );
23
24
        $list[] = array('Num' => 2);
25
        $this->assertEquals(2, count($list));
26
        $this->assertEquals(array('Num' => 2), $list->last());
27
28
        $list[] = array('Num' => 3);
29
        $this->assertEquals(3, count($list));
30
        $this->assertEquals(array('Num' => 3), $list->last());
31
    }
32
33
    public function testArrayAccessExists()
34
    {
35
        $list = new ArrayList(
36
            array(
37
            $one = new DataObject(array('Title' => 'one')),
38
            $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...
39
            $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...
40
            )
41
        );
42
        $this->assertEquals(count($list), 3);
43
        $this->assertTrue(isset($list[0]), 'First item in the set is set');
44
        $this->assertEquals($one, $list[0], 'First item in the set is accessible by array notation');
45
    }
46
47
    public function testArrayAccessUnset()
48
    {
49
        $list = new ArrayList(
50
            array(
51
            $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...
52
            $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...
53
            $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...
54
            )
55
        );
56
        unset($list[0]);
57
        $this->assertEquals(count($list), 2);
58
    }
59
60
    public function testArrayAccessSet()
61
    {
62
        $list = new ArrayList();
63
        $this->assertEquals(0, count($list));
64
        $list['testing!'] = $test = new DataObject(array('Title' => 'I\'m testing!'));
65
        $this->assertEquals($test, $list['testing!'], 'Set item is accessible by the key we set it as');
66
    }
67
68
    public function testCount()
69
    {
70
        $list = new ArrayList();
71
        $this->assertEquals(0, $list->count());
72
        $list = new ArrayList(array(1, 2, 3));
73
        $this->assertEquals(3, $list->count());
74
    }
75
76
    public function testExists()
77
    {
78
        $list = new ArrayList();
79
        $this->assertFalse($list->exists());
80
        $list = new ArrayList(array(1, 2, 3));
81
        $this->assertTrue($list->exists());
82
    }
83
84
    public function testToNestedArray()
85
    {
86
        $list = new ArrayList(
87
            array(
88
            array('First' => 'FirstFirst', 'Second' => 'FirstSecond'),
89
            (object) array('First' => 'SecondFirst', 'Second' => 'SecondSecond'),
90
            new ArrayListTest\TestObject('ThirdFirst', 'ThirdSecond')
91
            )
92
        );
93
94
        $this->assertEquals(
95
            $list->toNestedArray(),
96
            array(
97
            array('First' => 'FirstFirst', 'Second' => 'FirstSecond'),
98
            array('First' => 'SecondFirst', 'Second' => 'SecondSecond'),
99
            array('First' => 'ThirdFirst', 'Second' => 'ThirdSecond')
100
            )
101
        );
102
    }
103
104
    public function testEach()
105
    {
106
        $list = new ArrayList(array(1, 2, 3));
107
108
        $count = 0;
109
        $test = $this;
110
111
        $list->each(
112
            function ($item) use (&$count, $test) {
113
                $count++;
114
115
                $test->assertTrue(is_int($item));
116
            }
117
        );
118
119
        $this->assertEquals($list->Count(), $count);
120
    }
121
122
    public function testLimit()
123
    {
124
        $list = new ArrayList(
125
            array(
126
            array('Key' => 1), array('Key' => 2), array('Key' => 3)
127
            )
128
        );
129
        $this->assertEquals(
130
            $list->limit(2, 1)->toArray(),
131
            array(
132
            array('Key' => 2), array('Key' => 3)
133
            )
134
        );
135
    }
136
137
    /**
138
     * @expectedException PHPUnit_Framework_Error
139
     */
140
    public function testZeroLimit()
141
    {
142
        Deprecation::notification_version('4.3.0');
143
        $list = new ArrayList([
144
            ['Key' => 1],
145
            ['Key' => 2],
146
        ]);
147
        $list->limit(0);
148
    }
149
150
    public function testAddRemove()
151
    {
152
        $list = new ArrayList(
153
            array(
154
            array('Key' => 1), array('Key' => 2)
155
            )
156
        );
157
158
        $list->add(array('Key' => 3));
159
        $this->assertEquals(
160
            $list->toArray(),
161
            array(
162
            array('Key' => 1), array('Key' => 2), array('Key' => 3)
163
            )
164
        );
165
166
        $list->remove(array('Key' => 2));
167
        $this->assertEquals(
168
            array_values($list->toArray()),
169
            array(
170
            array('Key' => 1), array('Key' => 3)
171
            )
172
        );
173
    }
174
175
    public function testReplace()
176
    {
177
        $list = new ArrayList(
178
            array(
179
            array('Key' => 1),
180
            $two = (object) array('Key' => 2),
181
            (object) array('Key' => 3)
182
            )
183
        );
184
185
        $this->assertEquals(array('Key' => 1), $list[0]);
186
        $list->replace(array('Key' => 1), array('Replaced' => 1));
187
        $this->assertEquals(3, count($list));
188
        $this->assertEquals(array('Replaced' => 1), $list[0]);
189
190
        $this->assertEquals($two, $list[1]);
191
        $list->replace($two, array('Replaced' => 2));
192
        $this->assertEquals(3, count($list));
193
        $this->assertEquals(array('Replaced' => 2), $list[1]);
194
    }
195
196
    public function testMerge()
197
    {
198
        $list = new ArrayList(
199
            array(
200
            array('Num' => 1), array('Num' => 2)
201
            )
202
        );
203
        $list->merge(
204
            array(
205
            array('Num' => 3), array('Num' => 4)
206
            )
207
        );
208
209
        $this->assertEquals(4, count($list));
210
        $this->assertEquals(
211
            $list->toArray(),
212
            array(
213
            array('Num' => 1), array('Num' => 2), array('Num' => 3), array('Num' => 4)
214
            )
215
        );
216
    }
217
218
    public function testRemoveDuplicates()
219
    {
220
        $list = new ArrayList(
221
            array(
222
            array('ID' => 1, 'Field' => 1),
223
            array('ID' => 2, 'Field' => 2),
224
            array('ID' => 3, 'Field' => 3),
225
            array('ID' => 4, 'Field' => 1),
226
            (object) array('ID' => 5, 'Field' => 2)
227
            )
228
        );
229
230
        $this->assertEquals(5, count($list));
231
        $list->removeDuplicates();
232
        $this->assertEquals(5, count($list));
233
234
        $list->removeDuplicates('Field');
235
        $this->assertEquals(3, count($list));
236
        $this->assertEquals(array(1, 2, 3), $list->column('Field'));
237
        $this->assertEquals(array(1, 2, 3), $list->column('ID'));
238
    }
239
240
    public function testPushPop()
241
    {
242
        $list = new ArrayList(array('Num' => 1));
243
        $this->assertEquals(1, count($list));
244
245
        $list->push(array('Num' => 2));
246
        $this->assertEquals(2, count($list));
247
        $this->assertEquals(array('Num' => 2), $list->last());
248
249
        $list->push(array('Num' => 3));
250
        $this->assertEquals(3, count($list));
251
        $this->assertEquals(array('Num' => 3), $list->last());
252
253
        $this->assertEquals(array('Num' => 3), $list->pop());
254
        $this->assertEquals(2, count($list));
255
        $this->assertEquals(array('Num' => 2), $list->last());
256
    }
257
258
    public function testShiftUnshift()
259
    {
260
        $list = new ArrayList(array('Num' => 1));
261
        $this->assertEquals(1, count($list));
262
263
        $list->unshift(array('Num' => 2));
264
        $this->assertEquals(2, count($list));
265
        $this->assertEquals(array('Num' => 2), $list->first());
266
267
        $list->unshift(array('Num' => 3));
268
        $this->assertEquals(3, count($list));
269
        $this->assertEquals(array('Num' => 3), $list->first());
270
271
        $this->assertEquals(array('Num' => 3), $list->shift());
272
        $this->assertEquals(2, count($list));
273
        $this->assertEquals(array('Num' => 2), $list->first());
274
    }
275
276
    public function testFirstLast()
277
    {
278
        $list = new ArrayList(
279
            array(
280
            array('Key' => 1), array('Key' => 2), array('Key' => 3)
281
            )
282
        );
283
        $this->assertEquals($list->first(), array('Key' => 1));
284
        $this->assertEquals($list->last(), array('Key' => 3));
285
    }
286
287
    public function testMap()
288
    {
289
        $list = new ArrayList(
290
            array(
291
            array('ID' => 1, 'Name' => 'Steve',),
292
            (object) array('ID' => 3, 'Name' => 'Bob'),
293
            array('ID' => 5, 'Name' => 'John')
294
            )
295
        );
296
        $map = $list->map('ID', 'Name');
297
        // Items added after calling map should not be included retroactively
298
        $list->add(array('ID' => 7, 'Name' => 'Andrew'));
299
        $this->assertInstanceOf('SilverStripe\\ORM\\Map', $map);
300
        $this->assertEquals(
301
            array(
302
            1 => 'Steve',
303
            3 => 'Bob',
304
            5 => 'John'
305
            ),
306
            $map->toArray()
307
        );
308
    }
309
310
    public function testFind()
311
    {
312
        $list = new ArrayList(
313
            array(
314
            array('Name' => 'Steve'),
315
            (object) array('Name' => 'Bob'),
316
            array('Name' => 'John')
317
            )
318
        );
319
        $this->assertEquals(
320
            $list->find('Name', 'Bob'),
321
            (object) array(
322
            'Name' => 'Bob'
323
            )
324
        );
325
    }
326
327
    public function testColumn()
328
    {
329
        $list = new ArrayList(
330
            array(
331
            array('Name' => 'Steve'),
332
            (object) array('Name' => 'Bob'),
333
            array('Name' => 'John')
334
            )
335
        );
336
        $this->assertEquals(
337
            $list->column('Name'),
338
            array(
339
            'Steve', 'Bob', 'John'
340
            )
341
        );
342
    }
343
344
    public function testSortSimpleDefaultIsSortedASC()
345
    {
346
        $list = new ArrayList(
347
            array(
348
            array('Name' => 'Steve'),
349
            (object) array('Name' => 'Bob'),
350
            array('Name' => 'John'),
351
            array('Name' => 'bonny'),
352
            )
353
        );
354
355
        // Unquoted name
356
        $list1 = $list->sort('Name');
357
        $this->assertEquals(
358
            array(
359
            (object) array('Name' => 'Bob'),
360
            array('Name' => 'bonny'),
361
            array('Name' => 'John'),
362
            array('Name' => 'Steve'),
363
            ),
364
            $list1->toArray()
365
        );
366
367
        // Quoted name name
368
        $list2 = $list->sort('"Name"');
369
        $this->assertEquals(
370
            array(
371
            (object) array('Name' => 'Bob'),
372
            array('Name' => 'bonny'),
373
            array('Name' => 'John'),
374
            array('Name' => 'Steve'),
375
            ),
376
            $list2->toArray()
377
        );
378
379
        // Array (non-associative)
380
        $list3 = $list->sort(array('"Name"'));
381
        $this->assertEquals(
382
            array(
383
            (object) array('Name' => 'Bob'),
384
            array('Name' => 'bonny'),
385
            array('Name' => 'John'),
386
            array('Name' => 'Steve'),
387
            ),
388
            $list3->toArray()
389
        );
390
391
        // Quoted name name with table
392
        $list4 = $list->sort('"Record"."Name"');
393
        $this->assertEquals(
394
            array(
395
            (object) array('Name' => 'Bob'),
396
            array('Name' => 'bonny'),
397
            array('Name' => 'John'),
398
            array('Name' => 'Steve')
399
            ),
400
            $list4->toArray()
401
        );
402
403
        // Quoted name name with table (desc)
404
        $list5 = $list->sort('"Record"."Name" DESC');
405
        $this->assertEquals(
406
            array(
407
            array('Name' => 'Steve'),
408
            array('Name' => 'John'),
409
            array('Name' => 'bonny'),
410
            (object) array('Name' => 'Bob')
411
            ),
412
            $list5->toArray()
413
        );
414
415
        // Table without quotes
416
        $list6 = $list->sort('Record.Name');
417
        $this->assertEquals(
418
            array(
419
            (object) array('Name' => 'Bob'),
420
            array('Name' => 'bonny'),
421
            array('Name' => 'John'),
422
            array('Name' => 'Steve')
423
            ),
424
            $list6->toArray()
425
        );
426
427
        // Check original list isn't altered
428
        $this->assertEquals(
429
            array(
430
            array('Name' => 'Steve'),
431
            (object) array('Name' => 'Bob'),
432
            array('Name' => 'John'),
433
            array('Name' => 'bonny'),
434
            ),
435
            $list->toArray()
436
        );
437
    }
438
439
    public function testMixedCaseSort()
440
    {
441
        // Note: Natural sorting is not expected, so if 'bonny10' were included
442
        // below we would expect it to appear between bonny1 and bonny2. That's
443
        // undesirable though so we're not enforcing it in tests.
444
        $original = array(
445
            array('Name' => 'Steve'),
446
            (object) array('Name' => 'Bob'),
447
            array('Name' => 'John'),
448
            array('Name' => 'bonny'),
449
            array('Name' => 'bonny1'),
450
            //array('Name' => 'bonny10'),
451
            array('Name' => 'bonny2'),
452
        );
453
454
        $list = new ArrayList($original);
455
456
        $expected = array(
457
            (object) array('Name' => 'Bob'),
458
            array('Name' => 'bonny'),
459
            array('Name' => 'bonny1'),
460
            //array('Name' => 'bonny10'),
461
            array('Name' => 'bonny2'),
462
            array('Name' => 'John'),
463
            array('Name' => 'Steve'),
464
        );
465
466
        // Unquoted name
467
        $list1 = $list->sort('Name');
468
        $this->assertEquals($expected, $list1->toArray());
469
470
        // Quoted name name
471
        $list2 = $list->sort('"Name"');
472
        $this->assertEquals($expected, $list2->toArray());
473
474
        // Array (non-associative)
475
        $list3 = $list->sort(array('"Name"'));
476
        $this->assertEquals($expected, $list3->toArray());
477
478
        // Check original list isn't altered
479
        $this->assertEquals($original, $list->toArray());
480
    }
481
482
    public function testSortSimpleASCOrder()
483
    {
484
        $list = new ArrayList(
485
            array(
486
            array('Name' => 'Steve'),
487
            (object) array('Name' => 'Bob'),
488
            array('Name' => 'John')
489
            )
490
        );
491
492
        // Sort two arguments
493
        $list1 = $list->sort('Name', 'ASC');
494
        $this->assertEquals(
495
            $list1->toArray(),
496
            array(
497
            (object) array('Name' => 'Bob'),
498
            array('Name' => 'John'),
499
            array('Name' => 'Steve')
500
            )
501
        );
502
503
        // Sort single string
504
        $list2 = $list->sort('Name asc');
505
        $this->assertEquals(
506
            $list2->toArray(),
507
            array(
508
            (object) array('Name' => 'Bob'),
509
            array('Name' => 'John'),
510
            array('Name' => 'Steve')
511
            )
512
        );
513
514
        // Sort quoted string
515
        $list3 = $list->sort('"Name" ASCENDING');
516
        $this->assertEquals(
517
            $list3->toArray(),
518
            array(
519
            (object) array('Name' => 'Bob'),
520
            array('Name' => 'John'),
521
            array('Name' => 'Steve')
522
            )
523
        );
524
525
        // Sort array specifier
526
        $list4 = $list->sort(array('Name' => 'ascending'));
527
        $this->assertEquals(
528
            $list4->toArray(),
529
            array(
530
            (object) array('Name' => 'Bob'),
531
            array('Name' => 'John'),
532
            array('Name' => 'Steve')
533
            )
534
        );
535
536
        // Check original list isn't altered
537
        $this->assertEquals(
538
            $list->toArray(),
539
            array(
540
            array('Name' => 'Steve'),
541
            (object) array('Name' => 'Bob'),
542
            array('Name' => 'John')
543
            )
544
        );
545
    }
546
547
    public function testSortSimpleDESCOrder()
548
    {
549
        $list = new ArrayList(
550
            array(
551
            array('Name' => 'Steve'),
552
            (object) array('Name' => 'Bob'),
553
            array('Name' => 'John')
554
            )
555
        );
556
557
        // Sort two arguments
558
        $list1 = $list->sort('Name', 'DESC');
559
        $this->assertEquals(
560
            $list1->toArray(),
561
            array(
562
            array('Name' => 'Steve'),
563
            array('Name' => 'John'),
564
            (object) array('Name' => 'Bob')
565
            )
566
        );
567
568
        // Sort single string
569
        $list2 = $list->sort('Name desc');
570
        $this->assertEquals(
571
            $list2->toArray(),
572
            array(
573
            array('Name' => 'Steve'),
574
            array('Name' => 'John'),
575
            (object) array('Name' => 'Bob')
576
            )
577
        );
578
579
        // Sort quoted string
580
        $list3 = $list->sort('"Name" DESCENDING');
581
        $this->assertEquals(
582
            $list3->toArray(),
583
            array(
584
            array('Name' => 'Steve'),
585
            array('Name' => 'John'),
586
            (object) array('Name' => 'Bob')
587
            )
588
        );
589
590
        // Sort array specifier
591
        $list4 = $list->sort(array('Name' => 'descending'));
592
        $this->assertEquals(
593
            $list4->toArray(),
594
            array(
595
            array('Name' => 'Steve'),
596
            array('Name' => 'John'),
597
            (object) array('Name' => 'Bob')
598
            )
599
        );
600
601
        // Check original list isn't altered
602
        $this->assertEquals(
603
            $list->toArray(),
604
            array(
605
            array('Name' => 'Steve'),
606
            (object) array('Name' => 'Bob'),
607
            array('Name' => 'John')
608
            )
609
        );
610
    }
611
612
    public function testSortNumeric()
613
    {
614
        $list = new ArrayList(
615
            array(
616
            array('Sort' => 0),
617
            array('Sort' => -1),
618
            array('Sort' => 1),
619
            array('Sort' => -2),
620
            array('Sort' => 2),
621
            array('Sort' => -10),
622
            array('Sort' => 10)
623
            )
624
        );
625
626
        // Sort descending
627
        $list1 = $list->sort('Sort', 'DESC');
628
        $this->assertEquals(
629
            array(
630
            array('Sort' => 10),
631
            array('Sort' => 2),
632
            array('Sort' => 1),
633
            array('Sort' => 0),
634
            array('Sort' => -1),
635
            array('Sort' => -2),
636
            array('Sort' => -10)
637
            ),
638
            $list1->toArray()
639
        );
640
641
        // Sort ascending
642
        $list1 = $list->sort('Sort', 'ASC');
643
        $this->assertEquals(
644
            array(
645
            array('Sort' => -10),
646
            array('Sort' => -2),
647
            array('Sort' => -1),
648
            array('Sort' => 0),
649
            array('Sort' => 1),
650
            array('Sort' => 2),
651
            array('Sort' => 10)
652
            ),
653
            $list1->toArray()
654
        );
655
    }
656
657
    public function testReverse()
658
    {
659
        $list = new ArrayList(
660
            array(
661
            array('Name' => 'John'),
662
            array('Name' => 'Bob'),
663
            array('Name' => 'Steve')
664
            )
665
        );
666
667
        $list = $list->sort('Name', 'ASC');
668
        $list = $list->reverse();
669
670
        $this->assertEquals(
671
            $list->toArray(),
672
            array(
673
            array('Name' => 'Steve'),
674
            array('Name' => 'John'),
675
            array('Name' => 'Bob')
676
            )
677
        );
678
    }
679
680
    public function testSimpleMultiSort()
681
    {
682
        $list = new ArrayList(
683
            array(
684
            (object) array('Name'=>'Object1', 'F1'=>1, 'F2'=>2, 'F3'=>3),
685
            (object) array('Name'=>'Object2', 'F1'=>2, 'F2'=>1, 'F3'=>4),
686
            (object) array('Name'=>'Object3', 'F1'=>5, 'F2'=>2, 'F3'=>2),
687
            )
688
        );
689
690
        $list = $list->sort('F3', 'ASC');
691
        $this->assertEquals($list->first()->Name, 'Object3', 'Object3 should be first in the list');
692
        $this->assertEquals($list->last()->Name, 'Object2', 'Object2 should be last in the list');
693
694
        $list = $list->sort('F3', 'DESC');
695
        $this->assertEquals($list->first()->Name, 'Object2', 'Object2 should be first in the list');
696
        $this->assertEquals($list->last()->Name, 'Object3', 'Object3 should be last in the list');
697
    }
698
699
    public function testMultiSort()
700
    {
701
        $list = new ArrayList(
702
            array(
703
            (object) array('ID'=>3, 'Name'=>'Bert', 'Importance'=>1),
704
            (object) array('ID'=>1, 'Name'=>'Aron', 'Importance'=>2),
705
            (object) array('ID'=>2, 'Name'=>'Aron', 'Importance'=>1),
706
            )
707
        );
708
709
        $list = $list->sort(array('Name'=>'ASC', 'Importance'=>'ASC'));
710
        $this->assertEquals($list->first()->ID, 2, 'Aron.2 should be first in the list');
711
        $this->assertEquals($list->last()->ID, 3, 'Bert.3 should be last in the list');
712
713
        $list = $list->sort(array('Name'=>'ASC', 'Importance'=>'DESC'));
714
        $this->assertEquals($list->first()->ID, 1, 'Aron.2 should be first in the list');
715
        $this->assertEquals($list->last()->ID, 3, 'Bert.3 should be last in the list');
716
    }
717
718
    /**
719
     * Check that we don't cause recursion errors with array_multisort() and circular dependencies
720
     */
721
    public function testSortWithCircularDependencies()
722
    {
723
        $itemA = new stdClass;
724
        $childA = new stdClass;
725
        $itemA->child = $childA;
726
        $childA->parent = $itemA;
727
        $itemA->Sort = 1;
728
729
        $itemB = new stdClass;
730
        $childB = new stdClass;
731
        $itemB->child = $childB;
732
        $childB->parent = $itemB;
733
        $itemB->Sort = 1;
734
735
        $items = new ArrayList;
736
        $items->add($itemA);
737
        $items->add($itemB);
738
739
        // This call will trigger a fatal error if there are issues with circular dependencies
740
        $items->sort('Sort');
741
    }
742
    /**
743
     * $list->filter('Name', 'bob'); // only bob in the list
744
     */
745
    public function testSimpleFilter()
746
    {
747
        $list = new ArrayList(
748
            array(
749
            array('Name' => 'Steve'),
750
            (object) array('Name' => 'Bob'),
751
            array('Name' => 'John')
752
            )
753
        );
754
        $list = $list->filter('Name', 'Bob');
755
        $this->assertEquals(array((object)array('Name'=>'Bob')), $list->toArray(), 'List should only contain Bob');
756
    }
757
758
    /**
759
     * $list->filter('Name', array('Steve', 'John'); // Steve and John in list
760
     */
761
    public function testSimpleFilterWithMultiple()
762
    {
763
        $list = new ArrayList(
764
            array(
765
            array('Name' => 'Steve'),
766
            (object) array('Name' => 'Bob'),
767
            array('Name' => 'John')
768
            )
769
        );
770
771
        $expected = array(
772
            array('Name' => 'Steve'),
773
            array('Name' => 'John')
774
        );
775
        $list = $list->filter('Name', array('Steve','John'));
776
        $this->assertEquals($expected, $list->toArray(), 'List should only contain Steve and John');
777
    }
778
779
    /**
780
     * $list->filter('Name', array('Steve', 'John'); // negative version
781
     */
782
    public function testSimpleFilterWithMultipleNoMatch()
783
    {
784
        $list = new ArrayList(
785
            array(
786
            array('Name' => 'Steve', 'ID' => 1),
787
            (object) array('Name' => 'Steve', 'ID' => 2),
788
            array('Name' => 'John', 'ID' => 2)
789
            )
790
        );
791
        $list = $list->filter(array('Name'=>'Clair'));
792
        $this->assertEquals(array(), $list->toArray(), 'List should be empty');
793
    }
794
795
    /**
796
     * $list->filter(array('Name'=>'bob, 'Age'=>21)); // bob with the Age 21 in list
797
     */
798
    public function testMultipleFilter()
799
    {
800
        $list = new ArrayList(
801
            array(
802
            array('Name' => 'Steve', 'ID' => 1),
803
            (object) array('Name' => 'Steve', 'ID' => 2),
804
            array('Name' => 'John', 'ID' => 2)
805
            )
806
        );
807
        $list = $list->filter(array('Name'=>'Steve', 'ID'=>2));
808
        $this->assertEquals(
809
            array((object)array('Name'=>'Steve', 'ID'=>2)),
810
            $list->toArray(),
811
            'List should only contain object Steve'
812
        );
813
    }
814
815
    /**
816
     * $list->filter(array('Name'=>'bob, 'Age'=>21)); // negative version
817
     */
818
    public function testMultipleFilterNoMatch()
819
    {
820
        $list = new ArrayList(
821
            array(
822
            array('Name' => 'Steve', 'ID' => 1),
823
            (object) array('Name' => 'Steve', 'ID' => 2),
824
            array('Name' => 'John', 'ID' => 2)
825
            )
826
        );
827
        $list = $list->filter(array('Name'=>'Steve', 'ID'=>4));
828
        $this->assertEquals(array(), $list->toArray(), 'List should be empty');
829
    }
830
831
    /**
832
     * $list->filter(array('Name'=>'Steve', 'Age'=>array(21, 43))); // Steve with the Age 21 or 43
833
     */
834
    public function testMultipleWithArrayFilter()
835
    {
836
        $list = new ArrayList(
837
            array(
838
            array('Name' => 'Steve', 'ID' => 1, 'Age'=>21),
839
            array('Name' => 'Steve', 'ID' => 2, 'Age'=>18),
840
            array('Name' => 'Clair', 'ID' => 2, 'Age'=>21),
841
            array('Name' => 'Steve', 'ID' => 3, 'Age'=>43)
842
            )
843
        );
844
845
        $list = $list->filter(array('Name'=>'Steve','Age'=>array(21, 43)));
846
847
        $expected = array(
848
            array('Name' => 'Steve', 'ID' => 1, 'Age'=>21),
849
            array('Name' => 'Steve', 'ID' => 3, 'Age'=>43)
850
        );
851
        $this->assertEquals(2, $list->count());
852
        $this->assertEquals($expected, $list->toArray(), 'List should only contain Steve and Steve');
853
    }
854
855
    /**
856
     * $list->filter(array('Name'=>array('aziz','bob'), 'Age'=>array(21, 43)));
857
     */
858
    public function testMultipleWithArrayFilterAdvanced()
859
    {
860
        $list = new ArrayList(
861
            array(
862
            array('Name' => 'Steve', 'ID' => 1, 'Age'=>21),
863
            array('Name' => 'Steve', 'ID' => 2, 'Age'=>18),
864
            array('Name' => 'Clair', 'ID' => 2, 'Age'=>21),
865
            array('Name' => 'Clair', 'ID' => 2, 'Age'=>52),
866
            array('Name' => 'Steve', 'ID' => 3, 'Age'=>43)
867
            )
868
        );
869
870
        $list = $list->filter(array('Name'=>array('Steve','Clair'),'Age'=>array(21, 43)));
871
872
        $expected = array(
873
            array('Name' => 'Steve', 'ID' => 1, 'Age'=>21),
874
            array('Name' => 'Clair', 'ID' => 2, 'Age'=>21),
875
            array('Name' => 'Steve', 'ID' => 3, 'Age'=>43)
876
        );
877
878
        $this->assertEquals(3, $list->count());
879
        $this->assertEquals($expected, $list->toArray(), 'List should only contain Steve and Steve and Clair');
880
    }
881
882
    public function testFilterAny()
883
    {
884
885
        $list = new ArrayList(
886
            array(
887
            $steve = array('Name' => 'Steve', 'ID' => 1, 'Age' => 21),
888
            $bob = array('Name' => 'Bob', 'ID' => 2, 'Age' => 18),
889
            $clair = array('Name' => 'Clair', 'ID' => 3, 'Age' => 21),
890
            $phil = array('Name' => 'Phil', 'ID' => 4, 'Age' => 21),
891
            $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...
892
            $mike = array('Name' => 'Mike', 'ID' => 6, 'Age' => 43),
893
            )
894
        );
895
896
        // only bob in the list
897
        //$list = $list->filterAny('Name', 'bob');
898
        $filteredList = $list->filterAny('Name', 'Bob')->toArray();
899
        $this->assertCount(1, $filteredList);
900
        $this->assertContains($bob, $filteredList);
901
902
        // azis or bob in the list
903
        //$list = $list->filterAny('Name', array('aziz', 'bob');
904
        $filteredList = $list->filterAny('Name', array('Aziz', 'Bob'))->toArray();
905
        $this->assertCount(1, $filteredList);
906
        $this->assertContains($bob, $filteredList);
907
908
        $filteredList = $list->filterAny('Name', array('Steve', 'Bob'))->toArray();
909
        $this->assertCount(2, $filteredList);
910
        $this->assertContains($steve, $filteredList);
911
        $this->assertContains($bob, $filteredList);
912
913
        // bob or anyone aged 21 in the list
914
        //$list = $list->filterAny(array('Name'=>'bob, 'Age'=>21));
915
        $filteredList = $list->filterAny(array('Name' => 'Bob', 'Age' => 21))->toArray();
916
        $this->assertCount(4, $filteredList);
917
        $this->assertContains($bob, $filteredList);
918
        $this->assertContains($steve, $filteredList);
919
        $this->assertContains($clair, $filteredList);
920
        $this->assertContains($phil, $filteredList);
921
922
        // bob or anyone aged 21 or 43 in the list
923
        // $list = $list->filterAny(array('Name'=>'bob, 'Age'=>array(21, 43)));
924
        $filteredList = $list->filterAny(array('Name' => 'Bob', 'Age' => array(21, 43)))->toArray();
925
        $this->assertCount(5, $filteredList);
926
        $this->assertContains($bob, $filteredList);
927
        $this->assertContains($steve, $filteredList);
928
        $this->assertContains($clair, $filteredList);
929
        $this->assertContains($mike, $filteredList);
930
        $this->assertContains($phil, $filteredList);
931
932
        // all bobs, phils or anyone aged 21 or 43 in the list
933
        //$list = $list->filterAny(array('Name'=>array('bob','phil'), 'Age'=>array(21, 43)));
934
        $filteredList = $list->filterAny(array('Name' => array('Bob', 'Phil'), 'Age' => array(21, 43)))->toArray();
935
        $this->assertCount(5, $filteredList);
936
        $this->assertContains($bob, $filteredList);
937
        $this->assertContains($steve, $filteredList);
938
        $this->assertContains($clair, $filteredList);
939
        $this->assertContains($mike, $filteredList);
940
        $this->assertContains($phil, $filteredList);
941
942
        $filteredList = $list->filterAny(array('Name' => array('Bob', 'Nobody'), 'Age' => array(21, 43)))->toArray();
943
        $this->assertCount(5, $filteredList);
944
        $this->assertContains($bob, $filteredList);
945
        $this->assertContains($steve, $filteredList);
946
        $this->assertContains($clair, $filteredList);
947
        $this->assertContains($mike, $filteredList);
948
        $this->assertContains($phil, $filteredList);
949
    }
950
951
    /**
952
     * $list = $list->filterByCallback(function($item, $list) { return $item->Age == 21; })
953
     */
954
    public function testFilterByCallback()
955
    {
956
        $list = new ArrayList(
957
            array(
958
            $steve = array('Name' => 'Steve', 'ID' => 1, 'Age' => 21),
959
            array('Name' => 'Bob', 'ID' => 2, 'Age' => 18),
960
            $clair = array('Name' => 'Clair', 'ID' => 2, 'Age' => 21),
961
            array('Name' => 'Oscar', 'ID' => 2, 'Age' => 52),
962
            array('Name' => 'Mike', 'ID' => 3, 'Age' => 43)
963
            )
964
        );
965
966
        $list = $list->filterByCallback(
967
            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

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