Imported Upstream version 3.8.0
[platform/upstream/protobuf.git] / php / tests / map_field_test.php
1 <?php
2
3 require_once('test_util.php');
4
5 use Google\Protobuf\Internal\GPBType;
6 use Google\Protobuf\Internal\MapField;
7 use Foo\TestMessage;
8 use Foo\TestMessage\Sub;
9
10 class MapFieldTest extends \PHPUnit\Framework\TestCase {
11
12     #########################################################
13     # Test int32 field.
14     #########################################################
15
16     public function testInt32() {
17         $arr = new MapField(GPBType::INT32, GPBType::INT32);
18
19         // Test integer argument.
20         $arr[MAX_INT32] = MAX_INT32;
21         $this->assertSame(MAX_INT32, $arr[MAX_INT32]);
22         $arr[MIN_INT32] = MIN_INT32;
23         $this->assertSame(MIN_INT32, $arr[MIN_INT32]);
24         $this->assertEquals(2, count($arr));
25         $this->assertTrue(isset($arr[MAX_INT32]));
26         $this->assertTrue(isset($arr[MIN_INT32]));
27         unset($arr[MAX_INT32]);
28         unset($arr[MIN_INT32]);
29         $this->assertEquals(0, count($arr));
30
31         // Test float argument.
32         $arr[1.9] = 1.9;
33         $arr[2.1] = 2.1;
34         $this->assertSame(1, $arr[1]);
35         $this->assertSame(2, $arr[2]);
36         $arr[MAX_INT32_FLOAT] = MAX_INT32_FLOAT;
37         $this->assertSame(MAX_INT32, $arr[MAX_INT32]);
38         $arr[MIN_INT32_FLOAT] = MIN_INT32_FLOAT;
39         $this->assertSame(MIN_INT32, $arr[MIN_INT32]);
40         $this->assertEquals(4, count($arr));
41         unset($arr[1.9]);
42         unset($arr[2.9]);
43         unset($arr[MAX_INT32_FLOAT]);
44         unset($arr[MIN_INT32_FLOAT]);
45         $this->assertEquals(0, count($arr));
46
47         // Test string argument.
48         $arr['2'] = '2';
49         $this->assertSame(2, $arr[2]);
50         $arr['3.1'] = '3.1';
51         $this->assertSame(3, $arr[3]);
52         $arr[MAX_INT32_STRING] = MAX_INT32_STRING;
53         $this->assertSame(MAX_INT32, $arr[MAX_INT32]);
54         $this->assertEquals(3, count($arr));
55         unset($arr['2']);
56         unset($arr['3.1']);
57         unset($arr[MAX_INT32_STRING]);
58         $this->assertEquals(0, count($arr));
59
60         // Test foreach.
61         $arr = new MapField(GPBType::INT32, GPBType::INT32);
62         for ($i = 0; $i < 3; $i++) {
63           $arr[$i] = $i;
64         }
65         $i = 0;
66         $arr_test = [];
67         foreach ($arr as $key => $val) {
68           $this->assertSame($key, $val);
69           $arr_test[] = $key;
70           $i++;
71         }
72         $this->assertTrue(isset($arr_test[0]));
73         $this->assertTrue(isset($arr_test[1]));
74         $this->assertTrue(isset($arr_test[2]));
75         $this->assertSame(3, $i);
76     }
77
78     #########################################################
79     # Test uint32 field.
80     #########################################################
81
82     public function testUint32() {
83         $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
84
85         // Test integer argument.
86         $arr[MAX_UINT32] = MAX_UINT32;
87         $this->assertSame(-1, $arr[-1]);
88         $this->assertEquals(1, count($arr));
89         unset($arr[MAX_UINT32]);
90         $this->assertEquals(0, count($arr));
91
92         $arr[-1] = -1;
93         $this->assertSame(-1, $arr[-1]);
94         $arr[MIN_UINT32] = MIN_UINT32;
95         $this->assertSame(MIN_UINT32, $arr[MIN_UINT32]);
96         $this->assertEquals(2, count($arr));
97         unset($arr[-1]);
98         unset($arr[MIN_UINT32]);
99         $this->assertEquals(0, count($arr));
100
101         // Test float argument.
102         $arr[MAX_UINT32_FLOAT] = MAX_UINT32_FLOAT;
103         $this->assertSame(-1, $arr[-1]);
104         $this->assertEquals(1, count($arr));
105         unset($arr[MAX_UINT32_FLOAT]);
106         $this->assertEquals(0, count($arr));
107
108         $arr[3.1] = 3.1;
109         $this->assertSame(3, $arr[3]);
110         $arr[-1.0] = -1.0;
111         $this->assertSame(-1, $arr[-1]);
112         $arr[MIN_UINT32_FLOAT] = MIN_UINT32_FLOAT;
113         $this->assertSame(MIN_UINT32, $arr[MIN_UINT32]);
114         $this->assertEquals(3, count($arr));
115         unset($arr[3.1]);
116         unset($arr[-1.0]);
117         unset($arr[MIN_UINT32_FLOAT]);
118         $this->assertEquals(0, count($arr));
119
120         // Test string argument.
121         $arr[MAX_UINT32_STRING] = MAX_UINT32_STRING;
122         $this->assertSame(-1, $arr[-1]);
123         $this->assertEquals(1, count($arr));
124         unset($arr[MAX_UINT32_STRING]);
125         $this->assertEquals(0, count($arr));
126
127         $arr['7'] = '7';
128         $this->assertSame(7, $arr[7]);
129         $arr['3.1'] = '3.1';
130         $this->assertSame(3, $arr[3]);
131         $arr['-1.0'] = '-1.0';
132         $this->assertSame(-1, $arr[-1]);
133         $arr[MIN_UINT32_STRING] = MIN_UINT32_STRING;
134         $this->assertSame(MIN_UINT32, $arr[MIN_UINT32]);
135         $this->assertEquals(4, count($arr));
136         unset($arr['7']);
137         unset($arr['3.1']);
138         unset($arr['-1.0']);
139         unset($arr[MIN_UINT32_STRING]);
140         $this->assertEquals(0, count($arr));
141     }
142
143     #########################################################
144     # Test int64 field.
145     #########################################################
146
147     public function testInt64() {
148         $arr = new MapField(GPBType::INT64, GPBType::INT64);
149
150         // Test integer argument.
151         $arr[MAX_INT64] = MAX_INT64;
152         $arr[MIN_INT64] = MIN_INT64;
153         if (PHP_INT_SIZE == 4) {
154             $this->assertSame(MAX_INT64_STRING, $arr[MAX_INT64_STRING]);
155             $this->assertSame(MIN_INT64_STRING, $arr[MIN_INT64_STRING]);
156         } else {
157             $this->assertSame(MAX_INT64, $arr[MAX_INT64]);
158             $this->assertSame(MIN_INT64, $arr[MIN_INT64]);
159         }
160         $this->assertEquals(2, count($arr));
161         unset($arr[MAX_INT64]);
162         unset($arr[MIN_INT64]);
163         $this->assertEquals(0, count($arr));
164
165         // Test float argument.
166         $arr[1.1] = 1.1;
167         if (PHP_INT_SIZE == 4) {
168             $this->assertSame('1', $arr['1']);
169         } else {
170             $this->assertSame(1, $arr[1]);
171         }
172         $this->assertEquals(1, count($arr));
173         unset($arr[1.1]);
174         $this->assertEquals(0, count($arr));
175
176         // Test string argument.
177         $arr['2'] = '2';
178         $arr['3.1'] = '3.1';
179         $arr[MAX_INT64_STRING] = MAX_INT64_STRING;
180         $arr[MIN_INT64_STRING] = MIN_INT64_STRING;
181         if (PHP_INT_SIZE == 4) {
182             $this->assertSame('2', $arr['2']);
183             $this->assertSame('3', $arr['3']);
184             $this->assertSame(MAX_INT64_STRING, $arr[MAX_INT64_STRING]);
185             $this->assertSame(MIN_INT64_STRING, $arr[MIN_INT64_STRING]);
186         } else {
187             $this->assertSame(2, $arr[2]);
188             $this->assertSame(3, $arr[3]);
189             $this->assertSame(MAX_INT64, $arr[MAX_INT64]);
190             $this->assertSame(MIN_INT64, $arr[MIN_INT64]);
191         }
192         $this->assertEquals(4, count($arr));
193         unset($arr['2']);
194         unset($arr['3.1']);
195         unset($arr[MAX_INT64_STRING]);
196         unset($arr[MIN_INT64_STRING]);
197         $this->assertEquals(0, count($arr));
198     }
199
200     #########################################################
201     # Test uint64 field.
202     #########################################################
203
204     public function testUint64() {
205         $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
206
207         // Test integer argument.
208         $arr[MAX_UINT64] = MAX_UINT64;
209         if (PHP_INT_SIZE == 4) {
210             $this->assertSame(MAX_UINT64_STRING, $arr[MAX_UINT64_STRING]);
211         } else {
212             $this->assertSame(MAX_UINT64, $arr[MAX_UINT64]);
213         }
214         $this->assertEquals(1, count($arr));
215         unset($arr[MAX_UINT64]);
216         $this->assertEquals(0, count($arr));
217
218         // Test float argument.
219         $arr[1.1] = 1.1;
220         if (PHP_INT_SIZE == 4) {
221             $this->assertSame('1', $arr['1']);
222         } else {
223             $this->assertSame(1, $arr[1]);
224         }
225         $this->assertEquals(1, count($arr));
226         unset($arr[1.1]);
227         $this->assertEquals(0, count($arr));
228
229         // Test string argument.
230         $arr['2'] = '2';
231         $arr['3.1'] = '3.1';
232         $arr[MAX_UINT64_STRING] = MAX_UINT64_STRING;
233
234         if (PHP_INT_SIZE == 4) {
235             $this->assertSame('2', $arr['2']);
236             $this->assertSame('3', $arr['3']);
237             $this->assertSame(MAX_UINT64_STRING, $arr[MAX_UINT64_STRING]);
238         } else {
239             $this->assertSame(2, $arr[2]);
240             $this->assertSame(3, $arr[3]);
241             $this->assertSame(MAX_UINT64, $arr[MAX_UINT64]);
242         }
243
244         $this->assertEquals(3, count($arr));
245         unset($arr['2']);
246         unset($arr['3.1']);
247         unset($arr[MAX_UINT64_STRING]);
248         $this->assertEquals(0, count($arr));
249     }
250
251     #########################################################
252     # Test float field.
253     #########################################################
254
255     public function testFloat() {
256         $arr = new MapField(GPBType::INT32, GPBType::FLOAT);
257
258         // Test set.
259         $arr[0] = 1;
260         $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
261
262         $arr[1] = 1.1;
263         $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
264
265         $arr[2] = '2';
266         $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
267         $arr[3] = '3.1';
268         $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
269
270         $this->assertEquals(4, count($arr));
271     }
272
273     #########################################################
274     # Test double field.
275     #########################################################
276
277     public function testDouble() {
278         $arr = new MapField(GPBType::INT32, GPBType::DOUBLE);
279
280         // Test set.
281         $arr[0] = 1;
282         $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
283
284         $arr[1] = 1.1;
285         $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
286
287         $arr[2] = '2';
288         $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
289         $arr[3] = '3.1';
290         $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
291
292         $this->assertEquals(4, count($arr));
293     }
294
295     #########################################################
296     # Test bool field.
297     #########################################################
298
299     public function testBool() {
300         $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
301
302         // Test boolean.
303         $arr[True] = True;
304         $this->assertSame(True, $arr[True]);
305         $this->assertEquals(1, count($arr));
306         unset($arr[True]);
307         $this->assertEquals(0, count($arr));
308
309         $arr[False] = False;
310         $this->assertSame(False, $arr[False]);
311         $this->assertEquals(1, count($arr));
312         unset($arr[False]);
313         $this->assertEquals(0, count($arr));
314
315         // Test integer.
316         $arr[-1] = -1;
317         $this->assertSame(True, $arr[True]);
318         $this->assertEquals(1, count($arr));
319         unset($arr[-1]);
320         $this->assertEquals(0, count($arr));
321
322         $arr[0] = 0;
323         $this->assertSame(False, $arr[False]);
324         $this->assertEquals(1, count($arr));
325         unset($arr[0]);
326         $this->assertEquals(0, count($arr));
327
328         // Test float.
329         $arr[1.1] = 1.1;
330         $this->assertSame(True, $arr[True]);
331         $this->assertEquals(1, count($arr));
332         unset($arr[1.1]);
333         $this->assertEquals(0, count($arr));
334
335         $arr[0.0] = 0.0;
336         $this->assertSame(False, $arr[False]);
337         $this->assertEquals(1, count($arr));
338         unset($arr[0.0]);
339         $this->assertEquals(0, count($arr));
340
341         // Test string.
342         $arr['a'] = 'a';
343         $this->assertSame(True, $arr[True]);
344         $this->assertEquals(1, count($arr));
345         unset($arr['a']);
346         $this->assertEquals(0, count($arr));
347
348         $arr[''] = '';
349         $this->assertSame(False, $arr[False]);
350         $this->assertEquals(1, count($arr));
351         unset($arr['']);
352         $this->assertEquals(0, count($arr));
353     }
354
355     #########################################################
356     # Test string field.
357     #########################################################
358
359     public function testString() {
360         $arr = new MapField(GPBType::STRING, GPBType::STRING);
361
362         // Test set.
363         $arr['abc'] = 'abc';
364         $this->assertSame('abc', $arr['abc']);
365         $this->assertEquals(1, count($arr));
366         unset($arr['abc']);
367         $this->assertEquals(0, count($arr));
368
369         $arr[1] = 1;
370         $this->assertSame('1', $arr['1']);
371         $this->assertEquals(1, count($arr));
372         unset($arr[1]);
373         $this->assertEquals(0, count($arr));
374
375         $arr[1.1] = 1.1;
376         $this->assertSame('1.1', $arr['1.1']);
377         $this->assertEquals(1, count($arr));
378         unset($arr[1.1]);
379         $this->assertEquals(0, count($arr));
380
381         $arr[True] = True;
382         $this->assertSame('1', $arr['1']);
383         $this->assertEquals(1, count($arr));
384         unset($arr[True]);
385         $this->assertEquals(0, count($arr));
386
387         // Test foreach.
388         $arr = new MapField(GPBType::STRING, GPBType::STRING);
389         for ($i = 0; $i < 3; $i++) {
390           $arr[$i] = $i;
391         }
392         $i = 0;
393         $arr_test = [];
394         foreach ($arr as $key => $val) {
395           $this->assertSame($key, $val);
396           $arr_test[] = $key;
397           $i++;
398         }
399         $this->assertTrue(isset($arr_test['0']));
400         $this->assertTrue(isset($arr_test['1']));
401         $this->assertTrue(isset($arr_test['2']));
402         $this->assertSame(3, $i);
403     }
404
405     #########################################################
406     # Test message field.
407     #########################################################
408
409     public function testMessage() {
410         $arr = new MapField(GPBType::INT32,
411             GPBType::MESSAGE, Sub::class);
412
413         // Test append.
414         $sub_m = new Sub();
415         $sub_m->setA(1);
416         $arr[0] = $sub_m;
417         $this->assertSame(1, $arr[0]->getA());
418
419         $this->assertEquals(1, count($arr));
420
421         // Test foreach.
422         $arr = new MapField(GPBType::INT32,
423             GPBType::MESSAGE, Sub::class);
424         for ($i = 0; $i < 3; $i++) {
425           $arr[$i] = new Sub();;
426           $arr[$i]->setA($i);
427         }
428         $i = 0;
429         $key_test = [];
430         $value_test = [];
431         foreach ($arr as $key => $val) {
432           $key_test[] = $key;
433           $value_test[] = $val->getA();
434           $i++;
435         }
436         $this->assertTrue(isset($key_test['0']));
437         $this->assertTrue(isset($key_test['1']));
438         $this->assertTrue(isset($key_test['2']));
439         $this->assertTrue(isset($value_test['0']));
440         $this->assertTrue(isset($value_test['1']));
441         $this->assertTrue(isset($value_test['2']));
442         $this->assertSame(3, $i);
443     }
444
445     #########################################################
446     # Test reference in map
447     #########################################################
448
449     public function testMapElementIsReference()
450     {
451         // Bool elements
452         $values = [true => true];
453         array_walk($values, function (&$value) {});
454         $m = new TestMessage();
455         $m->setMapBoolBool($values);
456
457         // Int32 elements
458         $values = [1 => 1];
459         array_walk($values, function (&$value) {});
460         $m = new TestMessage();
461         $m->setMapInt32Int32($values);
462
463         // Double elements
464         $values = [1 => 1.0];
465         array_walk($values, function (&$value) {});
466         $m = new TestMessage();
467         $m->setMapInt32Double($values);
468
469         // String elements
470         $values = ['a' => 'a'];
471         array_walk($values, function (&$value) {});
472         $m = new TestMessage();
473         $m->setMapStringString($values);
474
475         // Message elements
476         $values = [1 => new Sub()];
477         array_walk($values, function (&$value) {});
478         $m = new TestMessage();
479         $m->setMapInt32Message($values);
480     }
481
482     #########################################################
483     # Test memory leak
484     #########################################################
485
486     // TODO(teboring): Add it back.
487     // public function testCycleLeak()
488     // {
489     //     $arr = new MapField(GPBType::INT32,
490     //         GPBType::MESSAGE, TestMessage::class);
491     //     $arr[0] = new TestMessage;
492     //     $arr[0]->SetMapRecursive($arr);
493
494     //     // Clean up memory before test.
495     //     gc_collect_cycles();
496     //     $start = memory_get_usage();
497     //     unset($arr);
498
499     //     // Explicitly trigger garbage collection.
500     //     gc_collect_cycles();
501
502     //     $end = memory_get_usage();
503     //     $this->assertLessThan($start, $end);
504     // }
505 }