diff --git a/.github/workflows/cs-fix.yml b/.github/workflows/cs-fix.yml new file mode 100644 index 0000000..cac49c3 --- /dev/null +++ b/.github/workflows/cs-fix.yml @@ -0,0 +1,14 @@ +.release-please-config: + json: +on: + push: + branches: + - '*' + +name: Fix Code Style + +jobs: + cs-fix: + permissions: + contents: write + uses: spiral/gh-actions/.github/workflows/cs-fix.yml@master diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml index 83ba7bf..68934ab 100644 --- a/.github/workflows/psalm.yml +++ b/.github/workflows/psalm.yml @@ -41,20 +41,12 @@ jobs: extensions: dom - name: Check Out Code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 1 - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache Dependencies - uses: actions/cache@v3 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: php-${{ matrix.php }}-${{ runner.os }}-composer- + - name: ๐Ÿ“ฅ Install dependencies with composer + uses: ramsey/composer-install@v3 - name: Install Composer Dependencies run: composer install --prefer-dist --no-interaction diff --git a/.github/workflows/run-test-suite.yml b/.github/workflows/run-test-suite.yml index b238af8..20c5a78 100644 --- a/.github/workflows/run-test-suite.yml +++ b/.github/workflows/run-test-suite.yml @@ -39,72 +39,42 @@ on: jobs: test: - name: (PHP ${{ matrix.php }}, ${{ matrix.os }}, ${{ matrix.dependencies }} deps + timeout-minutes: 4 runs-on: ${{ matrix.os }} - timeout-minutes: ${{ matrix.timeout-minutes }} - env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' } + concurrency: + cancel-in-progress: true + group: testing-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ matrix.php-version }}-${{ matrix.dependencies }} strategy: - fail-fast: ${{ inputs.fail-fast }} + fail-fast: false matrix: - php: [ 8.1, 8.2 ] - os: [ ubuntu-latest, windows-latest ] - dependencies: [ lowest , highest ] - timeout-minutes: [ '${{ inputs.test-timeout }}' ] - exclude: - - os: windows-latest - php: 8.2 - include: - - os: ubuntu-latest - php: 8.3 - dependencies: highest - timeout-minutes: 40 + os: + - ubuntu-latest + php-version: + - '8.1' + - '8.2' + - '8.3' + - '8.4' + dependencies: + - lowest + - locked + - highest steps: - - name: Set Git To Use LF - run: | - git config --global core.autocrlf false - git config --global core.eol lf + - name: ๐Ÿ“ฆ Check out the codebase + uses: actions/checkout@v5 - - name: Setup PHP ${{ matrix.php }} + - name: ๐Ÿ› ๏ธ Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: ${{ matrix.php }} - tools: composer:v2 - extensions: sockets, curl + php-version: ${{ matrix.php-version }} + ini-values: error_reporting=E_ALL - - name: Check Out Code - uses: actions/checkout@v4 - with: - fetch-depth: 1 - - - name: Validate composer.json and composer.lock - run: composer validate --strict - - - name: Get Composer Cache Directory - id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: ๐Ÿค– Validate composer.json and composer.lock + run: composer validate --ansi --strict - - name: Cache Composer Dependencies - uses: actions/cache@v3 + - name: ๐Ÿ“ฅ Install dependencies with composer + uses: ramsey/composer-install@v3 with: - path: ${{ steps.composer-cache.outputs.dir }} - key: php-${{ matrix.php }}-${{ matrix.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - php-${{ matrix.php }}-${{ matrix.os }}-composer- - - - name: Install lowest dependencies from composer.json - if: matrix.dependencies == 'lowest' - run: composer update --no-interaction --no-progress --prefer-lowest - - - name: Validate lowest dependencies - if: matrix.dependencies == 'lowest' - env: - COMPOSER_POOL_OPTIMIZER: 0 - run: vendor/bin/validate-prefer-lowest - - - name: Install highest dependencies from composer.json - if: matrix.dependencies == 'highest' - run: composer update --no-interaction --no-progress + dependency-versions: ${{ matrix.dependencies }} - - name: Run tests - run: vendor/bin/pest --testdox + - name: ๐Ÿงช Run tests + run: composer test diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index bc5bccc..97e61fd 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -31,33 +31,30 @@ jobs: fail-fast: false matrix: # Note: This workflow requires only the LATEST version of PHP - php: [ 8.2 ] - os: [ ubuntu-latest ] + os: + - ubuntu-latest + php-version: + - '8.2' + dependencies: + - locked steps: - - name: Set up PHP ${{ matrix.php }} - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: dom, sockets, grpc, curl + - name: ๐Ÿ“ฆ Check out the codebase + uses: actions/checkout@v5 - - name: Check Out Code - uses: actions/checkout@v4 + - name: ๐Ÿ› ๏ธ Setup PHP + uses: shivammathur/setup-php@v2 with: - fetch-depth: 1 + php-version: ${{ matrix.php-version }} + ini-values: error_reporting=E_ALL + coverage: none - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: ๐Ÿค– Validate composer.json and composer.lock + run: composer validate --ansi --strict - - name: Cache Dependencies - uses: actions/cache@v3 + - name: ๐Ÿ“ฅ Install dependencies with composer + uses: ramsey/composer-install@v3 with: - path: ${{ steps.composer-cache.outputs.dir }} - key: php-${{ matrix.php }}-${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: php-${{ matrix.php }}-${{ runner.os }}-composer- - - - name: Install Composer Dependencies - run: composer install --prefer-dist --no-interaction + dependency-versions: ${{ matrix.dependencies }} - - name: Verify - run: composer require --dev roave/security-advisories:dev-latest + - name: ๐Ÿ› Check installed packages for security vulnerability advisories + run: composer audit --ansi diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..38b5aed --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,12 @@ +include(__DIR__ . '/src') + ->include(__DIR__ . '/tests') + ->include(__FILE__) + ->allowRisky(true) + ->build(); diff --git a/composer.json b/composer.json index 4fee098..ac16e86 100644 --- a/composer.json +++ b/composer.json @@ -8,10 +8,6 @@ { "name": "Aleksei Gagarin (roxblnfk)", "homepage": "https://github.com/roxblnfk" - }, - { - "name": "Pavel Buchnev (butschster)", - "homepage": "https://github.com/butschster" } ], "autoload": { @@ -28,17 +24,13 @@ { "type": "patreon", "url": "https://patreon.com/roxblnfk" - }, - { - "type": "patreon", - "url": "https://patreon.com/butschster" } ], "minimum-stability": "dev", "prefer-stable": true, "require": { "php": ">=8.1", - "temporal/sdk": "^2.8" + "temporal/sdk": "^2.15" }, "suggest": { "buggregator/trap": "For better debugging and protobuf messages dumping" @@ -47,13 +39,31 @@ "buggregator/trap": "^1.4", "dereuromark/composer-prefer-lowest": "^0.1.10", "phpunit/phpunit": "^10.5", - "vimeo/psalm": "^5.23", - "pestphp/pest": "^2.34", - "pestphp/pest-plugin-arch": "^2.7" + "spiral/code-style": "^2.3.0", + "ta-tikoma/phpunit-architecture-test": "^0.8.4", + "vimeo/psalm": "^6.13" }, "config": { "allow-plugins": { "pestphp/pest-plugin": false } + }, + "scripts": { + "cs:diff": "php-cs-fixer fix --dry-run -v --diff", + "cs:fix": "php-cs-fixer fix -v", + "psalm": "psalm", + "psalm:baseline": "psalm --set-baseline=psalm-baseline.xml", + "psalm:ci": "psalm --output-format=github --shepherd --show-info=false --stats --threads=4", + "test": [ + "phpunit --color=always --no-coverage" + ], + "test:unit": [ + "@putenv XDEBUG_MODE=coverage", + "phpunit --color=always --testsuite=Unit" + ], + "test:arch": [ + "@putenv XDEBUG_MODE=coverage", + "phpunit --color=always --testsuite=Arch" + ] } } diff --git a/phpunit.xml b/phpunit.xml index 7140884..889ce7e 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -3,6 +3,7 @@ xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd" backupGlobals="false" colors="true" + cacheResultFile="runtime/phpunit/result.cache" processIsolation="false" executionOrder="random" failOnRisky="true" @@ -10,8 +11,8 @@ stopOnFailure="false" stopOnError="false" stderr="true" - cacheDirectory=".phpunit.cache" resolveDependencies="true" + displayDetailsOnTestsThatTriggerDeprecations="true" > diff --git a/src/Factory/ActivityStub.php b/src/Factory/ActivityStub.php index 537defa..78abb1c 100644 --- a/src/Factory/ActivityStub.php +++ b/src/Factory/ActivityStub.php @@ -4,7 +4,6 @@ namespace Temporal\Support\Factory; -use DateInterval; use Temporal\Activity\ActivityOptions; use Temporal\Internal\Workflow\ActivityProxy; use Temporal\Support\Attribute\RetryPolicy; @@ -15,7 +14,6 @@ use Temporal\Support\Internal\RetryOptions; use Temporal\Workflow; use Temporal\Workflow\ActivityStubInterface; -use Throwable; final class ActivityStub { @@ -29,29 +27,28 @@ final class ActivityStub * @param int<0, max>|null $retryAttempts Maximum number of attempts. When exceeded the retries stop even * if not expired yet. If not set or set to 0, it means unlimited, and rely on activity * {@see ActivityOptions::$scheduleToCloseTimeout} to stop. - * @param DateInterval|string|int|null $retryInitInterval Backoff interval for the first retry. + * @param \DateInterval|string|int|null $retryInitInterval Backoff interval for the first retry. * If $retryBackoff is 1.0 then it is used for all retries. * Int value in seconds. - * @param DateInterval|string|int|null $retryMaxInterval Maximum backoff interval between retries. + * @param \DateInterval|string|int|null $retryMaxInterval Maximum backoff interval between retries. * Exponential backoff leads to interval increase. This value is the cap of the interval. * Int value in seconds. * Default is 100x of $retryInitInterval. * @param float|null $retryBackoff Coefficient used to calculate the next retry backoff interval. * The next retry interval is previous interval multiplied by this coefficient. * Note: Must be greater than 1.0 - * @param list> $nonRetryables Non-retriable errors. Temporal server will stop retry + * @param list> $nonRetryables Non-retriable errors. Temporal server will stop retry * if error type matches this list. - * @param DateInterval|string|int $scheduleToStartTimeout Time activity can stay in task queue before it + * @param \DateInterval|string|int $scheduleToStartTimeout Time activity can stay in task queue before it * is picked up by a worker. If $scheduleToCloseTimeout is not provided then * both this and $startToCloseTimeout are required. - * @param DateInterval|string|int $startToCloseTimeout Maximum activity execution time after it was sent + * @param \DateInterval|string|int $startToCloseTimeout Maximum activity execution time after it was sent * to a worker. If $scheduleToCloseTimeout is not provided then both this * and $scheduleToStartTimeout are required. - * @param DateInterval|string|int $scheduleToCloseTimeout Overall timeout workflow is willing to wait for + * @param \DateInterval|string|int $scheduleToCloseTimeout Overall timeout workflow is willing to wait for * activity to complete. It includes time in a task queue ($scheduleToStartTimeout) plus activity * execution time ($startToCloseTimeout). * Either this option or both $scheduleToStartTimeout and $startToCloseTimeout are required. - * @param DateInterval|string|int $heartbeatTimeout * @param \Stringable|non-empty-string|null $activityId Business level activity ID, this is not needed * for most of the cases. If you have to specify this, then talk to the temporal team. * This is something will be done in the future. @@ -99,7 +96,7 @@ public static function activity( $scheduleToCloseTimeout === 0 or $options = $options->withScheduleToCloseTimeout($scheduleToCloseTimeout); $heartbeatTimeout === 0 or $options = $options->withHeartbeatTimeout($heartbeatTimeout); // Activity ID - $activityId === null or $options = $options->withActivityId((string)$activityId); + $activityId === null or $options = $options->withActivityId((string) $activityId); $cancellationType === 0 or $options = $options->withCancellationType($cancellationType); return $class === null diff --git a/src/Factory/WorkflowStub.php b/src/Factory/WorkflowStub.php index f5f13e6..88a747f 100644 --- a/src/Factory/WorkflowStub.php +++ b/src/Factory/WorkflowStub.php @@ -4,11 +4,13 @@ namespace Temporal\Support\Factory; -use DateInterval; use Temporal\Client\WorkflowClientInterface; use Temporal\Client\WorkflowOptions; use Temporal\Client\WorkflowStubInterface; use Temporal\Common\IdReusePolicy; +use Temporal\Common\Priority; +use Temporal\Common\TypedSearchAttributes; +use Temporal\Common\WorkflowIdConflictPolicy; use Temporal\Internal\Client\WorkflowProxy; use Temporal\Internal\Workflow\ChildWorkflowProxy; use Temporal\Support\Attribute\RetryPolicy; @@ -21,7 +23,6 @@ use Temporal\Workflow\ChildWorkflowCancellationType as ChildCancelType; use Temporal\Workflow\ChildWorkflowStubInterface; use Temporal\Workflow\ParentClosePolicy; -use Throwable; final class WorkflowStub { @@ -35,30 +36,30 @@ final class WorkflowStub * @param int<0, max>|null $retryAttempts Maximum number of attempts. When exceeded the retries stop even * if not expired yet. If not set or set to 0, it means unlimited, and rely on activity * {@see ActivityOptions::$scheduleToCloseTimeout} to stop. - * @param DateInterval|string|int|null $retryInitInterval Backoff interval for the first retry. + * @param \DateInterval|string|int|null $retryInitInterval Backoff interval for the first retry. * If $retryBackoff is 1.0 then it is used for all retries. * Int value in seconds. - * @param DateInterval|string|int|null $retryMaxInterval Maximum backoff interval between retries. + * @param \DateInterval|string|int|null $retryMaxInterval Maximum backoff interval between retries. * Exponential backoff leads to interval increase. This value is the cap of the interval. * Int value in seconds. * Default is 100x of $retryInitInterval. * @param float|null $retryBackoff Coefficient used to calculate the next retry backoff interval. * The next retry interval is previous interval multiplied by this coefficient. * Note: Must be greater than 1.0 - * @param list> $nonRetryables Non-retriable errors. Temporal server will stop retry + * @param list> $nonRetryables Non-retriable errors. Temporal server will stop retry * if error type matches this list. - * @param DateInterval|string|int $executionTimeout The maximum time that parent workflow is willing to wait + * @param \DateInterval|string|int $executionTimeout The maximum time that parent workflow is willing to wait * for a child execution (which includes retries and continue as new calls). * If exceeded the child is automatically terminated by the Temporal service. * Int value in seconds. - * @param DateInterval|string|int $runTimeout The time after which workflow run is automatically terminated by + * @param \DateInterval|string|int $runTimeout The time after which workflow run is automatically terminated by * the Temporal service. * Do not rely on the run timeout for business level timeouts. * It is preferred to use in workflow timers for this purpose. * Int value in seconds. * @param int<10, 60> $taskTimeout Maximum execution time of a single workflow task. Int value in seconds. * Default is 10 seconds. The maximum accepted value is 60 seconds. - * @param DateInterval|string|int $startDelay Time to wait before dispatching the first Workflow task. + * @param \DateInterval|string|int $startDelay Time to wait before dispatching the first Workflow task. * If the Workflow gets a Signal before the delay, a Workflow task will be dispatched and the rest * of the delay will be ignored. A Signal from {@see WorkflowClientInterface::startWithSignal()} * won't trigger a workflow task. Cannot be set the same time as a $cronSchedule. @@ -98,6 +99,11 @@ public static function workflow( ?string $cronSchedule = null, array $searchAttributes = [], array $memo = [], + ?TypedSearchAttributes $typedSearchAttributes = null, + WorkflowIdConflictPolicy $idConflictPolicy = WorkflowIdConflictPolicy::Unspecified, + ?Priority $priority = null, + string $staticSummary = '', + string $staticDetails = '', ): object { $isTyped = self::isClassOrInterface($type); /** @psalm-suppress ArgumentTypeCoercion */ @@ -115,21 +121,32 @@ public static function workflow( attribute: $attributes->first(RetryPolicy::class), ); - $options = WorkflowOptions::new()->withRetryOptions($retryOptions); + $options = WorkflowOptions::new() + ->withRetryOptions($retryOptions) + ->withStaticSummary($staticSummary) + ->withStaticDetails($staticDetails); + ; $taskQueue ??= $attributes->first(TaskQueue::class)?->name; $taskQueue === null or $options = $options->withTaskQueue($taskQueue); // Start options $startDelay === 0 or $options = $options->withWorkflowStartDelay($startDelay); $eagerStart and $options = $options->withEagerStart(true); $cronSchedule === null or $options = $options->withCronSchedule($cronSchedule); + $priority === null or $options = $options->withPriority($priority); + $typedSearchAttributes === null or $options = $options->withTypedSearchAttributes($typedSearchAttributes); + // Timeouts $executionTimeout === 0 or $options = $options->withWorkflowExecutionTimeout($executionTimeout); $runTimeout === 0 or $options = $options->withWorkflowRunTimeout($executionTimeout); $taskTimeout !== 10 and $options = $options->withWorkflowTaskTimeout(\max(60, $taskTimeout)); + // Workflow ID - $workflowId === null or $options = $options->withWorkflowId((string)$workflowId); + $workflowId === null or $options = $options->withWorkflowId((string) $workflowId); $workflowIdReusePolicy === IdReusePolicy::Unspecified or $options = $options ->withWorkflowIdReusePolicy($workflowIdReusePolicy); + $idConflictPolicy === WorkflowIdConflictPolicy::Unspecified or $options = $options + ->withWorkflowIdConflictPolicy($idConflictPolicy); + // Metadata $searchAttributes === [] or $options = $options->withSearchAttributes($searchAttributes); $memo === [] or $options = $options->withMemo($memo); @@ -152,23 +169,23 @@ public static function workflow( * @param int<0, max>|null $retryAttempts Maximum number of attempts. When exceeded the retries stop even * if not expired yet. If not set or set to 0, it means unlimited, and rely on activity * {@see ActivityOptions::$scheduleToCloseTimeout} to stop. - * @param DateInterval|string|int|null $retryInitInterval Backoff interval for the first retry. + * @param \DateInterval|string|int|null $retryInitInterval Backoff interval for the first retry. * If $retryBackoff is 1.0 then it is used for all retries. * Int value in seconds. - * @param DateInterval|string|int|null $retryMaxInterval Maximum backoff interval between retries. + * @param \DateInterval|string|int|null $retryMaxInterval Maximum backoff interval between retries. * Exponential backoff leads to interval increase. This value is the cap of the interval. * Int value in seconds. * Default is 100x of $retryInitInterval. * @param float|null $retryBackoff Coefficient used to calculate the next retry backoff interval. * The next retry interval is previous interval multiplied by this coefficient. * Note: Must be greater than 1.0 - * @param list> $nonRetryables Non-retriable errors. Temporal server will stop retry + * @param list> $nonRetryables Non-retriable errors. Temporal server will stop retry * if error type matches this list. - * @param DateInterval|string|int $executionTimeout The maximum time that parent workflow is willing to wait + * @param \DateInterval|string|int $executionTimeout The maximum time that parent workflow is willing to wait * for a child execution (which includes retries and continue as new calls). * If exceeded the child is automatically terminated by the Temporal service. * Int value in seconds. - * @param DateInterval|string|int $runTimeout The time after which workflow run is automatically terminated by + * @param \DateInterval|string|int $runTimeout The time after which workflow run is automatically terminated by * the Temporal service. * Do not rely on the run timeout for business level timeouts. * It is preferred to use in workflow timers for this purpose. @@ -209,6 +226,9 @@ public static function childWorkflow( ?string $cronSchedule = null, array $searchAttributes = [], array $memo = [], + ?Priority $priority = null, + string $staticSummary = '', + string $staticDetails = '', ): object { $isTyped = self::isClassOrInterface($type); /** @psalm-suppress ArgumentTypeCoercion */ @@ -226,7 +246,10 @@ public static function childWorkflow( attribute: $attributes->first(RetryPolicy::class), ); - $options = Workflow\ChildWorkflowOptions::new()->withRetryOptions($retryOptions); + $options = Workflow\ChildWorkflowOptions::new() + ->withRetryOptions($retryOptions) + ->withStaticSummary($staticSummary) + ->withStaticDetails($staticDetails); $taskQueue ??= $attributes->first(TaskQueue::class)?->name; $taskQueue === null or $options = $options->withTaskQueue($taskQueue); @@ -237,15 +260,17 @@ public static function childWorkflow( ->withParentClosePolicy($parentClosePolicy); $childCancellationType === ChildCancelType::TRY_CANCEL or $options = $options ->withChildWorkflowCancellationType($childCancellationType); + $priority === null or $options = $options->withPriority($priority); // Timeouts $executionTimeout === 0 or $options = $options->withWorkflowExecutionTimeout($executionTimeout); $runTimeout === 0 or $options = $options->withWorkflowRunTimeout($executionTimeout); $taskTimeout !== 10 and $options = $options->withWorkflowTaskTimeout(\max(60, $taskTimeout)); // Workflow ID - $workflowId === null or $options = $options->withWorkflowId((string)$workflowId); + $workflowId === null or $options = $options->withWorkflowId((string) $workflowId); $workflowIdReusePolicy === IdReusePolicy::Unspecified or $options = $options ->withWorkflowIdReusePolicy($workflowIdReusePolicy); + // Metadata $searchAttributes === [] or $options = $options->withSearchAttributes($searchAttributes); $memo === [] or $options = $options->withMemo($memo); diff --git a/tests/Arch/ArchTest.php b/tests/Arch/ArchTest.php new file mode 100644 index 0000000..dd02189 --- /dev/null +++ b/tests/Arch/ArchTest.php @@ -0,0 +1,42 @@ +layer(); + + foreach ($layer as $object) { + foreach ($object->uses as $use) { + foreach ($functions as $function) { + $function === $use and throw new \Exception( + \sprintf( + 'Function `%s()` is used in %s.', + $function, + $object->name, + ), + ); + } + } + } + + $this->assertTrue(true); + } +} diff --git a/tests/Arch/DebugTest.php b/tests/Arch/DebugTest.php deleted file mode 100644 index 0febb51..0000000 --- a/tests/Arch/DebugTest.php +++ /dev/null @@ -1,8 +0,0 @@ -expect(['trap', 'dd', 'dump', 'exit', 'die', 'print_r', 'var_dump', 'echo', 'print', 'sleep', 'usleep']) - ->not - ->toBeUsed(); diff --git a/tests/Unit/Factory/ActivityStubTest.php b/tests/Unit/Factory/ActivityStubTest.php index 8e57db5..cbf6693 100644 --- a/tests/Unit/Factory/ActivityStubTest.php +++ b/tests/Unit/Factory/ActivityStubTest.php @@ -39,8 +39,8 @@ class: AttributedWithoutInterface::class, $this->assertSame(3, $options->retryOptions->maximumAttempts); $this->assertSame(10.0, $options->retryOptions->backoffCoefficient); $this->assertSame([RuntimeException::class], $options->retryOptions->nonRetryableExceptions); - $this->assertSame('5.0', $options->retryOptions->initialInterval->format('%s.%f')); - $this->assertSame('500.0', $options->retryOptions->maximumInterval->format('%s.%f')); + $this->assertSame('0.5.0', $options->retryOptions->initialInterval->format('%i.%s.%f')); + $this->assertSame('8.20.0', $options->retryOptions->maximumInterval->format('%i.%s.%f')); } public function testAttributeOverrides(): void @@ -63,8 +63,8 @@ class: AttributedWithoutInterface::class, [LogicException::class, RuntimeException::class], $options->retryOptions->nonRetryableExceptions, ); - $this->assertSame('10.0', $options->retryOptions->initialInterval->format('%s.%f')); - $this->assertSame('200.0', $options->retryOptions->maximumInterval->format('%s.%f')); + $this->assertSame('0.10.0', $options->retryOptions->initialInterval->format('%i.%s.%f')); + $this->assertSame('3.20.0', $options->retryOptions->maximumInterval->format('%i.%s.%f')); } public function testUntypedActivity(): void diff --git a/tests/Unit/Factory/ChildWorkflowStubTest.php b/tests/Unit/Factory/ChildWorkflowStubTest.php index 2436bb1..3925153 100644 --- a/tests/Unit/Factory/ChildWorkflowStubTest.php +++ b/tests/Unit/Factory/ChildWorkflowStubTest.php @@ -40,8 +40,8 @@ public function testDefaultsFromAttributes(): void $this->assertSame(3, $options->retryOptions->maximumAttempts); $this->assertSame(10.0, $options->retryOptions->backoffCoefficient); $this->assertSame([RuntimeException::class], $options->retryOptions->nonRetryableExceptions); - $this->assertSame('5.0', $options->retryOptions->initialInterval->format('%s.%f')); - $this->assertSame('500.0', $options->retryOptions->maximumInterval->format('%s.%f')); + $this->assertSame('0.5.0', $options->retryOptions->initialInterval->format('%i.%s.%f')); + $this->assertSame('8.20.0', $options->retryOptions->maximumInterval->format('%i.%s.%f')); } public function testAttributeOverrides(): void @@ -64,8 +64,8 @@ public function testAttributeOverrides(): void [LogicException::class, RuntimeException::class], $options->retryOptions->nonRetryableExceptions, ); - $this->assertSame('10.0', $options->retryOptions->initialInterval->format('%s.%f')); - $this->assertSame('200.0', $options->retryOptions->maximumInterval->format('%s.%f')); + $this->assertSame('0.10.0', $options->retryOptions->initialInterval->format('%i.%s.%f')); + $this->assertSame('3.20.0', $options->retryOptions->maximumInterval->format('%i.%s.%f')); } public function testUntypedChildCreated(): void diff --git a/tests/Unit/Factory/WorkflowStubTest.php b/tests/Unit/Factory/WorkflowStubTest.php index e503070..ab220c0 100644 --- a/tests/Unit/Factory/WorkflowStubTest.php +++ b/tests/Unit/Factory/WorkflowStubTest.php @@ -42,8 +42,8 @@ public function testDefaultsFromAttributes(): void [RuntimeException::class], $input->options->retryOptions->nonRetryableExceptions, ); - self::assertSame('5.0', $input->options->retryOptions->initialInterval->format('%s.%f')); - self::assertSame('500.0', $input->options->retryOptions->maximumInterval->format('%s.%f')); + self::assertSame('0.5.0', $input->options->retryOptions->initialInterval->format('%i.%s.%f')); + self::assertSame('8.20.0', $input->options->retryOptions->maximumInterval->format('%i.%s.%f')); } public function testAttributeOverrides(): void @@ -79,8 +79,8 @@ public function testAttributeOverrides(): void [LogicException::class, RuntimeException::class], $input->options->retryOptions->nonRetryableExceptions, ); - self::assertSame('10.0', $input->options->retryOptions->initialInterval->format('%s.%f')); - self::assertSame('200.0', $input->options->retryOptions->maximumInterval->format('%s.%f')); + self::assertSame('0.10.0', $input->options->retryOptions->initialInterval->format('%i.%s.%f')); + self::assertSame('3.20.0', $input->options->retryOptions->maximumInterval->format('%i.%s.%f')); } public function testUntypedWorkflowCreated(): void