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