getListSetPropertyValue5MethodAppend()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace DimshTests\Models\Collections;
4
5
use Dimsh\Models\Collections\Collection;
6
use PHPUnit\Framework\TestCase;
7
8
class CollectionTest extends TestCase
9
{
10
    protected function getNewTestBasicObject()
11
    {
12
        return new TestBasicObject;
13
    }
14
15
    protected function getArray()
16
    {
17
        $arr = ['a'];
18
        return $arr;
19
    }
20
21
    /**
22
     * Tell if two variables are PHP References to each other.
23
     *
24
     * @param $var1
25
     * @param $var2
26
     *
27
     * @return bool
28
     */
29
    protected function isReference(&$var1, &$var2)
30
    {
31
        //If a reference exists, the type IS the same
32
        if (gettype($var1) !== gettype($var2)) {
33
            return false;
34
        }
35
36
        $same = false;
37
38
        //We now only need to ask for var1 to be an array ;-)
39
        if (is_array($var1)) {
40
            //Look for an unused index in $var1
41
            do {
42
                $key = uniqid("is_ref_", true);
43
            } while (array_key_exists($key, $var1));
44
45
            //The two variables differ in content ... They can't be the same
46
            if (array_key_exists($key, $var2)) {
47
                return false;
48
            }
49
50
            //The arrays point to the same data if changes are reflected in $var2
51
            $data       = uniqid("is_ref_data_", true);
52
            $var1[$key] =& $data;
53
            //There seems to be a modification ...
54
            if (array_key_exists($key, $var2)) {
55
                if ($var2[$key] === $data) {
56
                    $same = true;
57
                }
58
            }
59
60
            //Undo our changes ...
61
            unset($var1[$key]);
62
        } elseif (is_object($var1)) {
63
            //The same objects are required to have equal class names ;-)
64
            if (get_class($var1) !== get_class($var2)) {
65
                return false;
66
            }
67
68
            $obj1 = array_keys(get_object_vars($var1));
69
            $obj2 = array_keys(get_object_vars($var2));
70
71
            //Look for an unused index in $var1
72
            do {
73
                $key = uniqid("is_ref_", true);
74
            } while (in_array($key, $obj1));
75
76
            //The two variables differ in content ... They can't be the same
77
            if (in_array($key, $obj2)) {
78
                return false;
79
            }
80
81
            //The arrays point to the same data if changes are reflected in $var2
82
            $data       = uniqid("is_ref_data_", true);
83
            $var1->$key =& $data;
84
            //There seems to be a modification ...
85
            if (isset($var2->$key)) {
86
                if ($var2->$key === $data) {
87
                    $same = true;
88
                }
89
            }
90
91
            //Undo our changes ...
92
            unset($var1->$key);
93
        } elseif (is_resource($var1)) {
94
            if (get_resource_type($var1) !== get_resource_type($var2)) {
95
                return false;
96
            }
97
98
            return ((string)$var1) === ((string)$var2);
99
        } else {
100
            //Simple variables ...
101
            if ($var1 !== $var2) {
102
                //Data mismatch ... They can't be the same ...
103
                return false;
104
            }
105
106
            //To check for a reference of a variable with simple type
107
            //simply store its old value and check against modifications of the second variable ;-)
108
109
            do {
110
                $key = uniqid("is_ref_", true);
111
            } while ($key === $var1);
112
113
            $tmp  = $var1; //WE NEED A COPY HERE!!!
114
            $var1 = $key; //Set var1 to the value of $key (copy)
115
            $same = $var1 === $var2; //Check if $var2 was modified too ...
116
            $var1 = $tmp; //Undo our changes ...
117
        }
118
119
        return $same;
120
    }
121
122
    public function testSetupStrict()
123
    {
124
        $list = new TestBasicObjectsList;
125
        $this->expectException(\Exception::class);
126
        $list[] = 1;
127
    }
128
129
    public function testSetup()
130
    {
131
        $list = new TestBasicObjectsList;
132
        $this->assertEquals($list, $list->add(new TestBasicObject));
133
        $this->assertSame(1, $list->count());
134
        $this->assertCount(1, $list);
135
        $this->assertInstanceOf(TestBasicObject::class, $list[0]);
136
        $this->assertNotEmpty($list[0]);
137
        $this->assertFalse(isset($list[1]));
138
        unset($list[0]);
139
        $this->assertSame(0, $list->count());
140
        $this->assertCount(0, $list);
141
    }
142
143
    protected function getListSetPropertyValue5MethodAppend(TestBasicObject $myObject)
144
    {
145
        $list                      = new Collection();
146
        $myObject->public_property = 5;
147
        $list[]                    = $myObject;
148
        return $list;
149
    }
150
151
    protected function getListSetPropertyValue5MethodAdd(TestBasicObject $myObject)
152
    {
153
        $list                      = new Collection();
154
        $myObject->public_property = 5;
155
        $list->add($myObject);
156
        return $list;
157
    }
158
159
    public function testReferences()
160
    {
161
        $list   = new Collection();
162
        $list[] = $this->getNewTestBasicObject();
163
        $list->add($this->getNewTestBasicObject());
164
        $this->assertFalse($this->isReference($list[0], $list[1]));
165
166
        $myObject                  = new TestBasicObject();
167
        $myObject->public_property = 3;
168
        $list[] = $myObject;
169
170
        $myObject->public_property = 6;
171
        $this->assertTrue($this->isReference($list[2], $myObject));
172
        $this->assertEquals($list[2]->getMyHash(), $myObject->getMyHash());
173
        $this->assertSame(6, $list[2]->public_property);
174
    }
175
176
    public function testReferences2MethodAppend()
177
    {
178
        $myObject = new TestBasicObject();
179
        $list     = $this->getListSetPropertyValue5MethodAppend($myObject);
180
        $this->assertSame(5, $myObject->public_property);
181
        $this->assertSame(5, $list[0]->public_property);
182
183
        $list->rewind();
184
        $returnedObject = $list->current();
185
        $this->assertSame(5, $returnedObject->public_property);
186
187
        $this->assertTrue($this->isReference($myObject, $returnedObject));
188
189
        $returnedObject->public_property = 9;
190
        unset($list[0]);
191
        unset($returnedObject);
192
        $this->assertSame(9, $myObject->public_property);
193
    }
194
195
    public function testReferences2MethodAdd()
196
    {
197
        $myObject = new TestBasicObject();
198
        $list     = $this->getListSetPropertyValue5MethodAdd($myObject);
199
        $this->assertSame(5, $myObject->public_property);
200
        $this->assertSame(5, $list[0]->public_property);
201
202
        $list->rewind();
203
        $returnedObject = $list->current();
204
        $this->assertSame(5, $returnedObject->public_property);
205
206
        $this->assertTrue($this->isReference($myObject, $returnedObject));
207
208
        $returnedObject->public_property = 9;
209
        unset($list[0]);
210
        unset($returnedObject);
211
        $this->assertSame(9, $myObject->public_property);
212
    }
213
214
    public function testReferencesScalar()
215
    {
216
        $list = new Collection();
217
        $list->add("my string");
218
        $this->assertSame("my string", $list[0]);
219
        $list->add($this->getArray());
220
        $array = $this->getArray();
221
        $this->assertFalse($this->isReference($list[1], $array));
222
223
        $list[1][0] = 'b';
224
        $this->assertNotEquals($this->getArray(), $list[1]);
225
        $this->assertNotEquals($array, $list[1]);
226
        $array = $this->getArray();
227
        $this->assertNotEquals($array, $list[1]);
228
229
        unset($list);
230
231
        $list  = new Collection();
232
        $array = $this->getArray();
233
234
        $list->addByReference($array);
235
        $this->assertTrue($this->isReference($list[0], $array));
236
        $list[0][0] = 'b';
237
        $this->assertEquals($array, $list[0]);
238
239
        $list->rewind();
240
        $zero    = &$list[0];
241
        $current = $list->current();
242
243
        $this->assertTrue($this->isReference($zero, $array));
244
        $this->assertFalse($this->isReference($zero, $current));
245
    }
246
247
    public function testSwapAndReferencesWithSwap()
248
    {
249
        $list     = new Collection();
250
        $list[]   = "my string";
251
        $list[]   = "another string";
252
        $list[]   = ["array item"];
253
        $list[]   = 5;
254
        $list[]   = "last string";
255
        $myObject = new TestBasicObject();
256
        $list[]   = $myObject;
257
258
        $list->swap(1, 3);
259
        $this->assertSame("my string", $list[0]);
260
        $this->assertSame(5, $list[1]);
261
        $this->assertEquals(["array item"], $list[2]);
262
        $this->assertSame("another string", $list[3]);
263
264
        $clone1 = clone $list;
265
        $clone2 = clone $list;
266
267
        $clone1->swap(0, 1);
268
        $clone2->swapReorder(0, 1);
269
270
        $this->assertEquals($clone1->toArray(), $clone2->toArray());
271
        $this->assertFalse($this->isReference($clone1, $clone2));
272
273
        $myObject->public_property = 9;
274
275
        $this->assertSame(9, $clone1[5]->public_property);
276
        $this->assertTrue($this->isReference($clone1[5], $clone2[5]));
277
278
        $clone1->swap(0, 5);
279
        $clone2->swap(0, 5);
280
        $this->assertTrue($this->isReference($clone1[0], $clone2[0]));
281
    }
282
283
    public function testArrayFunctions()
284
    {
285
        $list_multi_2_flipped = new Collection();
286
        $list_multi_3_flipped = new Collection();
287
        for ($i = 1; $i < 6; $i++) {
288
            $list_multi_2_flipped[$i * 2] = $i;
289
            $list_multi_3_flipped[$i * 3] = $i;
290
        }
291
292
293
        $list_diff = $list_multi_2_flipped->diffKey($list_multi_3_flipped);
294
        $this->assertEquals([
295
          2  => 1,
296
          4  => 2,
297
          8  => 4,
298
          10 => 5,
299
        ], $list_diff->toArray());
300
301
        $list_diff = $list_multi_3_flipped->diffKey($list_multi_2_flipped);
302
        $this->assertEquals([
303
          3  => 1,
304
          9  => 3,
305
          12 => 4,
306
          15 => 5,
307
        ], $list_diff->toArray());
308
309
        $list_intersect = $list_multi_2_flipped->intersectKey($list_multi_3_flipped);
310
        $this->assertEquals([
311
          6 => 3,
312
        ], $list_intersect->toArray());
313
314
        $list_intersect = $list_multi_3_flipped->intersectKey($list_multi_2_flipped);
315
        $this->assertEquals([
316
          6 => 2,
317
        ], $list_intersect->toArray());
318
319
320
        $list_multi_2 = new Collection();
321
        $list_multi_4 = new Collection();
322
        for ($i = 1; $i < 6; $i++) {
323
            $list_multi_2[$i] = $i * 2;
324
            $list_multi_4[$i] = $i * 4;
325
        }
326
327
        $list_diff = $list_multi_2->diffRecursive($list_multi_4);
328
        $this->assertEquals([
329
          1 => 2,
330
          3 => 6,
331
          5 => 10,
332
        ], $list_diff->toArray());
333
334
        $list_diff = $list_multi_4->diffRecursive($list_multi_2);
335
        $this->assertEquals([
336
          3 => 12,
337
          4 => 16,
338
          5 => 20,
339
        ], $list_diff->toArray());
340
    }
341
342
    public function testOffsetGetOnNonExistedKey()
343
    {
344
        $collection = new Collection();
345
346
        $this->assertNull($collection->offsetGet('non_existed_key'));
347
    }
348
349
    public function testPrev()
350
    {
351
        $collection = new Collection();
352
        $collection[0] = 0;
353
        $collection[1] = 1;
354
        $collection[2] = 2;
355
356
        $this->assertSame(0, $collection->current());
357
358
        $collection->next();
359
360
        $this->assertSame(1, $collection->current());
361
362
        $collection->prev();
363
364
        $this->assertSame(0, $collection->current());
365
    }
366
367
    public function testValidOnEmptyCollection()
368
    {
369
        $collection = new Collection();
370
371
        $this->assertFalse($collection->valid());
372
    }
373
374
    /**
375
     * @expectedException        \Exception
376
     * @expectedExceptionMessage Calling next or rewind is required after call to unset, current item can't be accessed otherwise because it is removed
377
     */
378
    public function testCurrentThrowAfterUnsetException()
379
    {
380
        $collection = new Collection();
381
        $collection[] = 0;
382
        $collection->offsetUnset(0);
383
384
        $collection->current();
385
    }
386
387
    public function testLast()
388
    {
389
        $collection = new Collection();
390
        $collection[0] = 0;
391
        $collection[1] = 1;
392
        $collection[2] = 2;
393
394
        $this->assertSame(2, $collection->last());
395
    }
396
397
    public function testLastOnEmptyCollection()
398
    {
399
        $collection = new Collection();
400
401
        $this->assertNull($collection->last());
402
    }
403
404
    public function testFirst()
405
    {
406
        $collection = new Collection();
407
        $collection[0] = 0;
408
        $collection[1] = 1;
409
        $collection[2] = 2;
410
411
        $this->assertSame(0, $collection->first());
412
    }
413
414
    public function testFirstOnEmptyCollection()
415
    {
416
        $collection = new Collection();
417
418
        $this->assertNull($collection->first());
419
    }
420
421
    public function testKeys()
422
    {
423
        $collection = new Collection();
424
        $collection[] = 0;
425
        $collection[] = 1;
426
427
        $this->assertEquals([0, 1], $collection->keys());
428
    }
429
430
    public function testMerge()
431
    {
432
        $collection = new Collection();
433
        $collection[] = 0;
434
        $collection[] = 1;
435
        $collection[] = 2;
436
437
        $anotherCollection = new Collection();
438
        $collection[] = 3;
439
440
        $resultMergedCollection = $collection->merge($anotherCollection);
441
442
        $this->assertEquals([
443
          0,
444
          1,
445
          2,
446
          3,
447
        ], $resultMergedCollection->toArray());
448
    }
449
450
    public function testSwapOnSameOffsetPosition()
451
    {
452
        $collection = new Collection();
453
        $collection[] = 0;
454
        $collection[] = 1;
455
        $collection[] = 2;
456
457
        $this->assertInstanceOf(Collection::class, $collection->swap(1, 1));
458
        $this->assertEquals([
459
          0,
460
          1,
461
          2,
462
        ], $collection->toArray());
463
    }
464
465
    public function testSwapThrowExceptionOnInvalidPosition()
466
    {
467
        $collection = new Collection();
468
        $collection[] = 0;
469
        $collection[] = 1;
470
        $collection[] = 2;
471
472
        $this->expectException(\Exception::class);
473
474
        $collection->swap(3, 2);
475
    }
476
477
    public function testSwapReorderOnSameOffsetPosition()
478
    {
479
        $collection = new Collection();
480
        $collection[] = 0;
481
        $collection[] = 1;
482
        $collection[] = 2;
483
484
        $this->assertInstanceOf(Collection::class, $collection->swapReorder(1, 1));
485
        $this->assertEquals([
486
          0,
487
          1,
488
          2,
489
        ], $collection->toArray());
490
    }
491
492
    public function testSwapReorderThrowExceptionOnInvalidPosition()
493
    {
494
        $collection = new Collection();
495
        $collection[] = 0;
496
        $collection[] = 1;
497
        $collection[] = 2;
498
499
        $this->expectException(\Exception::class);
500
501
        $collection->swapReorder(3, 2);
502
    }
503
504
    public function testByPositionGet()
505
    {
506
        $collection = new Collection();
507
        $collection[] = 0;
508
        $collection[] = 1;
509
        $collection[] = 2;
510
511
        $this->assertSame(2, $collection->byPositionGet(2));
512
    }
513
514
    public function testByPositionGetOnOutOfRangePosition()
515
    {
516
        $collection = new Collection();
517
        $collection[] = 0;
518
        $collection[] = 1;
519
        $collection[] = 2;
520
521
        $this->assertNull($collection->byPositionGet(3));
522
    }
523
524
    public function testIsEmptyOnEmptyCollection()
525
    {
526
        $collection = new Collection();
527
528
        $this->assertTrue($collection->isEmpty());
529
    }
530
531
    public function testIsEmptyOnNotEmptyCollection()
532
    {
533
        $collection = new Collection();
534
        $collection[] = 0;
535
        $collection[] = 1;
536
        $collection[] = 2;
537
538
        $this->assertFalse($collection->isEmpty());
539
    }
540
541
    public function testDiffRecursiveAssocOnValueItems()
542
    {
543
        $anotherCollection = new Collection();
544
        $anotherCollection['key3'] = 0;
545
        $anotherCollection['key4'] = 1;
546
        $anotherCollection['key5'] = 2;
547
548
        $collection = new Collection();
549
        $collection['key0'] = 0;
550
        $collection['key1'] = 1;
551
        $collection['key2'] = 2;
552
553
        $this->assertEquals($collection->toArray(), $collection->diffRecursiveAssoc($anotherCollection)->toArray());
554
    }
555
556
    public function testDiffRecursiveAssocOnCollections()
557
    {
558
        $anotherCollection = new Collection();
559
        $anotherCollection[] = 0;
560
        $anotherCollection[] = 1;
561
        $anotherCollection[] = 2;
562
563
        $collection = new Collection();
564
        $collection['key0'] = $anotherCollection;
565
        $collection['key1'] = $anotherCollection;
566
        $collection['key2'] = $anotherCollection;
567
568
        $this->assertEquals([], $collection->diffRecursiveAssoc($collection)->toArray());
569
    }
570
571
    public function testDiffRecursiveAssocOnArrayValues()
572
    {
573
        $collection = new Collection();
574
        $collection['key0'] = [0, 1, 2, 3];
575
        $collection['key1'] = [0, 1, 2, 3];
576
        $collection['key2'] = [0, 1, 2, 3];
577
578
        $anotherCollection = new Collection();
579
        $anotherCollection[] = 0;
580
        $anotherCollection[] = 1;
581
        $anotherCollection[] = 2;
582
583
        $this->assertEquals($collection->toArray(), $collection->diffRecursiveAssoc($anotherCollection)->toArray());
584
    }
585
}
586