Completed
Push — master ( 4b1ef2...65002c )
by Abdulrahman
01:59
created

CollectionTest::testSetupStrict()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
class CollectionTest extends \PHPUnit\Framework\TestCase
4
{
5
    protected function getNewTestBasicObject()
6
    {
7
        return new TestBasicObject;
8
    }
9
10
    protected function getArray()
11
    {
12
        $arr = ['a'];
13
        return $arr;
14
    }
15
16
    /**
17
     * Tell if two variables are PHP References to each other.
18
     *
19
     * @param $var1
20
     * @param $var2
21
     *
22
     * @return bool
23
     */
24
    protected function isReference(&$var1, &$var2)
25
    {
26
        //If a reference exists, the type IS the same
27
        if (gettype($var1) !== gettype($var2)) {
28
            return false;
29
        }
30
31
        $same = false;
32
33
        //We now only need to ask for var1 to be an array ;-)
34
        if (is_array($var1)) {
35
            //Look for an unused index in $var1
36
            do {
37
                $key = uniqid("is_ref_", true);
38
            } while (array_key_exists($key, $var1));
39
40
            //The two variables differ in content ... They can't be the same
41
            if (array_key_exists($key, $var2)) {
42
                return false;
43
            }
44
45
            //The arrays point to the same data if changes are reflected in $var2
46
            $data       = uniqid("is_ref_data_", true);
47
            $var1[$key] =& $data;
48
            //There seems to be a modification ...
49
            if (array_key_exists($key, $var2)) {
50
                if ($var2[$key] === $data) {
51
                    $same = true;
52
                }
53
            }
54
55
            //Undo our changes ...
56
            unset($var1[$key]);
57
        } elseif (is_object($var1)) {
58
            //The same objects are required to have equal class names ;-)
59
            if (get_class($var1) !== get_class($var2)) {
60
                return false;
61
            }
62
63
            $obj1 = array_keys(get_object_vars($var1));
64
            $obj2 = array_keys(get_object_vars($var2));
65
66
            //Look for an unused index in $var1
67
            do {
68
                $key = uniqid("is_ref_", true);
69
            } while (in_array($key, $obj1));
70
71
            //The two variables differ in content ... They can't be the same
72
            if (in_array($key, $obj2)) {
73
                return false;
74
            }
75
76
            //The arrays point to the same data if changes are reflected in $var2
77
            $data       = uniqid("is_ref_data_", true);
78
            $var1->$key =& $data;
79
            //There seems to be a modification ...
80
            if (isset($var2->$key)) {
81
                if ($var2->$key === $data) {
82
                    $same = true;
83
                }
84
            }
85
86
            //Undo our changes ...
87
            unset($var1->$key);
88
        } elseif (is_resource($var1)) {
89
            if (get_resource_type($var1) !== get_resource_type($var2)) {
90
                return false;
91
            }
92
93
            return ((string)$var1) === ((string)$var2);
94
        } else {
95
            //Simple variables ...
96
            if ($var1 !== $var2) {
97
                //Data mismatch ... They can't be the same ...
98
                return false;
99
            }
100
101
            //To check for a reference of a variable with simple type
102
            //simply store its old value and check against modifications of the second variable ;-)
103
104
            do {
105
                $key = uniqid("is_ref_", true);
106
            } while ($key === $var1);
107
108
            $tmp  = $var1; //WE NEED A COPY HERE!!!
109
            $var1 = $key; //Set var1 to the value of $key (copy)
110
            $same = $var1 === $var2; //Check if $var2 was modified too ...
111
            $var1 = $tmp; //Undo our changes ...
112
        }
113
114
        return $same;
115
    }
116
117
    public function testSetupStrict()
118
    {
119
        $list = new TestBasicObjectsList;
120
        $this->expectException(\Exception::class);
121
        $list[] = 1;
122
    }
123
124
    public function testSetup()
125
    {
126
        $list = new TestBasicObjectsList;
127
        $this->assertEquals($list, $list->add(new TestBasicObject));
128
        $this->assertEquals(1, $list->count());
129
        $this->assertEquals(1, count($list));
130
        $this->assertInstanceOf(TestBasicObject::class, $list[0]);
131
        $this->assertTrue(isset($list[0]));
132
        $this->assertFalse(isset($list[1]));
133
        unset($list[0]);
134
        $this->assertEquals(0, $list->count());
135
        $this->assertEquals(0, count($list));
136
    }
137
138
    protected function getListSetPropertyValue5MethodAppend(TestBasicObject $myObject)
139
    {
140
        $list                      = new \Dimsh\Models\Collections\Collection();
141
        $myObject->public_property = 5;
142
        $list[]                    = $myObject;
143
        return $list;
144
    }
145
146
    protected function getListSetPropertyValue5MethodAdd(TestBasicObject $myObject)
147
    {
148
        $list                      = new \Dimsh\Models\Collections\Collection();
149
        $myObject->public_property = 5;
150
        $list->add($myObject);
151
        return $list;
152
    }
153
154
    public function testReferences()
155
    {
156
        $list   = new \Dimsh\Models\Collections\Collection();
157
        $list[] = $this->getNewTestBasicObject();
158
        $list->add($this->getNewTestBasicObject());
159
        $this->assertFalse($this->isReference($list[0], $list[1]));
160
161
        $myObject                  = new TestBasicObject();
162
        $myObject->public_property = 3;
163
        $list[] = $myObject;
164
165
        $myObject->public_property = 6;
166
        $this->assertTrue($this->isReference($list[2], $myObject));
167
        $this->assertEquals($list[2]->getMyHash(), $myObject->getMyHash());
168
        $this->assertEquals(6, $list[2]->public_property);
169
    }
170
171
    public function testReferences2MethodAppend()
172
    {
173
        $myObject = new TestBasicObject();
174
        $list     = $this->getListSetPropertyValue5MethodAppend($myObject);
175
        $this->assertEquals(5, $myObject->public_property);
176
        $this->assertEquals(5, $list[0]->public_property);
177
178
        $list->rewind();
179
        $returnedObject = $list->current();
180
        $this->assertEquals(5, $returnedObject->public_property);
181
182
        $this->assertTrue($this->isReference($myObject, $returnedObject));
183
184
        $returnedObject->public_property = 9;
185
        unset($list[0]);
186
        unset($returnedObject);
187
        $this->assertEquals(9, $myObject->public_property);
188
    }
189
190
    public function testReferences2MethodAdd()
191
    {
192
        $myObject = new TestBasicObject();
193
        $list     = $this->getListSetPropertyValue5MethodAdd($myObject);
194
        $this->assertEquals(5, $myObject->public_property);
195
        $this->assertEquals(5, $list[0]->public_property);
196
197
        $list->rewind();
198
        $returnedObject = $list->current();
199
        $this->assertEquals(5, $returnedObject->public_property);
200
201
        $this->assertTrue($this->isReference($myObject, $returnedObject));
202
203
        $returnedObject->public_property = 9;
204
        unset($list[0]);
205
        unset($returnedObject);
206
        $this->assertEquals(9, $myObject->public_property);
207
    }
208
209
    public function testReferencesScalar()
210
    {
211
        $list = new \Dimsh\Models\Collections\Collection();
212
        $list->add("my string");
213
        $this->assertEquals("my string", $list[0]);
214
        $list->add($this->getArray());
215
        $array = $this->getArray();
216
        $this->assertFalse($this->isReference($list[1], $array));
217
218
        $list[1][0] = 'b';
219
        $this->assertNotEquals($this->getArray(), $list[1]);
220
        $this->assertNotEquals($array, $list[1]);
221
        $array = $this->getArray();
222
        $this->assertNotEquals($array, $list[1]);
223
224
        unset($list);
225
226
        $list  = new \Dimsh\Models\Collections\Collection();
227
        $array = $this->getArray();
228
229
        $list->addByReference($array);
230
        $this->assertTrue($this->isReference($list[0], $array));
231
        $list[0][0] = 'b';
232
        $this->assertEquals($array, $list[0]);
233
234
        $list->rewind();
235
        $zero    = &$list[0];
236
        $current = $list->current();
237
238
        $this->assertTrue($this->isReference($zero, $array));
239
        $this->assertFalse($this->isReference($zero, $current));
240
    }
241
242
    public function testSwapAndReferencesWithSwap()
243
    {
244
        $list     = new \Dimsh\Models\Collections\Collection();
245
        $list[]   = "my string";
246
        $list[]   = "another string";
247
        $list[]   = ["array item"];
248
        $list[]   = 5;
249
        $list[]   = "last string";
250
        $myObject = new TestBasicObject();
251
        $list[]   = $myObject;
252
253
        $list->swap(1, 3);
254
        $this->assertEquals("my string", $list[0]);
255
        $this->assertEquals(5, $list[1]);
256
        $this->assertEquals("5", $list[1]);
257
        $this->assertEquals(["array item"], $list[2]);
258
        $this->assertEquals("another string", $list[3]);
259
260
        $clone1 = clone $list;
261
        $clone2 = clone $list;
262
263
        $clone1->swap(0, 1);
264
        $clone2->swapReorder(0, 1);
265
266
        $this->assertEquals($clone1->toArray(), $clone2->toArray());
267
        $this->assertFalse($this->isReference($clone1, $clone2));
268
269
        $myObject->public_property = 9;
270
271
        $this->assertEquals(9, $clone1[5]->public_property);
272
        $this->assertTrue($this->isReference($clone1[5], $clone2[5]));
273
274
        $clone1->swap(0, 5);
275
        $clone2->swap(0, 5);
276
        $this->assertTrue($this->isReference($clone1[0], $clone2[0]));
277
    }
278
279
    public function testArrayFunctions()
280
    {
281
        $list_multi_2_flipped = new \Dimsh\Models\Collections\Collection();
282
        $list_multi_3_flipped = new \Dimsh\Models\Collections\Collection();
283
        for ($i = 1; $i < 6; $i++) {
284
            $list_multi_2_flipped[$i * 2] = $i;
285
            $list_multi_3_flipped[$i * 3] = $i;
286
        }
287
288
289
        $list_diff = $list_multi_2_flipped->diffKey($list_multi_3_flipped);
290
        $this->assertEquals([
291
          2  => 1,
292
          4  => 2,
293
          8  => 4,
294
          10 => 5,
295
        ], $list_diff->toArray());
296
297
        $list_diff = $list_multi_3_flipped->diffKey($list_multi_2_flipped);
298
        $this->assertEquals([
299
          3  => 1,
300
          9  => 3,
301
          12 => 4,
302
          15 => 5,
303
        ], $list_diff->toArray());
304
305
        $list_intersect = $list_multi_2_flipped->intersectKey($list_multi_3_flipped);
306
        $this->assertEquals([
307
          6 => 3,
308
        ], $list_intersect->toArray());
309
310
        $list_intersect = $list_multi_3_flipped->intersectKey($list_multi_2_flipped);
311
        $this->assertEquals([
312
          6 => 2,
313
        ], $list_intersect->toArray());
314
315
316
        $list_multi_2 = new \Dimsh\Models\Collections\Collection();
317
        $list_multi_4 = new \Dimsh\Models\Collections\Collection();
318
        for ($i = 1; $i < 6; $i++) {
319
            $list_multi_2[$i] = $i * 2;
320
            $list_multi_4[$i] = $i * 4;
321
        }
322
323
        $list_diff = $list_multi_2->diffRecursive($list_multi_4);
324
        $this->assertEquals([
325
          1 => 2,
326
          3 => 6,
327
          5 => 10,
328
        ], $list_diff->toArray());
329
330
        $list_diff = $list_multi_4->diffRecursive($list_multi_2);
331
        $this->assertEquals([
332
          3 => 12,
333
          4 => 16,
334
          5 => 20,
335
        ], $list_diff->toArray());
336
    }
337
}
338