| <?php |
| |
| require_once('test_base.php'); |
| require_once('test_util.php'); |
| |
| use Google\Protobuf\Internal\RepeatedField; |
| use Google\Protobuf\Internal\GPBType; |
| use Foo\EmptyAnySerialization; |
| use Foo\TestInt32Value; |
| use Foo\TestStringValue; |
| use Foo\TestAny; |
| use Foo\TestEnum; |
| use Foo\TestLargeFieldNumber; |
| 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 DebugInfoTest extends TestBase |
| { |
| public function setUp(): void |
| { |
| if (extension_loaded('protobuf')) { |
| $this->markTestSkipped('__debugInfo is not supported for the protobuf extension'); |
| } |
| } |
| |
| public function testVarDumpOutput() |
| { |
| $m = new DoubleValue(); |
| $m->setValue(1.5); |
| var_dump($m); |
| $regex = <<<EOL |
| object(Google\Protobuf\DoubleValue)#%s (1) { |
| ["value"]=> |
| float(1.5) |
| } |
| EOL; |
| $this->expectOutputRegex('/' . sprintf(preg_quote($regex), '\d+') . '/'); |
| } |
| |
| public function testTopLevelDoubleValue() |
| { |
| $m = new DoubleValue(); |
| $m->setValue(1.5); |
| $this->assertSame(['value' => 1.5], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelFloatValue() |
| { |
| $m = new FloatValue(); |
| $m->setValue(1.5); |
| $this->assertSame(['value' => 1.5], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelInt32Value() |
| { |
| $m = new Int32Value(); |
| $m->setValue(1); |
| $this->assertSame(['value' => 1], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelUInt32Value() |
| { |
| $m = new UInt32Value(); |
| $m->setValue(1); |
| $this->assertSame(['value' => 1], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelInt64Value() |
| { |
| $m = new Int64Value(); |
| $m->setValue(1); |
| $this->assertSame(['value' => '1'], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelUInt64Value() |
| { |
| $m = new UInt64Value(); |
| $m->setValue(1); |
| $this->assertSame(['value' => '1'], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelStringValue() |
| { |
| $m = new StringValue(); |
| $m->setValue("a"); |
| $this->assertSame(['value' => 'a'], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelBoolValue() |
| { |
| $m = new BoolValue(); |
| $m->setValue(true); |
| $this->assertSame(['value' => true], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelBytesValue() |
| { |
| $m = new BytesValue(); |
| $m->setValue("a"); |
| $this->assertSame(['value' => 'YQ=='], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelLongBytesValue() |
| { |
| $m = new BytesValue(); |
| $data = $this->generateRandomString(12007); |
| $m->setValue($data); |
| $expected = base64_encode($data); |
| $this->assertSame(['value' => $expected], $m->__debugInfo()); |
| } |
| |
| public function testJsonEncodeNullSubMessage() |
| { |
| $from = new TestMessage(); |
| $from->setOptionalMessage(null); |
| $data = $from->__debugInfo(); |
| $this->assertEquals([], $data); |
| } |
| |
| public function testDuration() |
| { |
| $m = new Google\Protobuf\Duration(); |
| $m->setSeconds(1234); |
| $m->setNanos(999999999); |
| $this->assertEquals([ |
| 'seconds' => 1234, |
| 'nanos' => 999999999, |
| ], $m->__debugInfo()); |
| } |
| |
| public function testTimestamp() |
| { |
| $m = new Google\Protobuf\Timestamp(); |
| $m->setSeconds(946684800); |
| $m->setNanos(123456789); |
| $this->assertEquals([ |
| 'seconds' => 946684800, |
| 'nanos' => 123456789, |
| ], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelValue() |
| { |
| $m = new Value(); |
| $m->setStringValue("a"); |
| $this->assertSame(['stringValue' => 'a'], $m->__debugInfo()); |
| |
| $m = new Value(); |
| $m->setNumberValue(1.5); |
| $this->assertSame(['numberValue' => 1.5], $m->__debugInfo()); |
| |
| $m = new Value(); |
| $m->setBoolValue(true); |
| $this->assertSame(['boolValue' => true], $m->__debugInfo()); |
| |
| $m = new Value(); |
| $m->setNullValue(\Google\Protobuf\NullValue::NULL_VALUE); |
| $this->assertSame(['nullValue' => 0], $m->__debugInfo()); |
| |
| $m = new Value(); |
| $struct = new Struct(); |
| $map = $struct->getFields(); |
| $sub = new Value(); |
| $sub->setNumberValue(1.5); |
| $map["a"] = $sub; |
| $m->setStructValue($struct); |
| $this->assertSame(['structValue' => ['a' => 1.5]], $m->__debugInfo()); |
| |
| $m = new Value(); |
| $list = new ListValue(); |
| $arr = $list->getValues(); |
| $sub = new Value(); |
| $sub->setNumberValue(1.5); |
| $arr[] = $sub; |
| $m->setListValue($list); |
| $this->assertSame(['listValue' => [1.5]], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelListValue() |
| { |
| $m = new ListValue(); |
| $arr = $m->getValues(); |
| $sub = new Value(); |
| $sub->setNumberValue(1.5); |
| $arr[] = $sub; |
| $this->assertSame([1.5], $m->__debugInfo()); |
| } |
| |
| public function testEmptyListValue() |
| { |
| $m = new Struct(); |
| $m->setFields(['test' => (new Value())->setListValue(new ListValue())]); |
| $this->assertSame(['test' => []], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelStruct() |
| { |
| $m = new Struct(); |
| $map = $m->getFields(); |
| $sub = new Value(); |
| $sub->setNumberValue(1.5); |
| $map["a"] = $sub; |
| $this->assertSame(['a' => 1.5], $m->__debugInfo()); |
| } |
| |
| public function testEmptyStruct() |
| { |
| $m = new Struct(); |
| $m->setFields(['test' => (new Value())->setStructValue(new Struct())]); |
| $this->assertSame(['test' => []], $m->__debugInfo()); |
| } |
| |
| public function testEmptyValue() |
| { |
| $m = new Value(); |
| $this->assertSame([], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelAny() |
| { |
| // Test a normal message. |
| $packed = new TestMessage(); |
| $packed->setOptionalInt32(123); |
| $packed->setOptionalString("abc"); |
| |
| $m = new Any(); |
| $m->pack($packed); |
| $expected = [ |
| '@type' => 'type.googleapis.com/foo.TestMessage', |
| 'optionalInt32' => 123, |
| 'optionalString' => 'abc', |
| ]; |
| $result = $m->__debugInfo(); |
| $this->assertSame($expected, $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->__debugInfo()); |
| |
| // 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->__debugInfo()); |
| |
| // 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->__debugInfo()); |
| } |
| |
| public function testAnyWithDefaultWrapperMessagePacked() |
| { |
| $any = new Any(); |
| $any->pack(new TestInt32Value([ |
| 'field' => new Int32Value(['value' => 0]), |
| ])); |
| $this->assertSame( |
| ['@type' => 'type.googleapis.com/foo.TestInt32Value', 'field' => 0], |
| $any->__debugInfo() |
| ); |
| } |
| |
| public function testTopLevelFieldMask() |
| { |
| $m = new FieldMask(); |
| $m->setPaths(["foo.bar_baz", "qux"]); |
| $this->assertSame(['paths' => ['foo.bar_baz', 'qux']], $m->__debugInfo()); |
| } |
| |
| public function testEmptyAnySerialization() |
| { |
| $m = new EmptyAnySerialization(); |
| |
| $any = new Any(); |
| $any->pack($m); |
| |
| $data = $any->__debugInfo(); |
| $this->assertEquals(['@type' => 'type.googleapis.com/foo.EmptyAnySerialization'], $data); |
| } |
| |
| public function testRepeatedStringValue() |
| { |
| $m = new TestStringValue(); |
| $r = [new StringValue(['value' => 'a'])]; |
| $m->setRepeatedField($r); |
| $this->assertSame(['repeatedField' => ['a']], $m->__debugInfo()); |
| } |
| |
| public function testMapStringValue() |
| { |
| $m = new TestStringValue(); |
| $m->mergeFromJsonString("{\"map_field\":{\"1\": \"a\"}}"); |
| $this->assertSame(['mapField' => [1 => 'a']], $m->__debugInfo()); |
| } |
| |
| public function testNestedAny() |
| { |
| // Make sure packed message has been created at least once. |
| $m = new TestAny(); |
| $m->mergeFromJsonString( |
| "{\"any\":{\"optionalInt32\": 1, " . |
| "\"@type\":\"type.googleapis.com/foo.TestMessage\", " . |
| "\"optionalInt64\": 2}}"); |
| $this->assertSame([ |
| 'any' => [ |
| '@type' => 'type.googleapis.com/foo.TestMessage', |
| 'optionalInt32' => 1, |
| 'optionalInt64' => '2', |
| ] |
| ], $m->__debugInfo()); |
| } |
| |
| public function testEnum() |
| { |
| $m = new TestMessage(); |
| $m->setOneofEnum(TestEnum::ZERO); |
| $this->assertSame(['oneofEnum' => 'ZERO'], $m->__debugInfo()); |
| } |
| |
| public function testTopLevelRepeatedField() |
| { |
| $r1 = new RepeatedField(GPBType::class); |
| $r1[] = 'a'; |
| $this->assertSame(['a'], $r1->__debugInfo()); |
| |
| $r2 = new RepeatedField(TestMessage::class); |
| $r2[] = new TestMessage(['optional_int32' => -42]); |
| $r2[] = new TestMessage(['optional_int64' => 43]); |
| $this->assertSame([ |
| ['optionalInt32' => -42], |
| ['optionalInt64' => '43'], |
| ], $r2->__debugInfo()); |
| |
| $r3 = new RepeatedField(RepeatedField::class); |
| $r3[] = $r1; |
| $r3[] = $r2; |
| |
| $this->assertSame([ |
| ['a'], |
| [ |
| ['optionalInt32' => -42], |
| ['optionalInt64' => '43'], |
| ], |
| ], $r3->__debugInfo()); |
| } |
| |
| public function testEverything() |
| { |
| $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])], |
| ]); |
| |
| $this->assertSame([ |
| 'optionalInt32' => -42, |
| 'optionalInt64' => '-43', |
| 'optionalUint32' => 42, |
| 'optionalUint64' => '43', |
| 'optionalSint32' => -44, |
| 'optionalSint64' => '-45', |
| 'optionalFixed32' => 46, |
| 'optionalFixed64' => '47', |
| 'optionalSfixed32' => -46, |
| 'optionalSfixed64' => '-47', |
| 'optionalFloat' => 1.5, |
| 'optionalDouble' => 1.6, |
| 'optionalBool' => true, |
| 'optionalString' => 'a', |
| 'optionalBytes' => 'YmJiYg==', |
| 'optionalEnum' => 'ONE', |
| 'optionalMessage' => [ |
| 'a' => 33, |
| ], |
| 'repeatedInt32' => [ |
| -42, |
| -52, |
| ], |
| 'repeatedInt64' => [ |
| '-43', |
| '-53', |
| ], |
| 'repeatedUint32' => [ |
| 42, |
| 52, |
| ], |
| 'repeatedUint64' => [ |
| '43', |
| '53', |
| ], |
| 'repeatedSint32' => [ |
| -44, |
| -54, |
| ], |
| 'repeatedSint64' => [ |
| '-45', |
| '-55', |
| ], |
| 'repeatedFixed32' => [ |
| 46, |
| 56, |
| ], |
| 'repeatedFixed64' => [ |
| '47', |
| '57', |
| ], |
| 'repeatedSfixed32' => [ |
| -46, |
| -56, |
| ], |
| 'repeatedSfixed64' => [ |
| '-47', |
| '-57', |
| ], |
| 'repeatedFloat' => [ |
| 1.5, |
| 2.5, |
| ], |
| 'repeatedDouble' => [ |
| 1.6, |
| 2.6, |
| ], |
| 'repeatedBool' => [ |
| true, |
| false, |
| ], |
| 'repeatedString' => [ |
| 'a', |
| 'c', |
| ], |
| 'repeatedBytes' => [ |
| 'YmJiYg==', |
| 'ZGRkZA==', |
| ], |
| 'repeatedEnum' => [ |
| 'ZERO', |
| 'ONE', |
| ], |
| 'repeatedMessage' => [ |
| [ |
| 'a' => 34, |
| ], |
| [ |
| 'a' => 35, |
| ], |
| ], |
| 'mapInt32Int32' => [ |
| -62 => -62, |
| ], |
| 'mapInt64Int64' => [ |
| -63 => '-63', |
| ], |
| 'mapUint32Uint32' => [ |
| 62 => 62, |
| ], |
| 'mapUint64Uint64' => [ |
| 63 => '63', |
| ], |
| 'mapSint32Sint32' => [ |
| -64 => -64, |
| ], |
| 'mapSint64Sint64' => [ |
| -65 => '-65', |
| ], |
| 'mapFixed32Fixed32' => [ |
| 66 => 66, |
| ], |
| 'mapFixed64Fixed64' => [ |
| 67 => '67', |
| ], |
| 'mapSfixed32Sfixed32' => [ |
| -68 => -68, |
| ], |
| 'mapSfixed64Sfixed64' => [ |
| -69 => '-69', |
| ], |
| 'mapInt32Float' => [ |
| 1 => 3.5, |
| ], |
| 'mapInt32Double' => [ |
| 1 => 3.6, |
| ], |
| 'mapBoolBool' => [ |
| 'true' => true, |
| ], |
| 'mapStringString' => [ |
| 'e' => 'e', |
| ], |
| 'mapInt32Bytes' => [ |
| 1 => 'ZmZmZg==', |
| ], |
| 'mapInt32Enum' => [ |
| 1 => 'ONE', |
| ], |
| 'mapInt32Message' => [ |
| 1 => ['a' => 36], |
| ], |
| ], $m->__debugInfo()); |
| } |
| |
| private function generateRandomString($length = 10) |
| { |
| $randomString = str_repeat("+", $length); |
| for ($i = 0; $i < $length; $i++) { |
| $randomString[$i] = chr(rand(0, 255)); |
| } |
| return $randomString; |
| } |
| } |