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