array_test.php 15.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
<?php

require_once('test_util.php');

use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBType;
use Foo\TestMessage;
use Foo\TestMessage_Sub;

class RepeatedFieldTest extends PHPUnit_Framework_TestCase
{

    #########################################################
    # Test int32 field.
    #########################################################

    public function testInt32()
    {
        $arr = new RepeatedField(GPBType::INT32);

        // Test append.
22
        $arr[] = MAX_INT32;
23
        $this->assertSame(MAX_INT32, $arr[0]);
24
        $arr[] = MIN_INT32;
25 26
        $this->assertSame(MIN_INT32, $arr[1]);

27
        $arr[] = 1.1;
28
        $this->assertSame(1, $arr[2]);
29
        $arr[] = MAX_INT32_FLOAT;
30
        $this->assertSame(MAX_INT32, $arr[3]);
31
        $arr[] = MAX_INT32_FLOAT;
32 33
        $this->assertSame(MAX_INT32, $arr[4]);

34
        $arr[] = '2';
35
        $this->assertSame(2, $arr[5]);
36
        $arr[] = '3.1';
37
        $this->assertSame(3, $arr[6]);
38
        $arr[] = MAX_INT32_STRING;
39 40 41 42 43 44 45 46 47 48
        $this->assertSame(MAX_INT32, $arr[7]);

        $this->assertEquals(8, count($arr));

        for ($i = 0; $i < count($arr); $i++) {
            $arr[$i] = 0;
            $this->assertSame(0, $arr[$i]);
        }

        // Test set.
49
        $arr[0] = MAX_INT32;
50
        $this->assertSame(MAX_INT32, $arr[0]);
51
        $arr[1] = MIN_INT32;
52 53
        $this->assertSame(MIN_INT32, $arr[1]);

54
        $arr[2] = 1.1;
55
        $this->assertSame(1, $arr[2]);
56
        $arr[3] = MAX_INT32_FLOAT;
57
        $this->assertSame(MAX_INT32, $arr[3]);
58
        $arr[4] = MAX_INT32_FLOAT;
59 60
        $this->assertSame(MAX_INT32, $arr[4]);

61
        $arr[5] = '2';
62
        $this->assertSame(2, $arr[5]);
63
        $arr[6] = '3.1';
64
        $this->assertSame(3, $arr[6]);
65
        $arr[7] = MAX_INT32_STRING;
66
        $this->assertSame(MAX_INT32, $arr[7]);
67 68 69 70

        // Test foreach.
        $arr = new RepeatedField(GPBType::INT32);
        for ($i = 0; $i < 3; $i++) {
71
          $arr[] = $i;
72 73 74 75 76 77
        }
        $i = 0;
        foreach ($arr as $val) {
          $this->assertSame($i++, $val);
        }
        $this->assertSame(3, $i);
78 79 80 81 82 83 84 85 86 87 88
    }

    #########################################################
    # Test uint32 field.
    #########################################################

    public function testUint32()
    {
        $arr = new RepeatedField(GPBType::UINT32);

        // Test append.
89
        $arr[] = MAX_UINT32;
90
        $this->assertSame(-1, $arr[0]);
91
        $arr[] = -1;
92
        $this->assertSame(-1, $arr[1]);
93
        $arr[] = MIN_UINT32;
94 95
        $this->assertSame(MIN_UINT32, $arr[2]);

96
        $arr[] = 1.1;
97
        $this->assertSame(1, $arr[3]);
98
        $arr[] = MAX_UINT32_FLOAT;
99
        $this->assertSame(-1, $arr[4]);
100
        $arr[] = -1.0;
101
        $this->assertSame(-1, $arr[5]);
102
        $arr[] = MIN_UINT32_FLOAT;
103 104
        $this->assertSame(MIN_UINT32, $arr[6]);

105
        $arr[] = '2';
106
        $this->assertSame(2, $arr[7]);
107
        $arr[] = '3.1';
108
        $this->assertSame(3, $arr[8]);
109
        $arr[] = MAX_UINT32_STRING;
110
        $this->assertSame(-1, $arr[9]);
111
        $arr[] = '-1.0';
112
        $this->assertSame(-1, $arr[10]);
113
        $arr[] = MIN_UINT32_STRING;
114 115 116 117 118 119 120 121 122 123
        $this->assertSame(MIN_UINT32, $arr[11]);

        $this->assertEquals(12, count($arr));

        for ($i = 0; $i < count($arr); $i++) {
            $arr[$i] = 0;
            $this->assertSame(0, $arr[$i]);
        }

        // Test set.
124
        $arr[0] = MAX_UINT32;
125
        $this->assertSame(-1, $arr[0]);
126
        $arr[1] = -1;
127
        $this->assertSame(-1, $arr[1]);
128
        $arr[2] = MIN_UINT32;
129 130
        $this->assertSame(MIN_UINT32, $arr[2]);

131
        $arr[3] = 1.1;
132
        $this->assertSame(1, $arr[3]);
133
        $arr[4] = MAX_UINT32_FLOAT;
134
        $this->assertSame(-1, $arr[4]);
135
        $arr[5] = -1.0;
136
        $this->assertSame(-1, $arr[5]);
137
        $arr[6] = MIN_UINT32_FLOAT;
138 139
        $this->assertSame(MIN_UINT32, $arr[6]);

140
        $arr[7] = '2';
141
        $this->assertSame(2, $arr[7]);
142
        $arr[8] = '3.1';
143
        $this->assertSame(3, $arr[8]);
144
        $arr[9] = MAX_UINT32_STRING;
145
        $this->assertSame(-1, $arr[9]);
146
        $arr[10] = '-1.0';
147
        $this->assertSame(-1, $arr[10]);
148
        $arr[11] = MIN_UINT32_STRING;
149 150 151 152 153 154 155 156 157 158 159 160
        $this->assertSame(MIN_UINT32, $arr[11]);
    }

