Completed
Push — 3.4 ( 17c658...420cba )
by Daniel
10:26
created

ArrayListTest::testSimpleExcludeNoMatch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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