PHP: Add support for primitive types in setters (#5126)
* Add support for primitive types in setters * Update to address PR feedback * Add tests and fixes for repeated fields * Remove repeated field code, add getters * Cleanup, test getters and oneofs * Move boxing logic into separate class * Add tests for wrapper type constructor args * Update to add new setXXXValue methods * Fix tests for invalid values * Fix c extension for wrapper accessors * Fix the bug that well known types didn't call Message_construct * Address PR comments * Refactoring init message with array logic * Add include path to protoc * Add missing TSRM_LS defintion * Fix TSRM_LS * Fix dist checkpull/5236/head
parent
9e69594adf
commit
6a51c03823
14 changed files with 512 additions and 74 deletions
@ -0,0 +1,22 @@ |
||||
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; |
||||
} |
||||
} |
@ -0,0 +1,228 @@ |
||||
<?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", "setDoubleValueValue", "getDoubleValue", "getDoubleValueValue", [ |
||||
[1.1, new DoubleValue(["value" => 1.1])], |
||||
[2.2, new DoubleValue(["value" => 2.2])], |
||||
[null, null], |
||||
[0, new DoubleValue()], |
||||
]], |
||||
[TestWrapperSetters::class, FloatValue::class, "setFloatValue", "setFloatValueValue", "getFloatValue", "getFloatValueValue", [ |
||||
[1.1, new FloatValue(["value" => 1.1])], |
||||
[2.2, new FloatValue(["value" => 2.2])], |
||||
[null, null], |
||||
[0, new FloatValue()], |
||||
]], |
||||
[TestWrapperSetters::class, Int64Value::class, "setInt64Value", "setInt64ValueValue", "getInt64Value", "getInt64ValueValue", [ |
||||
[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", "setUInt64ValueValue", "getUInt64Value", "getUInt64ValueValue", [ |
||||
[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", "setInt32ValueValue", "getInt32Value", "getInt32ValueValue", [ |
||||
[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", "setUInt32ValueValue", "getUInt32Value", "getUInt32ValueValue", [ |
||||
[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", "setBoolValueValue", "getBoolValue", "getBoolValueValue", [ |
||||
[true, new BoolValue(["value" => true])], |
||||
[false, new BoolValue(["value" => false])], |
||||
[null, null], |
||||
]], |
||||
[TestWrapperSetters::class, StringValue::class, "setStringValue", "setStringValueValue", "getStringValue", "getStringValueValue", [ |
||||
["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", "setBytesValueValue", "getBytesValue", "getBytesValueValue", [ |
||||
["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", "setDoubleValueOneofValue", "getDoubleValueOneof", "getDoubleValueOneofValue", [ |
||||
[1.1, new DoubleValue(["value" => 1.1])], |
||||
[2.2, new DoubleValue(["value" => 2.2])], |
||||
[null, null], |
||||
[0, new DoubleValue()], |
||||
]],[TestWrapperSetters::class, StringValue::class, "setStringValueOneof", "setStringValueOneofValue", "getStringValueOneof", "getStringValueOneofValue", [ |
||||
["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, "setDoubleValueValue", "abc"], |
||||
[TestWrapperSetters::class, "setDoubleValueValue", []], |
||||
[TestWrapperSetters::class, "setDoubleValueValue", new stdClass()], |
||||
[TestWrapperSetters::class, "setDoubleValueValue", new DoubleValue()], |
||||
|
||||
[TestWrapperSetters::class, "setFloatValueValue", "abc"], |
||||
[TestWrapperSetters::class, "setFloatValueValue", []], |
||||
[TestWrapperSetters::class, "setFloatValueValue", new stdClass()], |
||||
[TestWrapperSetters::class, "setFloatValueValue", new FloatValue()], |
||||
|
||||
[TestWrapperSetters::class, "setInt64ValueValue", "abc"], |
||||
[TestWrapperSetters::class, "setInt64ValueValue", []], |
||||
[TestWrapperSetters::class, "setInt64ValueValue", new stdClass()], |
||||
[TestWrapperSetters::class, "setInt64ValueValue", new Int64Value()], |
||||
|
||||
[TestWrapperSetters::class, "setUInt64ValueValue", "abc"], |
||||
[TestWrapperSetters::class, "setUInt64ValueValue", []], |
||||
[TestWrapperSetters::class, "setUInt64ValueValue", new stdClass()], |
||||
[TestWrapperSetters::class, "setUInt64ValueValue", new UInt64Value()], |
||||
|
||||
[TestWrapperSetters::class, "setInt32ValueValue", "abc"], |
||||
[TestWrapperSetters::class, "setInt32ValueValue", []], |
||||
[TestWrapperSetters::class, "setInt32ValueValue", new stdClass()], |
||||
[TestWrapperSetters::class, "setInt32ValueValue", new Int32Value()], |
||||
|
||||
[TestWrapperSetters::class, "setUInt32ValueValue", "abc"], |
||||
[TestWrapperSetters::class, "setUInt32ValueValue", []], |
||||
[TestWrapperSetters::class, "setUInt32ValueValue", new stdClass()], |
||||
[TestWrapperSetters::class, "setUInt32ValueValue", new UInt32Value()], |
||||
|
||||
[TestWrapperSetters::class, "setBoolValueValue", []], |
||||
[TestWrapperSetters::class, "setBoolValueValue", new stdClass()], |
||||
[TestWrapperSetters::class, "setBoolValueValue", new BoolValue()], |
||||
|
||||
[TestWrapperSetters::class, "setStringValueValue", []], |
||||
[TestWrapperSetters::class, "setStringValueValue", new stdClass()], |
||||
[TestWrapperSetters::class, "setStringValueValue", new StringValue()], |
||||
|
||||
[TestWrapperSetters::class, "setBytesValueValue", []], |
||||
[TestWrapperSetters::class, "setBytesValueValue", new stdClass()], |
||||
[TestWrapperSetters::class, "setBytesValueValue", 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"], |
||||
]; |
||||
} |
||||
} |
Loading…
Reference in new issue