    #########################################################
    # Test int64 field.
    #########################################################

    public function testInt64()
    {
        $arr = new RepeatedField(GPBType::INT64);

        // Test append.
161 162 163 164 165 166 167
        $arr[] = MAX_INT64;
        $arr[] = MIN_INT64;
        $arr[] = 1.1;
        $arr[] = '2';
        $arr[] = '3.1';
        $arr[] = MAX_INT64_STRING;
        $arr[] = MIN_INT64_STRING;
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
        if (PHP_INT_SIZE == 4) {
            $this->assertSame(MAX_INT64, $arr[0]);
            $this->assertSame(MIN_INT64, $arr[1]);
            $this->assertSame('1', $arr[2]);
            $this->assertSame('2', $arr[3]);
            $this->assertSame('3', $arr[4]);
            $this->assertSame(MAX_INT64_STRING, $arr[5]);
            $this->assertSame(MIN_INT64_STRING, $arr[6]);
        } else {
            $this->assertSame(MAX_INT64, $arr[0]);
            $this->assertSame(MIN_INT64, $arr[1]);
            $this->assertSame(1, $arr[2]);
            $this->assertSame(2, $arr[3]);
            $this->assertSame(3, $arr[4]);
            $this->assertSame(MAX_INT64, $arr[5]);
            $this->assertSame(MIN_INT64, $arr[6]);
        }

186 187 188 189 190

        $this->assertEquals(7, count($arr));

        for ($i = 0; $i < count($arr); $i++) {
            $arr[$i] = 0;
191 192 193 194 195
            if (PHP_INT_SIZE == 4) {
                $this->assertSame('0', $arr[$i]);
            } else {
                $this->assertSame(0, $arr[$i]);
            }
196 197 198
        }

        // Test set.
199 200 201 202 203 204 205
        $arr[0] = MAX_INT64;
        $arr[1] = MIN_INT64;
        $arr[2] = 1.1;
        $arr[3] = '2';
        $arr[4] = '3.1';
        $arr[5] = MAX_INT64_STRING;
        $arr[6] = MIN_INT64_STRING;
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223

        if (PHP_INT_SIZE == 4) {
            $this->assertSame(MAX_INT64_STRING, $arr[0]);
            $this->assertSame(MIN_INT64_STRING, $arr[1]);
            $this->assertSame('1', $arr[2]);
            $this->assertSame('2', $arr[3]);
            $this->assertSame('3', $arr[4]);
            $this->assertSame(MAX_INT64_STRING, $arr[5]);
            $this->assertEquals(MIN_INT64_STRING, $arr[6]);
        } else {
            $this->assertSame(MAX_INT64, $arr[0]);
            $this->assertSame(MIN_INT64, $arr[1]);
            $this->assertSame(1, $arr[2]);
            $this->assertSame(2, $arr[3]);
            $this->assertSame(3, $arr[4]);
            $this->assertSame(MAX_INT64, $arr[5]);
            $this->assertEquals(MIN_INT64, $arr[6]);
        }
224 225 226 227 228 229 230 231 232 233 234
    }

    #########################################################
    # Test uint64 field.
    #########################################################

