Completed
Push — master ( 61abbf...bcc21c )
by Daniel
09:54
created

ArrayListTest::testCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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

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

Loading history...
769
			return $item->Age == 21;
770
		});
771
772
		$expected = array(
773
			new ArrayData(array('Name' => 'Steve', 'ID' => 1, 'Age' => 21)),
774
			new ArrayData(array('Name' => 'Clair', 'ID' => 2, 'Age' => 21)),
775
		);
776
777
		$this->assertEquals(2, $list->count());
778
		$this->assertEquals($expected, $list->toArray(), 'List should only contain Steve and Clair');
779
		$this->assertTrue($list instanceof Filterable, 'The List should be of type SS_Filterable');
780
	}
781
782
	/**
783
	 * $list->exclude('Name', 'bob'); // exclude bob from list
784
	 */
785
	public function testSimpleExclude() {
786
		$list = new ArrayList(array(
787
			array('Name' => 'Steve'),
788
			array('Name' => 'Bob'),
789
			array('Name' => 'John')
790
		));
791
792
		$list = $list->exclude('Name', 'Bob');
793
		$expected = array(
794
			array('Name' => 'Steve'),
795
			array('Name' => 'John')
796
		);
797
		$this->assertEquals(2, $list->count());
798
		$this->assertEquals($expected, $list->toArray(), 'List should not contain Bob');
799
	}
800
801
	/**
802
	 * $list->exclude('Name', 'bob'); // No exclusion version
803
	 */
804
	public function testSimpleExcludeNoMatch() {
805
		$list = new ArrayList(array(
806
			array('Name' => 'Steve'),
807
			array('Name' => 'Bob'),
808
			array('Name' => 'John')
809
		));
810
811
		$list = $list->exclude('Name', 'Clair');
812
		$expected = array(
813
			array('Name' => 'Steve'),
814
			array('Name' => 'Bob'),
815
			array('Name' => 'John')
816
		);
817
		$this->assertEquals($expected, $list->toArray(), 'List should be unchanged');
818
	}
819
820
	/**
821
	 * $list->exclude('Name', array('Steve','John'));
822
	 */
823
	public function testSimpleExcludeWithArray() {
824
		$list = new ArrayList(array(
825
			array('Name' => 'Steve'),
826
			array('Name' => 'Bob'),
827
			array('Name' => 'John')
828
		));
829
		$list = $list->exclude('Name', array('Steve','John'));
830
		$expected = array(array('Name' => 'Bob'));
831
		$this->assertEquals(1, $list->count());
832
		$this->assertEquals($expected, $list->toArray(), 'List should only contain Bob');
833
	}
834
835
	/**
836
	 * $list->exclude(array('Name'=>'bob, 'Age'=>21)); // exclude all Bob that has Age 21
837
	 */
838
	public function testExcludeWithTwoArrays() {
839
		$list = new ArrayList(array(
840
			array('Name' => 'Bob' , 'Age' => 21),
841
			array('Name' => 'Bob' , 'Age' => 32),
842
			array('Name' => 'John', 'Age' => 21)
843
		));
844
845
		$list = $list->exclude(array('Name' => 'Bob', 'Age' => 21));
846
847
		$expected = array(
848
			array('Name' => 'Bob', 'Age' => 32),
849
			array('Name' => 'John', 'Age' => 21)
850
		);
851
852
		$this->assertEquals(2, $list->count());
853
		$this->assertEquals($expected, $list->toArray(), 'List should only contain John and Bob');
854
	}
855
856
	/**
857
	 * $list->exclude(array('Name'=>array('bob','phil'), 'Age'=>array(10, 16)));
858
	 */
859
	public function testMultipleExclude() {
860
		$list = new ArrayList(array(
861
			array('Name' => 'bob', 'Age' => 10),
862
			array('Name' => 'phil', 'Age' => 11),
863
			array('Name' => 'bob', 'Age' => 12),
864
			array('Name' => 'phil', 'Age' => 12),
865
			array('Name' => 'bob', 'Age' => 14),
866
			array('Name' => 'phil', 'Age' => 14),
867
			array('Name' => 'bob', 'Age' => 16),
868
			array('Name' => 'phil', 'Age' => 16)
869
		));
870
871
		$list = $list->exclude(array('Name'=>array('bob','phil'),'Age'=>array(10, 16)));
872
		$expected = array(
873
			array('Name' => 'phil', 'Age' => 11),
874
			array('Name' => 'bob', 'Age' => 12),
875
			array('Name' => 'phil', 'Age' => 12),
876
			array('Name' => 'bob', 'Age' => 14),
877
			array('Name' => 'phil', 'Age' => 14),
878
		);
879
		$this->assertEquals($expected, $list->toArray());
880
	}
881
882
	/**
883
	 * $list->exclude(array('Name'=>array('bob','phil'), 'Age'=>array(10, 16), 'Bananas'=>true));
884
	 */
