Import cobalt 25.master.0.1034729
diff --git a/third_party/protobuf/php/tests/array_test.php b/third_party/protobuf/php/tests/array_test.php
new file mode 100644
index 0000000..b251404
--- /dev/null
+++ b/third_party/protobuf/php/tests/array_test.php
@@ -0,0 +1,593 @@
+<?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.
+ $arr[] = MAX_INT32;
+ $this->assertSame(MAX_INT32, $arr[0]);
+ $arr[] = MIN_INT32;
+ $this->assertSame(MIN_INT32, $arr[1]);
+
+ $arr[] = 1.1;
+ $this->assertSame(1, $arr[2]);
+ $arr[] = MAX_INT32_FLOAT;
+ $this->assertSame(MAX_INT32, $arr[3]);
+ $arr[] = MAX_INT32_FLOAT;
+ $this->assertSame(MAX_INT32, $arr[4]);
+
+ $arr[] = '2';
+ $this->assertSame(2, $arr[5]);
+ $arr[] = '3.1';
+ $this->assertSame(3, $arr[6]);
+ $arr[] = MAX_INT32_STRING;
+ $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.
+ $arr[0] = MAX_INT32;
+ $this->assertSame(MAX_INT32, $arr[0]);
+ $arr[1] = MIN_INT32;
+ $this->assertSame(MIN_INT32, $arr[1]);
+
+ $arr[2] = 1.1;
+ $this->assertSame(1, $arr[2]);
+ $arr[3] = MAX_INT32_FLOAT;
+ $this->assertSame(MAX_INT32, $arr[3]);
+ $arr[4] = MAX_INT32_FLOAT;
+ $this->assertSame(MAX_INT32, $arr[4]);
+
+ $arr[5] = '2';
+ $this->assertSame(2, $arr[5]);
+ $arr[6] = '3.1';
+ $this->assertSame(3, $arr[6]);
+ $arr[7] = MAX_INT32_STRING;
+ $this->assertSame(MAX_INT32, $arr[7]);
+
+ // Test foreach.
+ $arr = new RepeatedField(GPBType::INT32);
+ for ($i = 0; $i < 3; $i++) {
+ $arr[] = $i;
+ }
+ $i = 0;
+ foreach ($arr as $val) {
+ $this->assertSame($i++, $val);
+ }
+ $this->assertSame(3, $i);
+ }
+
+ #########################################################
+ # Test uint32 field.
+ #########################################################
+
+ public function testUint32()
+ {
+ $arr = new RepeatedField(GPBType::UINT32);
+
+ // Test append.
+ $arr[] = MAX_UINT32;
+ $this->assertSame(-1, $arr[0]);
+ $arr[] = -1;
+ $this->assertSame(-1, $arr[1]);
+ $arr[] = MIN_UINT32;
+ $this->assertSame(MIN_UINT32, $arr[2]);
+
+ $arr[] = 1.1;
+ $this->assertSame(1, $arr[3]);
+ $arr[] = MAX_UINT32_FLOAT;
+ $this->assertSame(-1, $arr[4]);
+ $arr[] = -1.0;
+ $this->assertSame(-1, $arr[5]);
+ $arr[] = MIN_UINT32_FLOAT;
+ $this->assertSame(MIN_UINT32, $arr[6]);
+
+ $arr[] = '2';
+ $this->assertSame(2, $arr[7]);
+ $arr[] = '3.1';
+ $this->assertSame(3, $arr[8]);
+ $arr[] = MAX_UINT32_STRING;
+ $this->assertSame(-1, $arr[9]);
+ $arr[] = '-1.0';
+ $this->assertSame(-1, $arr[10]);
+ $arr[] = MIN_UINT32_STRING;
+ $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.
+ $arr[0] = MAX_UINT32;
+ $this->assertSame(-1, $arr[0]);
+ $arr[1] = -1;
+ $this->assertSame(-1, $arr[1]);
+ $arr[2] = MIN_UINT32;
+ $this->assertSame(MIN_UINT32, $arr[2]);
+
+ $arr[3] = 1.1;
+ $this->assertSame(1, $arr[3]);
+ $arr[4] = MAX_UINT32_FLOAT;
+ $this->assertSame(-1, $arr[4]);
+ $arr[5] = -1.0;
+ $this->assertSame(-1, $arr[5]);
+ $arr[6] = MIN_UINT32_FLOAT;
+ $this->assertSame(MIN_UINT32, $arr[6]);
+
+ $arr[7] = '2';
+ $this->assertSame(2, $arr[7]);
+ $arr[8] = '3.1';
+ $this->assertSame(3, $arr[8]);
+ $arr[9] = MAX_UINT32_STRING;
+ $this->assertSame(-1, $arr[9]);
+ $arr[10] = '-1.0';
+ $this->assertSame(-1, $arr[10]);
+ $arr[11] = MIN_UINT32_STRING;
+ $this->assertSame(MIN_UINT32, $arr[11]);
+ }
+
+ #########################################################
+ # Test int64 field.
+ #########################################################
+
+ public function testInt64()
+ {
+ $arr = new RepeatedField(GPBType::INT64);
+
+ // Test append.
+ $arr[] = MAX_INT64;
+ $arr[] = MIN_INT64;
+ $arr[] = 1.1;
+ $arr[] = '2';
+ $arr[] = '3.1';
+ $arr[] = MAX_INT64_STRING;
+ $arr[] = MIN_INT64_STRING;
+ 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]);
+ }
+
+
+ $this->assertEquals(7, count($arr));
+
+ for ($i = 0; $i < count($arr); $i++) {
+ $arr[$i] = 0;
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('0', $arr[$i]);
+ } else {
+ $this->assertSame(0, $arr[$i]);
+ }
+ }
+
+ // Test set.
+ $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;
+
+ 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]);
+ }
+ }
+
+ #########################################################
+ # Test uint64 field.
+ #########################################################
+
+ public function testUint64()
+ {
+ $arr = new RepeatedField(GPBType::UINT64);
+
+ // Test append.
+ $arr[] = MAX_UINT64;
+ $arr[] = 1.1;
+ $arr[] = '2';
+ $arr[] = '3.1';
+ $arr[] = MAX_UINT64_STRING;
+
+ 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));
+
+ for ($i = 0; $i < count($arr); $i++) {
+ $arr[$i] = 0;
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('0', $arr[$i]);
+ } else {
+ $this->assertSame(0, $arr[$i]);
+ }
+ }
+
+ // Test set.
+ $arr[0] = MAX_UINT64;
+ $arr[1] = 1.1;
+ $arr[2] = '2';
+ $arr[3] = '3.1';
+ $arr[4] = MAX_UINT64_STRING;
+
+ 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]);
+ }
+ }
+
+ #########################################################
+ # Test float field.
+ #########################################################
+
+ public function testFloat()
+ {
+ $arr = new RepeatedField(GPBType::FLOAT);
+
+ // Test append.
+ $arr[] = 1;
+ $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+
+ $arr[] = 1.1;
+ $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+
+ $arr[] = '2';
+ $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+ $arr[] = '3.1';
+ $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.
+ $arr[0] = 1;
+ $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+
+ $arr[1] = 1.1;
+ $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+
+ $arr[2] = '2';
+ $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+ $arr[3] = '3.1';
+ $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
+ }
+
+ #########################################################
+ # Test double field.
+ #########################################################
+
+ public function testDouble()
+ {
+ $arr = new RepeatedField(GPBType::DOUBLE);
+
+ // Test append.
+ $arr[] = 1;
+ $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+
+ $arr[] = 1.1;
+ $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+
+ $arr[] = '2';
+ $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+ $arr[] = '3.1';
+ $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.
+ $arr[0] = 1;
+ $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+
+ $arr[1] = 1.1;
+ $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+
+ $arr[2] = '2';
+ $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+ $arr[3] = '3.1';
+ $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
+ }
+
+ #########################################################
+ # Test bool field.
+ #########################################################
+
+ public function testBool()
+ {
+ $arr = new RepeatedField(GPBType::BOOL);
+
+ // Test append.
+ $arr[] = true;
+ $this->assertSame(true, $arr[0]);
+
+ $arr[] = -1;
+ $this->assertSame(true, $arr[1]);
+
+ $arr[] = 1.1;
+ $this->assertSame(true, $arr[2]);
+
+ $arr[] = '';
+ $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.
+ $arr[0] = true;
+ $this->assertSame(true, $arr[0]);
+
+ $arr[1] = -1;
+ $this->assertSame(true, $arr[1]);
+
+ $arr[2] = 1.1;
+ $this->assertSame(true, $arr[2]);
+
+ $arr[3] = '';
+ $this->assertSame(false, $arr[3]);
+ }
+
+ #########################################################
+ # Test string field.
+ #########################################################
+
+ public function testString()
+ {
+ $arr = new RepeatedField(GPBType::STRING);
+
+ // Test append.
+ $arr[] = 'abc';
+ $this->assertSame('abc', $arr[0]);
+
+ $arr[] = 1;
+ $this->assertSame('1', $arr[1]);
+
+ $arr[] = 1.1;
+ $this->assertSame('1.1', $arr[2]);
+
+ $arr[] = true;
+ $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.
+ $arr[0] = 'abc';
+ $this->assertSame('abc', $arr[0]);
+
+ $arr[1] = 1;
+ $this->assertSame('1', $arr[1]);
+
+ $arr[2] = 1.1;
+ $this->assertSame('1.1', $arr[2]);
+
+ $arr[3] = true;
+ $this->assertSame('1', $arr[3]);
+ }
+
+ #########################################################
+ # Test message field.
+ #########################################################
+
+ public function testMessage()
+ {
+ $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+
+ // Test append.
+ $sub_m = new Sub();
+ $sub_m->setA(1);
+ $arr[] = $sub_m;
+ $this->assertSame(1, $arr[0]->getA());
+
+ $this->assertEquals(1, count($arr));
+
+ // Test set.
+ $sub_m = new Sub();
+ $sub_m->setA(2);
+ $arr[0] = $sub_m;
+ $this->assertSame(2, $arr[0]->getA());
+
+ // Test foreach.
+ $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+ for ($i = 0; $i < 3; $i++) {
+ $arr[] = new Sub();
+ $arr[$i]->setA($i);
+ }
+ $i = 0;
+ foreach ($arr as $val) {
+ $this->assertSame($i++, $val->getA());
+ }
+ $this->assertSame(3, $i);
+ }
+
+ #########################################################
+ # Test offset type
+ #########################################################
+
+ public function testOffset()
+ {
+ $arr = new RepeatedField(GPBType::INT32);
+ $arr[] = 0;
+
+ $arr[0] = 1;
+ $this->assertSame(1, $arr[0]);
+ $this->assertSame(1, count($arr));
+
+ $arr['0'] = 2;
+ $this->assertSame(2, $arr['0']);
+ $this->assertSame(2, $arr[0]);
+ $this->assertSame(1, count($arr));
+
+ $arr[0.0] = 3;
+ $this->assertSame(3, $arr[0.0]);
+ $this->assertSame(1, count($arr));
+ }
+
+ public function testInsertRemoval()
+ {
+ $arr = new RepeatedField(GPBType::INT32);
+
+ $arr[] = 0;
+ $arr[] = 1;
+ $arr[] = 2;
+ $this->assertSame(3, count($arr));
+
+ unset($arr[2]);
+ $this->assertSame(2, count($arr));
+ $this->assertSame(0, $arr[0]);
+ $this->assertSame(1, $arr[1]);
+
+ $arr[] = 3;
+ $this->assertSame(3, count($arr));
+ $this->assertSame(0, $arr[0]);
+ $this->assertSame(1, $arr[1]);
+ $this->assertSame(3, $arr[2]);
+ }
+
+ #########################################################
+ # Test reference in array
+ #########################################################
+
+ public function testArrayElementIsReferenceInSetters()
+ {
+ // Bool elements
+ $values = [true];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setRepeatedBool($values);
+
+ // Int32 elements
+ $values = [1];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setRepeatedInt32($values);
+
+ // Double elements
+ $values = [1.0];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setRepeatedDouble($values);
+
+ // String elements
+ $values = ['a'];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setRepeatedString($values);
+
+ // Message elements
+ $m = new TestMessage();
+ $subs = [1, 2];
+ foreach ($subs as &$sub) {
+ $sub = new Sub(['a' => $sub]);
+ }
+ $m->setRepeatedMessage($subs);
+ }
+
+ #########################################################
+ # Test memory leak
+ #########################################################
+
+ 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);
+ }
+}
diff --git a/third_party/protobuf/php/tests/autoload.php b/third_party/protobuf/php/tests/autoload.php
old mode 100644
new mode 100755
index af88ba0..b98b13a
--- a/third_party/protobuf/php/tests/autoload.php
+++ b/third_party/protobuf/php/tests/autoload.php
@@ -1,4 +1,27 @@
<?php
-require_once('test.pb.php');
-require_once('test_util.php');
+error_reporting(E_ALL);
+
+function getGeneratedFiles($dir, &$results = array())
+{
+ $files = scandir($dir);
+
+ foreach ($files as $key => $value) {
+ $path = realpath($dir.DIRECTORY_SEPARATOR.$value);
+ if (!is_dir($path)) {
+ $results[] = $path;
+ } else if ($value != "." && $value != "..") {
+ getGeneratedFiles($path, $results);
+ }
+ }
+ return $results;
+}
+
+foreach (getGeneratedFiles("generated") as $filename)
+{
+ if (!is_dir($filename)) {
+ include_once $filename;
+ }
+
+}
+
diff --git a/third_party/protobuf/php/tests/bootstrap_phpunit.php b/third_party/protobuf/php/tests/bootstrap_phpunit.php
new file mode 100644
index 0000000..8452f15
--- /dev/null
+++ b/third_party/protobuf/php/tests/bootstrap_phpunit.php
@@ -0,0 +1,5 @@
+<?php
+
+require_once("vendor/autoload.php");
+
+error_reporting(E_ALL);
diff --git a/third_party/protobuf/php/tests/compatibility_test.sh b/third_party/protobuf/php/tests/compatibility_test.sh
new file mode 100755
index 0000000..f4af524
--- /dev/null
+++ b/third_party/protobuf/php/tests/compatibility_test.sh
@@ -0,0 +1,164 @@
+#!/bin/bash
+
+function use_php() {
+ VERSION=$1
+
+ OLD_PATH=$PATH
+ OLD_CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH
+ OLD_C_INCLUDE_PATH=$C_INCLUDE_PATH
+
+ export PATH=/usr/local/php-${VERSION}/bin:$OLD_PATH
+ export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$OLD_CPLUS_INCLUDE_PATH
+ export C_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$OLD_C_INCLUDE_PATH
+}
+
+function generate_proto() {
+ PROTOC1=$1
+ PROTOC2=$2
+
+ rm -rf generated
+ mkdir generated
+
+ $PROTOC1 --php_out=generated proto/test_include.proto
+ $PROTOC2 --php_out=generated \
+ proto/test.proto \
+ proto/test_no_namespace.proto \
+ proto/test_prefix.proto \
+ proto/test_php_namespace.proto \
+ proto/test_empty_php_namespace.proto \
+ proto/test_reserved_enum_lower.proto \
+ proto/test_reserved_enum_upper.proto \
+ proto/test_reserved_enum_value_lower.proto \
+ proto/test_reserved_enum_value_upper.proto \
+ proto/test_reserved_message_lower.proto \
+ proto/test_reserved_message_upper.proto \
+ proto/test_service.proto \
+ proto/test_service_namespace.proto \
+ proto/test_descriptors.proto
+
+ pushd ../../src
+ $PROTOC2 --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto
+ popd
+}
+
+# Remove tests to expect error. These were added to API tests by mistake.
+function remove_error_test() {
+ local TEMPFILE=`tempfile`
+ cat $1 | \
+ awk -v file=`basename $1` -v dir=`basename $(dirname $1)` '
+ BEGIN {
+ show = 1
+ }
+ /@expectedException PHPUnit_Framework_Error/ { show = 0; next; }
+ / *\*\// { print; next; }
+ / *}/ {
+ if (!show) {
+ show = 1;
+ next;
+ }
+ }
+ show { print }
+ ' > $TEMPFILE
+ cp $TEMPFILE $1
+}
+
+set -ex
+
+# Change to the script's directory.
+cd $(dirname $0)
+
+# The old version of protobuf that we are testing compatibility against.
+case "$1" in
+ ""|3.5.0)
+ OLD_VERSION=3.5.0
+ OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/$OLD_VERSION/protoc-$OLD_VERSION-linux-x86_64.exe
+ ;;
+ *)
+ echo "[ERROR]: Unknown version number: $1"
+ exit 1
+ ;;
+esac
+
+# Extract the latest protobuf version number.
+VERSION_NUMBER=`grep "PHP_PROTOBUF_VERSION" ../ext/google/protobuf/protobuf.h | sed "s|#define PHP_PROTOBUF_VERSION \"\(.*\)\"|\1|"`
+
+echo "Running compatibility tests between $VERSION_NUMBER and $OLD_VERSION"
+
+# Check protoc
+[ -f ../../src/protoc ] || {
+ echo "[ERROR]: Please build protoc first."
+ exit 1
+}
+
+# Download old test.
+rm -rf protobuf
+git clone https://github.com/protocolbuffers/protobuf.git
+pushd protobuf
+git checkout v$OLD_VERSION
+popd
+
+# Build and copy the new runtime
+use_php 7.1
+pushd ../ext/google/protobuf
+make clean || true
+phpize && ./configure && make
+popd
+
+rm -rf protobuf/php/ext
+rm -rf protobuf/php/src
+cp -r ../ext protobuf/php/ext/
+cp -r ../src protobuf/php/src/
+
+# Download old version protoc compiler (for linux)
+wget $OLD_VERSION_PROTOC -O old_protoc
+chmod +x old_protoc
+
+NEW_PROTOC=`pwd`/../../src/protoc
+OLD_PROTOC=`pwd`/old_protoc
+cd protobuf/php
+composer install
+
+# Remove implementation detail tests.
+tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php )
+sed -i.bak '/php_implementation_test.php/d' phpunit.xml
+sed -i.bak '/generated_phpdoc_test.php/d' phpunit.xml
+sed -i.bak 's/generated_phpdoc_test.php//g' tests/test.sh
+sed -i.bak 's/generated_service_test.php//g' tests/test.sh
+sed -i.bak '/memory_leak_test.php/d' tests/test.sh
+sed -i.bak '/^ public function testTimestamp()$/,/^ }$/d' tests/well_known_test.php
+sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/array_test.php
+sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/map_field_test.php
+sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/test_base.php
+for t in "${tests[@]}"
+do
+ remove_error_test tests/$t
+done
+
+cd tests
+
+# Test A.1:
+# proto set 1: use old version
+# proto set 2 which may import protos in set 1: use old version
+generate_proto $OLD_PROTOC $OLD_PROTOC
+./test.sh
+pushd ..
+./vendor/bin/phpunit
+popd
+
+# Test A.2:
+# proto set 1: use new version
+# proto set 2 which may import protos in set 1: use old version
+generate_proto $NEW_PROTOC $OLD_PROTOC
+./test.sh
+pushd ..
+./vendor/bin/phpunit
+popd
+
+# Test A.3:
+# proto set 1: use old version
+# proto set 2 which may import protos in set 1: use new version
+generate_proto $OLD_PROTOC $NEW_PROTOC
+./test.sh
+pushd ..
+./vendor/bin/phpunit
+popd
diff --git a/third_party/protobuf/php/tests/compile_extension.sh b/third_party/protobuf/php/tests/compile_extension.sh
new file mode 100755
index 0000000..bbd6696
--- /dev/null
+++ b/third_party/protobuf/php/tests/compile_extension.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+EXTENSION_PATH=$1
+
+pushd $EXTENSION_PATH
+make clean || true
+set -e
+# Add following in configure for debug: --enable-debug CFLAGS='-g -O0'
+phpize && ./configure CFLAGS='-g -O0' && make
+popd
diff --git a/third_party/protobuf/php/tests/descriptors_test.php b/third_party/protobuf/php/tests/descriptors_test.php
new file mode 100644
index 0000000..93683b8
--- /dev/null
+++ b/third_party/protobuf/php/tests/descriptors_test.php
@@ -0,0 +1,246 @@
+<?php
+
+require_once('generated/Descriptors/TestDescriptorsEnum.php');
+require_once('generated/Descriptors/TestDescriptorsMessage.php');
+require_once('test_base.php');
+require_once('test_util.php');
+
+use Google\Protobuf\DescriptorPool;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\MapField;
+use Descriptors\TestDescriptorsEnum;
+use Descriptors\TestDescriptorsMessage;
+use Descriptors\TestDescriptorsMessage\Sub;
+
+class DescriptorsTest extends TestBase
+{
+
+ // Redefine these here for compatibility with c extension
+ const GPBLABEL_OPTIONAL = 1;
+ const GPBLABEL_REQUIRED = 2;
+ const GPBLABEL_REPEATED = 3;
+
+ const GPBTYPE_DOUBLE = 1;
+ const GPBTYPE_FLOAT = 2;
+ const GPBTYPE_INT64 = 3;
+ const GPBTYPE_UINT64 = 4;
+ const GPBTYPE_INT32 = 5;
+ const GPBTYPE_FIXED64 = 6;
+ const GPBTYPE_FIXED32 = 7;
+ const GPBTYPE_BOOL = 8;
+ const GPBTYPE_STRING = 9;
+ const GPBTYPE_GROUP = 10;
+ const GPBTYPE_MESSAGE = 11;
+ const GPBTYPE_BYTES = 12;
+ const GPBTYPE_UINT32 = 13;
+ const GPBTYPE_ENUM = 14;
+ const GPBTYPE_SFIXED32 = 15;
+ const GPBTYPE_SFIXED64 = 16;
+ const GPBTYPE_SINT32 = 17;
+ const GPBTYPE_SINT64 = 18;
+
+ #########################################################
+ # Test descriptor pool.
+ #########################################################
+
+ public function testDescriptorPool()
+ {
+ $pool = DescriptorPool::getGeneratedPool();
+
+ $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
+ $this->assertInstanceOf('\Google\Protobuf\Descriptor', $desc);
+
+ $enumDesc = $pool->getEnumDescriptorByClassName(get_class(new TestDescriptorsEnum()));
+ $this->assertInstanceOf('\Google\Protobuf\EnumDescriptor', $enumDesc);
+ }
+
+ public function testDescriptorPoolIncorrectArgs()
+ {
+ $pool = DescriptorPool::getGeneratedPool();
+
+ $desc = $pool->getDescriptorByClassName('NotAClass');
+ $this->assertNull($desc);
+
+ $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsEnum()));
+ $this->assertNull($desc);
+
+ $enumDesc = $pool->getEnumDescriptorByClassName(get_class(new TestDescriptorsMessage()));
+ $this->assertNull($enumDesc);
+ }
+
+ #########################################################
+ # Test descriptor.
+ #########################################################
+
+ public function testDescriptor()
+ {
+ $pool = DescriptorPool::getGeneratedPool();
+ $class = get_class(new TestDescriptorsMessage());
+ $this->assertSame('Descriptors\TestDescriptorsMessage', $class);
+ $desc = $pool->getDescriptorByClassName($class);
+
+ $this->assertSame('descriptors.TestDescriptorsMessage', $desc->getFullName());
+ $this->assertSame($class, $desc->getClass());
+
+ $this->assertInstanceOf('\Google\Protobuf\FieldDescriptor', $desc->getField(0));
+ $this->assertSame(7, $desc->getFieldCount());
+
+ $this->assertInstanceOf('\Google\Protobuf\OneofDescriptor', $desc->getOneofDecl(0));
+ $this->assertSame(1, $desc->getOneofDeclCount());
+ }
+
+ #########################################################
+ # Test enum descriptor.
+ #########################################################
+
+ public function testEnumDescriptor()
+ {
+ // WARNINIG - we need to do this so that TestDescriptorsEnum is registered!!?
+ new TestDescriptorsMessage();
+
+ $pool = DescriptorPool::getGeneratedPool();
+
+ $enumDesc = $pool->getEnumDescriptorByClassName(get_class(new TestDescriptorsEnum()));
+
+ // Build map of enum values
+ $enumDescMap = [];
+ for ($i = 0; $i < $enumDesc->getValueCount(); $i++) {
+ $enumValueDesc = $enumDesc->getValue($i);
+ $this->assertInstanceOf('\Google\Protobuf\EnumValueDescriptor', $enumValueDesc);
+ $enumDescMap[$enumValueDesc->getNumber()] = $enumValueDesc->getName();
+ }
+
+ $this->assertSame('ZERO', $enumDescMap[0]);
+ $this->assertSame('ONE', $enumDescMap[1]);
+
+ $this->assertSame(2, $enumDesc->getValueCount());
+ }
+
+ #########################################################
+ # Test field descriptor.
+ #########################################################
+
+ public function testFieldDescriptor()
+ {
+ $pool = DescriptorPool::getGeneratedPool();
+ $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
+
+ $fieldDescMap = $this->buildFieldMap($desc);
+
+ // Optional int field
+ $fieldDesc = $fieldDescMap[1];
+ $this->assertSame('optional_int32', $fieldDesc->getName());
+ $this->assertSame(1, $fieldDesc->getNumber());
+ $this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
+ $this->assertSame(self::GPBTYPE_INT32, $fieldDesc->getType());
+ $this->assertFalse($fieldDesc->isMap());
+
+ // Optional enum field
+ $fieldDesc = $fieldDescMap[16];
+ $this->assertSame('optional_enum', $fieldDesc->getName());
+ $this->assertSame(16, $fieldDesc->getNumber());
+ $this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
+ $this->assertSame(self::GPBTYPE_ENUM, $fieldDesc->getType());
+ $this->assertInstanceOf('\Google\Protobuf\EnumDescriptor', $fieldDesc->getEnumType());
+ $this->assertFalse($fieldDesc->isMap());
+
+ // Optional message field
+ $fieldDesc = $fieldDescMap[17];
+ $this->assertSame('optional_message', $fieldDesc->getName());
+ $this->assertSame(17, $fieldDesc->getNumber());
+ $this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
+ $this->assertSame(self::GPBTYPE_MESSAGE, $fieldDesc->getType());
+ $this->assertInstanceOf('\Google\Protobuf\Descriptor', $fieldDesc->getMessageType());
+ $this->assertFalse($fieldDesc->isMap());
+
+ // Repeated int field
+ $fieldDesc = $fieldDescMap[31];
+ $this->assertSame('repeated_int32', $fieldDesc->getName());
+ $this->assertSame(31, $fieldDesc->getNumber());
+ $this->assertSame(self::GPBLABEL_REPEATED, $fieldDesc->getLabel());
+ $this->assertSame(self::GPBTYPE_INT32, $fieldDesc->getType());
+ $this->assertFalse($fieldDesc->isMap());
+
+ // Repeated message field
+ $fieldDesc = $fieldDescMap[47];
+ $this->assertSame('repeated_message', $fieldDesc->getName());
+ $this->assertSame(47, $fieldDesc->getNumber());
+ $this->assertSame(self::GPBLABEL_REPEATED, $fieldDesc->getLabel());
+ $this->assertSame(self::GPBTYPE_MESSAGE, $fieldDesc->getType());
+ $this->assertInstanceOf('\Google\Protobuf\Descriptor', $fieldDesc->getMessageType());
+ $this->assertFalse($fieldDesc->isMap());
+
+ // Oneof int field
+ // Tested further in testOneofDescriptor()
+ $fieldDesc = $fieldDescMap[51];
+ $this->assertSame('oneof_int32', $fieldDesc->getName());
+ $this->assertSame(51, $fieldDesc->getNumber());
+ $this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
+ $this->assertSame(self::GPBTYPE_INT32, $fieldDesc->getType());
+ $this->assertFalse($fieldDesc->isMap());
+
+ // Map int-enum field
+ $fieldDesc = $fieldDescMap[71];
+ $this->assertSame('map_int32_enum', $fieldDesc->getName());
+ $this->assertSame(71, $fieldDesc->getNumber());
+ $this->assertSame(self::GPBLABEL_REPEATED, $fieldDesc->getLabel());
+ $this->assertSame(self::GPBTYPE_MESSAGE, $fieldDesc->getType());
+ $this->assertTrue($fieldDesc->isMap());
+ $mapDesc = $fieldDesc->getMessageType();
+ $this->assertSame('descriptors.TestDescriptorsMessage.MapInt32EnumEntry', $mapDesc->getFullName());
+ $this->assertSame(self::GPBTYPE_INT32, $mapDesc->getField(0)->getType());
+ $this->assertSame(self::GPBTYPE_ENUM, $mapDesc->getField(1)->getType());
+ }
+
+ /**
+ * @expectedException \Exception
+ */
+ public function testFieldDescriptorEnumException()
+ {
+ $pool = DescriptorPool::getGeneratedPool();
+ $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
+ $fieldDesc = $desc->getField(0);
+ $fieldDesc->getEnumType();
+ }
+
+ /**
+ * @expectedException \Exception
+ */
+ public function testFieldDescriptorMessageException()
+ {
+ $pool = DescriptorPool::getGeneratedPool();
+ $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
+ $fieldDesc = $desc->getField(0);
+ $fieldDesc->getMessageType();
+ }
+
+ #########################################################
+ # Test oneof descriptor.
+ #########################################################
+
+ public function testOneofDescriptor()
+ {
+ $pool = DescriptorPool::getGeneratedPool();
+ $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
+
+ $fieldDescMap = $this->buildFieldMap($desc);
+ $fieldDesc = $fieldDescMap[51];
+
+ $oneofDesc = $desc->getOneofDecl(0);
+
+ $this->assertSame('my_oneof', $oneofDesc->getName());
+ $fieldDescFromOneof = $oneofDesc->getField(0);
+ $this->assertSame($fieldDesc, $fieldDescFromOneof);
+ $this->assertSame(1, $oneofDesc->getFieldCount());
+ }
+
+ private function buildFieldMap($desc)
+ {
+ $fieldDescMap = [];
+ for ($i = 0; $i < $desc->getFieldCount(); $i++) {
+ $fieldDesc = $desc->getField($i);
+ $fieldDescMap[$fieldDesc->getNumber()] = $fieldDesc;
+ }
+ return $fieldDescMap;
+ }
+}
diff --git a/third_party/protobuf/php/tests/encode_decode_test.php b/third_party/protobuf/php/tests/encode_decode_test.php
new file mode 100644
index 0000000..5b373bb
--- /dev/null
+++ b/third_party/protobuf/php/tests/encode_decode_test.php
@@ -0,0 +1,1178 @@
+<?php
+
+require_once('test_base.php');
+require_once('test_util.php');
+
+use Google\Protobuf\RepeatedField;
+use Google\Protobuf\GPBType;
+use Foo\TestAny;
+use Foo\TestEnum;
+use Foo\TestMessage;
+use Foo\TestMessage\Sub;
+use Foo\TestPackedMessage;
+use Foo\TestRandomFieldOrder;
+use Foo\TestUnpackedMessage;
+use Google\Protobuf\Any;
+use Google\Protobuf\DoubleValue;
+use Google\Protobuf\FieldMask;
+use Google\Protobuf\FloatValue;
+use Google\Protobuf\Int32Value;
+use Google\Protobuf\UInt32Value;
+use Google\Protobuf\Int64Value;
+use Google\Protobuf\UInt64Value;
+use Google\Protobuf\BoolValue;
+use Google\Protobuf\StringValue;
+use Google\Protobuf\BytesValue;
+use Google\Protobuf\Value;
+use Google\Protobuf\ListValue;
+use Google\Protobuf\Struct;
+use Google\Protobuf\GPBEmpty;
+
+class EncodeDecodeTest extends TestBase
+{
+ public function testDecodeJsonSimple()
+ {
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"optionalInt32\":1}");
+ $this->assertEquals(1, $m->getOptionalInt32());
+ }
+
+ public function testDecodeTopLevelBoolValue()
+ {
+ $m = new BoolValue();
+
+ $m->mergeFromJsonString("true");
+ $this->assertEquals(true, $m->getValue());
+
+ $m->mergeFromJsonString("false");
+ $this->assertEquals(false, $m->getValue());
+ }
+
+ public function testEncodeTopLevelBoolValue()
+ {
+ $m = new BoolValue();
+ $m->setValue(true);
+ $this->assertSame("true", $m->serializeToJsonString());
+ }
+
+ public function testDecodeTopLevelDoubleValue()
+ {
+ $m = new DoubleValue();
+ $m->mergeFromJsonString("1.5");
+ $this->assertEquals(1.5, $m->getValue());
+ }
+
+ public function testEncodeTopLevelDoubleValue()
+ {
+ $m = new DoubleValue();
+ $m->setValue(1.5);
+ $this->assertSame("1.5", $m->serializeToJsonString());
+ }
+
+ public function testDecodeTopLevelFloatValue()
+ {
+ $m = new FloatValue();
+ $m->mergeFromJsonString("1.5");
+ $this->assertEquals(1.5, $m->getValue());
+ }
+
+ public function testEncodeTopLevelFloatValue()
+ {
+ $m = new FloatValue();
+ $m->setValue(1.5);
+ $this->assertSame("1.5", $m->serializeToJsonString());
+ }
+
+ public function testDecodeTopLevelInt32Value()
+ {
+ $m = new Int32Value();
+ $m->mergeFromJsonString("1");
+ $this->assertEquals(1, $m->getValue());
+ }
+
+ public function testEncodeTopLevelInt32Value()
+ {
+ $m = new Int32Value();
+ $m->setValue(1);
+ $this->assertSame("1", $m->serializeToJsonString());
+ }
+
+ public function testDecodeTopLevelUInt32Value()
+ {
+ $m = new UInt32Value();
+ $m->mergeFromJsonString("1");
+ $this->assertEquals(1, $m->getValue());
+ }
+
+ public function testEncodeTopLevelUInt32Value()
+ {
+ $m = new UInt32Value();
+ $m->setValue(1);
+ $this->assertSame("1", $m->serializeToJsonString());
+ }
+
+ public function testDecodeTopLevelInt64Value()
+ {
+ $m = new Int64Value();
+ $m->mergeFromJsonString("1");
+ $this->assertEquals(1, $m->getValue());
+ }
+
+ # public function testEncodeTopLevelInt64Value()
+ # {
+ # $m = new Int64Value();
+ # $m->setValue(1);
+ # $this->assertSame("\"1\"", $m->serializeToJsonString());
+ # }
+
+ public function testDecodeTopLevelUInt64Value()
+ {
+ $m = new UInt64Value();
+ $m->mergeFromJsonString("1");
+ $this->assertEquals(1, $m->getValue());
+ }
+
+ # public function testEncodeTopLevelUInt64Value()
+ # {
+ # $m = new UInt64Value();
+ # $m->setValue(1);
+ # $this->assertSame("\"1\"", $m->serializeToJsonString());
+ # }
+
+ public function testDecodeTopLevelStringValue()
+ {
+ $m = new StringValue();
+ $m->mergeFromJsonString("\"a\"");
+ $this->assertSame("a", $m->getValue());
+ }
+
+ public function testEncodeTopLevelStringValue()
+ {
+ $m = new StringValue();
+ $m->setValue("a");
+ $this->assertSame("\"a\"", $m->serializeToJsonString());
+ }
+
+ public function testDecodeTopLevelBytesValue()
+ {
+ $m = new BytesValue();
+ $m->mergeFromJsonString("\"YQ==\"");
+ $this->assertSame("a", $m->getValue());
+ }
+
+ public function testEncodeTopLevelBytesValue()
+ {
+ $m = new BytesValue();
+ $m->setValue("a");
+ $this->assertSame("\"YQ==\"", $m->serializeToJsonString());
+ }
+
+ public function generateRandomString($length = 10) {
+ $randomString = str_repeat("+", $length);
+ for ($i = 0; $i < $length; $i++) {
+ $randomString[$i] = rand(0, 255);
+ }
+ return $randomString;
+ }
+
+ public function testEncodeTopLevelLongBytesValue()
+ {
+ $m = new BytesValue();
+ $data = $this->generateRandomString(12007);
+ $m->setValue($data);
+ $expected = "\"" . base64_encode($data) . "\"";
+ $this->assertSame(strlen($expected), strlen($m->serializeToJsonString()));
+ }
+
+ public function testEncode()
+ {
+ $from = new TestMessage();
+ $this->expectEmptyFields($from);
+ $this->setFields($from);
+ $this->expectFields($from);
+
+ $data = $from->serializeToString();
+ $this->assertSame(bin2hex(TestUtil::getGoldenTestMessage()),
+ bin2hex($data));
+ }
+
+ public function testDecode()
+ {
+ $to = new TestMessage();
+ $to->mergeFromString(TestUtil::getGoldenTestMessage());
+ $this->expectFields($to);
+ }
+
+ public function testEncodeDecode()
+ {
+ $from = new TestMessage();
+ $this->expectEmptyFields($from);
+ $this->setFields($from);
+ $this->expectFields($from);
+
+ $data = $from->serializeToString();
+
+ $to = new TestMessage();
+ $to->mergeFromString($data);
+ $this->expectFields($to);
+ }
+
+ public function testEncodeDecodeEmpty()
+ {
+ $from = new TestMessage();
+ $this->expectEmptyFields($from);
+
+ $data = $from->serializeToString();
+
+ $to = new TestMessage();
+ $to->mergeFromString($data);
+ $this->expectEmptyFields($to);
+ }
+
+ public function testEncodeDecodeOneof()
+ {
+ $m = new TestMessage();
+
+ $m->setOneofInt32(1);
+ $data = $m->serializeToString();
+ $n = new TestMessage();
+ $n->mergeFromString($data);
+ $this->assertSame(1, $n->getOneofInt32());
+
+ $m->setOneofFloat(2.0);
+ $data = $m->serializeToString();
+ $n = new TestMessage();
+ $n->mergeFromString($data);
+ $this->assertSame(2.0, $n->getOneofFloat());
+
+ $m->setOneofString('abc');
+ $data = $m->serializeToString();
+ $n = new TestMessage();
+ $n->mergeFromString($data);
+ $this->assertSame('abc', $n->getOneofString());
+
+ $sub_m = new Sub();
+ $sub_m->setA(1);
+ $m->setOneofMessage($sub_m);
+ $data = $m->serializeToString();
+ $n = new TestMessage();
+ $n->mergeFromString($data);
+ $this->assertSame(1, $n->getOneofMessage()->getA());
+
+ // Encode default value
+ $m->setOneofEnum(TestEnum::ZERO);
+ $data = $m->serializeToString();
+ $n = new TestMessage();
+ $n->mergeFromString($data);
+ $this->assertSame("oneof_enum", $n->getMyOneof());
+ $this->assertSame(TestEnum::ZERO, $n->getOneofEnum());
+
+ $m->setOneofString("");
+ $data = $m->serializeToString();
+ $n = new TestMessage();
+ $n->mergeFromString($data);
+ $this->assertSame("oneof_string", $n->getMyOneof());
+ $this->assertSame("", $n->getOneofString());
+
+ $sub_m = new Sub();
+ $m->setOneofMessage($sub_m);
+ $data = $m->serializeToString();
+ $n = new TestMessage();
+ $n->mergeFromString($data);
+ $this->assertSame("oneof_message", $n->getMyOneof());
+ $this->assertFalse(is_null($n->getOneofMessage()));
+
+ }
+
+ public function testJsonEncodeDecodeOneof()
+ {
+ $m = new TestMessage();
+
+ $m->setOneofEnum(TestEnum::ONE);
+ $data = $m->serializeToJsonString();
+ $n = new TestMessage();
+ $n->mergeFromJsonString($data);
+ $this->assertSame("oneof_enum", $n->getMyOneof());
+ $this->assertSame(TestEnum::ONE, $n->getOneofEnum());
+
+ $m->setOneofString("a");
+ $data = $m->serializeToJsonString();
+ $n = new TestMessage();
+ $n->mergeFromJsonString($data);
+ $this->assertSame("oneof_string", $n->getMyOneof());
+ $this->assertSame("a", $n->getOneofString());
+
+ $m->setOneofBytes("bbbb");
+ $data = $m->serializeToJsonString();
+ $n = new TestMessage();
+ $n->mergeFromJsonString($data);
+ $this->assertSame("oneof_bytes", $n->getMyOneof());
+ $this->assertSame("bbbb", $n->getOneofBytes());
+
+ $sub_m = new Sub();
+ $m->setOneofMessage($sub_m);
+ $data = $m->serializeToJsonString();
+ $n = new TestMessage();
+ $n->mergeFromJsonString($data);
+ $this->assertSame("oneof_message", $n->getMyOneof());
+ $this->assertFalse(is_null($n->getOneofMessage()));
+ }
+
+ public function testPackedEncode()
+ {
+ $from = new TestPackedMessage();
+ TestUtil::setTestPackedMessage($from);
+ $this->assertSame(TestUtil::getGoldenTestPackedMessage(),
+ $from->serializeToString());
+ }
+
+ public function testPackedDecodePacked()
+ {
+ $to = new TestPackedMessage();
+ $to->mergeFromString(TestUtil::getGoldenTestPackedMessage());
+ TestUtil::assertTestPackedMessage($to);
+ $this->assertTrue(true);
+ }
+
+ public function testPackedDecodeUnpacked()
+ {
+ $to = new TestPackedMessage();
+ $to->mergeFromString(TestUtil::getGoldenTestUnpackedMessage());
+ TestUtil::assertTestPackedMessage($to);
+ $this->assertTrue(true);
+ }
+
+ public function testUnpackedEncode()
+ {
+ $from = new TestUnpackedMessage();
+ TestUtil::setTestPackedMessage($from);
+ $this->assertSame(TestUtil::getGoldenTestUnpackedMessage(),
+ $from->serializeToString());
+ }
+
+ public function testUnpackedDecodePacked()
+ {
+ $to = new TestUnpackedMessage();
+ $to->mergeFromString(TestUtil::getGoldenTestPackedMessage());
+ TestUtil::assertTestPackedMessage($to);
+ $this->assertTrue(true);
+ }
+
+ public function testUnpackedDecodeUnpacked()
+ {
+ $to = new TestUnpackedMessage();
+ $to->mergeFromString(TestUtil::getGoldenTestUnpackedMessage());
+ TestUtil::assertTestPackedMessage($to);
+ $this->assertTrue(true);
+ }
+
+ public function testDecodeInt64()
+ {
+ // Read 64 testing
+ $testVals = array(
+ '10' => '100a',
+ '100' => '1064',
+ '800' => '10a006',
+ '6400' => '108032',
+ '70400' => '1080a604',
+ '774400' => '1080a22f',
+ '9292800' => '108098b704',
+ '74342400' => '1080c0b923',
+ '743424000' => '108080bfe202',
+ '8177664000' => '108080b5bb1e',
+ '65421312000' => '108080a8dbf301',
+ '785055744000' => '108080e0c7ec16',
+ '9420668928000' => '10808080dd969202',
+ '103627358208000' => '10808080fff9c717',
+ '1139900940288000' => '10808080f5bd978302',
+ '13678811283456000' => '10808080fce699a618',
+ '109430490267648000' => '10808080e0b7ceb1c201',
+ '984874412408832000' => '10808080e0f5c1bed50d',
+ );
+
+ $msg = new TestMessage();
+ foreach ($testVals as $original => $encoded) {
+ $msg->setOptionalInt64($original);
+ $data = $msg->serializeToString();
+ $this->assertSame($encoded, bin2hex($data));
+ $msg->setOptionalInt64(0);
+ $msg->mergeFromString($data);
+ $this->assertEquals($original, $msg->getOptionalInt64());
+ }
+ }
+
+ public function testDecodeToExistingMessage()
+ {
+ $m1 = new TestMessage();
+ $this->setFields($m1);
+ $this->expectFields($m1);
+
+ $m2 = new TestMessage();
+ $this->setFields2($m2);
+ $data = $m2->serializeToString();
+
+ $m1->mergeFromString($data);
+ $this->expectFieldsMerged($m1);
+ }
+
+ public function testDecodeFieldNonExist()
+ {
+ $data = hex2bin('c80501');
+ $m = new TestMessage();
+ $m->mergeFromString($data);
+ $this->assertTrue(true);
+ }
+
+ public function testEncodeNegativeInt32()
+ {
+ $m = new TestMessage();
+ $m->setOptionalInt32(-1);
+ $data = $m->serializeToString();
+ $this->assertSame("08ffffffffffffffffff01", bin2hex($data));
+ }
+
+ public function testDecodeNegativeInt32()
+ {
+ $m = new TestMessage();
+ $this->assertEquals(0, $m->getOptionalInt32());
+ $m->mergeFromString(hex2bin("08ffffffffffffffffff01"));
+ $this->assertEquals(-1, $m->getOptionalInt32());
+
+ $m = new TestMessage();
+ $this->assertEquals(0, $m->getOptionalInt32());
+ $m->mergeFromString(hex2bin("08ffffffff0f"));
+ $this->assertEquals(-1, $m->getOptionalInt32());
+ }
+
+ public function testRandomFieldOrder()
+ {
+ $m = new TestRandomFieldOrder();
+ $data = $m->serializeToString();
+ $this->assertSame("", $data);
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidInt32()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('08'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidSubMessage()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('9A010108'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidInt64()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('10'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidUInt32()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('18'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidUInt64()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('20'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidSInt32()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('28'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidSInt64()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('30'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidFixed32()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('3D'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidFixed64()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('41'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidSFixed32()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('4D'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidSFixed64()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('51'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidFloat()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('5D'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidDouble()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('61'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidBool()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('68'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidStringLengthMiss()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('72'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidStringDataMiss()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('7201'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidBytesLengthMiss()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('7A'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidBytesDataMiss()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('7A01'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidEnum()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('8001'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidMessageLengthMiss()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('8A01'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidMessageDataMiss()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(hex2bin('8A0101'));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeInvalidPackedMessageLength()
+ {
+ $m = new TestPackedMessage();
+ $m->mergeFromString(hex2bin('D205'));
+ }
+
+ public function testUnknown()
+ {
+ // Test preserve unknown for varint.
+ $m = new TestMessage();
+ $from = hex2bin('F80601'); // TODO(teboring): Add a util to encode
+ // varint for better readability
+ $m->mergeFromString($from);
+ $to = $m->serializeToString();
+ $this->assertSame(bin2hex($from), bin2hex($to));
+
+ // Test preserve unknown for 64-bit.
+ $m = new TestMessage();
+ $from = hex2bin('F9060000000000000000');
+ $m->mergeFromString($from);
+ $to = $m->serializeToString();
+ $this->assertSame(bin2hex($from), bin2hex($to));
+
+ // Test preserve unknown for length delimited.
+ $m = new TestMessage();
+ $from = hex2bin('FA0600');
+ $m->mergeFromString($from);
+ $to = $m->serializeToString();
+ $this->assertSame(bin2hex($from), bin2hex($to));
+
+ // Test preserve unknown for 32-bit.
+ $m = new TestMessage();
+ $from = hex2bin('FD0600000000');
+ $m->mergeFromString($from);
+ $to = $m->serializeToString();
+ $this->assertSame(bin2hex($from), bin2hex($to));
+
+ // Test discard unknown in message.
+ $m = new TestMessage();
+ $from = hex2bin('F80601');
+ $m->mergeFromString($from);
+ $m->discardUnknownFields();
+ $to = $m->serializeToString();
+ $this->assertSame("", bin2hex($to));
+
+ // Test discard unknown for singular message field.
+ $m = new TestMessage();
+ $from = hex2bin('8A0103F80601');
+ $m->mergeFromString($from);
+ $m->discardUnknownFields();
+ $to = $m->serializeToString();
+ $this->assertSame("8a0100", bin2hex($to));
+
+ // Test discard unknown for repeated message field.
+ $m = new TestMessage();
+ $from = hex2bin('FA0203F80601');
+ $m->mergeFromString($from);
+ $m->discardUnknownFields();
+ $to = $m->serializeToString();
+ $this->assertSame("fa0200", bin2hex($to));
+
+ // Test discard unknown for map message value field.
+ $m = new TestMessage();
+ $from = hex2bin("BA050708011203F80601");
+ $m->mergeFromString($from);
+ $m->discardUnknownFields();
+ $to = $m->serializeToString();
+ $this->assertSame("ba050408011200", bin2hex($to));
+
+ // Test discard unknown for singular message field.
+ $m = new TestMessage();
+ $from = hex2bin('9A0403F80601');
+ $m->mergeFromString($from);
+ $m->discardUnknownFields();
+ $to = $m->serializeToString();
+ $this->assertSame("9a0400", bin2hex($to));
+ }
+
+ public function testJsonUnknown()
+ {
+ // Test unknown number
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":1,
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown bool
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":true,
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown string
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":\"abc\",
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown null
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":null,
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown array
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":[],
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown number array
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":[1],
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown bool array
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":[true],
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown string array
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":[\"a\"],
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown null array
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":[null],
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown array array
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":[[]],
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown object array
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":[{}],
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown double value array
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":[1, 2],
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown object
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":{},
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown number object
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":{\"a\":1},
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown bool object
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":{\"a\":true},
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown string object
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":{\"a\":\"a\"},
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown null object
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":{\"a\":null},
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown array object
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":{\"a\":[]},
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown object object
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":{\"a\":{}},
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+
+ // Test unknown double value object
+ $m = new TestMessage();
+ $m->mergeFromJsonString("{\"unknown\":{\"a\":1, \"b\":1},
+ \"optionalInt32\":1}", true);
+ $this->assertSame(1, $m->getOptionalInt32());
+ }
+
+ public function testJsonEncode()
+ {
+ $from = new TestMessage();
+ $this->setFields($from);
+ $data = $from->serializeToJsonString();
+ $to = new TestMessage();
+ $to->mergeFromJsonString($data);
+ $this->expectFields($to);
+ }
+
+ public function testDecodeDuration()
+ {
+ $m = new Google\Protobuf\Duration();
+ $m->mergeFromJsonString("\"1234.5678s\"");
+ $this->assertEquals(1234, $m->getSeconds());
+ $this->assertEquals(567800000, $m->getNanos());
+ }
+
+ public function testEncodeDuration()
+ {
+ $m = new Google\Protobuf\Duration();
+ $m->setSeconds(1234);
+ $m->setNanos(999999999);
+ $this->assertEquals("\"1234.999999999s\"", $m->serializeToJsonString());
+ }
+
+ public function testDecodeTimestamp()
+ {
+ $m = new Google\Protobuf\Timestamp();
+ $m->mergeFromJsonString("\"2000-01-01T00:00:00.123456789Z\"");
+ $this->assertEquals(946684800, $m->getSeconds());
+ $this->assertEquals(123456789, $m->getNanos());
+ }
+
+ public function testEncodeTimestamp()
+ {
+ $m = new Google\Protobuf\Timestamp();
+ $m->setSeconds(946684800);
+ $m->setNanos(123456789);
+ $this->assertEquals("\"2000-01-01T00:00:00.123456789Z\"",
+ $m->serializeToJsonString());
+ }
+
+ public function testDecodeTopLevelValue()
+ {
+ $m = new Value();
+ $m->mergeFromJsonString("\"a\"");
+ $this->assertSame("a", $m->getStringValue());
+
+ $m = new Value();
+ $m->mergeFromJsonString("1.5");
+ $this->assertSame(1.5, $m->getNumberValue());
+
+ $m = new Value();
+ $m->mergeFromJsonString("true");
+ $this->assertSame(true, $m->getBoolValue());
+
+ $m = new Value();
+ $m->mergeFromJsonString("null");
+ $this->assertSame("null_value", $m->getKind());
+
+ $m = new Value();
+ $m->mergeFromJsonString("[1]");
+ $this->assertSame("list_value", $m->getKind());
+
+ $m = new Value();
+ $m->mergeFromJsonString("{\"a\":1}");
+ $this->assertSame("struct_value", $m->getKind());
+ }
+
+ public function testEncodeTopLevelValue()
+ {
+ $m = new Value();
+ $m->setStringValue("a");
+ $this->assertSame("\"a\"", $m->serializeToJsonString());
+
+ $m = new Value();
+ $m->setNumberValue(1.5);
+ $this->assertSame("1.5", $m->serializeToJsonString());
+
+ $m = new Value();
+ $m->setBoolValue(true);
+ $this->assertSame("true", $m->serializeToJsonString());
+
+ $m = new Value();
+ $m->setNullValue(0);
+ $this->assertSame("null", $m->serializeToJsonString());
+ }
+
+ public function testDecodeTopLevelListValue()
+ {
+ $m = new ListValue();
+ $m->mergeFromJsonString("[1]");
+ $this->assertSame(1.0, $m->getValues()[0]->getNumberValue());
+ }
+
+ public function testEncodeTopLevelListValue()
+ {
+ $m = new ListValue();
+ $arr = $m->getValues();
+ $sub = new Value();
+ $sub->setNumberValue(1.5);
+ $arr[] = $sub;
+ $this->assertSame("[1.5]", $m->serializeToJsonString());
+ }
+
+ public function testEncodeEmptyListValue()
+ {
+ $m = new Struct();
+ $m->setFields(['test' => (new Value())->setListValue(new ListValue())]);
+ $this->assertSame('{"test":[]}', $m->serializeToJsonString());
+ }
+
+ public function testDecodeTopLevelStruct()
+ {
+ $m = new Struct();
+ $m->mergeFromJsonString("{\"a\":{\"b\":1}}");
+ $this->assertSame(1.0, $m->getFields()["a"]
+ ->getStructValue()
+ ->getFields()["b"]->getNumberValue());
+ }
+
+ public function testEncodeTopLevelStruct()
+ {
+ $m = new Struct();
+ $map = $m->getFields();
+ $sub = new Value();
+ $sub->setNumberValue(1.5);
+ $map["a"] = $sub;
+ $this->assertSame("{\"a\":1.5}", $m->serializeToJsonString());
+ }
+
+ public function testEncodeEmptyStruct()
+ {
+ $m = new Struct();
+ $m->setFields(['test' => (new Value())->setStructValue(new Struct())]);
+ $this->assertSame('{"test":{}}', $m->serializeToJsonString());
+ }
+
+ public function testDecodeTopLevelAny()
+ {
+ // Make sure packed message has been created at least once.
+ $packed = new TestMessage();
+
+ $m1 = new Any();
+ $m1->mergeFromJsonString(
+ "{\"optionalInt32\": 1, " .
+ "\"@type\":\"type.googleapis.com/foo.TestMessage\"}");
+ $this->assertSame("type.googleapis.com/foo.TestMessage",
+ $m1->getTypeUrl());
+ $this->assertSame("0801", bin2hex($m1->getValue()));
+
+ $m2 = new Any();
+ $m2->mergeFromJsonString(
+ "{\"@type\":\"type.googleapis.com/foo.TestMessage\", " .
+ "\"optionalInt32\": 1}");
+ $this->assertSame("type.googleapis.com/foo.TestMessage",
+ $m2->getTypeUrl());
+ $this->assertSame("0801", bin2hex($m2->getValue()));
+
+ $m3 = new Any();
+ $m3->mergeFromJsonString(
+ "{\"optionalInt32\": 1, " .
+ "\"@type\":\"type.googleapis.com/foo.TestMessage\", " .
+ "\"optionalInt64\": 2}");
+ $this->assertSame("type.googleapis.com/foo.TestMessage",
+ $m3->getTypeUrl());
+ $this->assertSame("08011002", bin2hex($m3->getValue()));
+ }
+
+ public function testDecodeAny()
+ {
+ // Make sure packed message has been created at least once.
+ $packed = new TestMessage();
+
+ $m1 = new TestAny();
+ $m1->mergeFromJsonString(
+ "{\"any\": {\"optionalInt32\": 1, " .
+ "\"@type\":\"type.googleapis.com/foo.TestMessage\"}}");
+ $this->assertSame("type.googleapis.com/foo.TestMessage",
+ $m1->getAny()->getTypeUrl());
+ $this->assertSame("0801", bin2hex($m1->getAny()->getValue()));
+
+ $m2 = new TestAny();
+ $m2->mergeFromJsonString(
+ "{\"any\":{\"@type\":\"type.googleapis.com/foo.TestMessage\", " .
+ "\"optionalInt32\": 1}}");
+ $this->assertSame("type.googleapis.com/foo.TestMessage",
+ $m2->getAny()->getTypeUrl());
+ $this->assertSame("0801", bin2hex($m2->getAny()->getValue()));
+
+ $m3 = new TestAny();
+ $m3->mergeFromJsonString(
+ "{\"any\":{\"optionalInt32\": 1, " .
+ "\"@type\":\"type.googleapis.com/foo.TestMessage\", " .
+ "\"optionalInt64\": 2}}");
+ $this->assertSame("type.googleapis.com/foo.TestMessage",
+ $m3->getAny()->getTypeUrl());
+ $this->assertSame("08011002", bin2hex($m3->getAny()->getValue()));
+ }
+
+ public function testDecodeAnyWithWellKnownPacked()
+ {
+ // Make sure packed message has been created at least once.
+ $packed = new Int32Value();
+
+ $m1 = new TestAny();
+ $m1->mergeFromJsonString(
+ "{\"any\":" .
+ " {\"@type\":\"type.googleapis.com/google.protobuf.Int32Value\"," .
+ " \"value\":1}}");
+ $this->assertSame("type.googleapis.com/google.protobuf.Int32Value",
+ $m1->getAny()->getTypeUrl());
+ $this->assertSame("0801", bin2hex($m1->getAny()->getValue()));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testDecodeAnyWithUnknownPacked()
+ {
+ $m = new TestAny();
+ $m->mergeFromJsonString(
+ "{\"any\":" .
+ " {\"@type\":\"type.googleapis.com/unknown\"," .
+ " \"value\":1}}");
+ }
+
+ public function testEncodeTopLevelAny()
+ {
+ // Test a normal message.
+ $packed = new TestMessage();
+ $packed->setOptionalInt32(123);
+ $packed->setOptionalString("abc");
+
+ $m = new Any();
+ $m->pack($packed);
+ $expected1 =
+ "{\"@type\":\"type.googleapis.com/foo.TestMessage\"," .
+ "\"optional_int32\":123,\"optional_string\":\"abc\"}";
+ $expected2 =
+ "{\"@type\":\"type.googleapis.com/foo.TestMessage\"," .
+ "\"optionalInt32\":123,\"optionalString\":\"abc\"}";
+ $result = $m->serializeToJsonString();
+ $this->assertTrue($expected1 === $result || $expected2 === $result);
+
+ // Test a well known message.
+ $packed = new Int32Value();
+ $packed->setValue(123);
+
+ $m = new Any();
+ $m->pack($packed);
+ $this->assertSame(
+ "{\"@type\":\"type.googleapis.com/google.protobuf.Int32Value\"," .
+ "\"value\":123}",
+ $m->serializeToJsonString());
+
+ // Test an Any message.
+ $outer = new Any();
+ $outer->pack($m);
+ $this->assertSame(
+ "{\"@type\":\"type.googleapis.com/google.protobuf.Any\"," .
+ "\"value\":{\"@type\":\"type.googleapis.com/google.protobuf.Int32Value\"," .
+ "\"value\":123}}",
+ $outer->serializeToJsonString());
+
+ // Test a Timestamp message.
+ $packed = new Google\Protobuf\Timestamp();
+ $packed->setSeconds(946684800);
+ $packed->setNanos(123456789);
+ $m = new Any();
+ $m->pack($packed);
+ $this->assertSame(
+ "{\"@type\":\"type.googleapis.com/google.protobuf.Timestamp\"," .
+ "\"value\":\"2000-01-01T00:00:00.123456789Z\"}",
+ $m->serializeToJsonString());
+ }
+
+ public function testDecodeTopLevelFieldMask()
+ {
+ $m = new TestMessage();
+ $m->setMapStringString(['a'=>'abcdefg']);
+ $data1 = $m->serializeToJsonString();
+ $n = new TestMessage();
+ $n->mergeFromJsonString($data1);
+ $data2 = $n->serializeToJsonString();
+ $this->assertSame($data1, $data2);
+
+ $m = new FieldMask();
+ $m->mergeFromJsonString("\"foo.barBaz,qux\"");
+ $this->assertSame("foo.bar_baz", $m->getPaths()[0]);
+ $this->assertSame("qux", $m->getPaths()[1]);
+ }
+
+ public function testEncodeTopLevelFieldMask()
+ {
+ $m = new FieldMask();
+ $m->setPaths(["foo.bar_baz", "qux"]);
+ $this->assertSame("\"foo.barBaz,qux\"", $m->serializeToJsonString());
+ }
+
+ public function testDecodeEmptyFieldMask()
+ {
+ $m = new FieldMask();
+ $m->mergeFromJsonString("\"\"");
+ $this->assertEquals("", $m->serializeToString());
+ }
+
+ public function testJsonDecodeMapWithDefaultValueKey()
+ {
+ $m = new TestMessage();
+ $m->getMapInt32Int32()[0] = 0;
+ $this->assertSame("{\"mapInt32Int32\":{\"0\":0}}",
+ $m->serializeToJsonString());
+
+ $m = new TestMessage();
+ $m->getMapStringString()[""] = "";
+ $this->assertSame("{\"mapStringString\":{\"\":\"\"}}",
+ $m->serializeToJsonString());
+ }
+
+ public function testJsonDecodeNumericStringMapKey()
+ {
+ $m = new TestMessage();
+ $m->getMapStringString()["1"] = "1";
+ $data = $m->serializeToJsonString();
+ $this->assertSame("{\"mapStringString\":{\"1\":\"1\"}}", $data);
+ $n = new TestMessage();
+ $n->mergeFromJsonString($data);
+ }
+
+}
diff --git a/third_party/protobuf/php/tests/gdb_test.sh b/third_party/protobuf/php/tests/gdb_test.sh
new file mode 100755
index 0000000..da5f3f3
--- /dev/null
+++ b/third_party/protobuf/php/tests/gdb_test.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+VERSION=$1
+
+export PATH=/usr/local/php-$VERSION/bin:$PATH
+export C_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$C_INCLUDE_PATH
+export CPLUS_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$CPLUS_INCLUDE_PATH
+
+php -i | grep "Configuration"
+
+# gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which
+# phpunit` --bootstrap autoload.php tmp_test.php
+#
+# gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php generated_class_test.php
+gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php encode_decode_test.php
+#
+# gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
+#
+# USE_ZEND_ALLOC=0 valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
diff --git a/third_party/protobuf/php/tests/generated_class_test.php b/third_party/protobuf/php/tests/generated_class_test.php
new file mode 100644
index 0000000..d808e3f
--- /dev/null
+++ b/third_party/protobuf/php/tests/generated_class_test.php
@@ -0,0 +1,1509 @@
+<?php
+
+require_once('generated/NoNamespaceEnum.php');
+require_once('generated/NoNamespaceMessage.php');
+require_once('test_base.php');
+require_once('test_util.php');
+
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\MapField;
+use Google\Protobuf\Internal\GPBType;
+use Bar\TestLegacyMessage;
+use Bar\TestLegacyMessage_NestedEnum;
+use Bar\TestLegacyMessage_NestedMessage;
+use Foo\TestEnum;
+use Foo\TestIncludeNamespaceMessage;
+use Foo\TestIncludePrefixMessage;
+use Foo\TestMessage;
+use Foo\TestMessage\Sub;
+use Foo\TestMessage_Sub;
+use Foo\TestMessage\NestedEnum;
+use Foo\TestReverseFieldOrder;
+use Foo\testLowerCaseMessage;
+use Foo\testLowerCaseEnum;
+use PBEmpty\PBEcho\TestEmptyPackage;
+use Php\Test\TestNamespace;
+
+class GeneratedClassTest extends TestBase
+{
+
+ #########################################################
+ # Test field accessors.
+ #########################################################
+
+ public function testSetterGetter()
+ {
+ $m = new TestMessage();
+ $m->setOptionalInt32(1);
+ $this->assertSame(1, $m->getOptionalInt32());
+ }
+
+ #########################################################
+ # Test int32 field.
+ #########################################################
+
+ public function testInt32Field()
+ {
+ $m = new TestMessage();
+
+ // Set integer.
+ $m->setOptionalInt32(MAX_INT32);
+ $this->assertSame(MAX_INT32, $m->getOptionalInt32());
+ $m->setOptionalInt32(MIN_INT32);
+ $this->assertSame(MIN_INT32, $m->getOptionalInt32());
+
+ // Set float.
+ $m->setOptionalInt32(1.1);
+ $this->assertSame(1, $m->getOptionalInt32());
+ $m->setOptionalInt32(MAX_INT32_FLOAT);
+ $this->assertSame(MAX_INT32, $m->getOptionalInt32());
+ $m->setOptionalInt32(MIN_INT32_FLOAT);
+ $this->assertSame(MIN_INT32, $m->getOptionalInt32());
+
+ // Set string.
+ $m->setOptionalInt32('2');
+ $this->assertSame(2, $m->getOptionalInt32());
+ $m->setOptionalInt32('3.1');
+ $this->assertSame(3, $m->getOptionalInt32());
+ $m->setOptionalInt32(MAX_INT32_STRING);
+ $this->assertSame(MAX_INT32, $m->getOptionalInt32());
+ $m->setOptionalInt32(MIN_INT32_STRING);
+ $this->assertSame(MIN_INT32, $m->getOptionalInt32());
+ }
+
+ #########################################################
+ # Test uint32 field.
+ #########################################################
+
+ public function testUint32Field()
+ {
+ $m = new TestMessage();
+
+ // Set integer.
+ $m->setOptionalUint32(MAX_UINT32);
+ $this->assertSame(-1, $m->getOptionalUint32());
+ $m->setOptionalUint32(-1);
+ $this->assertSame(-1, $m->getOptionalUint32());
+ $m->setOptionalUint32(MIN_UINT32);
+ $this->assertSame(MIN_INT32, $m->getOptionalUint32());
+
+ // Set float.
+ $m->setOptionalUint32(1.1);
+ $this->assertSame(1, $m->getOptionalUint32());
+ $m->setOptionalUint32(MAX_UINT32_FLOAT);
+ $this->assertSame(-1, $m->getOptionalUint32());
+ $m->setOptionalUint32(-1.0);
+ $this->assertSame(-1, $m->getOptionalUint32());
+ $m->setOptionalUint32(MIN_UINT32_FLOAT);
+ $this->assertSame(MIN_INT32, $m->getOptionalUint32());
+
+ // Set string.
+ $m->setOptionalUint32('2');
+ $this->assertSame(2, $m->getOptionalUint32());
+ $m->setOptionalUint32('3.1');
+ $this->assertSame(3, $m->getOptionalUint32());
+ $m->setOptionalUint32(MAX_UINT32_STRING);
+ $this->assertSame(-1, $m->getOptionalUint32());
+ $m->setOptionalUint32('-1.0');
+ $this->assertSame(-1, $m->getOptionalUint32());
+ $m->setOptionalUint32(MIN_UINT32_STRING);
+ $this->assertSame(MIN_INT32, $m->getOptionalUint32());
+ }
+
+ #########################################################
+ # Test int64 field.
+ #########################################################
+
+ public function testInt64Field()
+ {
+ $m = new TestMessage();
+
+ // Set integer.
+ $m->setOptionalInt64(MAX_INT64);
+ $this->assertSame(MAX_INT64, $m->getOptionalInt64());
+ $m->setOptionalInt64(MIN_INT64);
+ $this->assertEquals(MIN_INT64, $m->getOptionalInt64());
+
+ // Set float.
+ $m->setOptionalInt64(1.1);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('1', $m->getOptionalInt64());
+ } else {
+ $this->assertSame(1, $m->getOptionalInt64());
+ }
+
+ // Set string.
+ $m->setOptionalInt64('2');
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('2', $m->getOptionalInt64());
+ } else {
+ $this->assertSame(2, $m->getOptionalInt64());
+ }
+
+ $m->setOptionalInt64('3.1');
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('3', $m->getOptionalInt64());
+ } else {
+ $this->assertSame(3, $m->getOptionalInt64());
+ }
+
+ $m->setOptionalInt64(MAX_INT64_STRING);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_INT64_STRING, $m->getOptionalInt64());
+ } else {
+ $this->assertSame(MAX_INT64, $m->getOptionalInt64());
+ }
+
+ $m->setOptionalInt64(MIN_INT64_STRING);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MIN_INT64_STRING, $m->getOptionalInt64());
+ } else {
+ $this->assertSame(MIN_INT64, $m->getOptionalInt64());
+ }
+ }
+
+ #########################################################
+ # Test uint64 field.
+ #########################################################
+
+ public function testUint64Field()
+ {
+ $m = new TestMessage();
+
+ // Set integer.
+ $m->setOptionalUint64(MAX_UINT64);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_UINT64_STRING, $m->getOptionalUint64());
+ } else {
+ $this->assertSame(MAX_UINT64, $m->getOptionalUint64());
+ }
+
+ // Set float.
+ $m->setOptionalUint64(1.1);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('1', $m->getOptionalUint64());
+ } else {
+ $this->assertSame(1, $m->getOptionalUint64());
+ }
+
+ // Set string.
+ $m->setOptionalUint64('2');
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('2', $m->getOptionalUint64());
+ } else {
+ $this->assertSame(2, $m->getOptionalUint64());
+ }
+
+ $m->setOptionalUint64('3.1');
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('3', $m->getOptionalUint64());
+ } else {
+ $this->assertSame(3, $m->getOptionalUint64());
+ }
+
+ $m->setOptionalUint64(MAX_UINT64_STRING);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_UINT64_STRING, $m->getOptionalUint64());
+ } else {
+ $this->assertSame(MAX_UINT64, $m->getOptionalUint64());
+ }
+ }
+
+ #########################################################
+ # Test enum field.
+ #########################################################
+
+ public function testEnumField()
+ {
+ $m = new TestMessage();
+
+ // Set enum.
+ $m->setOptionalEnum(TestEnum::ONE);
+ $this->assertEquals(TestEnum::ONE, $m->getOptionalEnum());
+
+ // Set integer.
+ $m->setOptionalEnum(1);
+ $this->assertEquals(TestEnum::ONE, $m->getOptionalEnum());
+
+ // Set float.
+ $m->setOptionalEnum(1.1);
+ $this->assertEquals(TestEnum::ONE, $m->getOptionalEnum());
+
+ // Set string.
+ $m->setOptionalEnum("1");
+ $this->assertEquals(TestEnum::ONE, $m->getOptionalEnum());
+
+ // Test Enum methods
+ $this->assertEquals('ONE', TestEnum::name(1));
+ $this->assertEquals(1, TestEnum::value('ONE'));
+ }
+
+ /**
+ * @expectedException UnexpectedValueException
+ * @expectedExceptionMessage Enum Foo\TestEnum has no name defined for value -1
+ */
+ public function testInvalidEnumValueThrowsException()
+ {
+ TestEnum::name(-1);
+ }
+
+ /**
+ * @expectedException UnexpectedValueException
+ * @expectedExceptionMessage Enum Foo\TestEnum has no value defined for name DOES_NOT_EXIST
+ */
+ public function testInvalidEnumNameThrowsException()
+ {
+ TestEnum::value('DOES_NOT_EXIST');
+ }
+
+ public function testNestedEnum()
+ {
+ $m = new TestMessage();
+ $m->setOptionalNestedEnum(NestedEnum::ZERO);
+ $this->assertTrue(true);
+ }
+
+ public function testLegacyNestedEnum()
+ {
+ $m = new TestMessage();
+ $m->setOptionalNestedEnum(\Foo\TestMessage_NestedEnum::ZERO);
+ $this->assertTrue(true);
+ }
+
+ public function testLegacyTypehintWithNestedEnums()
+ {
+ $this->legacyEnum(new TestLegacyMessage\NestedEnum);
+ }
+
+ private function legacyEnum(TestLegacyMessage_NestedEnum $enum)
+ {
+ // If we made it here without a PHP Fatal error, the typehint worked
+ $this->assertTrue(true);
+ }
+
+ #########################################################
+ # Test float field.
+ #########################################################
+
+ public function testFloatField()
+ {
+ $m = new TestMessage();
+
+ // Set integer.
+ $m->setOptionalFloat(1);
+ $this->assertEquals(1.0, $m->getOptionalFloat(), '', MAX_FLOAT_DIFF);
+
+ // Set float.
+ $m->setOptionalFloat(1.1);
+ $this->assertEquals(1.1, $m->getOptionalFloat(), '', MAX_FLOAT_DIFF);
+
+ // Set string.
+ $m->setOptionalFloat('2');
+ $this->assertEquals(2.0, $m->getOptionalFloat(), '', MAX_FLOAT_DIFF);
+ $m->setOptionalFloat('3.1');
+ $this->assertEquals(3.1, $m->getOptionalFloat(), '', MAX_FLOAT_DIFF);
+ }
+
+ #########################################################
+ # Test double field.
+ #########################################################
+
+ public function testDoubleField()
+ {
+ $m = new TestMessage();
+
+ // Set integer.
+ $m->setOptionalDouble(1);
+ $this->assertEquals(1.0, $m->getOptionalDouble(), '', MAX_FLOAT_DIFF);
+
+ // Set float.
+ $m->setOptionalDouble(1.1);
+ $this->assertEquals(1.1, $m->getOptionalDouble(), '', MAX_FLOAT_DIFF);
+
+ // Set string.
+ $m->setOptionalDouble('2');
+ $this->assertEquals(2.0, $m->getOptionalDouble(), '', MAX_FLOAT_DIFF);
+ $m->setOptionalDouble('3.1');
+ $this->assertEquals(3.1, $m->getOptionalDouble(), '', MAX_FLOAT_DIFF);
+ }
+
+ #########################################################
+ # Test bool field.
+ #########################################################
+
+ public function testBoolField()
+ {
+ $m = new TestMessage();
+
+ // Set bool.
+ $m->setOptionalBool(true);
+ $this->assertSame(true, $m->getOptionalBool());
+
+ // Set integer.
+ $m->setOptionalBool(-1);
+ $this->assertSame(true, $m->getOptionalBool());
+
+ // Set float.
+ $m->setOptionalBool(1.1);
+ $this->assertSame(true, $m->getOptionalBool());
+
+ // Set string.
+ $m->setOptionalBool('');
+ $this->assertSame(false, $m->getOptionalBool());
+ }
+
+ #########################################################
+ # Test string field.
+ #########################################################
+
+ public function testStringField()
+ {
+ $m = new TestMessage();
+
+ // Set string.
+ $m->setOptionalString('abc');
+ $this->assertSame('abc', $m->getOptionalString());
+
+ // Set integer.
+ $m->setOptionalString(1);
+ $this->assertSame('1', $m->getOptionalString());
+
+ // Set double.
+ $m->setOptionalString(1.1);
+ $this->assertSame('1.1', $m->getOptionalString());
+
+ // Set bool.
+ $m->setOptionalString(true);
+ $this->assertSame('1', $m->getOptionalString());
+ }
+
+ #########################################################
+ # Test bytes field.
+ #########################################################
+
+ public function testBytesField()
+ {
+ $m = new TestMessage();
+
+ // Set string.
+ $m->setOptionalBytes('abc');
+ $this->assertSame('abc', $m->getOptionalBytes());
+
+ // Set integer.
+ $m->setOptionalBytes(1);
+ $this->assertSame('1', $m->getOptionalBytes());
+
+ // Set double.
+ $m->setOptionalBytes(1.1);
+ $this->assertSame('1.1', $m->getOptionalBytes());
+
+ // Set bool.
+ $m->setOptionalBytes(true);
+ $this->assertSame('1', $m->getOptionalBytes());
+ }
+
+ public function testBytesFieldInvalidUTF8Success()
+ {
+ $m = new TestMessage();
+ $hex = hex2bin("ff");
+ $m->setOptionalBytes($hex);
+ $this->assertTrue(true);
+ }
+
+ #########################################################
+ # Test message field.
+ #########################################################
+
+ public function testMessageField()
+ {
+ $m = new TestMessage();
+
+ $sub_m = new Sub();
+ $sub_m->setA(1);
+ $m->setOptionalMessage($sub_m);
+ $this->assertSame(1, $m->getOptionalMessage()->getA());
+
+ $null = null;
+ $m->setOptionalMessage($null);
+ $this->assertNull($m->getOptionalMessage());
+ }
+
+ public function testLegacyMessageField()
+ {
+ $m = new TestMessage();
+
+ $sub_m = new TestMessage_Sub();
+ $sub_m->setA(1);
+ $m->setOptionalMessage($sub_m);
+ $this->assertSame(1, $m->getOptionalMessage()->getA());
+
+ $null = null;
+ $m->setOptionalMessage($null);
+ $this->assertNull($m->getOptionalMessage());
+ }
+
+ public function testLegacyTypehintWithNestedMessages()
+ {
+ $this->legacyMessage(new TestLegacyMessage\NestedMessage);
+ }
+
+ private function legacyMessage(TestLegacyMessage_NestedMessage $sub)
+ {
+ // If we made it here without a PHP Fatal error, the typehint worked
+ $this->assertTrue(true);
+ }
+
+ #########################################################
+ # Test repeated field.
+ #########################################################
+
+ public function testRepeatedField()
+ {
+ $m = new TestMessage();
+
+ $repeated_int32 = new RepeatedField(GPBType::INT32);
+ $m->setRepeatedInt32($repeated_int32);
+ $this->assertSame($repeated_int32, $m->getRepeatedInt32());
+ }
+
+ public function testRepeatedFieldViaArray()
+ {
+ $m = new TestMessage();
+
+ $arr = array();
+ $m->setRepeatedInt32($arr);
+ $this->assertSame(0, count($m->getRepeatedInt32()));
+
+ $arr = array(1, 2.1, "3");
+ $m->setRepeatedInt32($arr);
+ $this->assertTrue($m->getRepeatedInt32() instanceof RepeatedField);
+ $this->assertSame("Google\Protobuf\Internal\RepeatedField",
+ get_class($m->getRepeatedInt32()));
+ $this->assertSame(3, count($m->getRepeatedInt32()));
+ $this->assertSame(1, $m->getRepeatedInt32()[0]);
+ $this->assertSame(2, $m->getRepeatedInt32()[1]);
+ $this->assertSame(3, $m->getRepeatedInt32()[2]);
+ $this->assertFalse($arr instanceof RepeatedField);
+ }
+
+ #########################################################
+ # Test map field.
+ #########################################################
+
+ public function testMapField()
+ {
+ $m = new TestMessage();
+
+ $map_int32_int32 = new MapField(GPBType::INT32, GPBType::INT32);
+ $m->setMapInt32Int32($map_int32_int32);
+ $this->assertSame($map_int32_int32, $m->getMapInt32Int32());
+ }
+
+ public function testMapFieldViaArray()
+ {
+ $m = new TestMessage();
+
+ $dict = array();
+ $m->setMapInt32Int32($dict);
+ $this->assertSame(0, count($m->getMapInt32Int32()));
+
+ $dict = array(5 => 5, 6.1 => 6.1, "7" => "7");
+ $m->setMapInt32Int32($dict);
+ $this->assertTrue($m->getMapInt32Int32() instanceof MapField);
+ $this->assertSame(3, count($m->getMapInt32Int32()));
+ $this->assertSame(5, $m->getMapInt32Int32()[5]);
+ $this->assertSame(6, $m->getMapInt32Int32()[6]);
+ $this->assertSame(7, $m->getMapInt32Int32()[7]);
+ $this->assertFalse($dict instanceof MapField);
+ }
+
+ #########################################################
+ # Test oneof field.
+ #########################################################
+
+ public function testOneofField() {
+ $m = new TestMessage();
+
+ $this->assertSame("", $m->getMyOneof());
+
+ $m->setOneofInt32(1);
+ $this->assertSame(1, $m->getOneofInt32());
+ $this->assertSame(0.0, $m->getOneofFloat());
+ $this->assertSame('', $m->getOneofString());
+ $this->assertSame(NULL, $m->getOneofMessage());
+ $this->assertSame("oneof_int32", $m->getMyOneof());
+
+ $m->setOneofFloat(2.0);
+ $this->assertSame(0, $m->getOneofInt32());
+ $this->assertSame(2.0, $m->getOneofFloat());
+ $this->assertSame('', $m->getOneofString());
+ $this->assertSame(NULL, $m->getOneofMessage());
+ $this->assertSame("oneof_float", $m->getMyOneof());
+
+ $m->setOneofString('abc');
+ $this->assertSame(0, $m->getOneofInt32());
+ $this->assertSame(0.0, $m->getOneofFloat());
+ $this->assertSame('abc', $m->getOneofString());
+ $this->assertSame(NULL, $m->getOneofMessage());
+ $this->assertSame("oneof_string", $m->getMyOneof());
+
+ $sub_m = new Sub();
+ $sub_m->setA(1);
+ $m->setOneofMessage($sub_m);
+ $this->assertSame(0, $m->getOneofInt32());
+ $this->assertSame(0.0, $m->getOneofFloat());
+ $this->assertSame('', $m->getOneofString());
+ $this->assertSame(1, $m->getOneofMessage()->getA());
+ $this->assertSame("oneof_message", $m->getMyOneof());
+ }
+
+ #########################################################
+ # Test clear method.
+ #########################################################
+
+ public function testMessageClear()
+ {
+ $m = new TestMessage();
+ $this->setFields($m);
+ $this->expectFields($m);
+ $m->clear();
+ $this->expectEmptyFields($m);
+ }
+
+ #########################################################
+ # Test mergeFrom method.
+ #########################################################
+
+ public function testMessageMergeFrom()
+ {
+ $m = new TestMessage();
+ $this->setFields($m);
+ $this->expectFields($m);
+ $arr = $m->getOptionalMessage()->getB();
+ $arr[] = 1;
+
+ $n = new TestMessage();
+
+ // Singular
+ $n->setOptionalInt32(100);
+ $sub1 = new Sub();
+ $sub1->setA(101);
+
+ $b = $sub1->getB();
+ $b[] = 102;
+ $sub1->setB($b);
+
+ $n->setOptionalMessage($sub1);
+
+ // Repeated
+ $repeatedInt32 = $n->getRepeatedInt32();
+ $repeatedInt32[] = 200;
+ $n->setRepeatedInt32($repeatedInt32);
+
+ $repeatedString = $n->getRepeatedString();
+ $repeatedString[] = 'abc';
+ $n->setRepeatedString($repeatedString);
+
+ $sub2 = new Sub();
+ $sub2->setA(201);
+ $repeatedMessage = $n->getRepeatedMessage();
+ $repeatedMessage[] = $sub2;
+ $n->setRepeatedMessage($repeatedMessage);
+
+ // Map
+ $mapInt32Int32 = $n->getMapInt32Int32();
+ $mapInt32Int32[1] = 300;
+ $mapInt32Int32[-62] = 301;
+ $n->setMapInt32Int32($mapInt32Int32);
+
+ $mapStringString = $n->getMapStringString();
+ $mapStringString['def'] = 'def';
+ $n->setMapStringString($mapStringString);
+
+ $mapInt32Message = $n->getMapInt32Message();
+ $mapInt32Message[1] = new Sub();
+ $mapInt32Message[1]->setA(302);
+ $mapInt32Message[2] = new Sub();
+ $mapInt32Message[2]->setA(303);
+ $n->setMapInt32Message($mapInt32Message);
+
+ $m->mergeFrom($n);
+
+ $this->assertSame(100, $m->getOptionalInt32());
+ $this->assertSame(42, $m->getOptionalUint32());
+ $this->assertSame(101, $m->getOptionalMessage()->getA());
+ $this->assertSame(2, count($m->getOptionalMessage()->getB()));
+ $this->assertSame(1, $m->getOptionalMessage()->getB()[0]);
+ $this->assertSame(102, $m->getOptionalMessage()->getB()[1]);
+
+ $this->assertSame(3, count($m->getRepeatedInt32()));
+ $this->assertSame(200, $m->getRepeatedInt32()[2]);
+ $this->assertSame(2, count($m->getRepeatedUint32()));
+ $this->assertSame(3, count($m->getRepeatedString()));
+ $this->assertSame('abc', $m->getRepeatedString()[2]);
+ $this->assertSame(3, count($m->getRepeatedMessage()));
+ $this->assertSame(201, $m->getRepeatedMessage()[2]->getA());
+
+ $this->assertSame(2, count($m->getMapInt32Int32()));
+ $this->assertSame(300, $m->getMapInt32Int32()[1]);
+ $this->assertSame(301, $m->getMapInt32Int32()[-62]);
+ $this->assertSame(1, count($m->getMapUint32Uint32()));
+ $this->assertSame(2, count($m->getMapStringString()));
+ $this->assertSame('def', $m->getMapStringString()['def']);
+
+ $this->assertSame(2, count($m->getMapInt32Message()));
+ $this->assertSame(302, $m->getMapInt32Message()[1]->getA());
+ $this->assertSame(303, $m->getMapInt32Message()[2]->getA());
+
+ $this->assertSame("", $m->getMyOneof());
+
+ // Check sub-messages are copied by value.
+ $n->getOptionalMessage()->setA(-101);
+ $this->assertSame(101, $m->getOptionalMessage()->getA());
+
+ $repeatedMessage = $n->getRepeatedMessage();
+ $repeatedMessage[0]->setA(-201);
+ $n->setRepeatedMessage($repeatedMessage);
+ $this->assertSame(201, $m->getRepeatedMessage()[2]->getA());
+
+ $mapInt32Message = $n->getMapInt32Message();
+ $mapInt32Message[1]->setA(-302);
+ $n->setMapInt32Message($mapInt32Message);
+
+ $this->assertSame(302, $m->getMapInt32Message()[1]->getA());
+
+ // Test merge oneof.
+ $m = new TestMessage();
+
+ $n = new TestMessage();
+ $n->setOneofInt32(1);
+ $m->mergeFrom($n);
+ $this->assertSame(1, $m->getOneofInt32());
+
+ $sub = new Sub();
+ $n->setOneofMessage($sub);
+ $n->getOneofMessage()->setA(400);
+ $m->mergeFrom($n);
+ $this->assertSame(400, $m->getOneofMessage()->getA());
+ $n->getOneofMessage()->setA(-400);
+ $this->assertSame(400, $m->getOneofMessage()->getA());
+
+ // Test all fields
+ $m = new TestMessage();
+ $n = new TestMessage();
+ $this->setFields($m);
+ $n->mergeFrom($m);
+ $this->expectFields($n);
+ }
+
+ #########################################################
+ # Test message/enum without namespace.
+ #########################################################
+
+ public function testMessageWithoutNamespace()
+ {
+ $m = new TestMessage();
+ $n = new NoNameSpaceMessage();
+ $m->setOptionalNoNamespaceMessage($n);
+ $repeatedNoNamespaceMessage = $m->getRepeatedNoNamespaceMessage();
+ $repeatedNoNamespaceMessage[] = new NoNameSpaceMessage();
+ $m->setRepeatedNoNamespaceMessage($repeatedNoNamespaceMessage);
+
+ // test nested messages
+ $sub = new NoNamespaceMessage\NestedMessage();
+ $n->setNestedMessage($sub);
+
+ $this->assertTrue(true);
+ }
+
+ public function testEnumWithoutNamespace()
+ {
+ $m = new TestMessage();
+ $m->setOptionalNoNamespaceEnum(NoNameSpaceEnum::VALUE_A);
+ $repeatedNoNamespaceEnum = $m->getRepeatedNoNamespaceEnum();
+ $repeatedNoNamespaceEnum[] = NoNameSpaceEnum::VALUE_A;
+ $m->setRepeatedNoNamespaceEnum($repeatedNoNamespaceEnum);
+ $this->assertTrue(true);
+ }
+
+ #########################################################
+ # Test message with given namespace.
+ #########################################################
+
+ public function testNestedMessagesAndEnums()
+ {
+ $m = new TestMessage();
+ $n = new TestMessage\Sub();
+ $m->setOptionalMessage($n);
+ $m->setOptionalNestedEnum(TestMessage\NestedEnum::ZERO);
+ $this->assertSame($n, $m->getOptionalMessage());
+ $this->assertSame(TestMessage\NestedEnum::ZERO, $m->getOptionalNestedEnum());
+ }
+
+ public function testMessagesAndEnumsWithPrefix()
+ {
+ // Test message prefix
+ $m = new TestIncludePrefixMessage();
+ $n = new PrefixTestPrefix();
+ $n->setA(1);
+ $m->setPrefixMessage($n);
+ $this->assertSame(1, $m->getPrefixMessage()->getA());
+
+ // Test nested message prefix
+ $o = new PrefixTestPrefix();
+ $p = new PrefixTestPrefix\PrefixNestedMessage();
+ $o->setNestedMessage($p);
+ $o->setNestedEnum(PrefixTestPrefix\PrefixNestedEnum::ZERO);
+ $this->assertSame($p, $o->getNestedMessage());
+ $this->assertSame(PrefixTestPrefix\PrefixNestedEnum::ZERO, $o->getNestedEnum());
+ }
+
+ public function testMessagesAndEnumsWithPhpNamespace()
+ {
+ $m = new TestNamespace();
+ $n = new TestNamespace\NestedMessage();
+ $m->setNestedMessage($n);
+ $m->setNestedEnum(TestNamespace\NestedEnum::ZERO);
+ $this->assertSame($n, $m->getNestedMessage());
+ $this->assertSame(TestNamespace\NestedEnum::ZERO, $m->getNestedEnum());
+ }
+
+ public function testMesssagesAndEnumsWithEmptyPhpNamespace()
+ {
+ $m = new TestEmptyNamespace();
+ $n = new TestEmptyNamespace\NestedMessage();
+ $m->setNestedMessage($n);
+ $m->setNestedEnum(TestEmptyNamespace\NestedEnum::ZERO);
+ $this->assertSame($n, $m->getNestedMessage());
+ $this->assertSame(TestEmptyNamespace\NestedEnum::ZERO, $m->getNestedEnum());
+ }
+
+ public function testMessagesAndEnumsWithNoNamespace()
+ {
+ $m = new NoNamespaceMessage();
+ $n = new NoNamespaceMessage\NestedMessage();
+ $m->setNestedMessage($n);
+ $m->setNestedEnum(NoNamespaceMessage\NestedEnum::ZERO);
+ $this->assertSame($n, $m->getNestedMessage());
+ $this->assertSame(NoNamespaceMessage\NestedEnum::ZERO, $m->getNestedEnum());
+ }
+
+ public function testReservedWordsInPackageName()
+ {
+ $m = new TestEmptyPackage();
+ $n = new TestEmptyPackage\NestedMessage();
+ $m->setNestedMessage($n);
+ $m->setNestedEnum(TestEmptyPackage\NestedEnum::ZERO);
+ $this->assertSame($n, $m->getNestedMessage());
+ $this->assertSame(TestEmptyPackage\NestedEnum::ZERO, $m->getNestedEnum());
+ }
+
+ public function testReservedWordsInNamespace()
+ {
+ $m = new TestNamespace();
+ $n = new TestNamespace\PBEmpty();
+ $o = new TestNamespace\PBEmpty\NestedMessage();
+ $n->setNestedMessage($o);
+ $n->setNestedEnum(TestNamespace\PBEmpty\NestedEnum::ZERO);
+ $m->setReservedName($n);
+ $this->assertSame($n, $m->getReservedName());
+ $this->assertSame($o, $n->getNestedMessage());
+ $this->assertSame(
+ TestNamespace\PBEmpty\NestedEnum::ZERO,
+ $n->getNestedEnum()
+ );
+ }
+
+ #########################################################
+ # Test prefix for reserved words.
+ #########################################################
+
+ public function testPrefixForReservedWords()
+ {
+ $m = new \Foo\TestMessage\PBEmpty();
+ $m = new \Foo\PBEmpty();
+ $m = new \PrefixEmpty();
+ $m = new \Foo\PBARRAY();
+
+ $m = new \Lower\PBabstract();
+ $m = new \Lower\PBand();
+ $m = new \Lower\PBarray();
+ $m = new \Lower\PBas();
+ $m = new \Lower\PBbreak();
+ $m = new \Lower\PBcallable();
+ $m = new \Lower\PBcase();
+ $m = new \Lower\PBcatch();
+ $m = new \Lower\PBclass();
+ $m = new \Lower\PBclone();
+ $m = new \Lower\PBconst();
+ $m = new \Lower\PBcontinue();
+ $m = new \Lower\PBdeclare();
+ $m = new \Lower\PBdefault();
+ $m = new \Lower\PBdie();
+ $m = new \Lower\PBdo();
+ $m = new \Lower\PBecho();
+ $m = new \Lower\PBelse();
+ $m = new \Lower\PBelseif();
+ $m = new \Lower\PBempty();
+ $m = new \Lower\PBenddeclare();
+ $m = new \Lower\PBendfor();
+ $m = new \Lower\PBendforeach();
+ $m = new \Lower\PBendif();
+ $m = new \Lower\PBendswitch();
+ $m = new \Lower\PBendwhile();
+ $m = new \Lower\PBeval();
+ $m = new \Lower\PBexit();
+ $m = new \Lower\PBextends();
+ $m = new \Lower\PBfinal();
+ $m = new \Lower\PBfor();
+ $m = new \Lower\PBforeach();
+ $m = new \Lower\PBfunction();
+ $m = new \Lower\PBglobal();
+ $m = new \Lower\PBgoto();
+ $m = new \Lower\PBif();
+ $m = new \Lower\PBimplements();
+ $m = new \Lower\PBinclude();
+ $m = new \Lower\PBinclude_once();
+ $m = new \Lower\PBinstanceof();
+ $m = new \Lower\PBinsteadof();
+ $m = new \Lower\PBinterface();
+ $m = new \Lower\PBisset();
+ $m = new \Lower\PBlist();
+ $m = new \Lower\PBnamespace();
+ $m = new \Lower\PBnew();
+ $m = new \Lower\PBor();
+ $m = new \Lower\PBprint();
+ $m = new \Lower\PBprivate();
+ $m = new \Lower\PBprotected();
+ $m = new \Lower\PBpublic();
+ $m = new \Lower\PBrequire();
+ $m = new \Lower\PBrequire_once();
+ $m = new \Lower\PBreturn();
+ $m = new \Lower\PBstatic();
+ $m = new \Lower\PBswitch();
+ $m = new \Lower\PBthrow();
+ $m = new \Lower\PBtrait();
+ $m = new \Lower\PBtry();
+ $m = new \Lower\PBunset();
+ $m = new \Lower\PBuse();
+ $m = new \Lower\PBvar();
+ $m = new \Lower\PBwhile();
+ $m = new \Lower\PBxor();
+ $m = new \Lower\PBint();
+ $m = new \Lower\PBfloat();
+ $m = new \Lower\PBbool();
+ $m = new \Lower\PBstring();
+ $m = new \Lower\PBtrue();
+ $m = new \Lower\PBfalse();
+ $m = new \Lower\PBnull();
+ $m = new \Lower\PBvoid();
+ $m = new \Lower\PBiterable();
+
+ $m = new \Upper\PBABSTRACT();
+ $m = new \Upper\PBAND();
+ $m = new \Upper\PBARRAY();
+ $m = new \Upper\PBAS();
+ $m = new \Upper\PBBREAK();
+ $m = new \Upper\PBCALLABLE();
+ $m = new \Upper\PBCASE();
+ $m = new \Upper\PBCATCH();
+ $m = new \Upper\PBCLASS();
+ $m = new \Upper\PBCLONE();
+ $m = new \Upper\PBCONST();
+ $m = new \Upper\PBCONTINUE();
+ $m = new \Upper\PBDECLARE();
+ $m = new \Upper\PBDEFAULT();
+ $m = new \Upper\PBDIE();
+ $m = new \Upper\PBDO();
+ $m = new \Upper\PBECHO();
+ $m = new \Upper\PBELSE();
+ $m = new \Upper\PBELSEIF();
+ $m = new \Upper\PBEMPTY();
+ $m = new \Upper\PBENDDECLARE();
+ $m = new \Upper\PBENDFOR();
+ $m = new \Upper\PBENDFOREACH();
+ $m = new \Upper\PBENDIF();
+ $m = new \Upper\PBENDSWITCH();
+ $m = new \Upper\PBENDWHILE();
+ $m = new \Upper\PBEVAL();
+ $m = new \Upper\PBEXIT();
+ $m = new \Upper\PBEXTENDS();
+ $m = new \Upper\PBFINAL();
+ $m = new \Upper\PBFOR();
+ $m = new \Upper\PBFOREACH();
+ $m = new \Upper\PBFUNCTION();
+ $m = new \Upper\PBGLOBAL();
+ $m = new \Upper\PBGOTO();
+ $m = new \Upper\PBIF();
+ $m = new \Upper\PBIMPLEMENTS();
+ $m = new \Upper\PBINCLUDE();
+ $m = new \Upper\PBINCLUDE_ONCE();
+ $m = new \Upper\PBINSTANCEOF();
+ $m = new \Upper\PBINSTEADOF();
+ $m = new \Upper\PBINTERFACE();
+ $m = new \Upper\PBISSET();
+ $m = new \Upper\PBLIST();
+ $m = new \Upper\PBNAMESPACE();
+ $m = new \Upper\PBNEW();
+ $m = new \Upper\PBOR();
+ $m = new \Upper\PBPRINT();
+ $m = new \Upper\PBPRIVATE();
+ $m = new \Upper\PBPROTECTED();
+ $m = new \Upper\PBPUBLIC();
+ $m = new \Upper\PBREQUIRE();
+ $m = new \Upper\PBREQUIRE_ONCE();
+ $m = new \Upper\PBRETURN();
+ $m = new \Upper\PBSTATIC();
+ $m = new \Upper\PBSWITCH();
+ $m = new \Upper\PBTHROW();
+ $m = new \Upper\PBTRAIT();
+ $m = new \Upper\PBTRY();
+ $m = new \Upper\PBUNSET();
+ $m = new \Upper\PBUSE();
+ $m = new \Upper\PBVAR();
+ $m = new \Upper\PBWHILE();
+ $m = new \Upper\PBXOR();
+ $m = new \Upper\PBINT();
+ $m = new \Upper\PBFLOAT();
+ $m = new \Upper\PBBOOL();
+ $m = new \Upper\PBSTRING();
+ $m = new \Upper\PBTRUE();
+ $m = new \Upper\PBFALSE();
+ $m = new \Upper\PBNULL();
+ $m = new \Upper\PBVOID();
+ $m = new \Upper\PBITERABLE();
+
+ $m = new \Lower_enum\PBabstract();
+ $m = new \Lower_enum\PBand();
+ $m = new \Lower_enum\PBarray();
+ $m = new \Lower_enum\PBas();
+ $m = new \Lower_enum\PBbreak();
+ $m = new \Lower_enum\PBcallable();
+ $m = new \Lower_enum\PBcase();
+ $m = new \Lower_enum\PBcatch();
+ $m = new \Lower_enum\PBclass();
+ $m = new \Lower_enum\PBclone();
+ $m = new \Lower_enum\PBconst();
+ $m = new \Lower_enum\PBcontinue();
+ $m = new \Lower_enum\PBdeclare();
+ $m = new \Lower_enum\PBdefault();
+ $m = new \Lower_enum\PBdie();
+ $m = new \Lower_enum\PBdo();
+ $m = new \Lower_enum\PBecho();
+ $m = new \Lower_enum\PBelse();
+ $m = new \Lower_enum\PBelseif();
+ $m = new \Lower_enum\PBempty();
+ $m = new \Lower_enum\PBenddeclare();
+ $m = new \Lower_enum\PBendfor();
+ $m = new \Lower_enum\PBendforeach();
+ $m = new \Lower_enum\PBendif();
+ $m = new \Lower_enum\PBendswitch();
+ $m = new \Lower_enum\PBendwhile();
+ $m = new \Lower_enum\PBeval();
+ $m = new \Lower_enum\PBexit();
+ $m = new \Lower_enum\PBextends();
+ $m = new \Lower_enum\PBfinal();
+ $m = new \Lower_enum\PBfor();
+ $m = new \Lower_enum\PBforeach();
+ $m = new \Lower_enum\PBfunction();
+ $m = new \Lower_enum\PBglobal();
+ $m = new \Lower_enum\PBgoto();
+ $m = new \Lower_enum\PBif();
+ $m = new \Lower_enum\PBimplements();
+ $m = new \Lower_enum\PBinclude();
+ $m = new \Lower_enum\PBinclude_once();
+ $m = new \Lower_enum\PBinstanceof();
+ $m = new \Lower_enum\PBinsteadof();
+ $m = new \Lower_enum\PBinterface();
+ $m = new \Lower_enum\PBisset();
+ $m = new \Lower_enum\PBlist();
+ $m = new \Lower_enum\PBnamespace();
+ $m = new \Lower_enum\PBnew();
+ $m = new \Lower_enum\PBor();
+ $m = new \Lower_enum\PBprint();
+ $m = new \Lower_enum\PBprivate();
+ $m = new \Lower_enum\PBprotected();
+ $m = new \Lower_enum\PBpublic();
+ $m = new \Lower_enum\PBrequire();
+ $m = new \Lower_enum\PBrequire_once();
+ $m = new \Lower_enum\PBreturn();
+ $m = new \Lower_enum\PBstatic();
+ $m = new \Lower_enum\PBswitch();
+ $m = new \Lower_enum\PBthrow();
+ $m = new \Lower_enum\PBtrait();
+ $m = new \Lower_enum\PBtry();
+ $m = new \Lower_enum\PBunset();
+ $m = new \Lower_enum\PBuse();
+ $m = new \Lower_enum\PBvar();
+ $m = new \Lower_enum\PBwhile();
+ $m = new \Lower_enum\PBxor();
+ $m = new \Lower_enum\PBint();
+ $m = new \Lower_enum\PBfloat();
+ $m = new \Lower_enum\PBbool();
+ $m = new \Lower_enum\PBstring();
+ $m = new \Lower_enum\PBtrue();
+ $m = new \Lower_enum\PBfalse();
+ $m = new \Lower_enum\PBnull();
+ $m = new \Lower_enum\PBvoid();
+ $m = new \Lower_enum\PBiterable();
+
+ $m = new \Upper_enum\PBABSTRACT();
+ $m = new \Upper_enum\PBAND();
+ $m = new \Upper_enum\PBARRAY();
+ $m = new \Upper_enum\PBAS();
+ $m = new \Upper_enum\PBBREAK();
+ $m = new \Upper_enum\PBCALLABLE();
+ $m = new \Upper_enum\PBCASE();
+ $m = new \Upper_enum\PBCATCH();
+ $m = new \Upper_enum\PBCLASS();
+ $m = new \Upper_enum\PBCLONE();
+ $m = new \Upper_enum\PBCONST();
+ $m = new \Upper_enum\PBCONTINUE();
+ $m = new \Upper_enum\PBDECLARE();
+ $m = new \Upper_enum\PBDEFAULT();
+ $m = new \Upper_enum\PBDIE();
+ $m = new \Upper_enum\PBDO();
+ $m = new \Upper_enum\PBECHO();
+ $m = new \Upper_enum\PBELSE();
+ $m = new \Upper_enum\PBELSEIF();
+ $m = new \Upper_enum\PBEMPTY();
+ $m = new \Upper_enum\PBENDDECLARE();
+ $m = new \Upper_enum\PBENDFOR();
+ $m = new \Upper_enum\PBENDFOREACH();
+ $m = new \Upper_enum\PBENDIF();
+ $m = new \Upper_enum\PBENDSWITCH();
+ $m = new \Upper_enum\PBENDWHILE();
+ $m = new \Upper_enum\PBEVAL();
+ $m = new \Upper_enum\PBEXIT();
+ $m = new \Upper_enum\PBEXTENDS();
+ $m = new \Upper_enum\PBFINAL();
+ $m = new \Upper_enum\PBFOR();
+ $m = new \Upper_enum\PBFOREACH();
+ $m = new \Upper_enum\PBFUNCTION();
+ $m = new \Upper_enum\PBGLOBAL();
+ $m = new \Upper_enum\PBGOTO();
+ $m = new \Upper_enum\PBIF();
+ $m = new \Upper_enum\PBIMPLEMENTS();
+ $m = new \Upper_enum\PBINCLUDE();
+ $m = new \Upper_enum\PBINCLUDE_ONCE();
+ $m = new \Upper_enum\PBINSTANCEOF();
+ $m = new \Upper_enum\PBINSTEADOF();
+ $m = new \Upper_enum\PBINTERFACE();
+ $m = new \Upper_enum\PBISSET();
+ $m = new \Upper_enum\PBLIST();
+ $m = new \Upper_enum\PBNAMESPACE();
+ $m = new \Upper_enum\PBNEW();
+ $m = new \Upper_enum\PBOR();
+ $m = new \Upper_enum\PBPRINT();
+ $m = new \Upper_enum\PBPRIVATE();
+ $m = new \Upper_enum\PBPROTECTED();
+ $m = new \Upper_enum\PBPUBLIC();
+ $m = new \Upper_enum\PBREQUIRE();
+ $m = new \Upper_enum\PBREQUIRE_ONCE();
+ $m = new \Upper_enum\PBRETURN();
+ $m = new \Upper_enum\PBSTATIC();
+ $m = new \Upper_enum\PBSWITCH();
+ $m = new \Upper_enum\PBTHROW();
+ $m = new \Upper_enum\PBTRAIT();
+ $m = new \Upper_enum\PBTRY();
+ $m = new \Upper_enum\PBUNSET();
+ $m = new \Upper_enum\PBUSE();
+ $m = new \Upper_enum\PBVAR();
+ $m = new \Upper_enum\PBWHILE();
+ $m = new \Upper_enum\PBXOR();
+ $m = new \Upper_enum\PBINT();
+ $m = new \Upper_enum\PBFLOAT();
+ $m = new \Upper_enum\PBBOOL();
+ $m = new \Upper_enum\PBSTRING();
+ $m = new \Upper_enum\PBTRUE();
+ $m = new \Upper_enum\PBFALSE();
+ $m = new \Upper_enum\PBNULL();
+ $m = new \Upper_enum\PBVOID();
+ $m = new \Upper_enum\PBITERABLE();
+
+ $m = \Lower_enum_value\NotAllowed::PBabstract;
+ $m = \Lower_enum_value\NotAllowed::PBand;
+ $m = \Lower_enum_value\NotAllowed::PBarray;
+ $m = \Lower_enum_value\NotAllowed::PBas;
+ $m = \Lower_enum_value\NotAllowed::PBbreak;
+ $m = \Lower_enum_value\NotAllowed::PBcallable;
+ $m = \Lower_enum_value\NotAllowed::PBcase;
+ $m = \Lower_enum_value\NotAllowed::PBcatch;
+ $m = \Lower_enum_value\NotAllowed::PBclass;
+ $m = \Lower_enum_value\NotAllowed::PBclone;
+ $m = \Lower_enum_value\NotAllowed::PBconst;
+ $m = \Lower_enum_value\NotAllowed::PBcontinue;
+ $m = \Lower_enum_value\NotAllowed::PBdeclare;
+ $m = \Lower_enum_value\NotAllowed::PBdefault;
+ $m = \Lower_enum_value\NotAllowed::PBdie;
+ $m = \Lower_enum_value\NotAllowed::PBdo;
+ $m = \Lower_enum_value\NotAllowed::PBecho;
+ $m = \Lower_enum_value\NotAllowed::PBelse;
+ $m = \Lower_enum_value\NotAllowed::PBelseif;
+ $m = \Lower_enum_value\NotAllowed::PBempty;
+ $m = \Lower_enum_value\NotAllowed::PBenddeclare;
+ $m = \Lower_enum_value\NotAllowed::PBendfor;
+ $m = \Lower_enum_value\NotAllowed::PBendforeach;
+ $m = \Lower_enum_value\NotAllowed::PBendif;
+ $m = \Lower_enum_value\NotAllowed::PBendswitch;
+ $m = \Lower_enum_value\NotAllowed::PBendwhile;
+ $m = \Lower_enum_value\NotAllowed::PBeval;
+ $m = \Lower_enum_value\NotAllowed::PBexit;
+ $m = \Lower_enum_value\NotAllowed::PBextends;
+ $m = \Lower_enum_value\NotAllowed::PBfinal;
+ $m = \Lower_enum_value\NotAllowed::PBfor;
+ $m = \Lower_enum_value\NotAllowed::PBforeach;
+ $m = \Lower_enum_value\NotAllowed::PBfunction;
+ $m = \Lower_enum_value\NotAllowed::PBglobal;
+ $m = \Lower_enum_value\NotAllowed::PBgoto;
+ $m = \Lower_enum_value\NotAllowed::PBif;
+ $m = \Lower_enum_value\NotAllowed::PBimplements;
+ $m = \Lower_enum_value\NotAllowed::PBinclude;
+ $m = \Lower_enum_value\NotAllowed::PBinclude_once;
+ $m = \Lower_enum_value\NotAllowed::PBinstanceof;
+ $m = \Lower_enum_value\NotAllowed::PBinsteadof;
+ $m = \Lower_enum_value\NotAllowed::PBinterface;
+ $m = \Lower_enum_value\NotAllowed::PBisset;
+ $m = \Lower_enum_value\NotAllowed::PBlist;
+ $m = \Lower_enum_value\NotAllowed::PBnamespace;
+ $m = \Lower_enum_value\NotAllowed::PBnew;
+ $m = \Lower_enum_value\NotAllowed::PBor;
+ $m = \Lower_enum_value\NotAllowed::PBprint;
+ $m = \Lower_enum_value\NotAllowed::PBprivate;
+ $m = \Lower_enum_value\NotAllowed::PBprotected;
+ $m = \Lower_enum_value\NotAllowed::PBpublic;
+ $m = \Lower_enum_value\NotAllowed::PBrequire;
+ $m = \Lower_enum_value\NotAllowed::PBrequire_once;
+ $m = \Lower_enum_value\NotAllowed::PBreturn;
+ $m = \Lower_enum_value\NotAllowed::PBstatic;
+ $m = \Lower_enum_value\NotAllowed::PBswitch;
+ $m = \Lower_enum_value\NotAllowed::PBthrow;
+ $m = \Lower_enum_value\NotAllowed::PBtrait;
+ $m = \Lower_enum_value\NotAllowed::PBtry;
+ $m = \Lower_enum_value\NotAllowed::PBunset;
+ $m = \Lower_enum_value\NotAllowed::PBuse;
+ $m = \Lower_enum_value\NotAllowed::PBvar;
+ $m = \Lower_enum_value\NotAllowed::PBwhile;
+ $m = \Lower_enum_value\NotAllowed::PBxor;
+ $m = \Lower_enum_value\NotAllowed::int;
+ $m = \Lower_enum_value\NotAllowed::float;
+ $m = \Lower_enum_value\NotAllowed::bool;
+ $m = \Lower_enum_value\NotAllowed::string;
+ $m = \Lower_enum_value\NotAllowed::true;
+ $m = \Lower_enum_value\NotAllowed::false;
+ $m = \Lower_enum_value\NotAllowed::null;
+ $m = \Lower_enum_value\NotAllowed::void;
+ $m = \Lower_enum_value\NotAllowed::iterable;
+
+ $m = \Upper_enum_value\NotAllowed::PBABSTRACT;
+ $m = \Upper_enum_value\NotAllowed::PBAND;
+ $m = \Upper_enum_value\NotAllowed::PBARRAY;
+ $m = \Upper_enum_value\NotAllowed::PBAS;
+ $m = \Upper_enum_value\NotAllowed::PBBREAK;
+ $m = \Upper_enum_value\NotAllowed::PBCALLABLE;
+ $m = \Upper_enum_value\NotAllowed::PBCASE;
+ $m = \Upper_enum_value\NotAllowed::PBCATCH;
+ $m = \Upper_enum_value\NotAllowed::PBCLASS;
+ $m = \Upper_enum_value\NotAllowed::PBCLONE;
+ $m = \Upper_enum_value\NotAllowed::PBCONST;
+ $m = \Upper_enum_value\NotAllowed::PBCONTINUE;
+ $m = \Upper_enum_value\NotAllowed::PBDECLARE;
+ $m = \Upper_enum_value\NotAllowed::PBDEFAULT;
+ $m = \Upper_enum_value\NotAllowed::PBDIE;
+ $m = \Upper_enum_value\NotAllowed::PBDO;
+ $m = \Upper_enum_value\NotAllowed::PBECHO;
+ $m = \Upper_enum_value\NotAllowed::PBELSE;
+ $m = \Upper_enum_value\NotAllowed::PBELSEIF;
+ $m = \Upper_enum_value\NotAllowed::PBEMPTY;
+ $m = \Upper_enum_value\NotAllowed::PBENDDECLARE;
+ $m = \Upper_enum_value\NotAllowed::PBENDFOR;
+ $m = \Upper_enum_value\NotAllowed::PBENDFOREACH;
+ $m = \Upper_enum_value\NotAllowed::PBENDIF;
+ $m = \Upper_enum_value\NotAllowed::PBENDSWITCH;
+ $m = \Upper_enum_value\NotAllowed::PBENDWHILE;
+ $m = \Upper_enum_value\NotAllowed::PBEVAL;
+ $m = \Upper_enum_value\NotAllowed::PBEXIT;
+ $m = \Upper_enum_value\NotAllowed::PBEXTENDS;
+ $m = \Upper_enum_value\NotAllowed::PBFINAL;
+ $m = \Upper_enum_value\NotAllowed::PBFOR;
+ $m = \Upper_enum_value\NotAllowed::PBFOREACH;
+ $m = \Upper_enum_value\NotAllowed::PBFUNCTION;
+ $m = \Upper_enum_value\NotAllowed::PBGLOBAL;
+ $m = \Upper_enum_value\NotAllowed::PBGOTO;
+ $m = \Upper_enum_value\NotAllowed::PBIF;
+ $m = \Upper_enum_value\NotAllowed::PBIMPLEMENTS;
+ $m = \Upper_enum_value\NotAllowed::PBINCLUDE;
+ $m = \Upper_enum_value\NotAllowed::PBINCLUDE_ONCE;
+ $m = \Upper_enum_value\NotAllowed::PBINSTANCEOF;
+ $m = \Upper_enum_value\NotAllowed::PBINSTEADOF;
+ $m = \Upper_enum_value\NotAllowed::PBINTERFACE;
+ $m = \Upper_enum_value\NotAllowed::PBISSET;
+ $m = \Upper_enum_value\NotAllowed::PBLIST;
+ $m = \Upper_enum_value\NotAllowed::PBNAMESPACE;
+ $m = \Upper_enum_value\NotAllowed::PBNEW;
+ $m = \Upper_enum_value\NotAllowed::PBOR;
+ $m = \Upper_enum_value\NotAllowed::PBPRINT;
+ $m = \Upper_enum_value\NotAllowed::PBPRIVATE;
+ $m = \Upper_enum_value\NotAllowed::PBPROTECTED;
+ $m = \Upper_enum_value\NotAllowed::PBPUBLIC;
+ $m = \Upper_enum_value\NotAllowed::PBREQUIRE;
+ $m = \Upper_enum_value\NotAllowed::PBREQUIRE_ONCE;
+ $m = \Upper_enum_value\NotAllowed::PBRETURN;
+ $m = \Upper_enum_value\NotAllowed::PBSTATIC;
+ $m = \Upper_enum_value\NotAllowed::PBSWITCH;
+ $m = \Upper_enum_value\NotAllowed::PBTHROW;
+ $m = \Upper_enum_value\NotAllowed::PBTRAIT;
+ $m = \Upper_enum_value\NotAllowed::PBTRY;
+ $m = \Upper_enum_value\NotAllowed::PBUNSET;
+ $m = \Upper_enum_value\NotAllowed::PBUSE;
+ $m = \Upper_enum_value\NotAllowed::PBVAR;
+ $m = \Upper_enum_value\NotAllowed::PBWHILE;
+ $m = \Upper_enum_value\NotAllowed::PBXOR;
+ $m = \Upper_enum_value\NotAllowed::INT;
+ $m = \Upper_enum_value\NotAllowed::FLOAT;
+ $m = \Upper_enum_value\NotAllowed::BOOL;
+ $m = \Upper_enum_value\NotAllowed::STRING;
+ $m = \Upper_enum_value\NotAllowed::TRUE;
+ $m = \Upper_enum_value\NotAllowed::FALSE;
+ $m = \Upper_enum_value\NotAllowed::NULL;
+ $m = \Upper_enum_value\NotAllowed::VOID;
+ $m = \Upper_enum_value\NotAllowed::ITERABLE;
+
+ $this->assertTrue(true);
+ }
+
+ #########################################################
+ # Test fluent setters.
+ #########################################################
+
+ public function testFluentSetters()
+ {
+ $m = (new TestMessage())
+ ->setOptionalInt32(1)
+ ->setOptionalUInt32(2);
+ $this->assertSame(1, $m->getOptionalInt32());
+ $this->assertSame(2, $m->getOptionalUInt32());
+ }
+
+ #########################################################
+ # Test Reverse Field Order.
+ #########################################################
+
+ public function testReverseFieldOrder()
+ {
+ $m = new TestReverseFieldOrder();
+ $m->setB("abc");
+ $this->assertSame("abc", $m->getB());
+ $this->assertNotSame("abc", $m->getA());
+ }
+
+ #########################################################
+ # Test Reverse Field Order.
+ #########################################################
+
+ public function testLowerCase()
+ {
+ $m = new testLowerCaseMessage();
+ $n = testLowerCaseEnum::VALUE;
+ $this->assertTrue(true);
+ }
+
+ #########################################################
+ # Test Array Constructor.
+ #########################################################
+
+ public function testArrayConstructor()
+ {
+ $m = new TestMessage([
+ 'optional_int32' => -42,
+ 'optional_int64' => -43,
+ 'optional_uint32' => 42,
+ 'optional_uint64' => 43,
+ 'optional_sint32' => -44,
+ 'optional_sint64' => -45,
+ 'optional_fixed32' => 46,
+ 'optional_fixed64' => 47,
+ 'optional_sfixed32' => -46,
+ 'optional_sfixed64' => -47,
+ 'optional_float' => 1.5,
+ 'optional_double' => 1.6,
+ 'optional_bool' => true,
+ 'optional_string' => 'a',
+ 'optional_bytes' => 'bbbb',
+ 'optional_enum' => TestEnum::ONE,
+ 'optional_message' => new Sub([
+ 'a' => 33
+ ]),
+ 'repeated_int32' => [-42, -52],
+ 'repeated_int64' => [-43, -53],
+ 'repeated_uint32' => [42, 52],
+ 'repeated_uint64' => [43, 53],
+ 'repeated_sint32' => [-44, -54],
+ 'repeated_sint64' => [-45, -55],
+ 'repeated_fixed32' => [46, 56],
+ 'repeated_fixed64' => [47, 57],
+ 'repeated_sfixed32' => [-46, -56],
+ 'repeated_sfixed64' => [-47, -57],
+ 'repeated_float' => [1.5, 2.5],
+ 'repeated_double' => [1.6, 2.6],
+ 'repeated_bool' => [true, false],
+ 'repeated_string' => ['a', 'c'],
+ 'repeated_bytes' => ['bbbb', 'dddd'],
+ 'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE],
+ 'repeated_message' => [new Sub(['a' => 34]),
+ new Sub(['a' => 35])],
+ 'map_int32_int32' => [-62 => -62],
+ 'map_int64_int64' => [-63 => -63],
+ 'map_uint32_uint32' => [62 => 62],
+ 'map_uint64_uint64' => [63 => 63],
+ 'map_sint32_sint32' => [-64 => -64],
+ 'map_sint64_sint64' => [-65 => -65],
+ 'map_fixed32_fixed32' => [66 => 66],
+ 'map_fixed64_fixed64' => [67 => 67],
+ 'map_sfixed32_sfixed32' => [-68 => -68],
+ 'map_sfixed64_sfixed64' => [-69 => -69],
+ 'map_int32_float' => [1 => 3.5],
+ 'map_int32_double' => [1 => 3.6],
+ 'map_bool_bool' => [true => true],
+ 'map_string_string' => ['e' => 'e'],
+ 'map_int32_bytes' => [1 => 'ffff'],
+ 'map_int32_enum' => [1 => TestEnum::ONE],
+ 'map_int32_message' => [1 => new Sub(['a' => 36])],
+ ]);
+
+ TestUtil::assertTestMessage($m);
+ $this->assertTrue(true);
+ }
+
+ public function testReferenceInArrayConstructor()
+ {
+ $keys = [[
+ 'optional_bool' => true,
+ 'repeated_bool' => [true],
+ 'map_bool_bool' => [true => true],
+ 'optional_double' => 1.0,
+ 'repeated_double' => [1.0],
+ 'map_int32_double' => [1 => 1.0],
+ 'optional_int32' => 1,
+ 'repeated_int32' => [1],
+ 'map_int32_int32' => [1 => 1],
+ 'optional_string' => 'a',
+ 'repeated_string' => ['a'],
+ 'map_string_string' => ['a' => 'a'],
+ 'optional_message' => ['a' => 1],
+ 'repeated_message' => [['a' => 1]],
+ 'map_int32_message' => [1 => ['a' => 1]],
+ ]];
+
+ foreach ($keys as &$key) {
+ foreach ($key as $id => &$value) {
+ if ($id === 'repeated_bool') {
+ foreach ($value as &$element) {
+ }
+ }
+ if ($id === 'map_bool_bool') {
+ foreach ($value as $mapKey => &$element) {
+ }
+ }
+ if ($id === 'repeated_double') {
+ foreach ($value as &$element) {
+ }
+ }
+ if ($id === 'map_int32_double') {
+ foreach ($value as $mapKey => &$element) {
+ }
+ }
+ if ($id === 'repeated_int32') {
+ foreach ($value as &$element) {
+ }
+ }
+ if ($id === 'map_int32_int32') {
+ foreach ($value as $mapKey => &$element) {
+ }
+ }
+ if ($id === 'repeated_string') {
+ foreach ($value as &$element) {
+ }
+ }
+ if ($id === 'map_string_string') {
+ foreach ($value as $mapKey => &$element) {
+ }
+ }
+ if ($id === 'optional_message') {
+ $value = new Sub($value);
+ }
+ if ($id === 'repeated_message') {
+ foreach ($value as &$element) {
+ $element = new Sub($element);
+ }
+ }
+ if ($id === 'map_int32_message') {
+ foreach ($value as $mapKey => &$element) {
+ $element = new Sub($element);
+ }
+ }
+ }
+ $key = new TestMessage($key);
+ }
+ }
+
+ public function testOneofMessageInArrayConstructor()
+ {
+ $m = new TestMessage([
+ 'oneof_message' => new Sub(),
+ ]);
+ $this->assertSame('oneof_message', $m->getMyOneof());
+ $this->assertNotNull($m->getOneofMessage());
+ }
+
+ public function testOneofStringInArrayConstructor()
+ {
+ $m = new TestMessage([
+ 'oneof_string' => 'abc',
+ ]);
+ }
+
+ #########################################################
+ # Test message equals.
+ #########################################################
+
+ public function testMessageEquals()
+ {
+ $m = new TestMessage();
+ TestUtil::setTestMessage($m);
+ $n = new TestMessage();
+ TestUtil::setTestMessage($n);
+ $this->assertEquals($m, $n);
+ }
+
+ #########################################################
+ # Test reference of value
+ #########################################################
+
+ public function testValueIsReference()
+ {
+ // Bool element
+ $values = [true];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setOptionalBool($values[0]);
+
+ // Int32 element
+ $values = [1];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setOptionalInt32($values[0]);
+
+ // Double element
+ $values = [1.0];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setOptionalDouble($values[0]);
+
+ // String element
+ $values = ['a'];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setOptionalString($values[0]);
+ }
+}
diff --git a/third_party/protobuf/php/tests/generated_phpdoc_test.php b/third_party/protobuf/php/tests/generated_phpdoc_test.php
new file mode 100644
index 0000000..526927f
--- /dev/null
+++ b/third_party/protobuf/php/tests/generated_phpdoc_test.php
@@ -0,0 +1,345 @@
+<?php
+
+require_once('generated/NoNamespaceEnum.php');
+require_once('generated/NoNamespaceMessage.php');
+require_once('test_base.php');
+require_once('test_util.php');
+
+use Foo\TestMessage;
+
+class GeneratedPhpdocTest extends TestBase
+{
+ public function testPhpDocForClass()
+ {
+ $class = new ReflectionClass('Foo\TestMessage');
+ $doc = $class->getDocComment();
+ $this->assertContains('foo.TestMessage', $doc);
+ }
+
+ public function testPhpDocForConstructor()
+ {
+ $class = new ReflectionClass('Foo\TestMessage');
+ $doc = $class->getMethod('__construct')->getDocComment();
+ $this->assertContains('@param array $data', $doc);
+ $this->assertContains('@type int $optional_int32', $doc);
+ }
+
+ /**
+ * @dataProvider providePhpDocForGettersAndSetters
+ */
+ public function testPhpDocForIntGetters($methods, $expectedDoc)
+ {
+ $class = new ReflectionClass('Foo\TestMessage');
+ foreach ($methods as $method) {
+ $doc = $class->getMethod($method)->getDocComment();
+ $this->assertContains($expectedDoc, $doc);
+ }
+ }
+
+ public function providePhpDocForGettersAndSetters()
+ {
+ return [
+ [
+ [
+ 'setOptionalInt32',
+ 'setOptionalUint32',
+ 'setOptionalSint32',
+ 'setOptionalFixed32',
+ 'setOptionalSfixed32',
+ 'setOneofInt32',
+ 'setOneofUint32',
+ 'setOneofSint32',
+ 'setOneofFixed32',
+ 'setOneofSfixed32',
+ 'setOptionalEnum',
+ 'setOptionalNoNamespaceEnum',
+ 'setOptionalNestedEnum',
+ 'setOneofEnum'
+ ],
+ '@param int $var'
+ ],
+ [
+ [
+ 'setOptionalInt64',
+ 'setOptionalUint64',
+ 'setOptionalSint64',
+ 'setOptionalFixed64',
+ 'setOptionalSfixed64',
+ 'setOneofInt64',
+ 'setOneofUint64',
+ 'setOneofSint64',
+ 'setOneofFixed64',
+ 'setOneofSfixed64',
+ ],
+ '@param int|string $var'
+ ],
+ [
+ [
+ 'getOptionalInt32',
+ 'getOptionalUint32',
+ 'getOptionalSint32',
+ 'getOptionalFixed32',
+ 'getOptionalSfixed32',
+ 'getOneofInt32',
+ 'getOneofUint32',
+ 'getOneofSint32',
+ 'getOneofFixed32',
+ 'getOneofSfixed32',
+ 'getOptionalEnum',
+ 'getOptionalNoNamespaceEnum',
+ 'getOptionalNestedEnum',
+ 'getOneofEnum',
+ ],
+ '@return int'
+ ],
+ [
+ [
+ 'setOptionalInt64',
+ 'setOptionalUint64',
+ 'setOptionalSint64',
+ 'setOptionalFixed64',
+ 'setOptionalSfixed64',
+ 'setOneofInt64',
+ 'setOneofUint64',
+ 'setOneofSint64',
+ 'setOneofFixed64',
+ 'setOneofSfixed64',
+ ],
+ '@param int|string $var'
+ ],
+ [
+ [
+ 'getRepeatedInt32',
+ 'getRepeatedInt64',
+ 'getRepeatedUint32',
+ 'getRepeatedUint64',
+ 'getRepeatedSint32',
+ 'getRepeatedSint64',
+ 'getRepeatedFixed32',
+ 'getRepeatedFixed64',
+ 'getRepeatedSfixed32',
+ 'getRepeatedSfixed64',
+ 'getRepeatedFloat',
+ 'getRepeatedDouble',
+ 'getRepeatedBool',
+ 'getRepeatedString',
+ 'getRepeatedBytes',
+ 'getRepeatedEnum',
+ 'getRepeatedMessage',
+ 'getRepeatedRecursive',
+ 'getRepeatedNoNamespaceMessage',
+ 'getRepeatedNoNamespaceEnum',
+ ],
+ '@return \Google\Protobuf\Internal\RepeatedField'
+ ],
+ [
+ [
+ 'getMapInt32Int32',
+ 'getMapInt64Int64',
+ 'getMapUint32Uint32',
+ 'getMapUint64Uint64',
+ 'getMapSint32Sint32',
+ 'getMapSint64Sint64',
+ 'getMapFixed32Fixed32',
+ 'getMapFixed64Fixed64',
+ 'getMapSfixed32Sfixed32',
+ 'getMapSfixed64Sfixed64',
+ 'getMapInt32Float',
+ 'getMapInt32Double',
+ 'getMapBoolBool',
+ 'getMapStringString',
+ 'getMapInt32Bytes',
+ 'getMapInt32Enum',
+ 'getMapInt32Message',
+ 'getMapRecursive',
+ ],
+ '@return \Google\Protobuf\Internal\MapField'
+ ],
+ [
+ [
+ 'setRepeatedInt32',
+ 'setRepeatedUint32',
+ 'setRepeatedSint32',
+ 'setRepeatedFixed32',
+ 'setRepeatedSfixed32',
+ 'setRepeatedEnum',
+ 'setRepeatedNoNamespaceEnum',
+ ],
+ '@param int[]|\Google\Protobuf\Internal\RepeatedField $var'
+ ],
+ [
+ [
+ 'setRepeatedInt64',
+ 'setRepeatedUint64',
+ 'setRepeatedSint64',
+ 'setRepeatedFixed64',
+ 'setRepeatedSfixed64',
+ ],
+ '@param int[]|string[]|\Google\Protobuf\Internal\RepeatedField $var'
+ ],
+ [
+ [
+ 'setRepeatedFloat',
+ 'setRepeatedDouble',
+ ],
+ '@param float[]|\Google\Protobuf\Internal\RepeatedField $var'
+ ],
+ [
+ [
+ 'setRepeatedBool',
+ ],
+ '@param bool[]|\Google\Protobuf\Internal\RepeatedField $var'
+ ],
+ [
+ [
+ 'setRepeatedString',
+ 'setRepeatedBytes',
+ ],
+ '@param string[]|\Google\Protobuf\Internal\RepeatedField $var'
+ ],
+ [
+ [
+ 'setRepeatedMessage',
+ ],
+ '@param \Foo\TestMessage\Sub[]|\Google\Protobuf\Internal\RepeatedField $var'
+ ],
+ [
+ [
+ 'setRepeatedRecursive',
+ ],
+ '@param \Foo\TestMessage[]|\Google\Protobuf\Internal\RepeatedField $var'
+ ],
+ [
+ [
+ 'setRepeatedNoNamespaceMessage',
+ ],
+ '@param \NoNamespaceMessage[]|\Google\Protobuf\Internal\RepeatedField $var'
+ ],
+ [
+ [
+ 'setMapInt32Int32',
+ 'setMapInt64Int64',
+ 'setMapUint32Uint32',
+ 'setMapUint64Uint64',
+ 'setMapSint32Sint32',
+ 'setMapSint64Sint64',
+ 'setMapFixed32Fixed32',
+ 'setMapFixed64Fixed64',
+ 'setMapSfixed32Sfixed32',
+ 'setMapSfixed64Sfixed64',
+ 'setMapInt32Float',
+ 'setMapInt32Double',
+ 'setMapBoolBool',
+ 'setMapStringString',
+ 'setMapInt32Bytes',
+ 'setMapInt32Enum',
+ 'setMapInt32Message',
+ 'setMapRecursive',
+ ],
+ '@param array|\Google\Protobuf\Internal\MapField $var'
+ ],
+ [
+ [
+ 'getOptionalFloat',
+ 'getOptionalDouble',
+ 'getOneofDouble',
+ 'getOneofFloat',
+ ],
+ '@return float'
+ ],
+ [
+ [
+ 'setOptionalFloat',
+ 'setOptionalDouble',
+ 'setOneofDouble',
+ 'setOneofFloat',
+ ],
+ '@param float $var'
+ ],
+ [
+ [
+ 'getOptionalBool',
+ 'getOneofBool',
+ ],
+ '@return bool'],
+ [
+ [
+ 'setOptionalBool',
+ 'setOneofBool',
+ ],
+ '@param bool $var'
+ ],
+ [
+ [
+ 'getOptionalString',
+ 'getOptionalBytes',
+ 'getOneofString',
+ 'getOneofBytes',
+ 'getMyOneof',
+ ],
+ '@return string'
+ ],
+ [
+ [
+ 'setOptionalString',
+ 'setOptionalBytes',
+ 'setOneofString',
+ 'setOneofBytes',
+ ],
+ '@param string $var'
+ ],
+
+ [
+ [
+ 'getOptionalMessage',
+ 'getOneofMessage'
+ ],
+ '@return \Foo\TestMessage\Sub'
+ ],
+ [
+ [
+ 'setOptionalMessage',
+ 'setOneofMessage'
+ ],
+ '@param \Foo\TestMessage\Sub $var'
+ ],
+ [
+ [
+ 'getOptionalIncludedMessage'
+ ],
+ '@return \Bar\TestInclude'
+ ],
+ [
+ [
+ 'setOptionalIncludedMessage'
+ ],
+ '@param \Bar\TestInclude $var'
+ ],
+ [
+ [
+ 'getRecursive'
+ ],
+ '@return \Foo\TestMessage'
+ ],
+ [
+ [
+ 'setRecursive'
+ ],
+ '@param \Foo\TestMessage $var'
+ ],
+
+ [
+ [
+ 'getOptionalNoNamespaceMessage'
+ ],
+ '@return \NoNamespaceMessage'
+ ],
+ [
+ [
+ 'setOptionalNoNamespaceMessage'
+ ],
+ '@param \NoNamespaceMessage $var'
+ ],
+ ];
+ }
+}
diff --git a/third_party/protobuf/php/tests/generated_service_test.php b/third_party/protobuf/php/tests/generated_service_test.php
new file mode 100644
index 0000000..5407db9
--- /dev/null
+++ b/third_party/protobuf/php/tests/generated_service_test.php
@@ -0,0 +1,110 @@
+<?php
+
+require_once('test_base.php');
+require_once('test_util.php');
+
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\MapField;
+use Google\Protobuf\Internal\GPBType;
+use Foo\Greeter;
+use Foo\HelloRequest;
+use Foo\HelloReply;
+
+class GeneratedServiceTest extends TestBase
+{
+ /**
+ * @var \ReflectionClass
+ */
+ private $serviceClass;
+
+ /**
+ * @var \ReflectionClass
+ */
+ private $namespacedServiceClass;
+
+ /**
+ * @var array
+ */
+ private $methodNames = [
+ 'sayHello',
+ 'sayHelloAgain'
+ ];
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->serviceClass = new ReflectionClass('Foo\GreeterInterface');
+
+ $this->namespacedServiceClass = new ReflectionClass('Bar\OtherGreeterInterface');
+ }
+
+ public function testIsInterface()
+ {
+ $this->assertTrue($this->serviceClass->isInterface());
+ }
+
+ public function testPhpDocForClass()
+ {
+ $this->assertContains('foo.Greeter', $this->serviceClass->getDocComment());
+ }
+
+ public function testPhpDocForNamespacedClass()
+ {
+ $this->assertContains('foo.OtherGreeter', $this->namespacedServiceClass->getDocComment());
+ }
+
+ public function testServiceMethodsAreGenerated()
+ {
+ $this->assertCount(count($this->methodNames), $this->serviceClass->getMethods());
+ foreach ($this->methodNames as $methodName) {
+ $this->assertTrue($this->serviceClass->hasMethod($methodName));
+ }
+ }
+
+ public function testPhpDocForServiceMethod()
+ {
+ foreach ($this->methodNames as $methodName) {
+ $docComment = $this->serviceClass->getMethod($methodName)->getDocComment();
+ $this->assertContains($methodName, $docComment);
+ $this->assertContains('@param \Foo\HelloRequest $request', $docComment);
+ $this->assertContains('@return \Foo\HelloReply', $docComment);
+ }
+ }
+
+ public function testPhpDocForServiceMethodInNamespacedClass()
+ {
+ foreach ($this->methodNames as $methodName) {
+ $docComment = $this->namespacedServiceClass->getMethod($methodName)->getDocComment();
+ $this->assertContains($methodName, $docComment);
+ $this->assertContains('@param \Foo\HelloRequest $request', $docComment);
+ $this->assertContains('@return \Foo\HelloReply', $docComment);
+ }
+ }
+
+ public function testParamForServiceMethod()
+ {
+ foreach ($this->methodNames as $methodName) {
+ $method = $this->serviceClass->getMethod($methodName);
+ $this->assertCount(1, $method->getParameters());
+ $param = $method->getParameters()[0];
+ $this->assertFalse($param->isOptional());
+ $this->assertSame('request', $param->getName());
+ // ReflectionParameter::getType only exists in PHP 7+, so get the type from __toString
+ $this->assertContains('Foo\HelloRequest $request', (string) $param);
+ }
+ }
+
+ public function testParamForServiceMethodInNamespacedClass()
+ {
+ foreach ($this->methodNames as $methodName) {
+ $method = $this->serviceClass->getMethod($methodName);
+ $this->assertCount(1, $method->getParameters());
+ $param = $method->getParameters()[0];
+ $this->assertFalse($param->isOptional());
+ $this->assertSame('request', $param->getName());
+ // ReflectionParameter::getType only exists in PHP 7+, so get the type from __toString
+ $this->assertContains('Foo\HelloRequest $request', (string) $param);
+ }
+ }
+}
diff --git a/third_party/protobuf/php/tests/map_field_test.php b/third_party/protobuf/php/tests/map_field_test.php
new file mode 100644
index 0000000..577be68
--- /dev/null
+++ b/third_party/protobuf/php/tests/map_field_test.php
@@ -0,0 +1,505 @@
+<?php
+
+require_once('test_util.php');
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\MapField;
+use Foo\TestMessage;
+use Foo\TestMessage\Sub;
+
+class MapFieldTest extends \PHPUnit\Framework\TestCase {
+
+ #########################################################
+ # Test int32 field.
+ #########################################################
+
+ public function testInt32() {
+ $arr = new MapField(GPBType::INT32, GPBType::INT32);
+
+ // Test integer argument.
+ $arr[MAX_INT32] = MAX_INT32;
+ $this->assertSame(MAX_INT32, $arr[MAX_INT32]);
+ $arr[MIN_INT32] = MIN_INT32;
+ $this->assertSame(MIN_INT32, $arr[MIN_INT32]);
+ $this->assertEquals(2, count($arr));
+ $this->assertTrue(isset($arr[MAX_INT32]));
+ $this->assertTrue(isset($arr[MIN_INT32]));
+ unset($arr[MAX_INT32]);
+ unset($arr[MIN_INT32]);
+ $this->assertEquals(0, count($arr));
+
+ // Test float argument.
+ $arr[1.9] = 1.9;
+ $arr[2.1] = 2.1;
+ $this->assertSame(1, $arr[1]);
+ $this->assertSame(2, $arr[2]);
+ $arr[MAX_INT32_FLOAT] = MAX_INT32_FLOAT;
+ $this->assertSame(MAX_INT32, $arr[MAX_INT32]);
+ $arr[MIN_INT32_FLOAT] = MIN_INT32_FLOAT;
+ $this->assertSame(MIN_INT32, $arr[MIN_INT32]);
+ $this->assertEquals(4, count($arr));
+ unset($arr[1.9]);
+ unset($arr[2.9]);
+ unset($arr[MAX_INT32_FLOAT]);
+ unset($arr[MIN_INT32_FLOAT]);
+ $this->assertEquals(0, count($arr));
+
+ // Test string argument.
+ $arr['2'] = '2';
+ $this->assertSame(2, $arr[2]);
+ $arr['3.1'] = '3.1';
+ $this->assertSame(3, $arr[3]);
+ $arr[MAX_INT32_STRING] = MAX_INT32_STRING;
+ $this->assertSame(MAX_INT32, $arr[MAX_INT32]);
+ $this->assertEquals(3, count($arr));
+ unset($arr['2']);
+ unset($arr['3.1']);
+ unset($arr[MAX_INT32_STRING]);
+ $this->assertEquals(0, count($arr));
+
+ // Test foreach.
+ $arr = new MapField(GPBType::INT32, GPBType::INT32);
+ for ($i = 0; $i < 3; $i++) {
+ $arr[$i] = $i;
+ }
+ $i = 0;
+ $arr_test = [];
+ foreach ($arr as $key => $val) {
+ $this->assertSame($key, $val);
+ $arr_test[] = $key;
+ $i++;
+ }
+ $this->assertTrue(isset($arr_test[0]));
+ $this->assertTrue(isset($arr_test[1]));
+ $this->assertTrue(isset($arr_test[2]));
+ $this->assertSame(3, $i);
+ }
+
+ #########################################################
+ # Test uint32 field.
+ #########################################################
+
+ public function testUint32() {
+ $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
+
+ // Test integer argument.
+ $arr[MAX_UINT32] = MAX_UINT32;
+ $this->assertSame(-1, $arr[-1]);
+ $this->assertEquals(1, count($arr));
+ unset($arr[MAX_UINT32]);
+ $this->assertEquals(0, count($arr));
+
+ $arr[-1] = -1;
+ $this->assertSame(-1, $arr[-1]);
+ $arr[MIN_UINT32] = MIN_UINT32;
+ $this->assertSame(MIN_UINT32, $arr[MIN_UINT32]);
+ $this->assertEquals(2, count($arr));
+ unset($arr[-1]);
+ unset($arr[MIN_UINT32]);
+ $this->assertEquals(0, count($arr));
+
+ // Test float argument.
+ $arr[MAX_UINT32_FLOAT] = MAX_UINT32_FLOAT;
+ $this->assertSame(-1, $arr[-1]);
+ $this->assertEquals(1, count($arr));
+ unset($arr[MAX_UINT32_FLOAT]);
+ $this->assertEquals(0, count($arr));
+
+ $arr[3.1] = 3.1;
+ $this->assertSame(3, $arr[3]);
+ $arr[-1.0] = -1.0;
+ $this->assertSame(-1, $arr[-1]);
+ $arr[MIN_UINT32_FLOAT] = MIN_UINT32_FLOAT;
+ $this->assertSame(MIN_UINT32, $arr[MIN_UINT32]);
+ $this->assertEquals(3, count($arr));
+ unset($arr[3.1]);
+ unset($arr[-1.0]);
+ unset($arr[MIN_UINT32_FLOAT]);
+ $this->assertEquals(0, count($arr));
+
+ // Test string argument.
+ $arr[MAX_UINT32_STRING] = MAX_UINT32_STRING;
+ $this->assertSame(-1, $arr[-1]);
+ $this->assertEquals(1, count($arr));
+ unset($arr[MAX_UINT32_STRING]);
+ $this->assertEquals(0, count($arr));
+
+ $arr['7'] = '7';
+ $this->assertSame(7, $arr[7]);
+ $arr['3.1'] = '3.1';
+ $this->assertSame(3, $arr[3]);
+ $arr['-1.0'] = '-1.0';
+ $this->assertSame(-1, $arr[-1]);
+ $arr[MIN_UINT32_STRING] = MIN_UINT32_STRING;
+ $this->assertSame(MIN_UINT32, $arr[MIN_UINT32]);
+ $this->assertEquals(4, count($arr));
+ unset($arr['7']);
+ unset($arr['3.1']);
+ unset($arr['-1.0']);
+ unset($arr[MIN_UINT32_STRING]);
+ $this->assertEquals(0, count($arr));
+ }
+
+ #########################################################
+ # Test int64 field.
+ #########################################################
+
+ public function testInt64() {
+ $arr = new MapField(GPBType::INT64, GPBType::INT64);
+
+ // Test integer argument.
+ $arr[MAX_INT64] = MAX_INT64;
+ $arr[MIN_INT64] = MIN_INT64;
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_INT64_STRING, $arr[MAX_INT64_STRING]);
+ $this->assertSame(MIN_INT64_STRING, $arr[MIN_INT64_STRING]);
+ } else {
+ $this->assertSame(MAX_INT64, $arr[MAX_INT64]);
+ $this->assertSame(MIN_INT64, $arr[MIN_INT64]);
+ }
+ $this->assertEquals(2, count($arr));
+ unset($arr[MAX_INT64]);
+ unset($arr[MIN_INT64]);
+ $this->assertEquals(0, count($arr));
+
+ // Test float argument.
+ $arr[1.1] = 1.1;
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('1', $arr['1']);
+ } else {
+ $this->assertSame(1, $arr[1]);
+ }
+ $this->assertEquals(1, count($arr));
+ unset($arr[1.1]);
+ $this->assertEquals(0, count($arr));
+
+ // Test string argument.
+ $arr['2'] = '2';
+ $arr['3.1'] = '3.1';
+ $arr[MAX_INT64_STRING] = MAX_INT64_STRING;
+ $arr[MIN_INT64_STRING] = MIN_INT64_STRING;
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('2', $arr['2']);
+ $this->assertSame('3', $arr['3']);
+ $this->assertSame(MAX_INT64_STRING, $arr[MAX_INT64_STRING]);
+ $this->assertSame(MIN_INT64_STRING, $arr[MIN_INT64_STRING]);
+ } else {
+ $this->assertSame(2, $arr[2]);
+ $this->assertSame(3, $arr[3]);
+ $this->assertSame(MAX_INT64, $arr[MAX_INT64]);
+ $this->assertSame(MIN_INT64, $arr[MIN_INT64]);
+ }
+ $this->assertEquals(4, count($arr));
+ unset($arr['2']);
+ unset($arr['3.1']);
+ unset($arr[MAX_INT64_STRING]);
+ unset($arr[MIN_INT64_STRING]);
+ $this->assertEquals(0, count($arr));
+ }
+
+ #########################################################
+ # Test uint64 field.
+ #########################################################
+
+ public function testUint64() {
+ $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
+
+ // Test integer argument.
+ $arr[MAX_UINT64] = MAX_UINT64;
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_UINT64_STRING, $arr[MAX_UINT64_STRING]);
+ } else {
+ $this->assertSame(MAX_UINT64, $arr[MAX_UINT64]);
+ }
+ $this->assertEquals(1, count($arr));
+ unset($arr[MAX_UINT64]);
+ $this->assertEquals(0, count($arr));
+
+ // Test float argument.
+ $arr[1.1] = 1.1;
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('1', $arr['1']);
+ } else {
+ $this->assertSame(1, $arr[1]);
+ }
+ $this->assertEquals(1, count($arr));
+ unset($arr[1.1]);
+ $this->assertEquals(0, count($arr));
+
+ // Test string argument.
+ $arr['2'] = '2';
+ $arr['3.1'] = '3.1';
+ $arr[MAX_UINT64_STRING] = MAX_UINT64_STRING;
+
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('2', $arr['2']);
+ $this->assertSame('3', $arr['3']);
+ $this->assertSame(MAX_UINT64_STRING, $arr[MAX_UINT64_STRING]);
+ } else {
+ $this->assertSame(2, $arr[2]);
+ $this->assertSame(3, $arr[3]);
+ $this->assertSame(MAX_UINT64, $arr[MAX_UINT64]);
+ }
+
+ $this->assertEquals(3, count($arr));
+ unset($arr['2']);
+ unset($arr['3.1']);
+ unset($arr[MAX_UINT64_STRING]);
+ $this->assertEquals(0, count($arr));
+ }
+
+ #########################################################
+ # Test float field.
+ #########################################################
+
+ public function testFloat() {
+ $arr = new MapField(GPBType::INT32, GPBType::FLOAT);
+
+ // Test set.
+ $arr[0] = 1;
+ $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+
+ $arr[1] = 1.1;
+ $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+
+ $arr[2] = '2';
+ $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+ $arr[3] = '3.1';
+ $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
+
+ $this->assertEquals(4, count($arr));
+ }
+
+ #########################################################
+ # Test double field.
+ #########################################################
+
+ public function testDouble() {
+ $arr = new MapField(GPBType::INT32, GPBType::DOUBLE);
+
+ // Test set.
+ $arr[0] = 1;
+ $this->assertEquals(1.0, $arr[0], '', MAX_FLOAT_DIFF);
+
+ $arr[1] = 1.1;
+ $this->assertEquals(1.1, $arr[1], '', MAX_FLOAT_DIFF);
+
+ $arr[2] = '2';
+ $this->assertEquals(2.0, $arr[2], '', MAX_FLOAT_DIFF);
+ $arr[3] = '3.1';
+ $this->assertEquals(3.1, $arr[3], '', MAX_FLOAT_DIFF);
+
+ $this->assertEquals(4, count($arr));
+ }
+
+ #########################################################
+ # Test bool field.
+ #########################################################
+
+ public function testBool() {
+ $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
+
+ // Test boolean.
+ $arr[True] = True;
+ $this->assertSame(True, $arr[True]);
+ $this->assertEquals(1, count($arr));
+ unset($arr[True]);
+ $this->assertEquals(0, count($arr));
+
+ $arr[False] = False;
+ $this->assertSame(False, $arr[False]);
+ $this->assertEquals(1, count($arr));
+ unset($arr[False]);
+ $this->assertEquals(0, count($arr));
+
+ // Test integer.
+ $arr[-1] = -1;
+ $this->assertSame(True, $arr[True]);
+ $this->assertEquals(1, count($arr));
+ unset($arr[-1]);
+ $this->assertEquals(0, count($arr));
+
+ $arr[0] = 0;
+ $this->assertSame(False, $arr[False]);
+ $this->assertEquals(1, count($arr));
+ unset($arr[0]);
+ $this->assertEquals(0, count($arr));
+
+ // Test float.
+ $arr[1.1] = 1.1;
+ $this->assertSame(True, $arr[True]);
+ $this->assertEquals(1, count($arr));
+ unset($arr[1.1]);
+ $this->assertEquals(0, count($arr));
+
+ $arr[0.0] = 0.0;
+ $this->assertSame(False, $arr[False]);
+ $this->assertEquals(1, count($arr));
+ unset($arr[0.0]);
+ $this->assertEquals(0, count($arr));
+
+ // Test string.
+ $arr['a'] = 'a';
+ $this->assertSame(True, $arr[True]);
+ $this->assertEquals(1, count($arr));
+ unset($arr['a']);
+ $this->assertEquals(0, count($arr));
+
+ $arr[''] = '';
+ $this->assertSame(False, $arr[False]);
+ $this->assertEquals(1, count($arr));
+ unset($arr['']);
+ $this->assertEquals(0, count($arr));
+ }
+
+ #########################################################
+ # Test string field.
+ #########################################################
+
+ public function testString() {
+ $arr = new MapField(GPBType::STRING, GPBType::STRING);
+
+ // Test set.
+ $arr['abc'] = 'abc';
+ $this->assertSame('abc', $arr['abc']);
+ $this->assertEquals(1, count($arr));
+ unset($arr['abc']);
+ $this->assertEquals(0, count($arr));
+
+ $arr[1] = 1;
+ $this->assertSame('1', $arr['1']);
+ $this->assertEquals(1, count($arr));
+ unset($arr[1]);
+ $this->assertEquals(0, count($arr));
+
+ $arr[1.1] = 1.1;
+ $this->assertSame('1.1', $arr['1.1']);
+ $this->assertEquals(1, count($arr));
+ unset($arr[1.1]);
+ $this->assertEquals(0, count($arr));
+
+ $arr[True] = True;
+ $this->assertSame('1', $arr['1']);
+ $this->assertEquals(1, count($arr));
+ unset($arr[True]);
+ $this->assertEquals(0, count($arr));
+
+ // Test foreach.
+ $arr = new MapField(GPBType::STRING, GPBType::STRING);
+ for ($i = 0; $i < 3; $i++) {
+ $arr[$i] = $i;
+ }
+ $i = 0;
+ $arr_test = [];
+ foreach ($arr as $key => $val) {
+ $this->assertSame($key, $val);
+ $arr_test[] = $key;
+ $i++;
+ }
+ $this->assertTrue(isset($arr_test['0']));
+ $this->assertTrue(isset($arr_test['1']));
+ $this->assertTrue(isset($arr_test['2']));
+ $this->assertSame(3, $i);
+ }
+
+ #########################################################
+ # Test message field.
+ #########################################################
+
+ public function testMessage() {
+ $arr = new MapField(GPBType::INT32,
+ GPBType::MESSAGE, Sub::class);
+
+ // Test append.
+ $sub_m = new Sub();
+ $sub_m->setA(1);
+ $arr[0] = $sub_m;
+ $this->assertSame(1, $arr[0]->getA());
+
+ $this->assertEquals(1, count($arr));
+
+ // Test foreach.
+ $arr = new MapField(GPBType::INT32,
+ GPBType::MESSAGE, Sub::class);
+ for ($i = 0; $i < 3; $i++) {
+ $arr[$i] = new Sub();;
+ $arr[$i]->setA($i);
+ }
+ $i = 0;
+ $key_test = [];
+ $value_test = [];
+ foreach ($arr as $key => $val) {
+ $key_test[] = $key;
+ $value_test[] = $val->getA();
+ $i++;
+ }
+ $this->assertTrue(isset($key_test['0']));
+ $this->assertTrue(isset($key_test['1']));
+ $this->assertTrue(isset($key_test['2']));
+ $this->assertTrue(isset($value_test['0']));
+ $this->assertTrue(isset($value_test['1']));
+ $this->assertTrue(isset($value_test['2']));
+ $this->assertSame(3, $i);
+ }
+
+ #########################################################
+ # Test reference in map
+ #########################################################
+
+ public function testMapElementIsReference()
+ {
+ // Bool elements
+ $values = [true => true];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setMapBoolBool($values);
+
+ // Int32 elements
+ $values = [1 => 1];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setMapInt32Int32($values);
+
+ // Double elements
+ $values = [1 => 1.0];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setMapInt32Double($values);
+
+ // String elements
+ $values = ['a' => 'a'];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setMapStringString($values);
+
+ // Message elements
+ $values = [1 => new Sub()];
+ array_walk($values, function (&$value) {});
+ $m = new TestMessage();
+ $m->setMapInt32Message($values);
+ }
+
+ #########################################################
+ # Test memory leak
+ #########################################################
+
+ // TODO(teboring): Add it back.
+ // public function testCycleLeak()
+ // {
+ // $arr = new MapField(GPBType::INT32,
+ // GPBType::MESSAGE, TestMessage::class);
+ // $arr[0] = new TestMessage;
+ // $arr[0]->SetMapRecursive($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);
+ // }
+}
diff --git a/third_party/protobuf/php/tests/memory_leak_test.php b/third_party/protobuf/php/tests/memory_leak_test.php
new file mode 100644
index 0000000..142f467
--- /dev/null
+++ b/third_party/protobuf/php/tests/memory_leak_test.php
@@ -0,0 +1,208 @@
+<?php
+
+# phpunit has memory leak by itself. Thus, it cannot be used to test memory leak.
+
+require_once('generated/NoNamespaceEnum.php');
+require_once('generated/NoNamespaceMessage.php');
+require_once('generated/NoNamespaceMessage/NestedEnum.php');
+require_once('generated/NoNamespaceMessage/NestedMessage.php');
+require_once('generated/PrefixEmpty.php');
+require_once('generated/PrefixTestPrefix.php');
+require_once('generated/PrefixTestPrefix/PrefixNestedEnum.php');
+require_once('generated/PrefixTestPrefix/PrefixNestedMessage.php');
+require_once('generated/TestEmptyNamespace.php');
+require_once('generated/TestEmptyNamespace/NestedEnum.php');
+require_once('generated/TestEmptyNamespace/NestedMessage.php');
+require_once('generated/Bar/TestInclude.php');
+require_once('generated/Bar/TestLegacyMessage.php');
+require_once('generated/Bar/TestLegacyMessage/NestedEnum.php');
+require_once('generated/Bar/TestLegacyMessage/NestedMessage.php');
+require_once('generated/Foo/PBARRAY.php');
+require_once('generated/Foo/PBEmpty.php');
+require_once('generated/Foo/TestAny.php');
+require_once('generated/Foo/TestEnum.php');
+require_once('generated/Foo/TestIncludeNamespaceMessage.php');
+require_once('generated/Foo/TestIncludePrefixMessage.php');
+require_once('generated/Foo/TestMessage.php');
+require_once('generated/Foo/TestMessage/PBEmpty.php');
+require_once('generated/Foo/TestMessage/NestedEnum.php');
+require_once('generated/Foo/TestMessage/Sub.php');
+require_once('generated/Foo/TestPackedMessage.php');
+require_once('generated/Foo/TestPhpDoc.php');
+require_once('generated/Foo/TestRandomFieldOrder.php');
+require_once('generated/Foo/TestReverseFieldOrder.php');
+require_once('generated/Foo/TestUnpackedMessage.php');
+require_once('generated/Foo/testLowerCaseMessage.php');
+require_once('generated/Foo/testLowerCaseEnum.php');
+require_once('generated/GPBMetadata/Proto/Test.php');
+require_once('generated/TestEmptyPhpNamespace.php');
+require_once('generated/GPBMetadata/Proto/TestInclude.php');
+require_once('generated/TestNoNamespace.php');
+require_once('generated/Metadata/Php/Test/TestPhpNamespace.php');
+require_once('generated/GPBMetadata/Proto/TestPrefix.php');
+require_once('generated/Php/Test/TestNamespace.php');
+require_once('generated/Php/Test/TestNamespace/PBEmpty.php');
+require_once('generated/Php/Test/TestNamespace/PBEmpty/NestedEnum.php');
+require_once('generated/Php/Test/TestNamespace/PBEmpty/NestedMessage.php');
+require_once('generated/Php/Test/TestNamespace/NestedEnum.php');
+require_once('generated/Php/Test/TestNamespace/NestedMessage.php');
+require_once('test_util.php');
+
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBType;
+use Foo\TestAny;
+use Foo\TestMessage;
+use Foo\TestMessage\Sub;
+
+$from = new TestMessage();
+TestUtil::setTestMessage($from);
+TestUtil::assertTestMessage($from);
+
+$data = $from->serializeToString();
+
+$to = new TestMessage();
+$to->mergeFromString($data);
+
+TestUtil::assertTestMessage($to);
+
+$from = new TestMessage();
+TestUtil::setTestMessage2($from);
+
+$data = $from->serializeToString();
+
+$to->mergeFromString($data);
+
+// TODO(teboring): This causes following tests fail in php7.
+# $from->setRecursive($from);
+
+$arr = new RepeatedField(GPBType::MESSAGE, TestMessage::class);
+$arr[] = new TestMessage;
+$arr[0]->SetRepeatedRecursive($arr);
+
+// Test oneof fields.
+$m = new TestMessage();
+
+$m->setOneofInt32(1);
+assert(1 === $m->getOneofInt32());
+assert(0.0 === $m->getOneofFloat());
+assert('' === $m->getOneofString());
+assert(NULL === $m->getOneofMessage());
+$data = $m->serializeToString();
+$n = new TestMessage();
+$n->mergeFromString($data);
+assert(1 === $n->getOneofInt32());
+
+$m->setOneofFloat(2.0);
+assert(0 === $m->getOneofInt32());
+assert(2.0 === $m->getOneofFloat());
+assert('' === $m->getOneofString());
+assert(NULL === $m->getOneofMessage());
+$data = $m->serializeToString();
+$n = new TestMessage();
+$n->mergeFromString($data);
+assert(2.0 === $n->getOneofFloat());
+
+$m->setOneofString('abc');
+assert(0 === $m->getOneofInt32());
+assert(0.0 === $m->getOneofFloat());
+assert('abc' === $m->getOneofString());
+assert(NULL === $m->getOneofMessage());
+$data = $m->serializeToString();
+$n = new TestMessage();
+$n->mergeFromString($data);
+assert('abc' === $n->getOneofString());
+
+$sub_m = new Sub();
+$sub_m->setA(1);
+$m->setOneofMessage($sub_m);
+assert(0 === $m->getOneofInt32());
+assert(0.0 === $m->getOneofFloat());
+assert('' === $m->getOneofString());
+assert(1 === $m->getOneofMessage()->getA());
+$data = $m->serializeToString();
+$n = new TestMessage();
+$n->mergeFromString($data);
+assert(1 === $n->getOneofMessage()->getA());
+
+$m = new TestMessage();
+$m->mergeFromString(hex2bin('F80601'));
+assert('f80601' === bin2hex($m->serializeToString()));
+
+// Test create repeated field via array.
+$str_arr = array("abc");
+$m = new TestMessage();
+$m->setRepeatedString($str_arr);
+
+// Test create map field via array.
+$str_arr = array("abc"=>"abc");
+$m = new TestMessage();
+$m->setMapStringString($str_arr);
+
+// Test unset
+$from = new TestMessage();
+TestUtil::setTestMessage($from);
+unset($from);
+
+// Test wellknown
+$from = new \Google\Protobuf\Timestamp();
+$from->setSeconds(1);
+assert(1, $from->getSeconds());
+
+$timestamp = new \Google\Protobuf\Timestamp();
+
+date_default_timezone_set('UTC');
+$from = new DateTime('2011-01-01T15:03:01.012345UTC');
+$timestamp->fromDateTime($from);
+assert($from->format('U') == $timestamp->getSeconds());
+assert(1000 * $from->format('u') == $timestamp->getNanos());
+
+$to = $timestamp->toDateTime();
+assert(\DateTime::class == get_class($to));
+assert($from->format('U') == $to->format('U'));
+
+$from = new \Google\Protobuf\Value();
+$from->setNumberValue(1);
+assert(1, $from->getNumberValue());
+
+// Test discard unknown in message.
+$m = new TestMessage();
+$from = hex2bin('F80601');
+$m->mergeFromString($from);
+$m->discardUnknownFields();
+$to = $m->serializeToString();
+assert("" === bin2hex($to));
+
+// Test clear
+$m = new TestMessage();
+TestUtil::setTestMessage($m);
+$m->clear();
+
+// Test unset map element
+$m = new TestMessage();
+$map = $m->getMapStringString();
+$map[1] = 1;
+unset($map[1]);
+
+// Test descriptor
+$pool = \Google\Protobuf\DescriptorPool::getGeneratedPool();
+$desc = $pool->getDescriptorByClassName("\Foo\TestMessage");
+$field = $desc->getField(1);
+
+$from = new TestMessage();
+$to = new TestMessage();
+TestUtil::setTestMessage($from);
+$to->mergeFrom($from);
+TestUtil::assertTestMessage($to);
+
+// Test decode Any
+// Make sure packed message has been created at least once.
+$packed = new TestMessage();
+
+$m = new TestAny();
+$m->mergeFromJsonString(
+ "{\"any\":" .
+ " {\"@type\":\"type.googleapis.com/foo.TestMessage\"," .
+ " \"optionalInt32\":1}}");
+assert("type.googleapis.com/foo.TestMessage" ===
+ $m->getAny()->getTypeUrl());
+assert("0801" === bin2hex($m->getAny()->getValue()));
diff --git a/third_party/protobuf/php/tests/php_implementation_test.php b/third_party/protobuf/php/tests/php_implementation_test.php
new file mode 100644
index 0000000..307b749
--- /dev/null
+++ b/third_party/protobuf/php/tests/php_implementation_test.php
@@ -0,0 +1,598 @@
+<?php
+
+require_once('test_base.php');
+require_once('test_util.php');
+
+use Foo\TestEnum;
+use Foo\TestMessage;
+use Foo\TestMessage\Sub;
+use Foo\TestPackedMessage;
+use Google\Protobuf\Internal\CodedInputStream;
+use Google\Protobuf\Internal\FileDescriptorSet;
+use Google\Protobuf\Internal\GPBLabel;
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\GPBWire;
+use Google\Protobuf\Internal\CodedOutputStream;
+
+/**
+ * Please note, this test is only intended to be run without the protobuf C
+ * extension.
+ */
+class ImplementationTest extends TestBase
+{
+ public function setUp()
+ {
+ if (extension_loaded('protobuf')) {
+ $this->markTestSkipped();
+ }
+ }
+
+ public function testReadInt32()
+ {
+ $value = null;
+
+ // Positive number.
+ $input = new CodedInputStream(hex2bin("01"));
+ GPBWire::readInt32($input, $value);
+ $this->assertSame(1, $value);
+
+ // Negative number.
+ $input = new CodedInputStream(hex2bin("ffffffff0f"));
+ GPBWire::readInt32($input, $value);
+ $this->assertSame(-1, $value);
+
+ // Discard overflow bits.
+ $input = new CodedInputStream(hex2bin("ffffffff7f"));
+ GPBWire::readInt32($input, $value);
+ $this->assertSame(-1, $value);
+ }
+
+ public function testReadUint32()
+ {
+ $value = null;
+
+ // Positive number.
+ $input = new CodedInputStream(hex2bin("01"));
+ GPBWire::readUint32($input, $value);
+ $this->assertSame(1, $value);
+
+ // Max uint32.
+ $input = new CodedInputStream(hex2bin("ffffffff0f"));
+ GPBWire::readUint32($input, $value);
+ $this->assertSame(-1, $value);
+
+ // Discard overflow bits.
+ $input = new CodedInputStream(hex2bin("ffffffff7f"));
+ GPBWire::readUint32($input, $value);
+ $this->assertSame(-1, $value);
+ }
+
+ public function testReadInt64()
+ {
+ $value = null;
+
+ // Positive number.
+ $input = new CodedInputStream(hex2bin("01"));
+ GPBWire::readInt64($input, $value);
+ $this->assertEquals(1, $value);
+
+ // Negative number.
+ $input = new CodedInputStream(hex2bin("ffffffffffffffffff01"));
+ GPBWire::readInt64($input, $value);
+ $this->assertEquals(-1, $value);
+
+ // Discard overflow bits.
+ $input = new CodedInputStream(hex2bin("ffffffffffffffffff0f"));
+ GPBWire::readInt64($input, $value);
+ $this->assertEquals(-1, $value);
+ }
+
+ public function testReadUint64()
+ {
+ $value = null;
+
+ // Positive number.
+ $input = new CodedInputStream(hex2bin("01"));
+ GPBWire::readUint64($input, $value);
+ $this->assertEquals(1, $value);
+
+ // Negative number.
+ $input = new CodedInputStream(hex2bin("FFFFFFFFFFFFFFFFFF01"));
+ GPBWire::readUint64($input, $value);
+ $this->assertEquals(-1, $value);
+
+ // Discard overflow bits.
+ $input = new CodedInputStream(hex2bin("FFFFFFFFFFFFFFFFFF0F"));
+ GPBWire::readUint64($input, $value);
+ $this->assertEquals(-1, $value);
+ }
+
+ public function testReadSint32()
+ {
+ $value = null;
+
+ $input = new CodedInputStream(hex2bin("00"));
+ GPBWire::readSint32($input, $value);
+ $this->assertSame(0, $value);
+
+ $input = new CodedInputStream(hex2bin("01"));
+ GPBWire::readSint32($input, $value);
+ $this->assertSame(-1, $value);
+
+ $input = new CodedInputStream(hex2bin("02"));
+ GPBWire::readSint32($input, $value);
+ $this->assertSame(1, $value);
+ }
+
+ public function testReadSint64()
+ {
+ $value = null;
+
+ $input = new CodedInputStream(hex2bin("00"));
+ GPBWire::readSint64($input, $value);
+ $this->assertEquals(0, $value);
+
+ $input = new CodedInputStream(hex2bin("01"));
+ GPBWire::readSint64($input, $value);
+ $this->assertEquals(-1, $value);
+
+ $input = new CodedInputStream(hex2bin("02"));
+ GPBWire::readSint64($input, $value);
+ $this->assertEquals(1, $value);
+ }
+
+ public function testReadFixed32()
+ {
+ $value = null;
+ $input = new CodedInputStream(hex2bin("12345678"));
+ GPBWire::readFixed32($input, $value);
+ $this->assertSame(0x78563412, $value);
+ }
+
+ public function testReadFixed64()
+ {
+ $value = null;
+ $input = new CodedInputStream(hex2bin("1234567812345678"));
+ GPBWire::readFixed64($input, $value);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame("8671175386481439762", $value);
+ } else {
+ $this->assertSame(0x7856341278563412, $value);
+ }
+ }
+
+ public function testReadSfixed32()
+ {
+ $value = null;
+ $input = new CodedInputStream(hex2bin("12345678"));
+ GPBWire::readSfixed32($input, $value);
+ $this->assertSame(0x78563412, $value);
+ }
+
+ public function testReadFloat()
+ {
+ $value = null;
+ $input = new CodedInputStream(hex2bin("0000803F"));
+ GPBWire::readFloat($input, $value);
+ $this->assertSame(1.0, $value);
+ }
+
+ public function testReadBool()
+ {
+ $value = null;
+
+ $input = new CodedInputStream(hex2bin("00"));
+ GPBWire::readBool($input, $value);
+ $this->assertSame(false, $value);
+
+ $input = new CodedInputStream(hex2bin("01"));
+ GPBWire::readBool($input, $value);
+ $this->assertSame(true, $value);
+ }
+
+ public function testReadDouble()
+ {
+ $value = null;
+ $input = new CodedInputStream(hex2bin("000000000000F03F"));
+ GPBWire::readDouble($input, $value);
+ $this->assertSame(1.0, $value);
+ }
+
+ public function testReadSfixed64()
+ {
+ $value = null;
+ $input = new CodedInputStream(hex2bin("1234567812345678"));
+ GPBWire::readSfixed64($input, $value);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame("8671175386481439762", $value);
+ } else {
+ $this->assertSame(0x7856341278563412, $value);
+ }
+ }
+
+ public function testZigZagEncodeDecode()
+ {
+ $this->assertSame(0, GPBWire::zigZagEncode32(0));
+ $this->assertSame(1, GPBWire::zigZagEncode32(-1));
+ $this->assertSame(2, GPBWire::zigZagEncode32(1));
+ $this->assertSame(3, GPBWire::zigZagEncode32(-2));
+ $this->assertSame(0x7FFFFFFE, GPBWire::zigZagEncode32(0x3FFFFFFF));
+ $this->assertSame(0x7FFFFFFF, GPBWire::zigZagEncode32(0xC0000000));
+ $this->assertSame(0x7FFFFFFF, GPBWire::zigZagEncode32(-1073741824));
+
+ $this->assertSame(0, GPBWire::zigZagDecode32(0));
+ $this->assertSame(-1, GPBWire::zigZagDecode32(1));
+ $this->assertSame(1, GPBWire::zigZagDecode32(2));
+ $this->assertSame(-2, GPBWire::zigZagDecode32(3));
+ $this->assertSame(0x3FFFFFFF, GPBWire::zigZagDecode32(0x7FFFFFFE));
+ $this->assertSame(-1073741824, GPBWire::zigZagDecode32(0x7FFFFFFF));
+ $this->assertSame(0x7FFFFFFF, GPBWire::zigZagDecode32(0xFFFFFFFE));
+ $this->assertSame((int)-2147483648,GPBWire::zigZagDecode32(0xFFFFFFFF));
+
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(-2, GPBWire::zigZagEncode32(0x7FFFFFFF));
+ $this->assertSame(-1, GPBWire::zigZagEncode32(0x80000000));
+ $this->assertSame('0', GPBWire::zigZagEncode64(0));
+ $this->assertSame('1', GPBWire::zigZagEncode64(-1));
+ $this->assertSame('2', GPBWire::zigZagEncode64(1));
+ $this->assertSame('3', GPBWire::zigZagEncode64(-2));
+ $this->assertSame(
+ '2147483646', // 0x7FFFFFE
+ GPBWire::zigZagEncode64(0x3FFFFFFF));
+ $this->assertSame(
+ '2147483647', // 0x7FFFFFF
+ GPBWire::zigZagEncode64(-1073741824)); // 0xFFFFFFFFC0000000
+ $this->assertSame(
+ '4294967294', // 0xFFFFFFFE
+ GPBWire::zigZagEncode64(2147483647)); // 0x7FFFFFFF
+ $this->assertSame(
+ '4294967295', // 0xFFFFFFFF
+ GPBWire::zigZagEncode64(-2147483648)); // 0xFFFFFFFF80000000
+ $this->assertSame(
+ '18446744073709551614', // 0xFFFFFFFFFFFFFFFE
+ // 0x7FFFFFFFFFFFFFFF
+ GPBWire::zigZagEncode64("9223372036854775807"));
+ $this->assertSame(
+ '18446744073709551615', // 0xFFFFFFFFFFFFFFFF
+ // 0x8000000000000000
+ GPBWire::zigZagEncode64("-9223372036854775808"));
+
+ $this->assertSame('0', GPBWire::zigZagDecode64(0));
+ $this->assertSame('-1', GPBWire::zigZagDecode64(1));
+ $this->assertSame('1', GPBWire::zigZagDecode64(2));
+ $this->assertSame('-2', GPBWire::zigZagDecode64(3));
+ } else {
+ $this->assertSame(4294967294, GPBWire::zigZagEncode32(0x7FFFFFFF));
+ $this->assertSame(4294967295, GPBWire::zigZagEncode32(0x80000000));
+ $this->assertSame(0, GPBWire::zigZagEncode64(0));
+ $this->assertSame(1, GPBWire::zigZagEncode64(-1));
+ $this->assertSame(2, GPBWire::zigZagEncode64(1));
+ $this->assertSame(3, GPBWire::zigZagEncode64(-2));
+ $this->assertSame(0x7FFFFFFE, GPBWire::zigZagEncode64(0x3FFFFFFF));
+ $this->assertSame(
+ 0x7FFFFFFF,
+ GPBWire::zigZagEncode64(0xFFFFFFFFC0000000));
+ $this->assertSame(
+ 0xFFFFFFFE,
+ GPBWire::zigZagEncode64(0x7FFFFFFF));
+ $this->assertSame(
+ 0xFFFFFFFF,
+ GPBWire::zigZagEncode64(0xFFFFFFFF80000000));
+ $this->assertSame(
+ -2, // 0xFFFFFFFFFFFFFFFE
+ GPBWire::zigZagEncode64(0x7FFFFFFFFFFFFFFF));
+ $this->assertSame(
+ -1, // 0xFFFFFFFFFFFFFFFF
+ GPBWire::zigZagEncode64(0x8000000000000000));
+
+ $this->assertSame(0, GPBWire::zigZagDecode64(0));
+ $this->assertSame(-1, GPBWire::zigZagDecode64(1));
+ $this->assertSame(1, GPBWire::zigZagDecode64(2));
+ $this->assertSame(-2, GPBWire::zigZagDecode64(3));
+ }
+
+ // Round trip
+ $this->assertSame(0, GPBWire::zigZagDecode32(GPBWire::zigZagEncode32(0)));
+ $this->assertSame(1, GPBWire::zigZagDecode32(GPBWire::zigZagEncode32(1)));
+ $this->assertSame(-1, GPBWire::zigZagDecode32(GPBWire::zigZagEncode32(-1)));
+ $this->assertSame(14927,
+ GPBWire::zigZagDecode32(GPBWire::zigZagEncode32(14927)));
+ $this->assertSame(-3612,
+ GPBWire::zigZagDecode32(GPBWire::zigZagEncode32(-3612)));
+ }
+
+ public function testDecode()
+ {
+ $m = new TestMessage();
+ $m->mergeFromString(TestUtil::getGoldenTestMessage());
+ TestUtil::assertTestMessage($m);
+ }
+
+ public function testDescriptorDecode()
+ {
+ $file_desc_set = new FileDescriptorSet();
+ $file_desc_set->mergeFromString(hex2bin(
+ "0a3b0a12746573745f696e636c7564652e70726f746f120362617222180a" .
+ "0b54657374496e636c75646512090a0161180120012805620670726f746f33"));
+
+ $this->assertSame(1, sizeof($file_desc_set->getFile()));
+
+ $file_desc = $file_desc_set->getFile()[0];
+ $this->assertSame("test_include.proto", $file_desc->getName());
+ $this->assertSame("bar", $file_desc->getPackage());
+ $this->assertSame(0, sizeof($file_desc->getDependency()));
+ $this->assertSame(1, sizeof($file_desc->getMessageType()));
+ $this->assertSame(0, sizeof($file_desc->getEnumType()));
+ $this->assertSame("proto3", $file_desc->getSyntax());
+
+ $desc = $file_desc->getMessageType()[0];
+ $this->assertSame("TestInclude", $desc->getName());
+ $this->assertSame(1, sizeof($desc->getField()));
+ $this->assertSame(0, sizeof($desc->getNestedType()));
+ $this->assertSame(0, sizeof($desc->getEnumType()));
+ $this->assertSame(0, sizeof($desc->getOneofDecl()));
+
+ $field = $desc->getField()[0];
+ $this->assertSame("a", $field->getName());
+ $this->assertSame(1, $field->getNumber());
+ $this->assertSame(GPBLabel::OPTIONAL, $field->getLabel());
+ $this->assertSame(GPBType::INT32, $field->getType());
+ }
+
+ public function testReadVarint64()
+ {
+ $var = 0;
+
+ // Empty buffer.
+ $input = new CodedInputStream(hex2bin(''));
+ $this->assertFalse($input->readVarint64($var));
+
+ // The largest varint is 10 bytes long.
+ $input = new CodedInputStream(hex2bin('8080808080808080808001'));
+ $this->assertFalse($input->readVarint64($var));
+
+ // Corrupted varint.
+ $input = new CodedInputStream(hex2bin('808080'));
+ $this->assertFalse($input->readVarint64($var));
+
+ // Normal case.
+ $input = new CodedInputStream(hex2bin('808001'));
+ $this->assertTrue($input->readVarint64($var));
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('16384', $var);
+ } else {
+ $this->assertSame(16384, $var);
+ }
+ $this->assertFalse($input->readVarint64($var));
+
+ // Read two varint.
+ $input = new CodedInputStream(hex2bin('808001808002'));
+ $this->assertTrue($input->readVarint64($var));
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('16384', $var);
+ } else {
+ $this->assertSame(16384, $var);
+ }
+ $this->assertTrue($input->readVarint64($var));
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('32768', $var);
+ } else {
+ $this->assertSame(32768, $var);
+ }
+ $this->assertFalse($input->readVarint64($var));
+
+ // Read 64 testing
+ $testVals = array(
+ '10' => '0a000000000000000000',
+ '100' => '64000000000000000000',
+ '800' => 'a0060000000000000000',
+ '6400' => '80320000000000000000',
+ '70400' => '80a60400000000000000',
+ '774400' => '80a22f00000000000000',
+ '9292800' => '8098b704000000000000',
+ '74342400' => '80c0b923000000000000',
+ '743424000' => '8080bfe2020000000000',
+ '8177664000' => '8080b5bb1e0000000000',
+ '65421312000' => '8080a8dbf30100000000',
+ '785055744000' => '8080e0c7ec1600000000',
+ '9420668928000' => '808080dd969202000000',
+ '103627358208000' => '808080fff9c717000000',
+ '1139900940288000' => '808080f5bd9783020000',
+ '13678811283456000' => '808080fce699a6180000',
+ '109430490267648000' => '808080e0b7ceb1c20100',
+ '984874412408832000' => '808080e0f5c1bed50d00',
+ );
+
+ foreach ($testVals as $original => $encoded) {
+ $input = new CodedInputStream(hex2bin($encoded));
+ $this->assertTrue($input->readVarint64($var));
+ $this->assertEquals($original, $var);
+ }
+ }
+
+ public function testReadVarint32()
+ {
+ $var = 0;
+
+ // Empty buffer.
+ $input = new CodedInputStream(hex2bin(''));
+ $this->assertFalse($input->readVarint32($var));
+
+ // The largest varint is 10 bytes long.
+ $input = new CodedInputStream(hex2bin('8080808080808080808001'));
+ $this->assertFalse($input->readVarint32($var));
+
+ // Corrupted varint.
+ $input = new CodedInputStream(hex2bin('808080'));
+ $this->assertFalse($input->readVarint32($var));
+
+ // Normal case.
+ $input = new CodedInputStream(hex2bin('808001'));
+ $this->assertTrue($input->readVarint32($var));
+ $this->assertSame(16384, $var);
+ $this->assertFalse($input->readVarint32($var));
+
+ // Read two varint.
+ $input = new CodedInputStream(hex2bin('808001808002'));
+ $this->assertTrue($input->readVarint32($var));
+ $this->assertSame(16384, $var);
+ $this->assertTrue($input->readVarint32($var));
+ $this->assertSame(32768, $var);
+ $this->assertFalse($input->readVarint32($var));
+
+ // Read a 64-bit integer. High-order bits should be discarded.
+ $input = new CodedInputStream(hex2bin('808081808001'));
+ $this->assertTrue($input->readVarint32($var));
+ $this->assertSame(16384, $var);
+ $this->assertFalse($input->readVarint32($var));
+ }
+
+ public function testReadTag()
+ {
+ $input = new CodedInputStream(hex2bin('808001'));
+ $tag = $input->readTag();
+ $this->assertSame(16384, $tag);
+ $tag = $input->readTag();
+ $this->assertSame(0, $tag);
+ }
+
+ public function testPushPopLimit()
+ {
+ $input = new CodedInputStream(hex2bin('808001'));
+ $old_limit = $input->pushLimit(0);
+ $tag = $input->readTag();
+ $this->assertSame(0, $tag);
+ $input->popLimit($old_limit);
+ $tag = $input->readTag();
+ $this->assertSame(16384, $tag);
+ }
+
+ public function testReadRaw()
+ {
+ $input = new CodedInputStream(hex2bin('808001'));
+ $buffer = null;
+
+ $this->assertTrue($input->readRaw(3, $buffer));
+ $this->assertSame(hex2bin('808001'), $buffer);
+
+ $this->assertFalse($input->readRaw(1, $buffer));
+ }
+
+ public function testWriteVarint32()
+ {
+ $output = new CodedOutputStream(3);
+ $output->writeVarint32(16384, true);
+ $this->assertSame(hex2bin('808001'), $output->getData());
+
+ // Negative numbers are padded to be compatible with int64.
+ $output = new CodedOutputStream(10);
+ $output->writeVarint32(-43, false);
+ $this->assertSame(hex2bin('D5FFFFFFFFFFFFFFFF01'), $output->getData());
+ }
+
+ public function testWriteVarint64()
+ {
+ $output = new CodedOutputStream(10);
+ $output->writeVarint64(-43);
+ $this->assertSame(hex2bin('D5FFFFFFFFFFFFFFFF01'), $output->getData());
+ }
+
+ public function testWriteLittleEndian32()
+ {
+ $output = new CodedOutputStream(4);
+ $output->writeLittleEndian32(46);
+ $this->assertSame(hex2bin('2E000000'), $output->getData());
+ }
+
+ public function testWriteLittleEndian64()
+ {
+ $output = new CodedOutputStream(8);
+ $output->writeLittleEndian64(47);
+ $this->assertSame(hex2bin('2F00000000000000'), $output->getData());
+ }
+
+ public function testByteSize()
+ {
+ $m = new TestMessage();
+ TestUtil::setTestMessage($m);
+ $this->assertSame(518, $m->byteSize());
+ }
+
+ public function testPackedByteSize()
+ {
+ $m = new TestPackedMessage();
+ TestUtil::setTestPackedMessage($m);
+ $this->assertSame(166, $m->byteSize());
+ }
+
+ /**
+ * @expectedException UnexpectedValueException
+ * @expectedExceptionMessage Invalid message property: optionalInt32
+ */
+ public function testArrayConstructorJsonCaseThrowsException()
+ {
+ $m = new TestMessage([
+ 'optionalInt32' => -42,
+ ]);
+ }
+
+ /**
+ * @expectedException Exception
+ * @expectedExceptionMessage Expect Foo\TestMessage_Sub.
+ */
+ public function testArraysForMessagesThrowsException()
+ {
+ $m = new TestMessage([
+ 'optional_message' => [
+ 'a' => 33
+ ]
+ ]);
+ }
+
+ public function testArrayConstructorWithNullValues()
+ {
+ $requestData = [
+ 'optional_bool' => null,
+ 'optional_string' => null,
+ 'optional_bytes' => null,
+ 'optional_message' => null,
+ ];
+
+ $m = new TestMessage($requestData);
+
+ $this->assertSame(false, $m->getOptionalBool());
+ $this->assertSame('', $m->getOptionalString());
+ $this->assertSame('', $m->getOptionalBytes());
+ $this->assertSame(null, $m->getOptionalMessage());
+ }
+
+ /**
+ * @dataProvider provideArrayConstructorWithNullValuesThrowsException
+ * @expectedException Exception
+ */
+ public function testArrayConstructorWithNullValuesThrowsException($requestData)
+ {
+ $m = new TestMessage($requestData);
+ }
+
+ public function provideArrayConstructorWithNullValuesThrowsException()
+ {
+ return [
+ [['optional_int32' => null]],
+ [['optional_int64' => null]],
+ [['optional_uint32' => null]],
+ [['optional_uint64' => null]],
+ [['optional_sint32' => null]],
+ [['optional_sint64' => null]],
+ [['optional_fixed32' => null]],
+ [['optional_fixed64' => null]],
+ [['optional_sfixed32' => null]],
+ [['optional_sfixed64' => null]],
+ [['optional_float' => null]],
+ [['optional_double' => null]],
+ [['optional_enum' => null]],
+ [['repeated_int32' => null]],
+ [['map_int32_int32' => null]],
+ ];
+ }
+}
diff --git a/third_party/protobuf/php/tests/proto/empty/echo.proto b/third_party/protobuf/php/tests/proto/empty/echo.proto
new file mode 100644
index 0000000..1817018
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/empty/echo.proto
@@ -0,0 +1,17 @@
+syntax = "proto3";
+
+package empty.echo;
+
+message TestEmptyPackage {
+ int32 a = 1;
+
+ // Test nested messages, enums, and reserved names
+ NestedMessage nested_message = 2;
+ NestedEnum nested_enum = 3;
+ message NestedMessage {
+ int32 a = 1;
+ }
+ enum NestedEnum {
+ ZERO = 0;
+ };
+}
diff --git a/third_party/protobuf/php/tests/proto/test.proto b/third_party/protobuf/php/tests/proto/test.proto
new file mode 100644
index 0000000..715f08b
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test.proto
@@ -0,0 +1,209 @@
+syntax = "proto3";
+
+import 'google/protobuf/any.proto';
+import 'google/protobuf/struct.proto';
+import 'proto/test_include.proto';
+import 'proto/test_no_namespace.proto';
+import 'proto/test_php_namespace.proto';
+import 'proto/test_empty_php_namespace.proto';
+import 'proto/test_prefix.proto';
+
+package foo;
+
+message TestMessage {
+ // Singular
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ sint32 optional_sint32 = 5;
+ sint64 optional_sint64 = 6;
+ fixed32 optional_fixed32 = 7;
+ fixed64 optional_fixed64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ sfixed64 optional_sfixed64 = 10;
+ float optional_float = 11;
+ double optional_double = 12;
+ bool optional_bool = 13;
+ string optional_string = 14;
+ bytes optional_bytes = 15;
+
+ TestEnum optional_enum = 16;
+ Sub optional_message = 17;
+ bar.TestInclude optional_included_message = 18;
+ TestMessage recursive = 19;
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated TestEnum repeated_enum = 46;
+ repeated Sub repeated_message = 47;
+ repeated TestMessage repeated_recursive = 48;
+
+ oneof my_oneof {
+ int32 oneof_int32 = 51;
+ int64 oneof_int64 = 52;
+ uint32 oneof_uint32 = 53;
+ uint64 oneof_uint64 = 54;
+ uint32 oneof_sint32 = 55;
+ uint64 oneof_sint64 = 56;
+ uint32 oneof_fixed32 = 57;
+ uint64 oneof_fixed64 = 58;
+ uint32 oneof_sfixed32 = 59;
+ uint64 oneof_sfixed64 = 60;
+ double oneof_double = 61;
+ float oneof_float = 62;
+ bool oneof_bool = 63;
+ string oneof_string = 64;
+ bytes oneof_bytes = 65;
+ TestEnum oneof_enum = 66;
+ Sub oneof_message = 67;
+ }
+
+ map<int32, int32> map_int32_int32 = 71;
+ map<int64, int64> map_int64_int64 = 72;
+ map<uint32, uint32> map_uint32_uint32 = 73;
+ map<uint64, uint64> map_uint64_uint64 = 74;
+ map<sint32, sint32> map_sint32_sint32 = 75;
+ map<sint64, sint64> map_sint64_sint64 = 76;
+ map<fixed32, fixed32> map_fixed32_fixed32 = 77;
+ map<fixed64, fixed64> map_fixed64_fixed64 = 78;
+ map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 79;
+ map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 80;
+ map<int32, float> map_int32_float = 81;
+ map<int32, double> map_int32_double = 82;
+ map<bool, bool> map_bool_bool = 83;
+ map<string, string> map_string_string = 84;
+ map<int32, bytes> map_int32_bytes = 85;
+ map<int32, TestEnum> map_int32_enum = 86;
+ map<int32, Sub> map_int32_message = 87;
+
+ map<int32, TestMessage> map_recursive = 88;
+
+ message Sub {
+ int32 a = 1;
+ repeated int32 b = 2;
+ }
+
+ // Reserved for non-existing field test.
+ // int32 non_exist = 89;
+
+ NoNamespaceMessage optional_no_namespace_message = 91;
+ NoNamespaceEnum optional_no_namespace_enum = 92;
+ repeated NoNamespaceMessage repeated_no_namespace_message = 93;
+ repeated NoNamespaceEnum repeated_no_namespace_enum = 94;
+
+ enum NestedEnum {
+ ZERO = 0;
+ }
+
+ NestedEnum optional_nested_enum = 101;
+
+ // Test prefix for reserved words.
+ message Empty {
+ int32 a = 1;
+ }
+
+ reserved 111;
+}
+
+enum TestEnum {
+ ZERO = 0;
+ ONE = 1;
+ TWO = 2;
+ ECHO = 3; // Test reserved name.
+}
+
+// Test prefix for reserved words.
+message Empty {
+ int32 a = 1;
+}
+
+message ARRAY {
+ int32 a = 1;
+}
+
+message TestPackedMessage {
+ repeated int32 repeated_int32 = 90 [packed = true];
+ repeated int64 repeated_int64 = 91 [packed = true];
+ repeated uint32 repeated_uint32 = 92 [packed = true];
+ repeated uint64 repeated_uint64 = 93 [packed = true];
+ repeated sint32 repeated_sint32 = 94 [packed = true];
+ repeated sint64 repeated_sint64 = 95 [packed = true];
+ repeated fixed32 repeated_fixed32 = 96 [packed = true];
+ repeated fixed64 repeated_fixed64 = 97 [packed = true];
+ repeated sfixed32 repeated_sfixed32 = 98 [packed = true];
+ repeated sfixed64 repeated_sfixed64 = 99 [packed = true];
+ repeated float repeated_float = 100 [packed = true];
+ repeated double repeated_double = 101 [packed = true];
+ repeated bool repeated_bool = 102 [packed = true];
+ repeated TestEnum repeated_enum = 103 [packed = true];
+}
+
+// Need to be in sync with TestPackedMessage.
+message TestUnpackedMessage {
+ repeated int32 repeated_int32 = 90 [packed = false];
+ repeated int64 repeated_int64 = 91 [packed = false];
+ repeated uint32 repeated_uint32 = 92 [packed = false];
+ repeated uint64 repeated_uint64 = 93 [packed = false];
+ repeated sint32 repeated_sint32 = 94 [packed = false];
+ repeated sint64 repeated_sint64 = 95 [packed = false];
+ repeated fixed32 repeated_fixed32 = 96 [packed = false];
+ repeated fixed64 repeated_fixed64 = 97 [packed = false];
+ repeated sfixed32 repeated_sfixed32 = 98 [packed = false];
+ repeated sfixed64 repeated_sfixed64 = 99 [packed = false];
+ repeated float repeated_float = 100 [packed = false];
+ repeated double repeated_double = 101 [packed = false];
+ repeated bool repeated_bool = 102 [packed = false];
+ repeated TestEnum repeated_enum = 103 [packed = false];
+}
+
+// /**/@<>&\{
+message TestPhpDoc {
+ int32 a = 1;
+}
+
+message TestIncludePrefixMessage {
+ TestPrefix prefix_message = 1;
+}
+
+message TestIncludeNamespaceMessage {
+ TestNamespace namespace_message = 1;
+ TestEmptyNamespace empty_namespace_message = 2;
+}
+
+// This will cause upb fields not ordered by the order in the generated code.
+message TestRandomFieldOrder {
+ int64 tag13 = 150;
+ string tag14 = 160;
+}
+
+message TestReverseFieldOrder {
+ repeated int32 a = 2;
+ string b = 1;
+}
+
+message testLowerCaseMessage {
+}
+
+enum testLowerCaseEnum {
+ VALUE = 0;
+}
+
+message TestAny {
+ google.protobuf.Any any = 1;
+}
diff --git a/third_party/protobuf/php/tests/proto/test_descriptors.proto b/third_party/protobuf/php/tests/proto/test_descriptors.proto
new file mode 100644
index 0000000..d42aec7
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_descriptors.proto
@@ -0,0 +1,35 @@
+syntax = "proto3";
+
+package descriptors;
+
+message TestDescriptorsMessage {
+ int32 optional_int32 = 1;
+ TestDescriptorsEnum optional_enum = 16;
+ Sub optional_message = 17;
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated Sub repeated_message = 47;
+
+ oneof my_oneof {
+ int32 oneof_int32 = 51;
+ }
+
+ map<int32, EnumSub> map_int32_enum = 71;
+
+ message Sub {
+ int32 a = 1;
+ repeated int32 b = 2;
+ }
+
+ enum EnumSub {
+ ZERO = 0;
+ ONE = 1;
+ }
+}
+
+enum TestDescriptorsEnum {
+ ZERO = 0;
+ ONE = 1;
+}
+
diff --git a/third_party/protobuf/php/tests/proto/test_empty_php_namespace.proto b/third_party/protobuf/php/tests/proto/test_empty_php_namespace.proto
new file mode 100644
index 0000000..c7ed165
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_empty_php_namespace.proto
@@ -0,0 +1,19 @@
+syntax = "proto3";
+
+package foo;
+option php_namespace = "";
+option php_metadata_namespace = "";
+
+message TestEmptyNamespace {
+ int32 a = 1;
+
+ // Test nested messages, enums, and reserved names
+ NestedMessage nested_message = 2;
+ NestedEnum nested_enum = 3;
+ message NestedMessage {
+ int32 a = 1;
+ }
+ enum NestedEnum {
+ ZERO = 0;
+ };
+}
diff --git a/third_party/protobuf/php/tests/proto/test_import_descriptor_proto.proto b/third_party/protobuf/php/tests/proto/test_import_descriptor_proto.proto
new file mode 100644
index 0000000..2a19940
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_import_descriptor_proto.proto
@@ -0,0 +1,14 @@
+syntax = "proto3";
+
+import "google/protobuf/descriptor.proto";
+
+message TestImportDescriptorProto {
+ extend google.protobuf.MethodOptions {
+ int32 a = 72295727;
+ }
+}
+
+extend google.protobuf.MethodOptions {
+ int32 a = 72295728;
+}
+
diff --git a/third_party/protobuf/php/tests/proto/test_include.proto b/third_party/protobuf/php/tests/proto/test_include.proto
new file mode 100644
index 0000000..a9072fe
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_include.proto
@@ -0,0 +1,18 @@
+syntax = "proto3";
+
+package bar;
+
+message TestInclude {
+ int32 a = 1;
+}
+
+message TestLegacyMessage {
+ NestedMessage message = 1;
+ NestedEnum enum = 2;
+ message NestedMessage {
+ int32 a = 1;
+ }
+ enum NestedEnum {
+ ZERO = 0;
+ }
+}
diff --git a/third_party/protobuf/php/tests/proto/test_no_namespace.proto b/third_party/protobuf/php/tests/proto/test_no_namespace.proto
new file mode 100644
index 0000000..cce42ea
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_no_namespace.proto
@@ -0,0 +1,22 @@
+syntax = "proto3";
+
+option php_metadata_namespace = "\\";
+
+message NoNamespaceMessage {
+ int32 a = 1;
+
+ // Test nested messages, enums, and reserved names
+ NestedMessage nested_message = 2;
+ NestedEnum nested_enum = 3;
+ message NestedMessage {
+ int32 a = 1;
+ }
+ enum NestedEnum {
+ ZERO = 0;
+ };
+}
+
+enum NoNamespaceEnum {
+ VALUE_A = 0;
+ VALUE_B = 1;
+}
diff --git a/third_party/protobuf/php/tests/proto/test_php_namespace.proto b/third_party/protobuf/php/tests/proto/test_php_namespace.proto
new file mode 100644
index 0000000..61085bf
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_php_namespace.proto
@@ -0,0 +1,31 @@
+syntax = "proto3";
+
+package foo;
+option php_namespace = "Php\\Test";
+option php_metadata_namespace = "Metadata\\Php\\Test";
+
+message TestNamespace {
+ int32 a = 1;
+
+ // Test nested messages, enums, and reserved names
+ NestedMessage nested_message = 2;
+ NestedEnum nested_enum = 3;
+ Empty reserved_name = 4;
+ message NestedMessage {
+ int32 a = 1;
+ }
+ enum NestedEnum {
+ ZERO = 0;
+ };
+ // Test reserved name
+ message Empty {
+ NestedMessage nested_message = 1;
+ NestedEnum nested_enum = 2;
+ message NestedMessage {
+ int32 a = 1;
+ }
+ enum NestedEnum {
+ ZERO = 0;
+ };
+ }
+}
diff --git a/third_party/protobuf/php/tests/proto/test_prefix.proto b/third_party/protobuf/php/tests/proto/test_prefix.proto
new file mode 100644
index 0000000..3fa1138
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_prefix.proto
@@ -0,0 +1,20 @@
+syntax = "proto3";
+
+option php_class_prefix = "Prefix";
+
+message TestPrefix {
+ int32 a = 1;
+ NestedMessage nested_message = 2;
+ NestedEnum nested_enum = 3;
+ message NestedMessage {
+ int32 a = 1;
+ }
+ enum NestedEnum {
+ ZERO = 0;
+ };
+}
+
+// Test prefix for reserved words.
+message Empty {
+ int32 a = 1;
+}
diff --git a/third_party/protobuf/php/tests/proto/test_reserved_enum_lower.proto b/third_party/protobuf/php/tests/proto/test_reserved_enum_lower.proto
new file mode 100644
index 0000000..d2daeaf
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_reserved_enum_lower.proto
@@ -0,0 +1,77 @@
+syntax = "proto3";
+
+package lower_enum;
+
+enum abstract { ZERO1 = 0; }
+enum and { ZERO2 = 0; }
+enum array { ZERO3 = 0; }
+enum as { ZERO4 = 0; }
+enum break { ZERO5 = 0; }
+enum callable { ZERO6 = 0; }
+enum case { ZERO7 = 0; }
+enum catch { ZERO8 = 0; }
+enum class { ZERO9 = 0; }
+enum clone { ZERO10 = 0; }
+enum const { ZERO11 = 0; }
+enum continue { ZERO12 = 0; }
+enum declare { ZERO13 = 0; }
+enum default { ZERO14 = 0; }
+enum die { ZERO15 = 0; }
+enum do { ZERO16 = 0; }
+enum echo { ZERO17 = 0; }
+enum else { ZERO18 = 0; }
+enum elseif { ZERO19 = 0; }
+enum empty { ZERO20 = 0; }
+enum enddeclare { ZERO21 = 0; }
+enum endfor { ZERO22 = 0; }
+enum endforeach { ZERO23 = 0; }
+enum endif { ZERO24 = 0; }
+enum endswitch { ZERO25 = 0; }
+enum endwhile { ZERO26 = 0; }
+enum eval { ZERO27 = 0; }
+enum exit { ZERO28 = 0; }
+enum extends { ZERO29 = 0; }
+enum final { ZERO30 = 0; }
+enum for { ZERO31 = 0; }
+enum foreach { ZERO32 = 0; }
+enum function { ZERO33 = 0; }
+enum global { ZERO34 = 0; }
+enum goto { ZERO35 = 0; }
+enum if { ZERO36 = 0; }
+enum implements { ZERO37 = 0; }
+enum include { ZERO38 = 0; }
+enum include_once { ZERO39 = 0; }
+enum instanceof { ZERO40 = 0; }
+enum insteadof { ZERO41 = 0; }
+enum interface { ZERO42 = 0; }
+enum isset { ZERO43 = 0; }
+enum list { ZERO44 = 0; }
+enum namespace { ZERO45 = 0; }
+enum new { ZERO46 = 0; }
+enum or { ZERO47 = 0; }
+enum print { ZERO48 = 0; }
+enum private { ZERO49 = 0; }
+enum protected { ZERO50 = 0; }
+enum public { ZERO51 = 0; }
+enum require { ZERO52 = 0; }
+enum require_once { ZERO53 = 0; }
+enum return { ZERO54 = 0; }
+enum static { ZERO55 = 0; }
+enum switch { ZERO56 = 0; }
+enum throw { ZERO57 = 0; }
+enum trait { ZERO58 = 0; }
+enum try { ZERO59 = 0; }
+enum unset { ZERO60 = 0; }
+enum use { ZERO61 = 0; }
+enum var { ZERO62 = 0; }
+enum while { ZERO63 = 0; }
+enum xor { ZERO64 = 0; }
+enum int { ZERO65 = 0; }
+enum float { ZERO66 = 0; }
+enum bool { ZERO67 = 0; }
+enum string { ZERO68 = 0; }
+enum true { ZERO69 = 0; }
+enum false { ZERO70 = 0; }
+enum null { ZERO71 = 0; }
+enum void { ZERO72 = 0; }
+enum iterable { ZERO73 = 0; }
diff --git a/third_party/protobuf/php/tests/proto/test_reserved_enum_upper.proto b/third_party/protobuf/php/tests/proto/test_reserved_enum_upper.proto
new file mode 100644
index 0000000..a396fea
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_reserved_enum_upper.proto
@@ -0,0 +1,77 @@
+syntax = "proto3";
+
+package upper_enum;
+
+enum ABSTRACT { ZERO1 = 0; }
+enum AND { ZERO2 = 0; }
+enum ARRAY { ZERO3 = 0; }
+enum AS { ZERO4 = 0; }
+enum BREAK { ZERO5 = 0; }
+enum CALLABLE { ZERO6 = 0; }
+enum CASE { ZERO7 = 0; }
+enum CATCH { ZERO8 = 0; }
+enum CLASS { ZERO9 = 0; }
+enum CLONE { ZERO10 = 0; }
+enum CONST { ZERO11 = 0; }
+enum CONTINUE { ZERO12 = 0; }
+enum DECLARE { ZERO13 = 0; }
+enum DEFAULT { ZERO14 = 0; }
+enum DIE { ZERO15 = 0; }
+enum DO { ZERO16 = 0; }
+enum ECHO { ZERO17 = 0; }
+enum ELSE { ZERO18 = 0; }
+enum ELSEIF { ZERO19 = 0; }
+enum EMPTY { ZERO20 = 0; }
+enum ENDDECLARE { ZERO21 = 0; }
+enum ENDFOR { ZERO22 = 0; }
+enum ENDFOREACH { ZERO23 = 0; }
+enum ENDIF { ZERO24 = 0; }
+enum ENDSWITCH { ZERO25 = 0; }
+enum ENDWHILE { ZERO26 = 0; }
+enum EVAL { ZERO27 = 0; }
+enum EXIT { ZERO28 = 0; }
+enum EXTENDS { ZERO29 = 0; }
+enum FINAL { ZERO30 = 0; }
+enum FOR { ZERO31 = 0; }
+enum FOREACH { ZERO32 = 0; }
+enum FUNCTION { ZERO33 = 0; }
+enum GLOBAL { ZERO34 = 0; }
+enum GOTO { ZERO35 = 0; }
+enum IF { ZERO36 = 0; }
+enum IMPLEMENTS { ZERO37 = 0; }
+enum INCLUDE { ZERO38 = 0; }
+enum INCLUDE_ONCE { ZERO39 = 0; }
+enum INSTANCEOF { ZERO40 = 0; }
+enum INSTEADOF { ZERO41 = 0; }
+enum INTERFACE { ZERO42 = 0; }
+enum ISSET { ZERO43 = 0; }
+enum LIST { ZERO44 = 0; }
+enum NAMESPACE { ZERO45 = 0; }
+enum NEW { ZERO46 = 0; }
+enum OR { ZERO47 = 0; }
+enum PRINT { ZERO48 = 0; }
+enum PRIVATE { ZERO49 = 0; }
+enum PROTECTED { ZERO50 = 0; }
+enum PUBLIC { ZERO51 = 0; }
+enum REQUIRE { ZERO52 = 0; }
+enum REQUIRE_ONCE { ZERO53 = 0; }
+enum RETURN { ZERO54 = 0; }
+enum STATIC { ZERO55 = 0; }
+enum SWITCH { ZERO56 = 0; }
+enum THROW { ZERO57 = 0; }
+enum TRAIT { ZERO58 = 0; }
+enum TRY { ZERO59 = 0; }
+enum UNSET { ZERO60 = 0; }
+enum USE { ZERO61 = 0; }
+enum VAR { ZERO62 = 0; }
+enum WHILE { ZERO63 = 0; }
+enum XOR { ZERO64 = 0; }
+enum INT { ZERO65 = 0; }
+enum FLOAT { ZERO66 = 0; }
+enum BOOL { ZERO67 = 0; }
+enum STRING { ZERO68 = 0; }
+enum TRUE { ZERO69 = 0; }
+enum FALSE { ZERO70 = 0; }
+enum NULL { ZERO71 = 0; }
+enum VOID { ZERO72 = 0; }
+enum ITERABLE { ZERO73 = 0; }
diff --git a/third_party/protobuf/php/tests/proto/test_reserved_enum_value_lower.proto b/third_party/protobuf/php/tests/proto/test_reserved_enum_value_lower.proto
new file mode 100644
index 0000000..96da319
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_reserved_enum_value_lower.proto
@@ -0,0 +1,79 @@
+syntax = "proto3";
+
+package lower_enum_value;
+
+enum NotAllowed {
+ abstract = 0;
+ and = 1;
+ array = 2;
+ as = 3;
+ break = 4;
+ callable = 5;
+ case = 6;
+ catch = 7;
+ class = 8;
+ clone = 9;
+ const = 10;
+ continue = 11;
+ declare = 12;
+ default = 13;
+ die = 14;
+ do = 15;
+ echo = 16;
+ else = 17;
+ elseif = 18;
+ empty = 19;
+ enddeclare = 20;
+ endfor = 21;
+ endforeach = 22;
+ endif = 23;
+ endswitch = 24;
+ endwhile = 25;
+ eval = 26;
+ exit = 27;
+ extends = 28;
+ final = 29;
+ for = 30;
+ foreach = 31;
+ function = 32;
+ global = 33;
+ goto = 34;
+ if = 35;
+ implements = 36;
+ include = 37;
+ include_once = 38;
+ instanceof = 39;
+ insteadof = 40;
+ interface = 41;
+ isset = 42;
+ list = 43;
+ namespace = 44;
+ new = 45;
+ or = 46;
+ print = 47;
+ private = 48;
+ protected = 49;
+ public = 50;
+ require = 51;
+ require_once = 52;
+ return = 53;
+ static = 54;
+ switch = 55;
+ throw = 56;
+ trait = 57;
+ try = 58;
+ unset = 59;
+ use = 60;
+ var = 61;
+ while = 62;
+ xor = 63;
+ int = 64;
+ float = 65;
+ bool = 66;
+ string = 67;
+ true = 68;
+ false = 69;
+ null = 70;
+ void = 71;
+ iterable = 72;
+}
diff --git a/third_party/protobuf/php/tests/proto/test_reserved_enum_value_upper.proto b/third_party/protobuf/php/tests/proto/test_reserved_enum_value_upper.proto
new file mode 100644
index 0000000..b026a85
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_reserved_enum_value_upper.proto
@@ -0,0 +1,79 @@
+syntax = "proto3";
+
+package upper_enum_value;
+
+enum NotAllowed {
+ ABSTRACT = 0;
+ AND = 1;
+ ARRAY = 2;
+ AS = 3;
+ BREAK = 4;
+ CALLABLE = 5;
+ CASE = 6;
+ CATCH = 7;
+ CLASS = 8;
+ CLONE = 9;
+ CONST = 10;
+ CONTINUE = 11;
+ DECLARE = 12;
+ DEFAULT = 13;
+ DIE = 14;
+ DO = 15;
+ ECHO = 16;
+ ELSE = 17;
+ ELSEIF = 18;
+ EMPTY = 19;
+ ENDDECLARE = 20;
+ ENDFOR = 21;
+ ENDFOREACH = 22;
+ ENDIF = 23;
+ ENDSWITCH = 24;
+ ENDWHILE = 25;
+ EVAL = 26;
+ EXIT = 27;
+ EXTENDS = 28;
+ FINAL = 29;
+ FOR = 30;
+ FOREACH = 31;
+ FUNCTION = 32;
+ GLOBAL = 33;
+ GOTO = 34;
+ IF = 35;
+ IMPLEMENTS = 36;
+ INCLUDE = 37;
+ INCLUDE_ONCE = 38;
+ INSTANCEOF = 39;
+ INSTEADOF = 40;
+ INTERFACE = 41;
+ ISSET = 42;
+ LIST = 43;
+ NAMESPACE = 44;
+ NEW = 45;
+ OR = 46;
+ PRINT = 47;
+ PRIVATE = 48;
+ PROTECTED = 49;
+ PUBLIC = 50;
+ REQUIRE = 51;
+ REQUIRE_ONCE = 52;
+ RETURN = 53;
+ STATIC = 54;
+ SWITCH = 55;
+ THROW = 56;
+ TRAIT = 57;
+ TRY = 58;
+ UNSET = 59;
+ USE = 60;
+ VAR = 61;
+ WHILE = 62;
+ XOR = 63;
+ INT = 64;
+ FLOAT = 65;
+ BOOL = 66;
+ STRING = 67;
+ TRUE = 68;
+ FALSE = 69;
+ NULL = 70;
+ VOID = 71;
+ ITERABLE = 72;
+}
diff --git a/third_party/protobuf/php/tests/proto/test_reserved_message_lower.proto b/third_party/protobuf/php/tests/proto/test_reserved_message_lower.proto
new file mode 100644
index 0000000..ed12080
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_reserved_message_lower.proto
@@ -0,0 +1,77 @@
+syntax = "proto3";
+
+package lower;
+
+message abstract {}
+message and {}
+message array {}
+message as {}
+message break {}
+message callable {}
+message case {}
+message catch {}
+message class {}
+message clone {}
+message const {}
+message continue {}
+message declare {}
+message default {}
+message die {}
+message do {}
+message echo {}
+message else {}
+message elseif {}
+message empty {}
+message enddeclare {}
+message endfor {}
+message endforeach {}
+message endif {}
+message endswitch {}
+message endwhile {}
+message eval {}
+message exit {}
+message extends {}
+message final {}
+message for {}
+message foreach {}
+message function {}
+message global {}
+message goto {}
+message if {}
+message implements {}
+message include {}
+message include_once {}
+message instanceof {}
+message insteadof {}
+message interface {}
+message isset {}
+message list {}
+message namespace {}
+message new {}
+message or {}
+message print {}
+message private {}
+message protected {}
+message public {}
+message require {}
+message require_once {}
+message return {}
+message static {}
+message switch {}
+message throw {}
+message trait {}
+message try {}
+message unset {}
+message use {}
+message var {}
+message while {}
+message xor {}
+message int {}
+message float {}
+message bool {}
+message string {}
+message true {}
+message false {}
+message null {}
+message void {}
+message iterable {}
diff --git a/third_party/protobuf/php/tests/proto/test_reserved_message_upper.proto b/third_party/protobuf/php/tests/proto/test_reserved_message_upper.proto
new file mode 100644
index 0000000..2917fd1
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_reserved_message_upper.proto
@@ -0,0 +1,77 @@
+syntax = "proto3";
+
+package upper;
+
+message ABSTRACT {}
+message AND {}
+message ARRAY {}
+message AS {}
+message BREAK {}
+message CALLABLE {}
+message CASE {}
+message CATCH {}
+message CLASS {}
+message CLONE {}
+message CONST {}
+message CONTINUE {}
+message DECLARE {}
+message DEFAULT {}
+message DIE {}
+message DO {}
+message ECHO {}
+message ELSE {}
+message ELSEIF {}
+message EMPTY {}
+message ENDDECLARE {}
+message ENDFOR {}
+message ENDFOREACH {}
+message ENDIF {}
+message ENDSWITCH {}
+message ENDWHILE {}
+message EVAL {}
+message EXIT {}
+message EXTENDS {}
+message FINAL {}
+message FOR {}
+message FOREACH {}
+message FUNCTION {}
+message GLOBAL {}
+message GOTO {}
+message IF {}
+message IMPLEMENTS {}
+message INCLUDE {}
+message INCLUDE_ONCE {}
+message INSTANCEOF {}
+message INSTEADOF {}
+message INTERFACE {}
+message ISSET {}
+message LIST {}
+message NAMESPACE {}
+message NEW {}
+message OR {}
+message PRINT {}
+message PRIVATE {}
+message PROTECTED {}
+message PUBLIC {}
+message REQUIRE {}
+message REQUIRE_ONCE {}
+message RETURN {}
+message STATIC {}
+message SWITCH {}
+message THROW {}
+message TRAIT {}
+message TRY {}
+message UNSET {}
+message USE {}
+message VAR {}
+message WHILE {}
+message XOR {}
+message INT {}
+message FLOAT {}
+message BOOL {}
+message STRING {}
+message TRUE {}
+message FALSE {}
+message NULL {}
+message VOID {}
+message ITERABLE {}
diff --git a/third_party/protobuf/php/tests/proto/test_service.proto b/third_party/protobuf/php/tests/proto/test_service.proto
new file mode 100644
index 0000000..a03dbc4
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_service.proto
@@ -0,0 +1,18 @@
+syntax = "proto3";
+
+package foo;
+
+option php_generic_services = true;
+
+service Greeter {
+ rpc SayHello (HelloRequest) returns (HelloReply) {}
+ rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
+}
+
+message HelloRequest {
+ string name = 1;
+}
+
+message HelloReply {
+ string message = 1;
+}
diff --git a/third_party/protobuf/php/tests/proto/test_service_namespace.proto b/third_party/protobuf/php/tests/proto/test_service_namespace.proto
new file mode 100644
index 0000000..719aa48
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_service_namespace.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+import "proto/test_service.proto";
+
+package foo;
+
+option php_generic_services = true;
+option php_namespace = "Bar";
+
+service OtherGreeter {
+ rpc SayHello (HelloRequest) returns (HelloReply) {}
+ rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
+}
diff --git a/third_party/protobuf/php/tests/proto/test_wrapper_type_setters.proto b/third_party/protobuf/php/tests/proto/test_wrapper_type_setters.proto
new file mode 100644
index 0000000..41ca7f3
--- /dev/null
+++ b/third_party/protobuf/php/tests/proto/test_wrapper_type_setters.proto
@@ -0,0 +1,26 @@
+syntax = "proto3";
+
+import "google/protobuf/wrappers.proto";
+
+package foo;
+
+message TestWrapperSetters {
+ google.protobuf.DoubleValue double_value = 1;
+ google.protobuf.FloatValue float_value = 2;
+ google.protobuf.Int64Value int64_value = 3;
+ google.protobuf.UInt64Value uint64_value = 4;
+ google.protobuf.Int32Value int32_value = 5;
+ google.protobuf.UInt32Value uint32_value = 6;
+ google.protobuf.BoolValue bool_value = 7;
+ google.protobuf.StringValue string_value = 8;
+ google.protobuf.BytesValue bytes_value = 9;
+
+ oneof wrapped_oneofs {
+ google.protobuf.DoubleValue double_value_oneof = 10;
+ google.protobuf.StringValue string_value_oneof = 11;
+ }
+
+ repeated google.protobuf.StringValue repeated_string_value = 12;
+
+ map<string, google.protobuf.StringValue> map_string_value = 13;
+}
diff --git a/third_party/protobuf/php/tests/test.sh b/third_party/protobuf/php/tests/test.sh
new file mode 100755
index 0000000..be6e97f
--- /dev/null
+++ b/third_party/protobuf/php/tests/test.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+VERSION=$1
+
+export PATH=/usr/local/php-$VERSION/bin:$PATH
+export C_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$C_INCLUDE_PATH
+export CPLUS_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$CPLUS_INCLUDE_PATH
+
+# Compile c extension
+/bin/bash ./compile_extension.sh ../ext/google/protobuf
+
+tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php descriptors_test.php wrapper_type_setters_test.php)
+
+for t in "${tests[@]}"
+do
+ echo "****************************"
+ echo "* $t"
+ echo "****************************"
+ php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php $t
+ echo ""
+done
+
+# # Make sure to run the memory test in debug mode.
+# php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
+
+export ZEND_DONT_UNLOAD_MODULES=1
+export USE_ZEND_ALLOC=0
+valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php
+
+# TODO(teboring): Only for debug (phpunit has memory leak which blocks this beging used by
+# regresssion test.)
+
+# for t in "${tests[@]}"
+# do
+# echo "****************************"
+# echo "* $t (memory leak)"
+# echo "****************************"
+# valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php $t
+# echo ""
+# done
diff --git a/third_party/protobuf/php/tests/test_base.php b/third_party/protobuf/php/tests/test_base.php
new file mode 100644
index 0000000..a4d951b
--- /dev/null
+++ b/third_party/protobuf/php/tests/test_base.php
@@ -0,0 +1,343 @@
+<?php
+
+use Foo\TestMessage;
+use Foo\TestEnum;
+use Foo\TestMessage\Sub;
+
+class TestBase extends \PHPUnit\Framework\TestCase
+{
+
+ public function setFields(TestMessage $m)
+ {
+ TestUtil::setTestMessage($m);
+ }
+
+ public function setFields2(TestMessage $m)
+ {
+ TestUtil::setTestMessage2($m);
+ }
+
+ public function expectFields(TestMessage $m)
+ {
+ $this->assertSame(-42, $m->getOptionalInt32());
+ $this->assertSame(42, $m->getOptionalUint32());
+ $this->assertSame(-44, $m->getOptionalSint32());
+ $this->assertSame(46, $m->getOptionalFixed32());
+ $this->assertSame(-46, $m->getOptionalSfixed32());
+ $this->assertSame(1.5, $m->getOptionalFloat());
+ $this->assertSame(1.6, $m->getOptionalDouble());
+ $this->assertSame(true, $m->getOptionalBool());
+ $this->assertSame('a', $m->getOptionalString());
+ $this->assertSame('bbbb', $m->getOptionalBytes());
+ $this->assertSame(TestEnum::ONE, $m->getOptionalEnum());
+ $this->assertSame(33, $m->getOptionalMessage()->getA());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('-43', $m->getOptionalInt64());
+ $this->assertSame('43', $m->getOptionalUint64());
+ $this->assertSame('-45', $m->getOptionalSint64());
+ $this->assertSame('47', $m->getOptionalFixed64());
+ $this->assertSame('-47', $m->getOptionalSfixed64());
+ } else {
+ $this->assertSame(-43, $m->getOptionalInt64());
+ $this->assertSame(43, $m->getOptionalUint64());
+ $this->assertSame(-45, $m->getOptionalSint64());
+ $this->assertSame(47, $m->getOptionalFixed64());
+ $this->assertSame(-47, $m->getOptionalSfixed64());
+ }
+
+ $this->assertEquals(-42, $m->getRepeatedInt32()[0]);
+ $this->assertEquals(42, $m->getRepeatedUint32()[0]);
+ $this->assertEquals(-43, $m->getRepeatedInt64()[0]);
+ $this->assertEquals(43, $m->getRepeatedUint64()[0]);
+ $this->assertEquals(-44, $m->getRepeatedSint32()[0]);
+ $this->assertEquals(-45, $m->getRepeatedSint64()[0]);
+ $this->assertEquals(46, $m->getRepeatedFixed32()[0]);
+ $this->assertEquals(47, $m->getRepeatedFixed64()[0]);
+ $this->assertEquals(-46, $m->getRepeatedSfixed32()[0]);
+ $this->assertEquals(-47, $m->getRepeatedSfixed64()[0]);
+ $this->assertEquals(1.5, $m->getRepeatedFloat()[0]);
+ $this->assertEquals(1.6, $m->getRepeatedDouble()[0]);
+ $this->assertEquals(true, $m->getRepeatedBool()[0]);
+ $this->assertEquals('a', $m->getRepeatedString()[0]);
+ $this->assertEquals('bbbb', $m->getRepeatedBytes()[0]);
+ $this->assertEquals(34, $m->getRepeatedMessage()[0]->GetA());
+
+ $this->assertEquals(-52, $m->getRepeatedInt32()[1]);
+ $this->assertEquals(52, $m->getRepeatedUint32()[1]);
+ $this->assertEquals(-53, $m->getRepeatedInt64()[1]);
+ $this->assertEquals(53, $m->getRepeatedUint64()[1]);
+ $this->assertEquals(-54, $m->getRepeatedSint32()[1]);
+ $this->assertEquals(-55, $m->getRepeatedSint64()[1]);
+ $this->assertEquals(56, $m->getRepeatedFixed32()[1]);
+ $this->assertEquals(57, $m->getRepeatedFixed64()[1]);
+ $this->assertEquals(-56, $m->getRepeatedSfixed32()[1]);
+ $this->assertEquals(-57, $m->getRepeatedSfixed64()[1]);
+ $this->assertEquals(2.5, $m->getRepeatedFloat()[1]);
+ $this->assertEquals(2.6, $m->getRepeatedDouble()[1]);
+ $this->assertEquals(false, $m->getRepeatedBool()[1]);
+ $this->assertEquals('c', $m->getRepeatedString()[1]);
+ $this->assertEquals('dddd', $m->getRepeatedBytes()[1]);
+ $this->assertEquals(35, $m->getRepeatedMessage()[1]->GetA());
+
+ if (PHP_INT_SIZE == 4) {
+ $this->assertEquals('-63', $m->getMapInt64Int64()['-63']);
+ $this->assertEquals('63', $m->getMapUint64Uint64()['63']);
+ $this->assertEquals('-65', $m->getMapSint64Sint64()['-65']);
+ $this->assertEquals('67', $m->getMapFixed64Fixed64()['67']);
+ $this->assertEquals('-69', $m->getMapSfixed64Sfixed64()['-69']);
+ } else {
+ $this->assertEquals(-63, $m->getMapInt64Int64()[-63]);
+ $this->assertEquals(63, $m->getMapUint64Uint64()[63]);
+ $this->assertEquals(-65, $m->getMapSint64Sint64()[-65]);
+ $this->assertEquals(67, $m->getMapFixed64Fixed64()[67]);
+ $this->assertEquals(-69, $m->getMapSfixed64Sfixed64()[-69]);
+ }
+ $this->assertEquals(-62, $m->getMapInt32Int32()[-62]);
+ $this->assertEquals(62, $m->getMapUint32Uint32()[62]);
+ $this->assertEquals(-64, $m->getMapSint32Sint32()[-64]);
+ $this->assertEquals(66, $m->getMapFixed32Fixed32()[66]);
+ $this->assertEquals(-68, $m->getMapSfixed32Sfixed32()[-68]);
+ $this->assertEquals(3.5, $m->getMapInt32Float()[1]);
+ $this->assertEquals(3.6, $m->getMapInt32Double()[1]);
+ $this->assertEquals(true , $m->getMapBoolBool()[true]);
+ $this->assertEquals('e', $m->getMapStringString()['e']);
+ $this->assertEquals('ffff', $m->getMapInt32Bytes()[1]);
+ $this->assertEquals(TestEnum::ONE, $m->getMapInt32Enum()[1]);
+ $this->assertEquals(36, $m->getMapInt32Message()[1]->GetA());
+ }
+
+ // Test message merged from setFields and setFields2.
+ public function expectFieldsMerged(TestMessage $m)
+ {
+ $this->assertSame(-144, $m->getOptionalSint32());
+ $this->assertSame(146, $m->getOptionalFixed32());
+ $this->assertSame(-146, $m->getOptionalSfixed32());
+ $this->assertSame(11.5, $m->getOptionalFloat());
+ $this->assertSame(11.6, $m->getOptionalDouble());
+ $this->assertSame(true, $m->getOptionalBool());
+ $this->assertSame('aa', $m->getOptionalString());
+ $this->assertSame('bb', $m->getOptionalBytes());
+ $this->assertSame(133, $m->getOptionalMessage()->getA());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('-143', $m->getOptionalInt64());
+ $this->assertSame('143', $m->getOptionalUint64());
+ $this->assertSame('-145', $m->getOptionalSint64());
+ $this->assertSame('147', $m->getOptionalFixed64());
+ $this->assertSame('-147', $m->getOptionalSfixed64());
+ } else {
+ $this->assertSame(-143, $m->getOptionalInt64());
+ $this->assertSame(143, $m->getOptionalUint64());
+ $this->assertSame(-145, $m->getOptionalSint64());
+ $this->assertSame(147, $m->getOptionalFixed64());
+ $this->assertSame(-147, $m->getOptionalSfixed64());
+ }
+
+ $this->assertEquals(-42, $m->getRepeatedInt32()[0]);
+ $this->assertEquals(42, $m->getRepeatedUint32()[0]);
+ $this->assertEquals(-43, $m->getRepeatedInt64()[0]);
+ $this->assertEquals(43, $m->getRepeatedUint64()[0]);
+ $this->assertEquals(-44, $m->getRepeatedSint32()[0]);
+ $this->assertEquals(-45, $m->getRepeatedSint64()[0]);
+ $this->assertEquals(46, $m->getRepeatedFixed32()[0]);
+ $this->assertEquals(47, $m->getRepeatedFixed64()[0]);
+ $this->assertEquals(-46, $m->getRepeatedSfixed32()[0]);
+ $this->assertEquals(-47, $m->getRepeatedSfixed64()[0]);
+ $this->assertEquals(1.5, $m->getRepeatedFloat()[0]);
+ $this->assertEquals(1.6, $m->getRepeatedDouble()[0]);
+ $this->assertEquals(true, $m->getRepeatedBool()[0]);
+ $this->assertEquals('a', $m->getRepeatedString()[0]);
+ $this->assertEquals('bbbb', $m->getRepeatedBytes()[0]);
+ $this->assertEquals(TestEnum::ZERO, $m->getRepeatedEnum()[0]);
+ $this->assertEquals(34, $m->getRepeatedMessage()[0]->GetA());
+
+ $this->assertEquals(-52, $m->getRepeatedInt32()[1]);
+ $this->assertEquals(52, $m->getRepeatedUint32()[1]);
+ $this->assertEquals(-53, $m->getRepeatedInt64()[1]);
+ $this->assertEquals(53, $m->getRepeatedUint64()[1]);
+ $this->assertEquals(-54, $m->getRepeatedSint32()[1]);
+ $this->assertEquals(-55, $m->getRepeatedSint64()[1]);
+ $this->assertEquals(56, $m->getRepeatedFixed32()[1]);
+ $this->assertEquals(57, $m->getRepeatedFixed64()[1]);
+ $this->assertEquals(-56, $m->getRepeatedSfixed32()[1]);
+ $this->assertEquals(-57, $m->getRepeatedSfixed64()[1]);
+ $this->assertEquals(2.5, $m->getRepeatedFloat()[1]);
+ $this->assertEquals(2.6, $m->getRepeatedDouble()[1]);
+ $this->assertEquals(false, $m->getRepeatedBool()[1]);
+ $this->assertEquals('c', $m->getRepeatedString()[1]);
+ $this->assertEquals('dddd', $m->getRepeatedBytes()[1]);
+ $this->assertEquals(TestEnum::ONE, $m->getRepeatedEnum()[1]);
+ $this->assertEquals(35, $m->getRepeatedMessage()[1]->GetA());
+
+ $this->assertEquals(-142, $m->getRepeatedInt32()[2]);
+ $this->assertEquals(142, $m->getRepeatedUint32()[2]);
+ $this->assertEquals(-143, $m->getRepeatedInt64()[2]);
+ $this->assertEquals(143, $m->getRepeatedUint64()[2]);
+ $this->assertEquals(-144, $m->getRepeatedSint32()[2]);
+ $this->assertEquals(-145, $m->getRepeatedSint64()[2]);
+ $this->assertEquals(146, $m->getRepeatedFixed32()[2]);
+ $this->assertEquals(147, $m->getRepeatedFixed64()[2]);
+ $this->assertEquals(-146, $m->getRepeatedSfixed32()[2]);
+ $this->assertEquals(-147, $m->getRepeatedSfixed64()[2]);
+ $this->assertEquals(11.5, $m->getRepeatedFloat()[2]);
+ $this->assertEquals(11.6, $m->getRepeatedDouble()[2]);
+ $this->assertEquals(false, $m->getRepeatedBool()[2]);
+ $this->assertEquals('aa', $m->getRepeatedString()[2]);
+ $this->assertEquals('bb', $m->getRepeatedBytes()[2]);
+ $this->assertEquals(TestEnum::TWO, $m->getRepeatedEnum()[2]);
+ $this->assertEquals(134, $m->getRepeatedMessage()[2]->GetA());
+
+ if (PHP_INT_SIZE == 4) {
+ $this->assertEquals('-163', $m->getMapInt64Int64()['-63']);
+ $this->assertEquals('163', $m->getMapUint64Uint64()['63']);
+ $this->assertEquals('-165', $m->getMapSint64Sint64()['-65']);
+ $this->assertEquals('167', $m->getMapFixed64Fixed64()['67']);
+ $this->assertEquals('-169', $m->getMapSfixed64Sfixed64()['-69']);
+ } else {
+ $this->assertEquals(-163, $m->getMapInt64Int64()[-63]);
+ $this->assertEquals(163, $m->getMapUint64Uint64()[63]);
+ $this->assertEquals(-165, $m->getMapSint64Sint64()[-65]);
+ $this->assertEquals(167, $m->getMapFixed64Fixed64()[67]);
+ $this->assertEquals(-169, $m->getMapSfixed64Sfixed64()[-69]);
+ }
+ $this->assertEquals(-162, $m->getMapInt32Int32()[-62]);
+ $this->assertEquals(162, $m->getMapUint32Uint32()[62]);
+ $this->assertEquals(-164, $m->getMapSint32Sint32()[-64]);
+ $this->assertEquals(166, $m->getMapFixed32Fixed32()[66]);
+ $this->assertEquals(-168, $m->getMapSfixed32Sfixed32()[-68]);
+ $this->assertEquals(13.5, $m->getMapInt32Float()[1]);
+ $this->assertEquals(13.6, $m->getMapInt32Double()[1]);
+ $this->assertEquals(false , $m->getMapBoolBool()[true]);
+ $this->assertEquals('ee', $m->getMapStringString()['e']);
+ $this->assertEquals('ff', $m->getMapInt32Bytes()[1]);
+ $this->assertEquals(TestEnum::TWO, $m->getMapInt32Enum()[1]);
+ $this->assertEquals(136, $m->getMapInt32Message()[1]->GetA());
+
+ if (PHP_INT_SIZE == 4) {
+ $this->assertEquals('-163', $m->getMapInt64Int64()['-163']);
+ $this->assertEquals('163', $m->getMapUint64Uint64()['163']);
+ $this->assertEquals('-165', $m->getMapSint64Sint64()['-165']);
+ $this->assertEquals('167', $m->getMapFixed64Fixed64()['167']);
+ $this->assertEquals('-169', $m->getMapSfixed64Sfixed64()['-169']);
+ } else {
+ $this->assertEquals(-163, $m->getMapInt64Int64()[-163]);
+ $this->assertEquals(163, $m->getMapUint64Uint64()[163]);
+ $this->assertEquals(-165, $m->getMapSint64Sint64()[-165]);
+ $this->assertEquals(167, $m->getMapFixed64Fixed64()[167]);
+ $this->assertEquals(-169, $m->getMapSfixed64Sfixed64()[-169]);
+ }
+ $this->assertEquals(-162, $m->getMapInt32Int32()[-162]);
+ $this->assertEquals(162, $m->getMapUint32Uint32()[162]);
+ $this->assertEquals(-164, $m->getMapSint32Sint32()[-164]);
+ $this->assertEquals(166, $m->getMapFixed32Fixed32()[166]);
+ $this->assertEquals(-168, $m->getMapSfixed32Sfixed32()[-168]);
+ $this->assertEquals(13.5, $m->getMapInt32Float()[2]);
+ $this->assertEquals(13.6, $m->getMapInt32Double()[2]);
+ $this->assertEquals(false , $m->getMapBoolBool()[false]);
+ $this->assertEquals('ee', $m->getMapStringString()['ee']);
+ $this->assertEquals('ff', $m->getMapInt32Bytes()[2]);
+ $this->assertEquals(TestEnum::TWO, $m->getMapInt32Enum()[2]);
+ $this->assertEquals(136, $m->getMapInt32Message()[2]->GetA());
+ }
+
+ public function expectEmptyFields(TestMessage $m)
+ {
+ $this->assertSame(0, $m->getOptionalInt32());
+ $this->assertSame(0, $m->getOptionalUint32());
+ $this->assertSame(0, $m->getOptionalSint32());
+ $this->assertSame(0, $m->getOptionalFixed32());
+ $this->assertSame(0, $m->getOptionalSfixed32());
+ $this->assertSame(0.0, $m->getOptionalFloat());
+ $this->assertSame(0.0, $m->getOptionalDouble());
+ $this->assertSame(false, $m->getOptionalBool());
+ $this->assertSame('', $m->getOptionalString());
+ $this->assertSame('', $m->getOptionalBytes());
+ $this->assertSame(0, $m->getOptionalEnum());
+ $this->assertNull($m->getOptionalMessage());
+ $this->assertNull($m->getOptionalIncludedMessage());
+ $this->assertNull($m->getRecursive());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame("0", $m->getOptionalInt64());
+ $this->assertSame("0", $m->getOptionalUint64());
+ $this->assertSame("0", $m->getOptionalSint64());
+ $this->assertSame("0", $m->getOptionalFixed64());
+ $this->assertSame("0", $m->getOptionalSfixed64());
+ } else {
+ $this->assertSame(0, $m->getOptionalInt64());
+ $this->assertSame(0, $m->getOptionalUint64());
+ $this->assertSame(0, $m->getOptionalSint64());
+ $this->assertSame(0, $m->getOptionalFixed64());
+ $this->assertSame(0, $m->getOptionalSfixed64());
+ }
+
+ $this->assertEquals(0, count($m->getRepeatedInt32()));
+ $this->assertEquals(0, count($m->getRepeatedUint32()));
+ $this->assertEquals(0, count($m->getRepeatedInt64()));
+ $this->assertEquals(0, count($m->getRepeatedUint64()));
+ $this->assertEquals(0, count($m->getRepeatedSint32()));
+ $this->assertEquals(0, count($m->getRepeatedSint64()));
+ $this->assertEquals(0, count($m->getRepeatedFixed32()));
+ $this->assertEquals(0, count($m->getRepeatedFixed64()));
+ $this->assertEquals(0, count($m->getRepeatedSfixed32()));
+ $this->assertEquals(0, count($m->getRepeatedSfixed64()));
+ $this->assertEquals(0, count($m->getRepeatedFloat()));
+ $this->assertEquals(0, count($m->getRepeatedDouble()));
+ $this->assertEquals(0, count($m->getRepeatedBool()));
+ $this->assertEquals(0, count($m->getRepeatedString()));
+ $this->assertEquals(0, count($m->getRepeatedBytes()));
+ $this->assertEquals(0, count($m->getRepeatedEnum()));
+ $this->assertEquals(0, count($m->getRepeatedMessage()));
+ $this->assertEquals(0, count($m->getRepeatedRecursive()));
+
+ $this->assertSame("", $m->getMyOneof());
+ $this->assertSame(0, $m->getOneofInt32());
+ $this->assertSame(0, $m->getOneofUint32());
+ $this->assertSame(0, $m->getOneofSint32());
+ $this->assertSame(0, $m->getOneofFixed32());
+ $this->assertSame(0, $m->getOneofSfixed32());
+ $this->assertSame(0.0, $m->getOneofFloat());
+ $this->assertSame(0.0, $m->getOneofDouble());
+ $this->assertSame(false, $m->getOneofBool());
+ $this->assertSame('', $m->getOneofString());
+ $this->assertSame('', $m->getOneofBytes());
+ $this->assertSame(0, $m->getOneofEnum());
+ $this->assertNull($m->getOptionalMessage());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame("0", $m->getOneofInt64());
+ $this->assertSame("0", $m->getOneofUint64());
+ $this->assertSame("0", $m->getOneofSint64());
+ $this->assertSame("0", $m->getOneofFixed64());
+ $this->assertSame("0", $m->getOneofSfixed64());
+ } else {
+ $this->assertSame(0, $m->getOneofInt64());
+ $this->assertSame(0, $m->getOneofUint64());
+ $this->assertSame(0, $m->getOneofSint64());
+ $this->assertSame(0, $m->getOneofFixed64());
+ $this->assertSame(0, $m->getOneofSfixed64());
+ }
+
+ $this->assertEquals(0, count($m->getMapInt64Int64()));
+ $this->assertEquals(0, count($m->getMapUint64Uint64()));
+ $this->assertEquals(0, count($m->getMapSint64Sint64()));
+ $this->assertEquals(0, count($m->getMapFixed64Fixed64()));
+ $this->assertEquals(0, count($m->getMapInt32Int32()));
+ $this->assertEquals(0, count($m->getMapUint32Uint32()));
+ $this->assertEquals(0, count($m->getMapSint32Sint32()));
+ $this->assertEquals(0, count($m->getMapFixed32Fixed32()));
+ $this->assertEquals(0, count($m->getMapSfixed32Sfixed32()));
+ $this->assertEquals(0, count($m->getMapSfixed64Sfixed64()));
+ $this->assertEquals(0, count($m->getMapInt32Float()));
+ $this->assertEquals(0, count($m->getMapInt32Double()));
+ $this->assertEquals(0, count($m->getMapBoolBool()));
+ $this->assertEquals(0, count($m->getMapStringString()));
+ $this->assertEquals(0, count($m->getMapInt32Bytes()));
+ $this->assertEquals(0, count($m->getMapInt32Enum()));
+ $this->assertEquals(0, count($m->getMapInt32Message()));
+ $this->assertEquals(0, count($m->getMapRecursive()));
+ }
+
+ // This test is to avoid the warning of no test by php unit.
+ public function testNone()
+ {
+ $this->assertTrue(true);
+ }
+}
diff --git a/third_party/protobuf/php/tests/test_util.php b/third_party/protobuf/php/tests/test_util.php
new file mode 100644
index 0000000..2c5b595
--- /dev/null
+++ b/third_party/protobuf/php/tests/test_util.php
@@ -0,0 +1,547 @@
+<?php
+
+use Foo\TestEnum;
+use Foo\TestMessage;
+use Foo\TestMessage\Sub;
+use Foo\TestPackedMessage;
+use Foo\TestUnpackedMessage;
+
+define('MAX_FLOAT_DIFF', 0.000001);
+
+if (PHP_INT_SIZE == 8) {
+ define('MAX_INT_STRING', '9223372036854775807');
+ define('MAX_INT_UPPER_STRING', '9223372036854775808');
+} else {
+ define('MAX_INT_STRING', '2147483647');
+ define('MAX_INT_UPPER_STRING', '2147483648');
+}
+
+define('MAX_INT32', 2147483647);
+define('MAX_INT32_FLOAT', 2147483647.0);
+define('MAX_INT32_STRING', '2147483647');
+
+define('MIN_INT32', (int)-2147483648);
+define('MIN_INT32_FLOAT', -2147483648.0);
+define('MIN_INT32_STRING', '-2147483648');
+
+define('MAX_UINT32', 4294967295);
+define('MAX_UINT32_FLOAT', 4294967295.0);
+define('MAX_UINT32_STRING', '4294967295');
+
+define('MIN_UINT32', (int)-2147483648);
+define('MIN_UINT32_FLOAT', -2147483648.0);
+define('MIN_UINT32_STRING', '-2147483648');
+
+define('MAX_INT64_STRING', '9223372036854775807');
+define('MIN_INT64_STRING', '-9223372036854775808');
+define('MAX_UINT64_STRING', '-9223372036854775808');
+
+if (PHP_INT_SIZE === 8) {
+ define('MAX_INT64', (int)9223372036854775807);
+ define('MIN_INT64', (int)-9223372036854775808);
+ define('MAX_UINT64', (int)-9223372036854775808);
+} else {
+ define('MAX_INT64', MAX_INT64_STRING);
+ define('MIN_INT64', MIN_INT64_STRING);
+ define('MAX_UINT64', MAX_UINT64_STRING);
+}
+
+class TestUtil
+{
+
+ public static function setTestMessage(TestMessage $m)
+ {
+ $m->setOptionalInt32(-42);
+ $m->setOptionalInt64(-43);
+ $m->setOptionalUint32(42);
+ $m->setOptionalUint64(43);
+ $m->setOptionalSint32(-44);
+ $m->setOptionalSint64(-45);
+ $m->setOptionalFixed32(46);
+ $m->setOptionalFixed64(47);
+ $m->setOptionalSfixed32(-46);
+ $m->setOptionalSfixed64(-47);
+ $m->setOptionalFloat(1.5);
+ $m->setOptionalDouble(1.6);
+ $m->setOptionalBool(true);
+ $m->setOptionalString('a');
+ $m->setOptionalBytes('bbbb');
+ $m->setOptionalEnum(TestEnum::ONE);
+ $sub = new Sub();
+ $m->setOptionalMessage($sub);
+ $m->getOptionalMessage()->SetA(33);
+
+ self::appendHelper($m, 'RepeatedInt32', -42);
+ self::appendHelper($m, 'RepeatedInt64', -43);
+ self::appendHelper($m, 'RepeatedUint32', 42);
+ self::appendHelper($m, 'RepeatedUint64', 43);
+ self::appendHelper($m, 'RepeatedSint32', -44);
+ self::appendHelper($m, 'RepeatedSint64', -45);
+ self::appendHelper($m, 'RepeatedFixed32', 46);
+ self::appendHelper($m, 'RepeatedFixed64', 47);
+ self::appendHelper($m, 'RepeatedSfixed32', -46);
+ self::appendHelper($m, 'RepeatedSfixed64', -47);
+ self::appendHelper($m, 'RepeatedFloat', 1.5);
+ self::appendHelper($m, 'RepeatedDouble', 1.6);
+ self::appendHelper($m, 'RepeatedBool', true);
+ self::appendHelper($m, 'RepeatedString', 'a');
+ self::appendHelper($m, 'RepeatedBytes', 'bbbb');
+ self::appendHelper($m, 'RepeatedEnum', TestEnum::ZERO);
+ self::appendHelper($m, 'RepeatedMessage', new Sub());
+ $m->getRepeatedMessage()[0]->setA(34);
+
+ self::appendHelper($m, 'RepeatedInt32', -52);
+ self::appendHelper($m, 'RepeatedInt64', -53);
+ self::appendHelper($m, 'RepeatedUint32', 52);
+ self::appendHelper($m, 'RepeatedUint64', 53);
+ self::appendHelper($m, 'RepeatedSint32', -54);
+ self::appendHelper($m, 'RepeatedSint64', -55);
+ self::appendHelper($m, 'RepeatedFixed32', 56);
+ self::appendHelper($m, 'RepeatedFixed64', 57);
+ self::appendHelper($m, 'RepeatedSfixed32', -56);
+ self::appendHelper($m, 'RepeatedSfixed64', -57);
+ self::appendHelper($m, 'RepeatedFloat', 2.5);
+ self::appendHelper($m, 'RepeatedDouble', 2.6);
+ self::appendHelper($m, 'RepeatedBool', false);
+ self::appendHelper($m, 'RepeatedString', 'c');
+ self::appendHelper($m, 'RepeatedBytes', 'dddd');
+ self::appendHelper($m, 'RepeatedEnum', TestEnum::ONE);
+ self::appendHelper($m, 'RepeatedMessage', new Sub());
+ $m->getRepeatedMessage()[1]->SetA(35);
+
+ self::kvUpdateHelper($m, 'MapInt32Int32', -62, -62);
+ self::kvUpdateHelper($m, 'MapInt64Int64', -63, -63);
+ self::kvUpdateHelper($m, 'MapUint32Uint32', 62, 62);
+ self::kvUpdateHelper($m, 'MapUint64Uint64', 63, 63);
+ self::kvUpdateHelper($m, 'MapSint32Sint32', -64, -64);
+ self::kvUpdateHelper($m, 'MapSint64Sint64', -65, -65);
+ self::kvUpdateHelper($m, 'MapFixed32Fixed32', 66, 66);
+ self::kvUpdateHelper($m, 'MapFixed64Fixed64', 67, 67);
+ self::kvUpdateHelper($m, 'MapSfixed32Sfixed32', -68, -68);
+ self::kvUpdateHelper($m, 'MapSfixed64Sfixed64', -69, -69);
+ self::kvUpdateHelper($m, 'MapInt32Float', 1, 3.5);
+ self::kvUpdateHelper($m, 'MapInt32Double', 1, 3.6);
+ self::kvUpdateHelper($m, 'MapBoolBool', true, true);
+ self::kvUpdateHelper($m, 'MapStringString', 'e', 'e');
+ self::kvUpdateHelper($m, 'MapInt32Bytes', 1, 'ffff');
+ self::kvUpdateHelper($m, 'MapInt32Enum', 1, TestEnum::ONE);
+ self::kvUpdateHelper($m, 'MapInt32Message', 1, new Sub());
+ $m->getMapInt32Message()[1]->SetA(36);
+ }
+
+ public static function setTestMessage2(TestMessage $m)
+ {
+ $sub = new Sub();
+
+ $m->setOptionalInt32(-142);
+ $m->setOptionalInt64(-143);
+ $m->setOptionalUint32(142);
+ $m->setOptionalUint64(143);
+ $m->setOptionalSint32(-144);
+ $m->setOptionalSint64(-145);
+ $m->setOptionalFixed32(146);
+ $m->setOptionalFixed64(147);
+ $m->setOptionalSfixed32(-146);
+ $m->setOptionalSfixed64(-147);
+ $m->setOptionalFloat(11.5);
+ $m->setOptionalDouble(11.6);
+ $m->setOptionalBool(true);
+ $m->setOptionalString('aa');
+ $m->setOptionalBytes('bb');
+ $m->setOptionalEnum(TestEnum::TWO);
+ $m->setOptionalMessage($sub);
+ $m->getOptionalMessage()->SetA(133);
+
+ self::appendHelper($m, 'RepeatedInt32', -142);
+ self::appendHelper($m, 'RepeatedInt64', -143);
+ self::appendHelper($m, 'RepeatedUint32', 142);
+ self::appendHelper($m, 'RepeatedUint64', 143);
+ self::appendHelper($m, 'RepeatedSint32', -144);
+ self::appendHelper($m, 'RepeatedSint64', -145);
+ self::appendHelper($m, 'RepeatedFixed32', 146);
+ self::appendHelper($m, 'RepeatedFixed64', 147);
+ self::appendHelper($m, 'RepeatedSfixed32', -146);
+ self::appendHelper($m, 'RepeatedSfixed64', -147);
+ self::appendHelper($m, 'RepeatedFloat', 11.5);
+ self::appendHelper($m, 'RepeatedDouble', 11.6);
+ self::appendHelper($m, 'RepeatedBool', false);
+ self::appendHelper($m, 'RepeatedString', 'aa');
+ self::appendHelper($m, 'RepeatedBytes', 'bb');
+ self::appendHelper($m, 'RepeatedEnum', TestEnum::TWO);
+ self::appendHelper($m, 'RepeatedMessage', new Sub());
+ $m->getRepeatedMessage()[0]->setA(134);
+
+ self::kvUpdateHelper($m, 'MapInt32Int32', -62, -162);
+ self::kvUpdateHelper($m, 'MapInt64Int64', -63, -163);
+ self::kvUpdateHelper($m, 'MapUint32Uint32', 62, 162);
+ self::kvUpdateHelper($m, 'MapUint64Uint64', 63, 163);
+ self::kvUpdateHelper($m, 'MapSint32Sint32', -64, -164);
+ self::kvUpdateHelper($m, 'MapSint64Sint64', -65, -165);
+ self::kvUpdateHelper($m, 'MapFixed32Fixed32', 66, 166);
+ self::kvUpdateHelper($m, 'MapFixed64Fixed64', 67, 167);
+ self::kvUpdateHelper($m, 'MapSfixed32Sfixed32', -68, -168);
+ self::kvUpdateHelper($m, 'MapSfixed64Sfixed64', -69, -169);
+ self::kvUpdateHelper($m, 'MapInt32Float', 1, 13.5);
+ self::kvUpdateHelper($m, 'MapInt32Double', 1, 13.6);
+ self::kvUpdateHelper($m, 'MapBoolBool', true, false);
+ self::kvUpdateHelper($m, 'MapStringString', 'e', 'ee');
+ self::kvUpdateHelper($m, 'MapInt32Bytes', 1, 'ff');
+ self::kvUpdateHelper($m, 'MapInt32Enum', 1, TestEnum::TWO);
+ self::kvUpdateHelper($m, 'MapInt32Message', 1, new Sub());
+ $m->getMapInt32Message()[1]->SetA(136);
+
+ self::kvUpdateHelper($m, 'MapInt32Int32', -162, -162);
+ self::kvUpdateHelper($m, 'MapInt64Int64', -163, -163);
+ self::kvUpdateHelper($m, 'MapUint32Uint32', 162, 162);
+ self::kvUpdateHelper($m, 'MapUint64Uint64', 163, 163);
+ self::kvUpdateHelper($m, 'MapSint32Sint32', -164, -164);
+ self::kvUpdateHelper($m, 'MapSint64Sint64', -165, -165);
+ self::kvUpdateHelper($m, 'MapFixed32Fixed32', 166, 166);
+ self::kvUpdateHelper($m, 'MapFixed64Fixed64', 167, 167);
+ self::kvUpdateHelper($m, 'MapSfixed32Sfixed32', -168, -168);
+ self::kvUpdateHelper($m, 'MapSfixed64Sfixed64', -169, -169);
+ self::kvUpdateHelper($m, 'MapInt32Float', 2, 13.5);
+ self::kvUpdateHelper($m, 'MapInt32Double', 2, 13.6);
+ self::kvUpdateHelper($m, 'MapBoolBool', false, false);
+ self::kvUpdateHelper($m, 'MapStringString', 'ee', 'ee');
+ self::kvUpdateHelper($m, 'MapInt32Bytes', 2, 'ff');
+ self::kvUpdateHelper($m, 'MapInt32Enum', 2, TestEnum::TWO);
+ self::kvUpdateHelper($m, 'MapInt32Message', 2, new Sub());
+ $m->getMapInt32Message()[2]->SetA(136);
+ }
+
+ public static function assertTestMessage(TestMessage $m)
+ {
+ if (PHP_INT_SIZE == 4) {
+ assert('-43' === $m->getOptionalInt64());
+ assert('43' === $m->getOptionalUint64());
+ assert('-45' === $m->getOptionalSint64());
+ assert('47' === $m->getOptionalFixed64());
+ assert('-47' === $m->getOptionalSfixed64());
+ } else {
+ assert(-43 === $m->getOptionalInt64());
+ assert(43 === $m->getOptionalUint64());
+ assert(-45 === $m->getOptionalSint64());
+ assert(47 === $m->getOptionalFixed64());
+ assert(-47 === $m->getOptionalSfixed64());
+ }
+ assert(-42 === $m->getOptionalInt32());
+ assert(42 === $m->getOptionalUint32());
+ assert(-44 === $m->getOptionalSint32());
+ assert(46 === $m->getOptionalFixed32());
+ assert(-46 === $m->getOptionalSfixed32());
+ assert(1.5 === $m->getOptionalFloat());
+ assert(1.6 === $m->getOptionalDouble());
+ assert(true=== $m->getOptionalBool());
+ assert('a' === $m->getOptionalString());
+ assert('bbbb' === $m->getOptionalBytes());
+ assert(TestEnum::ONE === $m->getOptionalEnum());
+ assert(33 === $m->getOptionalMessage()->getA());
+
+ if (PHP_INT_SIZE == 4) {
+ assert('-43' === $m->getRepeatedInt64()[0]);
+ assert('43' === $m->getRepeatedUint64()[0]);
+ assert('-45' === $m->getRepeatedSint64()[0]);
+ assert('47' === $m->getRepeatedFixed64()[0]);
+ assert('-47' === $m->getRepeatedSfixed64()[0]);
+ } else {
+ assert(-43 === $m->getRepeatedInt64()[0]);
+ assert(43 === $m->getRepeatedUint64()[0]);
+ assert(-45 === $m->getRepeatedSint64()[0]);
+ assert(47 === $m->getRepeatedFixed64()[0]);
+ assert(-47 === $m->getRepeatedSfixed64()[0]);
+ }
+ assert(-42 === $m->getRepeatedInt32()[0]);
+ assert(42 === $m->getRepeatedUint32()[0]);
+ assert(-44 === $m->getRepeatedSint32()[0]);
+ assert(46 === $m->getRepeatedFixed32()[0]);
+ assert(-46 === $m->getRepeatedSfixed32()[0]);
+ assert(1.5 === $m->getRepeatedFloat()[0]);
+ assert(1.6 === $m->getRepeatedDouble()[0]);
+ assert(true=== $m->getRepeatedBool()[0]);
+ assert('a' === $m->getRepeatedString()[0]);
+ assert('bbbb' === $m->getRepeatedBytes()[0]);
+ assert(TestEnum::ZERO === $m->getRepeatedEnum()[0]);
+ assert(34 === $m->getRepeatedMessage()[0]->getA());
+
+ if (PHP_INT_SIZE == 4) {
+ assert('-53' === $m->getRepeatedInt64()[1]);
+ assert('53' === $m->getRepeatedUint64()[1]);
+ assert('-55' === $m->getRepeatedSint64()[1]);
+ assert('57' === $m->getRepeatedFixed64()[1]);
+ assert('-57' === $m->getRepeatedSfixed64()[1]);
+ } else {
+ assert(-53 === $m->getRepeatedInt64()[1]);
+ assert(53 === $m->getRepeatedUint64()[1]);
+ assert(-55 === $m->getRepeatedSint64()[1]);
+ assert(57 === $m->getRepeatedFixed64()[1]);
+ assert(-57 === $m->getRepeatedSfixed64()[1]);
+ }
+ assert(-52 === $m->getRepeatedInt32()[1]);
+ assert(52 === $m->getRepeatedUint32()[1]);
+ assert(-54 === $m->getRepeatedSint32()[1]);
+ assert(56 === $m->getRepeatedFixed32()[1]);
+ assert(-56 === $m->getRepeatedSfixed32()[1]);
+ assert(2.5 === $m->getRepeatedFloat()[1]);
+ assert(2.6 === $m->getRepeatedDouble()[1]);
+ assert(false === $m->getRepeatedBool()[1]);
+ assert('c' === $m->getRepeatedString()[1]);
+ assert('dddd' === $m->getRepeatedBytes()[1]);
+ assert(TestEnum::ONE === $m->getRepeatedEnum()[1]);
+ assert(35 === $m->getRepeatedMessage()[1]->getA());
+
+ if (PHP_INT_SIZE == 4) {
+ assert('-63' === $m->getMapInt64Int64()['-63']);
+ assert('63' === $m->getMapUint64Uint64()['63']);
+ assert('-65' === $m->getMapSint64Sint64()['-65']);
+ assert('67' === $m->getMapFixed64Fixed64()['67']);
+ assert('-69' === $m->getMapSfixed64Sfixed64()['-69']);
+ } else {
+ assert(-63 === $m->getMapInt64Int64()[-63]);
+ assert(63 === $m->getMapUint64Uint64()[63]);
+ assert(-65 === $m->getMapSint64Sint64()[-65]);
+ assert(67 === $m->getMapFixed64Fixed64()[67]);
+ assert(-69 === $m->getMapSfixed64Sfixed64()[-69]);
+ }
+ assert(-62 === $m->getMapInt32Int32()[-62]);
+ assert(62 === $m->getMapUint32Uint32()[62]);
+ assert(-64 === $m->getMapSint32Sint32()[-64]);
+ assert(66 === $m->getMapFixed32Fixed32()[66]);
+ assert(-68 === $m->getMapSfixed32Sfixed32()[-68]);
+ assert(3.5 === $m->getMapInt32Float()[1]);
+ assert(3.6 === $m->getMapInt32Double()[1]);
+ assert(true === $m->getMapBoolBool()[true]);
+ assert('e' === $m->getMapStringString()['e']);
+ assert('ffff' === $m->getMapInt32Bytes()[1]);
+ assert(TestEnum::ONE === $m->getMapInt32Enum()[1]);
+ assert(36 === $m->getMapInt32Message()[1]->GetA());
+ }
+
+ public static function getGoldenTestMessage()
+ {
+ return hex2bin(
+ "08D6FFFFFFFFFFFFFFFF01" .
+ "10D5FFFFFFFFFFFFFFFF01" .
+ "182A" .
+ "202B" .
+ "2857" .
+ "3059" .
+ "3D2E000000" .
+ "412F00000000000000" .
+ "4DD2FFFFFF" .
+ "51D1FFFFFFFFFFFFFF" .
+ "5D0000C03F" .
+ "619A9999999999F93F" .
+ "6801" .
+ "720161" .
+ "7A0462626262" .
+ "800101" .
+ "8A01020821" .
+
+ "F801D6FFFFFFFFFFFFFFFF01" .
+ "F801CCFFFFFFFFFFFFFFFF01" .
+ "8002D5FFFFFFFFFFFFFFFF01" .
+ "8002CBFFFFFFFFFFFFFFFF01" .
+ "88022A" .
+ "880234" .
+ "90022B" .
+ "900235" .
+ "980257" .
+ "98026B" .
+ "A00259" .
+ "A0026D" .
+ "AD022E000000" .
+ "AD0238000000" .
+ "B1022F00000000000000" .
+ "B1023900000000000000" .
+ "BD02D2FFFFFF" .
+ "BD02C8FFFFFF" .
+ "C102D1FFFFFFFFFFFFFF" .
+ "C102C7FFFFFFFFFFFFFF" .
+ "CD020000C03F" .
+ "CD0200002040" .
+ "D1029A9999999999F93F" .
+ "D102CDCCCCCCCCCC0440" .
+ "D80201" .
+ "D80200" .
+ "E2020161" .
+ "E2020163" .
+ "EA020462626262" .
+ "EA020464646464" .
+ "F00200" .
+ "F00201" .
+ "FA02020822" .
+ "FA02020823" .
+
+ "BA041608C2FFFFFFFFFFFFFFFF0110C2FFFFFFFFFFFFFFFF01" .
+ "C2041608C1FFFFFFFFFFFFFFFF0110C1FFFFFFFFFFFFFFFF01" .
+ "CA0404083E103E" .
+ "D20404083F103F" .
+ "DA0404087f107F" .
+ "E20406088101108101" .
+ "EA040A0D420000001542000000" .
+ "F20412094300000000000000114300000000000000" .
+ "FA040A0DBCFFFFFF15BCFFFFFF" .
+ "82051209BBFFFFFFFFFFFFFF11BBFFFFFFFFFFFFFF" .
+ "8A050708011500006040" .
+ "92050B080111CDCCCCCCCCCC0C40" .
+ "9A050408011001" .
+ "A205060a0165120165" .
+ "AA05080801120466666666" .
+ "B2050408011001" .
+ "Ba0506080112020824"
+ );
+ }
+
+ public static function setTestPackedMessage($m)
+ {
+ self::appendHelper($m, 'RepeatedInt32', -42);
+ self::appendHelper($m, 'RepeatedInt32', -52);
+ self::appendHelper($m, 'RepeatedInt64', -43);
+ self::appendHelper($m, 'RepeatedInt64', -53);
+ self::appendHelper($m, 'RepeatedUint32', 42);
+ self::appendHelper($m, 'RepeatedUint32', 52);
+ self::appendHelper($m, 'RepeatedUint64', 43);
+ self::appendHelper($m, 'RepeatedUint64', 53);
+ self::appendHelper($m, 'RepeatedSint32', -44);
+ self::appendHelper($m, 'RepeatedSint32', -54);
+ self::appendHelper($m, 'RepeatedSint64', -45);
+ self::appendHelper($m, 'RepeatedSint64', -55);
+ self::appendHelper($m, 'RepeatedFixed32', 46);
+ self::appendHelper($m, 'RepeatedFixed32', 56);
+ self::appendHelper($m, 'RepeatedFixed64', 47);
+ self::appendHelper($m, 'RepeatedFixed64', 57);
+ self::appendHelper($m, 'RepeatedSfixed32', -46);
+ self::appendHelper($m, 'RepeatedSfixed32', -56);
+ self::appendHelper($m, 'RepeatedSfixed64', -47);
+ self::appendHelper($m, 'RepeatedSfixed64', -57);
+ self::appendHelper($m, 'RepeatedFloat', 1.5);
+ self::appendHelper($m, 'RepeatedFloat', 2.5);
+ self::appendHelper($m, 'RepeatedDouble', 1.6);
+ self::appendHelper($m, 'RepeatedDouble', 2.6);
+ self::appendHelper($m, 'RepeatedBool', true);
+ self::appendHelper($m, 'RepeatedBool', false);
+ self::appendHelper($m, 'RepeatedEnum', TestEnum::ONE);
+ self::appendHelper($m, 'RepeatedEnum', TestEnum::ZERO);
+ }
+
+ public static function assertTestPackedMessage($m)
+ {
+ assert(2 === count($m->getRepeatedInt32()));
+ assert(2 === count($m->getRepeatedInt64()));
+ assert(2 === count($m->getRepeatedUint32()));
+ assert(2 === count($m->getRepeatedUint64()));
+ assert(2 === count($m->getRepeatedSint32()));
+ assert(2 === count($m->getRepeatedSint64()));
+ assert(2 === count($m->getRepeatedFixed32()));
+ assert(2 === count($m->getRepeatedFixed64()));
+ assert(2 === count($m->getRepeatedSfixed32()));
+ assert(2 === count($m->getRepeatedSfixed64()));
+ assert(2 === count($m->getRepeatedFloat()));
+ assert(2 === count($m->getRepeatedDouble()));
+ assert(2 === count($m->getRepeatedBool()));
+ assert(2 === count($m->getRepeatedEnum()));
+
+ assert(-42 === $m->getRepeatedInt32()[0]);
+ assert(-52 === $m->getRepeatedInt32()[1]);
+ assert(42 === $m->getRepeatedUint32()[0]);
+ assert(52 === $m->getRepeatedUint32()[1]);
+ assert(-44 === $m->getRepeatedSint32()[0]);
+ assert(-54 === $m->getRepeatedSint32()[1]);
+ assert(46 === $m->getRepeatedFixed32()[0]);
+ assert(56 === $m->getRepeatedFixed32()[1]);
+ assert(-46 === $m->getRepeatedSfixed32()[0]);
+ assert(-56 === $m->getRepeatedSfixed32()[1]);
+ assert(1.5 === $m->getRepeatedFloat()[0]);
+ assert(2.5 === $m->getRepeatedFloat()[1]);
+ assert(1.6 === $m->getRepeatedDouble()[0]);
+ assert(2.6 === $m->getRepeatedDouble()[1]);
+ assert(true === $m->getRepeatedBool()[0]);
+ assert(false === $m->getRepeatedBool()[1]);
+ assert(TestEnum::ONE === $m->getRepeatedEnum()[0]);
+ assert(TestEnum::ZERO === $m->getRepeatedEnum()[1]);
+ if (PHP_INT_SIZE == 4) {
+ assert('-43' === $m->getRepeatedInt64()[0]);
+ assert('-53' === $m->getRepeatedInt64()[1]);
+ assert('43' === $m->getRepeatedUint64()[0]);
+ assert('53' === $m->getRepeatedUint64()[1]);
+ assert('-45' === $m->getRepeatedSint64()[0]);
+ assert('-55' === $m->getRepeatedSint64()[1]);
+ assert('47' === $m->getRepeatedFixed64()[0]);
+ assert('57' === $m->getRepeatedFixed64()[1]);
+ assert('-47' === $m->getRepeatedSfixed64()[0]);
+ assert('-57' === $m->getRepeatedSfixed64()[1]);
+ } else {
+ assert(-43 === $m->getRepeatedInt64()[0]);
+ assert(-53 === $m->getRepeatedInt64()[1]);
+ assert(43 === $m->getRepeatedUint64()[0]);
+ assert(53 === $m->getRepeatedUint64()[1]);
+ assert(-45 === $m->getRepeatedSint64()[0]);
+ assert(-55 === $m->getRepeatedSint64()[1]);
+ assert(47 === $m->getRepeatedFixed64()[0]);
+ assert(57 === $m->getRepeatedFixed64()[1]);
+ assert(-47 === $m->getRepeatedSfixed64()[0]);
+ assert(-57 === $m->getRepeatedSfixed64()[1]);
+ }
+ }
+
+ public static function getGoldenTestPackedMessage()
+ {
+ return hex2bin(
+ "D20514D6FFFFFFFFFFFFFFFF01CCFFFFFFFFFFFFFFFF01" .
+ "DA0514D5FFFFFFFFFFFFFFFF01CBFFFFFFFFFFFFFFFF01" .
+ "E205022A34" .
+ "EA05022B35" .
+ "F20502576B" .
+ "FA0502596D" .
+ "8206082E00000038000000" .
+ "8A06102F000000000000003900000000000000" .
+ "920608D2FFFFFFC8FFFFFF" .
+ "9A0610D1FFFFFFFFFFFFFFC7FFFFFFFFFFFFFF" .
+ "A206080000C03F00002040" .
+ "AA06109A9999999999F93FCDCCCCCCCCCC0440" .
+ "B206020100" .
+ "BA06020100"
+ );
+ }
+
+ public static function getGoldenTestUnpackedMessage()
+ {
+ return hex2bin(
+ "D005D6FFFFFFFFFFFFFFFF01D005CCFFFFFFFFFFFFFFFF01" .
+ "D805D5FFFFFFFFFFFFFFFF01D805CBFFFFFFFFFFFFFFFF01" .
+ "E0052AE00534" .
+ "E8052BE80535" .
+ "F00557F0056B" .
+ "F80559F8056D" .
+ "85062E000000850638000000" .
+ "89062F0000000000000089063900000000000000" .
+ "9506D2FFFFFF9506C8FFFFFF" .
+ "9906D1FFFFFFFFFFFFFF9906C7FFFFFFFFFFFFFF" .
+ "A5060000C03FA50600002040" .
+ "A9069A9999999999F93FA906CDCCCCCCCCCC0440" .
+ "B00601B00600" .
+ "B80601B80600"
+ );
+ }
+
+ private static function appendHelper($obj, $func_suffix, $value)
+ {
+ $getter_function = 'get'.$func_suffix;
+ $setter_function = 'set'.$func_suffix;
+
+ $arr = $obj->$getter_function();
+ $arr[] = $value;
+ $obj->$setter_function($arr);
+ }
+
+ private static function kvUpdateHelper($obj, $func_suffix, $key, $value)
+ {
+ $getter_function = 'get'.$func_suffix;
+ $setter_function = 'set'.$func_suffix;
+
+ $arr = $obj->$getter_function();
+ $arr[$key] = $value;
+ $obj->$setter_function($arr);
+ }
+}
diff --git a/third_party/protobuf/php/tests/undefined_test.php b/third_party/protobuf/php/tests/undefined_test.php
new file mode 100644
index 0000000..935d8be
--- /dev/null
+++ b/third_party/protobuf/php/tests/undefined_test.php
@@ -0,0 +1,920 @@
+<?php
+
+require_once('test_util.php');
+
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBType;
+use Foo\TestMessage;
+use Foo\TestMessage\Sub;
+
+class UndefinedTest extends PHPUnit_Framework_TestCase
+{
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt32AppendStringFail()
+ {
+ $arr = new RepeatedField(GPBType::INT32);
+ $arr[] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt32SetStringFail()
+ {
+ $arr = new RepeatedField(GPBType::INT32);
+ $arr[] = 0;
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt32AppendMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::INT32);
+ $arr[] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt32SetMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::INT32);
+ $arr[] = 0;
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint32AppendStringFail()
+ {
+ $arr = new RepeatedField(GPBType::UINT32);
+ $arr[] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint32SetStringFail()
+ {
+ $arr = new RepeatedField(GPBType::UINT32);
+ $arr[] = 0;
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint32AppendMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::UINT32);
+ $arr[] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint32SetMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::UINT32);
+ $arr[] = 0;
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt64AppendStringFail()
+ {
+ $arr = new RepeatedField(GPBType::INT64);
+ $arr[] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt64SetStringFail()
+ {
+ $arr = new RepeatedField(GPBType::INT64);
+ $arr[] = 0;
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt64AppendMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::INT64);
+ $arr[] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt64SetMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::INT64);
+ $arr[] = 0;
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint64AppendStringFail()
+ {
+ $arr = new RepeatedField(GPBType::UINT64);
+ $arr[] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint64SetStringFail()
+ {
+ $arr = new RepeatedField(GPBType::UINT64);
+ $arr[] = 0;
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint64AppendMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::UINT64);
+ $arr[] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint64SetMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::UINT64);
+ $arr[] = 0;
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testFloatAppendStringFail()
+ {
+ $arr = new RepeatedField(GPBType::FLOAT);
+ $arr[] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testFloatSetStringFail()
+ {
+ $arr = new RepeatedField(GPBType::FLOAT);
+ $arr[] = 0.0;
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testFloatAppendMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::FLOAT);
+ $arr[] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testFloatSetMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::FLOAT);
+ $arr[] = 0.0;
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testDoubleAppendStringFail()
+ {
+ $arr = new RepeatedField(GPBType::DOUBLE);
+ $arr[] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testDoubleSetStringFail()
+ {
+ $arr = new RepeatedField(GPBType::DOUBLE);
+ $arr[] = 0.0;
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testDoubleAppendMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::DOUBLE);
+ $arr[] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testDoubleSetMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::DOUBLE);
+ $arr[] = 0.0;
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testBoolAppendMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::BOOL);
+ $arr[] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testBoolSetMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::BOOL);
+ $arr[] = true;
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testStringAppendMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::STRING);
+ $arr[] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testStringSetMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::STRING);
+ $arr[] = 'abc';
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testStringAppendInvalidUTF8Fail()
+ {
+ $arr = new RepeatedField(GPBType::STRING);
+ $hex = hex2bin("ff");
+ $arr[] = $hex;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testStringSetInvalidUTF8Fail()
+ {
+ $arr = new RepeatedField(GPBType::STRING);
+ $arr[] = 'abc';
+ $hex = hex2bin("ff");
+ $arr[0] = $hex;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageAppendIntFail()
+ {
+ $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+ $arr[] = 1;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageSetIntFail()
+ {
+ $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+ $arr[] = new Sub;
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageAppendStringFail()
+ {
+ $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+ $arr[] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageSetStringFail()
+ {
+ $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+ $arr[] = new Sub;
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageAppendOtherMessageFail()
+ {
+ $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+ $arr[] = new TestMessage;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageAppendNullFail()
+ {
+ $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+ $null = null;
+ $arr[] = $null;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageSetNullFail()
+ {
+ $arr = new RepeatedField(GPBType::MESSAGE, Sub::class);
+ $arr[] = new Sub();
+ $null = null;
+ $arr[0] = $null;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testRemoveMiddleFail()
+ {
+ $arr = new RepeatedField(GPBType::INT32);
+
+ $arr[] = 0;
+ $arr[] = 1;
+ $arr[] = 2;
+ $this->assertSame(3, count($arr));
+
+ unset($arr[1]);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testRemoveEmptyFail()
+ {
+ $arr = new RepeatedField(GPBType::INT32);
+
+ unset($arr[0]);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageOffsetFail()
+ {
+ $arr = new RepeatedField(GPBType::INT32);
+ $arr[] = 0;
+ $arr[new Sub()] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testStringOffsetFail()
+ {
+ $arr = new RepeatedField(GPBType::INT32);
+ $arr[] = 0;
+ $arr['abc'] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testSetNonExistedOffsetFail()
+ {
+ $arr = new RepeatedField(GPBType::INT32);
+ $arr[0] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt32FieldInvalidTypeFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalInt32(new TestMessage());
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt32FieldInvalidStringFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalInt32('abc');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint32FieldInvalidTypeFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalUint32(new TestMessage());
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint32FieldInvalidStringFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalUint32('abc');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt64FieldInvalidTypeFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalInt64(new TestMessage());
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt64FieldInvalidStringFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalInt64('abc');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint64FieldInvalidTypeFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalUint64(new TestMessage());
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint64FieldInvalidStringFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalUint64('abc');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testFloatFieldInvalidTypeFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalFloat(new TestMessage());
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testFloatFieldInvalidStringFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalFloat('abc');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testDoubleFieldInvalidTypeFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalDouble(new TestMessage());
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testDoubleFieldInvalidStringFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalDouble('abc');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testBoolFieldInvalidStringFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalBool(new TestMessage());
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testStringFieldInvalidUTF8Fail()
+ {
+ $m = new TestMessage();
+ $hex = hex2bin("ff");
+ $m->setOptionalString($hex);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageFieldWrongTypeFail()
+ {
+ $m = new TestMessage();
+ $a = 1;
+ $m->setOptionalMessage($a);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageFieldWrongClassFail()
+ {
+ $m = new TestMessage();
+ $m->setOptionalMessage(new TestMessage());
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testRepeatedFieldWrongTypeFail()
+ {
+ $m = new TestMessage();
+ $a = 1;
+ $m->setRepeatedInt32($a);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testRepeatedFieldWrongObjectFail()
+ {
+ $m = new TestMessage();
+ $m->setRepeatedInt32($m);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testRepeatedFieldWrongRepeatedTypeFail()
+ {
+ $m = new TestMessage();
+
+ $repeated_int32 = new RepeatedField(GPBType::UINT32);
+ $m->setRepeatedInt32($repeated_int32);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testRepeatedFieldWrongRepeatedMessageClassFail()
+ {
+ $m = new TestMessage();
+
+ $repeated_message = new RepeatedField(GPBType::MESSAGE,
+ TestMessage::class);
+ $m->setRepeatedMessage($repeated_message);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMapFieldWrongTypeFail()
+ {
+ $m = new TestMessage();
+ $a = 1;
+ $m->setMapInt32Int32($a);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMapFieldWrongObjectFail()
+ {
+ $m = new TestMessage();
+ $m->setMapInt32Int32($m);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMapFieldWrongRepeatedTypeFail()
+ {
+ $m = new TestMessage();
+
+ $map_uint32_uint32 = new MapField(GPBType::UINT32, GPBType::UINT32);
+ $m->setMapInt32Int32($map_uint32_uint32);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMapFieldWrongRepeatedMessageClassFail()
+ {
+ $m = new TestMessage();
+
+ $map_int32_message = new MapField(GPBType::INT32,
+ GPBType::MESSAGE,
+ TestMessage::class);
+ $m->setMapInt32Message($map_int32_message);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageMergeFromInvalidTypeFail()
+ {
+ $m = new TestMessage();
+ $n = new Sub();
+ $m->mergeFrom($n);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt32SetStringKeyFail()
+ {
+ $arr = new MapField(GPBType::INT32, GPBType::INT32);
+ $arr['abc'] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt32SetStringValueFail()
+ {
+ $arr = new MapField(GPBType::INT32, GPBType::INT32);
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt32SetMessageKeyFail()
+ {
+ $arr = new MapField(GPBType::INT32, GPBType::INT32);
+ $arr[new Sub()] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt32SetMessageValueFail()
+ {
+ $arr = new MapField(GPBType::INT32, GPBType::INT32);
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint32SetStringKeyFail()
+ {
+ $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
+ $arr['abc'] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint32SetStringValueFail()
+ {
+ $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint32SetMessageKeyFail()
+ {
+ $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
+ $arr[new Sub()] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint32SetMessageValueFail()
+ {
+ $arr = new MapField(GPBType::UINT32, GPBType::UINT32);
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt64SetStringKeyFail()
+ {
+ $arr = new MapField(GPBType::INT64, GPBType::INT64);
+ $arr['abc'] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt64SetStringValueFail()
+ {
+ $arr = new MapField(GPBType::INT64, GPBType::INT64);
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt64SetMessageKeyFail()
+ {
+ $arr = new MapField(GPBType::INT64, GPBType::INT64);
+ $arr[new Sub()] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testInt64SetMessageValueFail()
+ {
+ $arr = new MapField(GPBType::INT64, GPBType::INT64);
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint64SetStringKeyFail()
+ {
+ $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
+ $arr['abc'] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint64SetStringValueFail()
+ {
+ $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint64SetMessageKeyFail()
+ {
+ $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
+ $arr[new Sub()] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testUint64SetMessageValueFail()
+ {
+ $arr = new MapField(GPBType::UINT64, GPBType::UINT64);
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testDoubleSetStringValueFail()
+ {
+ $arr = new MapField(GPBType::INT64, GPBType::DOUBLE);
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testDoubleSetMessageValueFail()
+ {
+ $arr = new MapField(GPBType::INT64, GPBType::DOUBLE);
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testBoolSetMessageKeyFail()
+ {
+ $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
+ $arr[new Sub()] = true;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testBoolSetMessageValueFail()
+ {
+ $arr = new MapField(GPBType::BOOL, GPBType::BOOL);
+ $arr[true] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testStringSetInvalidUTF8KeyFail()
+ {
+ $arr = new MapField(GPBType::STRING, GPBType::STRING);
+ $arr[hex2bin("ff")] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testStringSetInvalidUTF8ValueFail()
+ {
+ $arr = new MapField(GPBType::STRING, GPBType::STRING);
+ $arr['abc'] = hex2bin("ff");
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testStringSetMessageKeyFail()
+ {
+ $arr = new MapField(GPBType::STRING, GPBType::STRING);
+ $arr[new Sub()] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testStringSetMessageValueFail()
+ {
+ $arr = new MapField(GPBType::STRING, GPBType::STRING);
+ $arr['abc'] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageSetIntValueFail()
+ {
+ $arr =
+ new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
+ $arr[0] = 0;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageSetStringValueFail()
+ {
+ $arr =
+ new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
+ $arr[0] = 'abc';
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageSetOtherMessageValueFail()
+ {
+ $arr =
+ new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
+ $arr[0] = new Sub();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testMessageSetNullFailMap()
+ {
+ $arr =
+ new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
+ $null = NULL;
+ $arr[0] = $null;
+ }
+
+}
diff --git a/third_party/protobuf/php/tests/well_known_test.php b/third_party/protobuf/php/tests/well_known_test.php
new file mode 100644
index 0000000..a16e070
--- /dev/null
+++ b/third_party/protobuf/php/tests/well_known_test.php
@@ -0,0 +1,419 @@
+<?php
+
+require_once('test_base.php');
+require_once('test_util.php');
+
+use Foo\TestMessage;
+use Google\Protobuf\Any;
+use Google\Protobuf\Api;
+use Google\Protobuf\BoolValue;
+use Google\Protobuf\BytesValue;
+use Google\Protobuf\DoubleValue;
+use Google\Protobuf\Duration;
+use Google\Protobuf\Enum;
+use Google\Protobuf\EnumValue;
+use Google\Protobuf\Field;
+use Google\Protobuf\FieldMask;
+use Google\Protobuf\Field\Cardinality;
+use Google\Protobuf\Field\Kind;
+use Google\Protobuf\FloatValue;
+use Google\Protobuf\GPBEmpty;
+use Google\Protobuf\Int32Value;
+use Google\Protobuf\Int64Value;
+use Google\Protobuf\ListValue;
+use Google\Protobuf\Method;
+use Google\Protobuf\Mixin;
+use Google\Protobuf\NullValue;
+use Google\Protobuf\Option;
+use Google\Protobuf\SourceContext;
+use Google\Protobuf\StringValue;
+use Google\Protobuf\Struct;
+use Google\Protobuf\Syntax;
+use Google\Protobuf\Timestamp;
+use Google\Protobuf\Type;
+use Google\Protobuf\UInt32Value;
+use Google\Protobuf\UInt64Value;
+use Google\Protobuf\Value;
+
+class NotMessage {}
+
+class WellKnownTest extends TestBase {
+
+ public function testEmpty()
+ {
+ $msg = new GPBEmpty();
+ $this->assertTrue($msg instanceof \Google\Protobuf\Internal\Message);
+ }
+
+ public function testImportDescriptorProto()
+ {
+ $msg = new TestImportDescriptorProto();
+ $this->assertTrue(true);
+ }
+
+ public function testAny()
+ {
+ // Create embed message
+ $embed = new TestMessage();
+ $this->setFields($embed);
+ $data = $embed->serializeToString();
+
+ // Set any via normal setter.
+ $any = new Any();
+
+ $this->assertSame(
+ $any, $any->setTypeUrl("type.googleapis.com/foo.TestMessage"));
+ $this->assertSame("type.googleapis.com/foo.TestMessage",
+ $any->getTypeUrl());
+
+ $this->assertSame($any, $any->setValue($data));
+ $this->assertSame($data, $any->getValue());
+
+ // Test unpack.
+ $msg = $any->unpack();
+ $this->assertTrue($msg instanceof TestMessage);
+ $this->expectFields($msg);
+
+ // Test pack.
+ $any = new Any();
+ $any->pack($embed);
+ $this->assertSame($data, $any->getValue());
+ $this->assertSame("type.googleapis.com/foo.TestMessage", $any->getTypeUrl());
+
+ // Test is.
+ $this->assertTrue($any->is(TestMessage::class));
+ $this->assertFalse($any->is(Any::class));
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testAnyUnpackInvalidTypeUrl()
+ {
+ $any = new Any();
+ $any->setTypeUrl("invalid");
+ $any->unpack();
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testAnyUnpackMessageNotAdded()
+ {
+ $any = new Any();
+ $any->setTypeUrl("type.googleapis.com/MessageNotAdded");
+ $any->unpack();
+ }
+
+ /**
+ * @expectedException Exception
+ */
+ public function testAnyUnpackDecodeError()
+ {
+ $any = new Any();
+ $any->setTypeUrl("type.googleapis.com/foo.TestMessage");
+ $any->setValue("abc");
+ $any->unpack();
+ }
+
+ public function testApi()
+ {
+ $m = new Api();
+
+ $m->setName("a");
+ $this->assertSame("a", $m->getName());
+
+ $m->setMethods([new Method()]);
+ $this->assertSame(1, count($m->getMethods()));
+
+ $m->setOptions([new Option()]);
+ $this->assertSame(1, count($m->getOptions()));
+
+ $m->setVersion("a");
+ $this->assertSame("a", $m->getVersion());
+
+ $m->setSourceContext(new SourceContext());
+ $this->assertFalse(is_null($m->getSourceContext()));
+
+ $m->setMixins([new Mixin()]);
+ $this->assertSame(1, count($m->getMixins()));
+
+ $m->setSyntax(Syntax::SYNTAX_PROTO2);
+ $this->assertSame(Syntax::SYNTAX_PROTO2, $m->getSyntax());
+
+ $m = new Method();
+
+ $m->setName("a");
+ $this->assertSame("a", $m->getName());
+
+ $m->setRequestTypeUrl("a");
+ $this->assertSame("a", $m->getRequestTypeUrl());
+
+ $m->setRequestStreaming(true);
+ $this->assertSame(true, $m->getRequestStreaming());
+
+ $m->setResponseTypeUrl("a");
+ $this->assertSame("a", $m->getResponseTypeUrl());
+
+ $m->setResponseStreaming(true);
+ $this->assertSame(true, $m->getResponseStreaming());
+
+ $m->setOptions([new Option()]);
+ $this->assertSame(1, count($m->getOptions()));
+
+ $m = new Mixin();
+
+ $m->setName("a");
+ $this->assertSame("a", $m->getName());
+
+ $m->setRoot("a");
+ $this->assertSame("a", $m->getRoot());
+ }
+
+ public function testEnum()
+ {
+ $m = new Enum();
+
+ $m->setName("a");
+ $this->assertSame("a", $m->getName());
+
+ $m->setEnumvalue([new EnumValue()]);
+ $this->assertSame(1, count($m->getEnumvalue()));
+
+ $m->setOptions([new Option()]);
+ $this->assertSame(1, count($m->getOptions()));
+
+ $m->setSourceContext(new SourceContext());
+ $this->assertFalse(is_null($m->getSourceContext()));
+
+ $m->setSyntax(Syntax::SYNTAX_PROTO2);
+ $this->assertSame(Syntax::SYNTAX_PROTO2, $m->getSyntax());
+ }
+
+ public function testEnumValue()
+ {
+ $m = new EnumValue();
+
+ $m->setName("a");
+ $this->assertSame("a", $m->getName());
+
+ $m->setNumber(1);
+ $this->assertSame(1, $m->getNumber());
+
+ $m->setOptions([new Option()]);
+ $this->assertSame(1, count($m->getOptions()));
+ }
+
+ public function testField()
+ {
+ $m = new Field();
+
+ $m->setKind(Kind::TYPE_DOUBLE);
+ $this->assertSame(Kind::TYPE_DOUBLE, $m->getKind());
+
+ $m->setCardinality(Cardinality::CARDINALITY_OPTIONAL);
+ $this->assertSame(Cardinality::CARDINALITY_OPTIONAL, $m->getCardinality());
+
+ $m->setNumber(1);
+ $this->assertSame(1, $m->getNumber());
+
+ $m->setName("a");
+ $this->assertSame("a", $m->getName());
+
+ $m->setTypeUrl("a");
+ $this->assertSame("a", $m->getTypeUrl());
+
+ $m->setOneofIndex(1);
+ $this->assertSame(1, $m->getOneofIndex());
+
+ $m->setPacked(true);
+ $this->assertSame(true, $m->getPacked());
+
+ $m->setOptions([new Option()]);
+ $this->assertSame(1, count($m->getOptions()));
+
+ $m->setJsonName("a");
+ $this->assertSame("a", $m->getJsonName());
+
+ $m->setDefaultValue("a");
+ $this->assertSame("a", $m->getDefaultValue());
+ }
+
+ public function testFieldMask()
+ {
+ $m = new FieldMask();
+ $m->setPaths(["a"]);
+ $this->assertSame(1, count($m->getPaths()));
+ }
+
+ public function testOption()
+ {
+ $m = new Option();
+
+ $m->setName("a");
+ $this->assertSame("a", $m->getName());
+
+ $m->setValue(new Any());
+ $this->assertFalse(is_null($m->getValue()));
+ }
+
+ public function testSourceContext()
+ {
+ $m = new SourceContext();
+ $m->setFileName("a");
+ $this->assertSame("a", $m->getFileName());
+ }
+
+ public function testStruct()
+ {
+ $m = new ListValue();
+ $m->setValues([new Value()]);
+ $this->assertSame(1, count($m->getValues()));
+
+ $m = new Value();
+
+ $m->setNullValue(NullValue::NULL_VALUE);
+ $this->assertSame(NullValue::NULL_VALUE, $m->getNullValue());
+ $this->assertSame("null_value", $m->getKind());
+
+ $m->setNumberValue(1.0);
+ $this->assertSame(1.0, $m->getNumberValue());
+ $this->assertSame("number_value", $m->getKind());
+
+ $m->setStringValue("a");
+ $this->assertSame("a", $m->getStringValue());
+ $this->assertSame("string_value", $m->getKind());
+
+ $m->setBoolValue(true);
+ $this->assertSame(true, $m->getBoolValue());
+ $this->assertSame("bool_value", $m->getKind());
+
+ $m->setStructValue(new Struct());
+ $this->assertFalse(is_null($m->getStructValue()));
+ $this->assertSame("struct_value", $m->getKind());
+
+ $m->setListValue(new ListValue());
+ $this->assertFalse(is_null($m->getListValue()));
+ $this->assertSame("list_value", $m->getKind());
+
+ $m = new Struct();
+ $m->setFields(array("a"=>new Value()));
+ $this->assertSame(1, count($m->getFields()));
+ }
+
+ public function testTimestamp()
+ {
+ $timestamp = new Timestamp();
+
+ $timestamp->setSeconds(1);
+ $timestamp->setNanos(2);
+ $this->assertEquals(1, $timestamp->getSeconds());
+ $this->assertSame(2, $timestamp->getNanos());
+
+ date_default_timezone_set('UTC');
+ $from = new DateTime('2011-01-01T15:03:01.012345UTC');
+ $timestamp->fromDateTime($from);
+ $this->assertEquals($from->format('U'), $timestamp->getSeconds());
+ $this->assertEquals(1000 * $from->format('u'), $timestamp->getNanos());
+
+ $to = $timestamp->toDateTime();
+ $this->assertSame(\DateTime::class, get_class($to));
+ $this->assertSame($from->format('U'), $to->format('U'));
+ $this->assertSame($from->format('u'), $to->format('u'));
+ }
+
+ public function testType()
+ {
+ $m = new Type();
+
+ $m->setName("a");
+ $this->assertSame("a", $m->getName());
+
+ $m->setFields([new Field()]);
+ $this->assertSame(1, count($m->getFields()));
+
+ $m->setOneofs(["a"]);
+ $this->assertSame(1, count($m->getOneofs()));
+
+ $m->setOptions([new Option()]);
+ $this->assertSame(1, count($m->getOptions()));
+
+ $m->setSourceContext(new SourceContext());
+ $this->assertFalse(is_null($m->getSourceContext()));
+
+ $m->setSyntax(Syntax::SYNTAX_PROTO2);
+ $this->assertSame(Syntax::SYNTAX_PROTO2, $m->getSyntax());
+ }
+
+ public function testDuration()
+ {
+ $duration = new Duration();
+
+ $duration->setSeconds(1);
+ $duration->setNanos(2);
+ $this->assertEquals(1, $duration->getSeconds());
+ $this->assertSame(2, $duration->getNanos());
+ }
+
+ public function testWrappers()
+ {
+ $m = new DoubleValue();
+ $m->setValue(1.0);
+ $this->assertSame(1.0, $m->getValue());
+
+ $m = new FloatValue();
+ $m->setValue(1.0);
+ $this->assertSame(1.0, $m->getValue());
+
+ $m = new Int64Value();
+ $m->setValue(1);
+ $this->assertEquals(1, $m->getValue());
+
+ $m = new UInt64Value();
+ $m->setValue(1);
+ $this->assertEquals(1, $m->getValue());
+
+ $m = new Int32Value();
+ $m->setValue(1);
+ $this->assertSame(1, $m->getValue());
+
+ $m = new UInt32Value();
+ $m->setValue(1);
+ $this->assertSame(1, $m->getValue());
+
+ $m = new BoolValue();
+ $m->setValue(true);
+ $this->assertSame(true, $m->getValue());
+
+ $m = new StringValue();
+ $m->setValue("a");
+ $this->assertSame("a", $m->getValue());
+
+ $m = new BytesValue();
+ $m->setValue("a");
+ $this->assertSame("a", $m->getValue());
+ }
+
+ /**
+ * @dataProvider enumNameValueConversionDataProvider
+ */
+ public function testEnumNameValueConversion($class)
+ {
+ $reflectionClass = new ReflectionClass($class);
+ $constants = $reflectionClass->getConstants();
+ foreach ($constants as $k => $v) {
+ $this->assertSame($k, $class::name($v));
+ $this->assertSame($v, $class::value($k));
+ }
+ }
+
+ public function enumNameValueConversionDataProvider()
+ {
+ return [
+ ['\Google\Protobuf\Field\Cardinality'],
+ ['\Google\Protobuf\Field\Kind'],
+ ['\Google\Protobuf\NullValue'],
+ ['\Google\Protobuf\Syntax'],
+ ];
+ }
+}
diff --git a/third_party/protobuf/php/tests/wrapper_type_setters_test.php b/third_party/protobuf/php/tests/wrapper_type_setters_test.php
new file mode 100644
index 0000000..ad9f718
--- /dev/null
+++ b/third_party/protobuf/php/tests/wrapper_type_setters_test.php
@@ -0,0 +1,312 @@
+<?php
+
+require_once('test_base.php');
+require_once('test_util.php');
+
+use Foo\TestWrapperSetters;
+use Google\Protobuf\BoolValue;
+use Google\Protobuf\BytesValue;
+use Google\Protobuf\DoubleValue;
+use Google\Protobuf\FloatValue;
+use Google\Protobuf\Int32Value;
+use Google\Protobuf\Int64Value;
+use Google\Protobuf\StringValue;
+use Google\Protobuf\UInt32Value;
+use Google\Protobuf\UInt64Value;
+
+class WrapperTypeSettersTest extends TestBase
+{
+ /**
+ * @dataProvider gettersAndSettersDataProvider
+ */
+ public function testGettersAndSetters(
+ $class,
+ $wrapperClass,
+ $setter,
+ $valueSetter,
+ $getter,
+ $valueGetter,
+ $sequence
+ ) {
+ $oldSetterMsg = new $class();
+ $newSetterMsg = new $class();
+ foreach ($sequence as list($value, $expectedValue)) {
+ // Manually wrap the value to pass to the old setter
+ $wrappedValue = is_null($value) ? $value : new $wrapperClass(['value' => $value]);
+
+ // Set values using new and old setters
+ $oldSetterMsg->$setter($wrappedValue);
+ $newSetterMsg->$valueSetter($value);
+
+ // Get expected values old getter
+ $expectedValue = $oldSetterMsg->$getter();
+
+ // Check that old getter returns the same value after using the
+ // new setter
+ $actualValue = $newSetterMsg->$getter();
+ $this->assertEquals($expectedValue, $actualValue);
+
+ // Check that new getter returns the unwrapped value from
+ // $expectedValue
+ $actualValueNewGetter = $newSetterMsg->$valueGetter();
+ if (is_null($expectedValue)) {
+ $this->assertNull($actualValueNewGetter);
+ } else {
+ $this->assertEquals($expectedValue->getValue(), $actualValueNewGetter);
+ }
+ }
+ }
+
+ public function gettersAndSettersDataProvider()
+ {
+ return [
+ [TestWrapperSetters::class, DoubleValue::class, "setDoubleValue", "setDoubleValueUnwrapped", "getDoubleValue", "getDoubleValueUnwrapped", [
+ [1.1, new DoubleValue(["value" => 1.1])],
+ [2.2, new DoubleValue(["value" => 2.2])],
+ [null, null],
+ [0, new DoubleValue()],
+ ]],
+ [TestWrapperSetters::class, FloatValue::class, "setFloatValue", "setFloatValueUnwrapped", "getFloatValue", "getFloatValueUnwrapped", [
+ [1.1, new FloatValue(["value" => 1.1])],
+ [2.2, new FloatValue(["value" => 2.2])],
+ [null, null],
+ [0, new FloatValue()],
+ ]],
+ [TestWrapperSetters::class, Int64Value::class, "setInt64Value", "setInt64ValueUnwrapped", "getInt64Value", "getInt64ValueUnwrapped", [
+ [123, new Int64Value(["value" => 123])],
+ [-789, new Int64Value(["value" => -789])],
+ [null, null],
+ [0, new Int64Value()],
+ [5.5, new Int64Value(["value" => 5])], // Test conversion from float to int
+ ]],
+ [TestWrapperSetters::class, UInt64Value::class, "setUInt64Value", "setUInt64ValueUnwrapped", "getUInt64Value", "getUInt64ValueUnwrapped", [
+ [123, new UInt64Value(["value" => 123])],
+ [789, new UInt64Value(["value" => 789])],
+ [null, null],
+ [0, new UInt64Value()],
+ [5.5, new UInt64Value(["value" => 5])], // Test conversion from float to int
+ [-7, new UInt64Value(["value" => -7])], // Test conversion from -ve to +ve
+ ]],
+ [TestWrapperSetters::class, Int32Value::class, "setInt32Value", "setInt32ValueUnwrapped", "getInt32Value", "getInt32ValueUnwrapped", [
+ [123, new Int32Value(["value" => 123])],
+ [-789, new Int32Value(["value" => -789])],
+ [null, null],
+ [0, new Int32Value()],
+ [5.5, new Int32Value(["value" => 5])], // Test conversion from float to int
+ ]],
+ [TestWrapperSetters::class, UInt32Value::class, "setUInt32Value", "setUInt32ValueUnwrapped", "getUInt32Value", "getUInt32ValueUnwrapped", [
+ [123, new UInt32Value(["value" => 123])],
+ [789, new UInt32Value(["value" => 789])],
+ [null, null],
+ [0, new UInt32Value()],
+ [5.5, new UInt32Value(["value" => 5])], // Test conversion from float to int
+ [-7, new UInt32Value(["value" => -7])], // Test conversion from -ve to +ve
+ ]],
+ [TestWrapperSetters::class, BoolValue::class, "setBoolValue", "setBoolValueUnwrapped", "getBoolValue", "getBoolValueUnwrapped", [
+ [true, new BoolValue(["value" => true])],
+ [false, new BoolValue(["value" => false])],
+ [null, null],
+ ]],
+ [TestWrapperSetters::class, StringValue::class, "setStringValue", "setStringValueUnwrapped", "getStringValue", "getStringValueUnwrapped", [
+ ["asdf", new StringValue(["value" => "asdf"])],
+ ["", new StringValue(["value" => ""])],
+ [null, null],
+ ["", new StringValue()],
+ [5, new StringValue(["value" => "5"])], // Test conversion from number to string
+ [5.5, new StringValue(["value" => "5.5"])], // Test conversion from number to string
+ [-7, new StringValue(["value" => "-7"])], // Test conversion from number to string
+ [-7.5, new StringValue(["value" => "-7.5"])], // Test conversion from number to string
+ ]],
+ [TestWrapperSetters::class, BytesValue::class, "setBytesValue", "setBytesValueUnwrapped", "getBytesValue", "getBytesValueUnwrapped", [
+ ["asdf", new BytesValue(["value" => "asdf"])],
+ ["", new BytesValue(["value" => ""])],
+ [null, null],
+ ["", new BytesValue()],
+ [5, new BytesValue(["value" => "5"])], // Test conversion from number to bytes
+ [5.5, new BytesValue(["value" => "5.5"])], // Test conversion from number to bytes
+ [-7, new BytesValue(["value" => "-7"])], // Test conversion from number to bytes
+ [-7.5, new BytesValue(["value" => "-7.5"])], // Test conversion from number to bytes
+ ]],
+ [TestWrapperSetters::class, DoubleValue::class, "setDoubleValueOneof", "setDoubleValueOneofUnwrapped", "getDoubleValueOneof", "getDoubleValueOneofUnwrapped", [
+ [1.1, new DoubleValue(["value" => 1.1])],
+ [2.2, new DoubleValue(["value" => 2.2])],
+ [null, null],
+ [0, new DoubleValue()],
+ ]],[TestWrapperSetters::class, StringValue::class, "setStringValueOneof", "setStringValueOneofUnwrapped", "getStringValueOneof", "getStringValueOneofUnwrapped", [
+ ["asdf", new StringValue(["value" => "asdf"])],
+ ["", new StringValue(["value" => ""])],
+ [null, null],
+ ["", new StringValue()],
+ [5, new StringValue(["value" => "5"])], // Test conversion from number to string
+ [5.5, new StringValue(["value" => "5.5"])], // Test conversion from number to string
+ [-7, new StringValue(["value" => "-7"])], // Test conversion from number to string
+ [-7.5, new StringValue(["value" => "-7.5"])], // Test conversion from number to string
+ ]],
+ ];
+ }
+
+ /**
+ * @dataProvider invalidSettersDataProvider
+ * @expectedException \Exception
+ */
+ public function testInvalidSetters($class, $setter, $value)
+ {
+ (new $class())->$setter($value);
+ }
+
+ public function invalidSettersDataProvider()
+ {
+ return [
+ [TestWrapperSetters::class, "setDoubleValueUnwrapped", "abc"],
+ [TestWrapperSetters::class, "setDoubleValueUnwrapped", []],
+ [TestWrapperSetters::class, "setDoubleValueUnwrapped", new stdClass()],
+ [TestWrapperSetters::class, "setDoubleValueUnwrapped", new DoubleValue()],
+
+ [TestWrapperSetters::class, "setFloatValueUnwrapped", "abc"],
+ [TestWrapperSetters::class, "setFloatValueUnwrapped", []],
+ [TestWrapperSetters::class, "setFloatValueUnwrapped", new stdClass()],
+ [TestWrapperSetters::class, "setFloatValueUnwrapped", new FloatValue()],
+
+ [TestWrapperSetters::class, "setInt64ValueUnwrapped", "abc"],
+ [TestWrapperSetters::class, "setInt64ValueUnwrapped", []],
+ [TestWrapperSetters::class, "setInt64ValueUnwrapped", new stdClass()],
+ [TestWrapperSetters::class, "setInt64ValueUnwrapped", new Int64Value()],
+
+ [TestWrapperSetters::class, "setUInt64ValueUnwrapped", "abc"],
+ [TestWrapperSetters::class, "setUInt64ValueUnwrapped", []],
+ [TestWrapperSetters::class, "setUInt64ValueUnwrapped", new stdClass()],
+ [TestWrapperSetters::class, "setUInt64ValueUnwrapped", new UInt64Value()],
+
+ [TestWrapperSetters::class, "setInt32ValueUnwrapped", "abc"],
+ [TestWrapperSetters::class, "setInt32ValueUnwrapped", []],
+ [TestWrapperSetters::class, "setInt32ValueUnwrapped", new stdClass()],
+ [TestWrapperSetters::class, "setInt32ValueUnwrapped", new Int32Value()],
+
+ [TestWrapperSetters::class, "setUInt32ValueUnwrapped", "abc"],
+ [TestWrapperSetters::class, "setUInt32ValueUnwrapped", []],
+ [TestWrapperSetters::class, "setUInt32ValueUnwrapped", new stdClass()],
+ [TestWrapperSetters::class, "setUInt32ValueUnwrapped", new UInt32Value()],
+
+ [TestWrapperSetters::class, "setBoolValueUnwrapped", []],
+ [TestWrapperSetters::class, "setBoolValueUnwrapped", new stdClass()],
+ [TestWrapperSetters::class, "setBoolValueUnwrapped", new BoolValue()],
+
+ [TestWrapperSetters::class, "setStringValueUnwrapped", []],
+ [TestWrapperSetters::class, "setStringValueUnwrapped", new stdClass()],
+ [TestWrapperSetters::class, "setStringValueUnwrapped", new StringValue()],
+
+ [TestWrapperSetters::class, "setBytesValueUnwrapped", []],
+ [TestWrapperSetters::class, "setBytesValueUnwrapped", new stdClass()],
+ [TestWrapperSetters::class, "setBytesValueUnwrapped", new BytesValue()],
+ ];
+ }
+
+ /**
+ * @dataProvider constructorWithWrapperTypeDataProvider
+ */
+ public function testConstructorWithWrapperType($class, $wrapperClass, $wrapperField, $getter, $value)
+ {
+ $actualInstance = new $class([$wrapperField => $value]);
+ $expectedInstance = new $class([$wrapperField => new $wrapperClass(['value' => $value])]);
+ $this->assertEquals($expectedInstance->$getter()->getValue(), $actualInstance->$getter()->getValue());
+ }
+
+ public function constructorWithWrapperTypeDataProvider()
+ {
+ return [
+ [TestWrapperSetters::class, DoubleValue::class, 'double_value', 'getDoubleValue', 1.1],
+ [TestWrapperSetters::class, FloatValue::class, 'float_value', 'getFloatValue', 2.2],
+ [TestWrapperSetters::class, Int64Value::class, 'int64_value', 'getInt64Value', 3],
+ [TestWrapperSetters::class, UInt64Value::class, 'uint64_value', 'getUInt64Value', 4],
+ [TestWrapperSetters::class, Int32Value::class, 'int32_value', 'getInt32Value', 5],
+ [TestWrapperSetters::class, UInt32Value::class, 'uint32_value', 'getUInt32Value', 6],
+ [TestWrapperSetters::class, BoolValue::class, 'bool_value', 'getBoolValue', true],
+ [TestWrapperSetters::class, StringValue::class, 'string_value', 'getStringValue', "eight"],
+ [TestWrapperSetters::class, BytesValue::class, 'bytes_value', 'getBytesValue', "nine"],
+ ];
+ }
+
+ /**
+ * @dataProvider constructorWithRepeatedWrapperTypeDataProvider
+ */
+ public function testConstructorWithRepeatedWrapperType($wrapperField, $getter, $value)
+ {
+ $actualInstance = new TestWrapperSetters([$wrapperField => $value]);
+ foreach ($actualInstance->$getter() as $key => $actualWrapperValue) {
+ $actualInnerValue = $actualWrapperValue->getValue();
+ $expectedElement = $value[$key];
+ if (is_object($expectedElement) && is_a($expectedElement, '\Google\Protobuf\StringValue')) {
+ $expectedInnerValue = $expectedElement->getValue();
+ } else {
+ $expectedInnerValue = $expectedElement;
+ }
+ $this->assertEquals($expectedInnerValue, $actualInnerValue);
+ }
+ }
+
+ public function constructorWithRepeatedWrapperTypeDataProvider()
+ {
+ $sv7 = new StringValue(['value' => 'seven']);
+ $sv8 = new StringValue(['value' => 'eight']);
+
+ $testWrapperSetters = new TestWrapperSetters();
+ $testWrapperSetters->setRepeatedStringValue([$sv7, $sv8]);
+ $repeatedField = $testWrapperSetters->getRepeatedStringValue();
+
+ return [
+ ['repeated_string_value', 'getRepeatedStringValue', []],
+ ['repeated_string_value', 'getRepeatedStringValue', [$sv7]],
+ ['repeated_string_value', 'getRepeatedStringValue', [$sv7, $sv8]],
+ ['repeated_string_value', 'getRepeatedStringValue', ['seven']],
+ ['repeated_string_value', 'getRepeatedStringValue', [7]],
+ ['repeated_string_value', 'getRepeatedStringValue', [7.7]],
+ ['repeated_string_value', 'getRepeatedStringValue', ['seven', 'eight']],
+ ['repeated_string_value', 'getRepeatedStringValue', [$sv7, 'eight']],
+ ['repeated_string_value', 'getRepeatedStringValue', ['seven', $sv8]],
+ ['repeated_string_value', 'getRepeatedStringValue', $repeatedField],
+ ];
+ }
+
+ /**
+ * @dataProvider constructorWithMapWrapperTypeDataProvider
+ */
+ public function testConstructorWithMapWrapperType($wrapperField, $getter, $value)
+ {
+ $actualInstance = new TestWrapperSetters([$wrapperField => $value]);
+ foreach ($actualInstance->$getter() as $key => $actualWrapperValue) {
+ $actualInnerValue = $actualWrapperValue->getValue();
+ $expectedElement = $value[$key];
+ if (is_object($expectedElement) && is_a($expectedElement, '\Google\Protobuf\StringValue')) {
+ $expectedInnerValue = $expectedElement->getValue();
+ } elseif (is_object($expectedElement) && is_a($expectedElement, '\Google\Protobuf\Internal\MapEntry')) {
+ $expectedInnerValue = $expectedElement->getValue()->getValue();
+ } else {
+ $expectedInnerValue = $expectedElement;
+ }
+ $this->assertEquals($expectedInnerValue, $actualInnerValue);
+ }
+ }
+
+ public function constructorWithMapWrapperTypeDataProvider()
+ {
+ $sv7 = new StringValue(['value' => 'seven']);
+ $sv8 = new StringValue(['value' => 'eight']);
+
+ $testWrapperSetters = new TestWrapperSetters();
+ $testWrapperSetters->setMapStringValue(['key' => $sv7, 'key2' => $sv8]);
+ $mapField = $testWrapperSetters->getMapStringValue();
+
+ return [
+ ['map_string_value', 'getMapStringValue', []],
+ ['map_string_value', 'getMapStringValue', ['key' => $sv7]],
+ ['map_string_value', 'getMapStringValue', ['key' => $sv7, 'key2' => $sv8]],
+ ['map_string_value', 'getMapStringValue', ['key' => 'seven']],
+ ['map_string_value', 'getMapStringValue', ['key' => 7]],
+ ['map_string_value', 'getMapStringValue', ['key' => 7.7]],
+ ['map_string_value', 'getMapStringValue', ['key' => 'seven', 'key2' => 'eight']],
+ ['map_string_value', 'getMapStringValue', ['key' => $sv7, 'key2' => 'eight']],
+ ['map_string_value', 'getMapStringValue', ['key' => 'seven', 'key2' => $sv8]],
+ ['map_string_value', 'getMapStringValue', $mapField],
+ ];
+ }
+}