Skip to content

Commit

Permalink
Enum as a input for workflow (#216)
Browse files Browse the repository at this point in the history
* Enum as a input for workflow

* Skip test for lower PHP version

* Supress enum warning

Co-authored-by: Sergey Zhuk <[email protected]>
  • Loading branch information
cv65kr and seregazhuk authored Aug 1, 2022
1 parent f10d8d5 commit 6e1067e
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 3 deletions.
9 changes: 6 additions & 3 deletions src/DataConverter/JsonConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,12 @@ public function fromPayload(Payload $payload, Type $type)

if ((\is_object($data) || \is_array($data)) && $type->isClass()) {
try {
$instance = (new \ReflectionClass($type->getName()))
->newInstanceWithoutConstructor()
;
$reflection = new \ReflectionClass($type->getName());
if (PHP_VERSION_ID >= 80104 && $reflection->isEnum()) {
return $reflection->getConstant($data->name);
}

$instance = $reflection->newInstanceWithoutConstructor();
} catch (\ReflectionException $e) {
throw new DataConverterException($e->getMessage(), $e->getCode(), $e);
}
Expand Down
5 changes: 5 additions & 0 deletions src/DataConverter/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ public static function fromReflectionType(\ReflectionType $type): self
if ($type instanceof \ReflectionNamedType) {
$name = $type->getName();

/** @psalm-suppress UndefinedClass */
if (PHP_VERSION_ID >= 80104 && is_subclass_of($name, \UnitEnum::class)) {
return new self($type->getName(), true);
}

// Traversable types (i.e. Generator) not allowed
if (!$name instanceof \Traversable && $name !== 'array' && $name !== 'iterable') {
return new self($type->getName(), $type->allowsNull());
Expand Down
14 changes: 14 additions & 0 deletions tests/Fixtures/src/Activity/SimpleActivity.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use Temporal\DataConverter\Bytes;
use Temporal\Tests\DTO\Message;
use Temporal\Tests\DTO\User;
use Temporal\Tests\Unit\DTO\Enum\SimpleEnum;
use Temporal\Tests\Unit\DTO\Enum\ScalarEnum;

#[ActivityInterface(prefix: "SimpleActivity.")]
class SimpleActivity
Expand Down Expand Up @@ -99,4 +101,16 @@ public function fail()
{
throw new \Error("failed activity");
}

#[ActivityMethod]
public function simpleEnum(SimpleEnum $enum): SimpleEnum
{
return $enum;
}

#[ActivityMethod]
public function scalarEnum(ScalarEnum $enum): ScalarEnum
{
return $enum;
}
}
38 changes: 38 additions & 0 deletions tests/Fixtures/src/Workflow/ScalarEnumWorkflow.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/**
* This file is part of Temporal package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Temporal\Tests\Workflow;

use Temporal\Workflow\WorkflowMethod;
use Temporal\Workflow;
use Temporal\Tests\Activity\SimpleActivity;
use Temporal\Activity\ActivityOptions;
use Temporal\Common\RetryOptions;
use Temporal\Tests\Unit\DTO\Enum\ScalarEnum;

#[Workflow\WorkflowInterface]
class ScalarEnumWorkflow
{
#[WorkflowMethod(name: 'ScalarEnumWorkflow')]
public function handler(ScalarEnum $enum): iterable
{
$simple = Workflow::newActivityStub(
SimpleActivity::class,
ActivityOptions::new()
->withStartToCloseTimeout(5)
->withRetryOptions(
RetryOptions::new()->withMaximumAttempts(2)
)
);

return yield $simple->scalarEnum($enum);
}
}
38 changes: 38 additions & 0 deletions tests/Fixtures/src/Workflow/SimpleEnumWorkflow.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/**
* This file is part of Temporal package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Temporal\Tests\Workflow;

use Temporal\Workflow\WorkflowMethod;
use Temporal\Workflow;
use Temporal\Tests\Activity\SimpleActivity;
use Temporal\Activity\ActivityOptions;
use Temporal\Common\RetryOptions;
use Temporal\Tests\Unit\DTO\Enum\SimpleEnum;

#[Workflow\WorkflowInterface]
class SimpleEnumWorkflow
{
#[WorkflowMethod(name: 'SimpleEnumWorkflow')]
public function handler(SimpleEnum $enum): iterable
{
$simple = Workflow::newActivityStub(
SimpleActivity::class,
ActivityOptions::new()
->withStartToCloseTimeout(5)
->withRetryOptions(
RetryOptions::new()->withMaximumAttempts(2)
)
);

return yield $simple->simpleEnum($enum);
}
}
53 changes: 53 additions & 0 deletions tests/Functional/Client/EnumTestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

/**
* This file is part of Temporal package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Temporal\Tests\Functional\Client;

use Temporal\Tests\Workflow\SimpleEnumWorkflow;
use Temporal\Tests\Unit\DTO\Enum\SimpleEnum;
use Temporal\Tests\Workflow\ScalarEnumWorkflow;
use Temporal\Tests\Unit\DTO\Enum\ScalarEnum;

/**
* @group client
* @group functional
*/
class EnumTestCase extends ClientTestCase
{
public function setUp(): void
{
parent::setUp();

if (PHP_VERSION_ID < 80104) {
$this->markTestSkipped();
}
}

public function testSimpleEnum(): void
{
$client = $this->createClient();
$workflow = $client->newWorkflowStub(SimpleEnumWorkflow::class);

$result = $client->start($workflow, SimpleEnum::TEST);

$this->assertSame(SimpleEnum::TEST, $result->getResult(SimpleEnum::class));
}

public function testScalarEnum(): void
{
$client = $this->createClient();
$workflow = $client->newWorkflowStub(ScalarEnumWorkflow::class);

$result = $client->start($workflow, ScalarEnum::TESTED_ENUM);

$this->assertSame(ScalarEnum::TESTED_ENUM, $result->getResult(ScalarEnum::class));
}
}

0 comments on commit 6e1067e

Please sign in to comment.