From 3a96106d00a2c877f5c3241e4cb46edaba5f1195 Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Mon, 10 Jul 2023 13:37:16 +0400 Subject: [PATCH 1/2] Add supporting for PHP 8.2 types in `DataConverter` (`null`, `true`, `false`) --- src/DataConverter/DataConverter.php | 8 +++- src/DataConverter/Type.php | 5 ++- .../src/Activity/Php82TypesActivity.php | 37 +++++++++++++++++ .../src/Workflow/Php82TypesWorkflow.php | 41 +++++++++++++++++++ tests/Functional/Client/TypedStubTestCase.php | 15 +++++++ .../DataConverter/DataConverterTestCase.php | 23 ++++++++--- 6 files changed, 121 insertions(+), 8 deletions(-) create mode 100644 tests/Fixtures/src/Activity/Php82TypesActivity.php create mode 100644 tests/Fixtures/src/Workflow/Php82TypesWorkflow.php diff --git a/src/DataConverter/DataConverter.php b/src/DataConverter/DataConverter.php index d654c39e..47cb3e10 100644 --- a/src/DataConverter/DataConverter.php +++ b/src/DataConverter/DataConverter.php @@ -46,8 +46,12 @@ public function fromPayload(Payload $payload, $type) } $type = Type::create($type); - if ($type->getName() === Type::TYPE_VOID) { - return null; + if (\in_array($type->getName(), [Type::TYPE_VOID, Type::TYPE_NULL, Type::TYPE_FALSE, Type::TYPE_TRUE], true)) { + return match($type->getName()) { + Type::TYPE_VOID, Type::TYPE_NULL => null, + Type::TYPE_TRUE => true, + Type::TYPE_FALSE => false, + }; } return $this->converters[$encoding]->fromPayload($payload, $type); diff --git a/src/DataConverter/Type.php b/src/DataConverter/Type.php index 1bc89808..6d4cc266 100644 --- a/src/DataConverter/Type.php +++ b/src/DataConverter/Type.php @@ -26,6 +26,9 @@ final class Type public const TYPE_INT = 'int'; public const TYPE_FLOAT = 'float'; public const TYPE_VOID = 'void'; + public const TYPE_NULL = 'null'; + public const TYPE_TRUE = 'true'; + public const TYPE_FALSE = 'false'; /** * @var string @@ -46,7 +49,7 @@ public function __construct(string $name = Type::TYPE_ANY, bool $allowsNull = nu $this->name = $name; $this->allowsNull = $allowsNull ?? ( - $name === self::TYPE_ANY || $name === self::TYPE_VOID + $name === self::TYPE_ANY || $name === self::TYPE_VOID || $name === self::TYPE_NULL ); } diff --git a/tests/Fixtures/src/Activity/Php82TypesActivity.php b/tests/Fixtures/src/Activity/Php82TypesActivity.php new file mode 100644 index 00000000..87605727 --- /dev/null +++ b/tests/Fixtures/src/Activity/Php82TypesActivity.php @@ -0,0 +1,37 @@ +withStartToCloseTimeout(5) + ->withRetryOptions( + RetryOptions::new()->withMaximumAttempts(2), + ), + ); + + return [ + yield $simple->returnNull(null), + yield $simple->returnTrue(true), + yield $simple->returnFalse(false), + ]; + } +} diff --git a/tests/Functional/Client/TypedStubTestCase.php b/tests/Functional/Client/TypedStubTestCase.php index 71ae7ba0..7e44e7af 100644 --- a/tests/Functional/Client/TypedStubTestCase.php +++ b/tests/Functional/Client/TypedStubTestCase.php @@ -17,6 +17,7 @@ use Temporal\Tests\Unit\Declaration\Fixture\WorkflowWithoutHandler; use Temporal\Tests\Workflow\ActivityReturnTypeWorkflow; use Temporal\Tests\Workflow\GeneratorWorkflow; +use Temporal\Tests\Workflow\Php82TypesWorkflow; use Temporal\Tests\Workflow\QueryWorkflow; use Temporal\Tests\Workflow\SignalledWorkflowReusable; use Temporal\Tests\Workflow\SignalledWorkflowWithInheritance; @@ -159,4 +160,18 @@ public function testSignalRunningWorkflowWithInheritedSignalViaParentInterface() $result = $workflowRun->getResult(); $this->assertEquals(['test1'], $result); } + + /** + * @requires PHP >= 8.2 + */ + public function testPhp82Types(): void + { + $client = $this->createClient(); + + $workflow = $client->newWorkflowStub(Php82TypesWorkflow::class); + $workflowRun = $client->start($workflow); + $result = $workflowRun->getResult(); + + $this->assertSame([null, true, false], $result); + } } diff --git a/tests/Unit/DataConverter/DataConverterTestCase.php b/tests/Unit/DataConverter/DataConverterTestCase.php index ead9699c..032a7ee4 100644 --- a/tests/Unit/DataConverter/DataConverterTestCase.php +++ b/tests/Unit/DataConverter/DataConverterTestCase.php @@ -37,6 +37,9 @@ public function typesDataProvider(): array Type::TYPE_VOID . ' => ' . Type::TYPE_ANY => [Type::TYPE_ANY, null], Type::TYPE_ARRAY . ' => ' . Type::TYPE_ANY => [Type::TYPE_ANY, []], Type::TYPE_OBJECT . ' => ' . Type::TYPE_ANY => [Type::TYPE_ANY, (object)[]], + Type::TYPE_NULL . ' => ' . Type::TYPE_ANY => [Type::TYPE_ANY, null], + Type::TYPE_TRUE . ' => ' . Type::TYPE_ANY => [Type::TYPE_ANY, true], + Type::TYPE_FALSE . ' => ' . Type::TYPE_ANY => [Type::TYPE_ANY, false], Type::TYPE_ARRAY => [Type::TYPE_ARRAY, [1, 2, 3]], Type::TYPE_OBJECT => [Type::TYPE_OBJECT, (object)['field' => 'value']], @@ -45,6 +48,9 @@ public function typesDataProvider(): array Type::TYPE_INT => [Type::TYPE_INT, 42], Type::TYPE_FLOAT => [Type::TYPE_FLOAT, 0.1], Type::TYPE_VOID => [Type::TYPE_VOID, null], + Type::TYPE_NULL => [Type::TYPE_NULL, null], + Type::TYPE_TRUE => [Type::TYPE_TRUE, true], + Type::TYPE_FALSE => [Type::TYPE_FALSE, false], Type::TYPE_ARRAY . ' (associative) => ' . Type::TYPE_ARRAY => [Type::TYPE_ARRAY, ['field' => 'value']], ]; @@ -60,7 +66,8 @@ public function negativeTypesDataProvider(): array Type::TYPE_ARRAY . ' => ' . Type::TYPE_STRING => [Type::TYPE_STRING, [1, 2, 3]], Type::TYPE_FLOAT . ' => ' . Type::TYPE_STRING => [Type::TYPE_STRING, .42], Type::TYPE_INT . ' => ' . Type::TYPE_STRING => [Type::TYPE_STRING, 42], - Type::TYPE_BOOL . ' => ' . Type::TYPE_STRING => [Type::TYPE_STRING, true], + Type::TYPE_TRUE . ' => ' . Type::TYPE_STRING => [Type::TYPE_STRING, true], + Type::TYPE_FALSE . ' => ' . Type::TYPE_STRING => [Type::TYPE_STRING, false], Type::TYPE_VOID . ' => ' . Type::TYPE_STRING => [Type::TYPE_STRING, null], Type::TYPE_OBJECT . ' => ' . Type::TYPE_BOOL => [Type::TYPE_BOOL, (object)['field' => 'value']], @@ -74,14 +81,16 @@ public function negativeTypesDataProvider(): array Type::TYPE_ARRAY . ' => ' . Type::TYPE_INT => [Type::TYPE_INT, [1, 2, 3]], Type::TYPE_FLOAT . ' => ' . Type::TYPE_INT => [Type::TYPE_INT, .42], Type::TYPE_STRING . ' => ' . Type::TYPE_INT => [Type::TYPE_INT, 'string'], - Type::TYPE_BOOL . ' => ' . Type::TYPE_INT => [Type::TYPE_INT, true], + Type::TYPE_TRUE . ' => ' . Type::TYPE_INT => [Type::TYPE_INT, true], + Type::TYPE_FALSE . ' => ' . Type::TYPE_INT => [Type::TYPE_INT, false], Type::TYPE_VOID . ' => ' . Type::TYPE_INT => [Type::TYPE_INT, null], Type::TYPE_OBJECT . ' => ' . Type::TYPE_FLOAT => [Type::TYPE_FLOAT, (object)['field' => 'value']], Type::TYPE_ARRAY . ' => ' . Type::TYPE_FLOAT => [Type::TYPE_FLOAT, [1, 2, 3]], Type::TYPE_INT . ' => ' . Type::TYPE_FLOAT => [Type::TYPE_FLOAT, 42], Type::TYPE_STRING . ' => ' . Type::TYPE_FLOAT => [Type::TYPE_FLOAT, 'string'], - Type::TYPE_BOOL . ' => ' . Type::TYPE_FLOAT => [Type::TYPE_FLOAT, true], + Type::TYPE_TRUE . ' => ' . Type::TYPE_FLOAT => [Type::TYPE_FLOAT, true], + Type::TYPE_FALSE . ' => ' . Type::TYPE_FLOAT => [Type::TYPE_FLOAT, false], Type::TYPE_VOID . ' => ' . Type::TYPE_FLOAT => [Type::TYPE_FLOAT, null], Type::TYPE_ARRAY . ' => ' . Type::TYPE_OBJECT => [Type::TYPE_OBJECT, [1, 2, 3]], @@ -90,11 +99,14 @@ public function negativeTypesDataProvider(): array Type::TYPE_STRING . ' => ' . Type::TYPE_OBJECT => [Type::TYPE_OBJECT, 'string'], Type::TYPE_BOOL . ' => ' . Type::TYPE_OBJECT => [Type::TYPE_OBJECT, true], Type::TYPE_VOID . ' => ' . Type::TYPE_OBJECT => [Type::TYPE_OBJECT, null], + Type::TYPE_TRUE . ' => ' . Type::TYPE_OBJECT => [Type::TYPE_OBJECT, true], + Type::TYPE_FALSE . ' => ' . Type::TYPE_OBJECT => [Type::TYPE_OBJECT, false], Type::TYPE_FLOAT . ' => ' . Type::TYPE_ARRAY => [Type::TYPE_ARRAY, .42], Type::TYPE_INT . ' => ' . Type::TYPE_ARRAY => [Type::TYPE_ARRAY, 42], Type::TYPE_STRING . ' => ' . Type::TYPE_ARRAY => [Type::TYPE_ARRAY, 'string'], - Type::TYPE_BOOL . ' => ' . Type::TYPE_ARRAY => [Type::TYPE_ARRAY, true], + Type::TYPE_TRUE . ' => ' . Type::TYPE_ARRAY => [Type::TYPE_ARRAY, true], + Type::TYPE_FALSE . ' => ' . Type::TYPE_ARRAY => [Type::TYPE_ARRAY, false], Type::TYPE_VOID . ' => ' . Type::TYPE_ARRAY => [Type::TYPE_ARRAY, null], ]; } @@ -111,7 +123,8 @@ public function nullableTypesDataProvider(): array Type::TYPE_FLOAT . ' => ' . Type::TYPE_VOID => [Type::TYPE_VOID, .42], Type::TYPE_INT . ' => ' . Type::TYPE_VOID => [Type::TYPE_VOID, 42], Type::TYPE_STRING . ' => ' . Type::TYPE_VOID => [Type::TYPE_VOID, 'string'], - Type::TYPE_BOOL . ' => ' . Type::TYPE_VOID => [Type::TYPE_VOID, true], + Type::TYPE_TRUE . ' => ' . Type::TYPE_VOID => [Type::TYPE_VOID, true], + Type::TYPE_FALSE . ' => ' . Type::TYPE_VOID => [Type::TYPE_VOID, false], ]; } From 31cc90e7e47181eff398eea6b7a83e6f1f9e68ae Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Mon, 10 Jul 2023 16:11:03 +0400 Subject: [PATCH 2/2] Comment tests that break CI with PHP <8.2 --- .../src/Activity/Php82TypesActivity.php | 5 +++-- tests/Functional/Client/TypedStubTestCase.php | 21 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/Fixtures/src/Activity/Php82TypesActivity.php b/tests/Fixtures/src/Activity/Php82TypesActivity.php index 87605727..035bc12e 100644 --- a/tests/Fixtures/src/Activity/Php82TypesActivity.php +++ b/tests/Fixtures/src/Activity/Php82TypesActivity.php @@ -13,7 +13,8 @@ use Temporal\Activity\ActivityInterface; use Temporal\Activity\ActivityMethod; - +/* +todo: uncomment this with min php 8.2 requirement or when we can skip activities loading depending on php version #[ActivityInterface(prefix: "Php82.")] class Php82TypesActivity { @@ -34,4 +35,4 @@ public function returnFalse(false $value): false { return $value; } -} +}*/ diff --git a/tests/Functional/Client/TypedStubTestCase.php b/tests/Functional/Client/TypedStubTestCase.php index 7e44e7af..f3ffda95 100644 --- a/tests/Functional/Client/TypedStubTestCase.php +++ b/tests/Functional/Client/TypedStubTestCase.php @@ -163,15 +163,16 @@ public function testSignalRunningWorkflowWithInheritedSignalViaParentInterface() /** * @requires PHP >= 8.2 + * todo: uncomment this with min php 8.2 requirement or when we can skip activities loading depending on php version */ - public function testPhp82Types(): void - { - $client = $this->createClient(); - - $workflow = $client->newWorkflowStub(Php82TypesWorkflow::class); - $workflowRun = $client->start($workflow); - $result = $workflowRun->getResult(); - - $this->assertSame([null, true, false], $result); - } + // public function testPhp82Types(): void + // { + // $client = $this->createClient(); + // + // $workflow = $client->newWorkflowStub(Php82TypesWorkflow::class); + // $workflowRun = $client->start($workflow); + // $result = $workflowRun->getResult(); + // + // $this->assertSame([null, true, false], $result); + // } }