    public function testUint64()
    {
        $arr = new RepeatedField(GPBType::UINT64);

        // Test append.
235 236 237 238 239
        $arr[] = MAX_UINT64;
        $arr[] = 1.1;
        $arr[] = '2';
        $arr[] = '3.1';
        $arr[] = MAX_UINT64_STRING;
240

241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
        if (PHP_INT_SIZE == 4) {
            $this->assertSame(MAX_UINT64_STRING, $arr[0]);
            $this->assertSame('1', $arr[1]);
            $this->assertSame('2', $arr[2]);
            $this->assertSame('3', $arr[3]);
            $this->assertSame(MAX_UINT64_STRING, $arr[4]);
        } else {
            $this->assertSame(MAX_UINT64, $arr[0]);
            $this->assertSame(1, $arr[1]);
            $this->assertSame(2, $arr[2]);
            $this->assertSame(3, $arr[3]);
            $this->assertSame(MAX_UINT64, $arr[4]);
            $this->assertSame(5, count($arr));
        }

        $this->assertSame(5, count($arr));
257 258 259

        for ($i = 0; $i < count($arr); $i++) {
            $arr[$i] = 0;
260 261 262 263 264
            if (PHP_INT_SIZE == 4) {
                $this->assertSame('0', $arr[$i]);
            } else {
                $this->assertSame(0, $arr[$i]);
            }
265 266 267
        }

        // Test set.
268 269 270 271 272
        $arr[0] = MAX_UINT64;
        $arr[1] = 1.1;
        $arr[2] = '2';
        $arr[3] = '3.1';
        $arr[4] = MAX_UINT64_STRING;
273 274 275 276 277 278 279 280 281 282 283 284 285 286

        if (PHP_INT_SIZE == 4) {
            $this->assertSame(MAX_UINT64_STRING, $arr[0]);
            $this->assertSame('1', $arr[1]);
            $this->assertSame('2', $arr[2]);
            $this->assertSame('3', $arr[3]);
            $this->assertSame(MAX_UINT64_STRING, $arr[4]);
        } else {
            $this->assertSame(MAX_UINT64, $arr[0]);
            $this->assertSame(1, $arr[1]);
            $this->assertSame(2, $arr[2]);
            $this->assertSame(3, $arr[3]);
            $this->assertSame(MAX_UINT64, $arr[4]);
        }
287 288 289 290 291 292 293 294 295 296 297
    }

    #########################################################
    # Test float field.
    #########################################################

    public function testFloat()
    {
        $arr = new RepeatedField(GPBType::FLOAT);

        // Test append.
298
        $arr[] = 1;
299 300
        $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);

301
        $arr[] = 1.1;
302 303
        $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);

304
        $arr[] = '2';
305
        $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
306
        $arr[] = '3.1';
307 308 309 310 311 312 313 314 315 316
        $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);

        $this->assertEquals(4, count($arr));

        for ($i = 0; $i < count($arr); $i++) {
            $arr[$i] = 0;
            $this->assertSame(0.0, $arr[$i]);
        }

        // Test set.
317
        $arr[0] = 1;
318 319
        $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);

320
        $arr[1] = 1.1;
321 322
        $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);

323
        $arr[2] = '2';
324
        $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
325
        $arr[3] = '3.1';
326 327 328 329 330 331 332 333 334 335 336 337
        $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
    }

    #########################################################
    # Test double field.
    #########################################################

    public function testDouble()
    {
        $arr = new RepeatedField(GPBType::DOUBLE);

        // Test append.
338
        $arr[] = 1;
339 340
        $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);

341
        $arr[] = 1.1;
342 343
        $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);

344
        $arr[] = '2';
345
        $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
346
        $arr[] = '3.1';
347 348 349 350 351 352 353 354 355 356
        $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);

        $this->assertEquals(4, count($arr));

        for ($i = 0; $i < count($arr); $i++) {
            $arr[$i] = 0;
            $this->assertSame(0.0, $arr[$i]);
        }

        // Test set.
357
        $arr[0] = 1;
358 359
        $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);

360
        $arr[1] = 1.1;
361 362
        $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);

363
        $arr[2] = '2';
364
        $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
365
        $arr[3] = '3.1';