885
	public function testMultipleExcludeNoMatch() {
886
		$list = new ArrayList(array(
887
			array('Name' => 'bob', 'Age' => 10),
888
			array('Name' => 'phil', 'Age' => 11),
889
			array('Name' => 'bob', 'Age' => 12),
890
			array('Name' => 'phil', 'Age' => 12),
891
			array('Name' => 'bob', 'Age' => 14),
892
			array('Name' => 'phil', 'Age' => 14),
893
			array('Name' => 'bob', 'Age' => 16),
894
			array('Name' => 'phil', 'Age' => 16)
895
		));
896
897
		$list = $list->exclude(array('Name'=>array('bob','phil'),'Age'=>array(10, 16),'Bananas'=>true));
898
		$expected = array(
899
			array('Name' => 'bob', 'Age' => 10),
900
			array('Name' => 'phil', 'Age' => 11),
901
			array('Name' => 'bob', 'Age' => 12),
902
			array('Name' => 'phil', 'Age' => 12),
903
			array('Name' => 'bob', 'Age' => 14),
904
			array('Name' => 'phil', 'Age' => 14),
905
			array('Name' => 'bob', 'Age' => 16),
906
			array('Name' => 'phil', 'Age' => 16)
907
		);
908
		$this->assertEquals($expected, $list->toArray());
909
	}
910
911
	/**
912
	 * $list->exclude(array('Name'=>array('bob','phil'), 'Age'=>array(10, 16), 'HasBananas'=>true));
913
	 */
914
	public function testMultipleExcludeThreeArguments() {
915
		$list = new ArrayList(array(
916
			array('Name' => 'bob', 'Age' => 10, 'HasBananas'=>false),
917
			array('Name' => 'phil','Age' => 11, 'HasBananas'=>true),
918
			array('Name' => 'bob', 'Age' => 12, 'HasBananas'=>true),
919
			array('Name' => 'phil','Age' => 12, 'HasBananas'=>true),
920
			array('Name' => 'bob', 'Age' => 14, 'HasBananas'=>false),
921
			array('Name' => 'ann', 'Age' => 14, 'HasBananas'=>true),
922
			array('Name' => 'phil','Age' => 14, 'HasBananas'=>false),
923
			array('Name' => 'bob', 'Age' => 16, 'HasBananas'=>false),
924
			array('Name' => 'phil','Age' => 16, 'HasBananas'=>true),
925
			array('Name' => 'clair','Age' => 16, 'HasBananas'=>true)
926
		));
927
928
		$list = $list->exclude(array('Name'=>array('bob','phil'),'Age'=>array(10, 16),'HasBananas'=>true));
929
		$expected = array(
930
			array('Name' => 'bob', 'Age' => 10, 'HasBananas'=>false),
931
			array('Name' => 'phil','Age' => 11, 'HasBananas'=>true),
932
			array('Name' => 'bob', 'Age' => 12, 'HasBananas'=>true),
933
			array('Name' => 'phil','Age' => 12, 'HasBananas'=>true),
934
			array('Name' => 'bob', 'Age' => 14, 'HasBananas'=>false),
935
			array('Name' => 'ann', 'Age' => 14, 'HasBananas'=>true),
936
			array('Name' => 'phil','Age' => 14, 'HasBananas'=>false),
937
			array('Name' => 'bob', 'Age' => 16, 'HasBananas'=>false),
938
			array('Name' => 'clair','Age' => 16, 'HasBananas'=>true)
939
		);
940
		$this->assertEquals($expected, $list->toArray());
941
	}
942
943
	public function testCanFilterBy() {
944
		$list = new ArrayList(array(
945
			array('Name' => 'Steve'),
946
			array('Name' => 'Bob'),
947
			array('Name' => 'John')
948
		));
949
950
		$this->assertTrue($list->canFilterBy('Name'));
951
		$this->assertFalse($list->canFilterBy('Age'));
952
	}
953
954
	public function testCanFilterByEmpty() {
955
		$list = new ArrayList();
956
957
		$this->assertFalse($list->canFilterBy('Name'));
958
		$this->assertFalse($list->canFilterBy('Age'));
959
	}
960
961
	public function testByID() {
962
		$list = new ArrayList(array(
963
			array('ID' => 1, 'Name' => 'Steve'),
964
			array('ID' => 2, 'Name' => 'Bob'),
965
			array('ID' => 3, 'Name' => 'John')
966
		));
967
968
		$element = $list->byID(1);
969
		$this->assertEquals($element['Name'], 'Steve');
970
971
		$element = $list->byID(2);
972
		$this->assertEquals($element['Name'], 'Bob');
973
974
		$element = $list->byID(4);
975
		$this->assertNull($element);
976
	}
977
978
	public function testByIDs() {
979
		$list = new ArrayList(array(
980
			array('ID' => 1, 'Name' => 'Steve'),
981
			array('ID' => 2, 'Name' => 'Bob'),
982
			array('ID' => 3, 'Name' => 'John')
983
		));
984
		$knownIDs = $list->column('ID');
985
		$removedID = array_pop($knownIDs);
986
		$filteredItems = $list->byIDs($knownIDs);
987
		foreach ($filteredItems as $item) {
988
			$this->assertContains($item->ID, $knownIDs);
989
			$this->assertNotEquals($removedID, $item->ID);
990
		}
991
	}
992
993
	public function testByIDEmpty() {
994
		$list = new ArrayList();
995
996
		$element = $list->byID(1);
997
		$this->assertNull($element);
998
	}
999
}
1000
1001
/**
1002
 * @ignore
1003
 */
1004
class ArrayListTest_Object {
1005
1006
	public $First;
1007
	public $Second;
1008
1009
	public function __construct($first, $second) {
1010
		$this->First  = $first;
1011
		$this->Second = $second;
1012
	}
1013
1014
	public function toMap() {
1015
		return array('First' => $this->First, 'Second' => $this->Second);
1016
	}
1017
1018
}
1019