366 367 368 369 370 371 372 373 374 375 376 377
        $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
    }

    #########################################################
    # Test bool field.
    #########################################################

    public function testBool()
    {
        $arr = new RepeatedField(GPBType::BOOL);

        // Test append.
378
        $arr[] = true;
379 380
        $this->assertSame(true, $arr[0]);

381
        $arr[] = -1;
382 383
        $this->assertSame(true, $arr[1]);

384
        $arr[] = 1.1;
385 386
        $this->assertSame(true, $arr[2]);

387
        $arr[] = '';
388 389 390 391 392 393 394 395 396 397
        $this->assertSame(false, $arr[3]);

        $this->assertEquals(4, count($arr));

        for ($i = 0; $i < count($arr); $i++) {
            $arr[$i] = 0;
            $this->assertSame(false, $arr[$i]);
        }

        // Test set.
398
        $arr[0] = true;
399 400
        $this->assertSame(true, $arr[0]);

401
        $arr[1] = -1;
402 403
        $this->assertSame(true, $arr[1]);

404
        $arr[2] = 1.1;
405 406
        $this->assertSame(true, $arr[2]);

407
        $arr[3] = '';
408 409 410 411 412 413 414 415 416 417 418 419
        $this->assertSame(false, $arr[3]);
    }

    #########################################################
    # Test string field.
    #########################################################

    public function testString()
    {
        $arr = new RepeatedField(GPBType::STRING);

        // Test append.
420
        $arr[] = 'abc';
421 422
        $this->assertSame('abc', $arr[0]);

423
        $arr[] = 1;
424 425
        $this->assertSame('1', $arr[1]);

426
        $arr[] = 1.1;
427 428
        $this->assertSame('1.1', $arr[2]);

429
        $arr[] = true;
430 431 432 433 434 435 436 437 438 439
        $this->assertSame('1', $arr[3]);

        $this->assertEquals(4, count($arr));

        for ($i = 0; $i < count($arr); $i++) {
            $arr[$i] = '';
            $this->assertSame('', $arr[$i]);
        }

        // Test set.
440
        $arr[0] = 'abc';
441 442
        $this->assertSame('abc', $arr[0]);

443
        $arr[1] = 1;
444 445
        $this->assertSame('1', $arr[1]);

446
        $arr[2] = 1.1;
447 448
        $this->assertSame('1.1', $arr[2]);

449
        $arr[3] = true;
450 451 452 453 454 455 456 457 458 459 460 461 462 463
        $this->assertSame('1', $arr[3]);
    }

    #########################################################
    # Test message field.
    #########################################################

    public function testMessage()
    {
        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);

        // Test append.
        $sub_m = new TestMessage_Sub();
        $sub_m->setA(1);
464
        $arr[] = $sub_m;
465 466
        $this->assertSame(1, $arr[0]->getA());

467
        $this->assertEquals(1, count($arr));
468 469

        // Test set.
470 471
        $sub_m = new TestMessage_Sub();
        $sub_m->setA(2);
472
        $arr[0] = $sub_m;
473
        $this->assertSame(2, $arr[0]->getA());
474 475 476 477 478 479 480 481 482 483 484 485

        // Test foreach.
        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class);
        for ($i = 0; $i < 3; $i++) {
          $arr[] = new TestMessage_Sub();
          $arr[$i]->setA($i);
        }
        $i = 0;
        foreach ($arr as $val) {
          $this->assertSame($i++, $val->getA());
        }
        $this->assertSame(3, $i);
486 487 488 489 490 491 492 493 494
    }

    #########################################################
    # Test offset type
    #########################################################

    public function testOffset()
    {
        $arr = new RepeatedField(GPBType::INT32);
495
        $arr[] = 0;
496

497
        $arr[0] = 1;
498 499 500
        $this->assertSame(1, $arr[0]);
        $this->assertSame(1, count($arr));

501
        $arr['0'] = 2;
502 503 504 505
        $this->assertSame(2, $arr['0']);
        $this->assertSame(2, $arr[0]);
        $this->assertSame(1, count($arr));

506
        $arr[0.0] = 3;
507 508 509 510
        $this->assertSame(3, $arr[0.0]);
        $this->assertSame(1, count($arr));
    }

511 512 513 514
    public function testInsertRemoval()
    {
        $arr = new RepeatedField(GPBType::INT32);

515 516 517
        $arr[] = 0;
        $arr[] = 1;
        $arr[] = 2;
518 519 520 521 522 523 524
        $this->assertSame(3, count($arr));

        unset($arr[2]);
        $this->assertSame(2, count($arr));
        $this->assertSame(0, $arr[0]);
        $this->assertSame(1, $arr[1]);

525
        $arr[] = 3;
526 527 528 529 530
        $this->assertSame(3, count($arr));
        $this->assertSame(0, $arr[0]);
        $this->assertSame(1, $arr[1]);
        $this->assertSame(3, $arr[2]);
    }
531 532 533 534 535

    #########################################################
    # Test memory leak
    #########################################################

536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
    public function testCycleLeak()
    {
        gc_collect_cycles();
        $arr = new RepeatedField(GPBType::MESSAGE, TestMessage::class);
        $arr[] = new TestMessage;
        $arr[0]->SetRepeatedRecursive($arr);

        // Clean up memory before test.
        gc_collect_cycles();
        $start = memory_get_usage();
        unset($arr);

        // Explicitly trigger garbage collection.
        gc_collect_cycles();

        $end = memory_get_usage();
        $this->assertLessThan($start, $end);
    }
554
}