Skip to content

Commit 347e344

Browse files
authored
Merge pull request #570: Fix decoding of non-nullable interval fields when null is gotten
2 parents 2b4202b + 9a9a87a commit 347e344

File tree

8 files changed

+107
-37
lines changed

8 files changed

+107
-37
lines changed

psalm-baseline.xml

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<files psalm-version="6.4.1@09a200c15910905ddc49e5edd37b73f9c78f7580">
2+
<files psalm-version="6.7.1@a2f190972555ea01b0cfcc1913924d6c5fc1a64e">
33
<file src="src/Activity.php">
44
<ImplicitToStringCast>
55
<code><![CDATA[$type]]></code>
@@ -51,19 +51,9 @@
5151
</ArgumentTypeCoercion>
5252
</file>
5353
<file src="src/Client/Schedule/Action/StartWorkflowAction.php">
54-
<DocblockTypeContradiction>
55-
<code><![CDATA[$timeout === null]]></code>
56-
<code><![CDATA[$timeout === null]]></code>
57-
<code><![CDATA[$timeout === null]]></code>
58-
</DocblockTypeContradiction>
5954
<InaccessibleProperty>
6055
<code><![CDATA[$workflowType->name]]></code>
6156
</InaccessibleProperty>
62-
<RedundantConditionGivenDocblockType>
63-
<code><![CDATA[DateInterval::parse($timeout, DateInterval::FORMAT_SECONDS)]]></code>
64-
<code><![CDATA[DateInterval::parse($timeout, DateInterval::FORMAT_SECONDS)]]></code>
65-
<code><![CDATA[DateInterval::parse($timeout, DateInterval::FORMAT_SECONDS)]]></code>
66-
</RedundantConditionGivenDocblockType>
6757
</file>
6858
<file src="src/Client/Schedule/Info/ScheduleActionResult.php">
6959
<PropertyNotSetInConstructor>
@@ -219,8 +209,6 @@
219209
</file>
220210
<file src="src/Common/RetryOptions.php">
221211
<PossiblyNullArgument>
222-
<code><![CDATA[$interval]]></code>
223-
<code><![CDATA[$interval]]></code>
224212
<code><![CDATA[DateInterval::toDuration($this->initialInterval)]]></code>
225213
<code><![CDATA[DateInterval::toDuration($this->maximumInterval)]]></code>
226214
</PossiblyNullArgument>
@@ -1141,6 +1129,11 @@
11411129
<code><![CDATA[$header ?? Header::empty()]]></code>
11421130
</PropertyTypeCoercion>
11431131
</file>
1132+
<file src="src/Internal/Workflow/Process/DeferredGenerator.php">
1133+
<UnevaluatedCode>
1134+
<code><![CDATA[yield;]]></code>
1135+
</UnevaluatedCode>
1136+
</file>
11441137
<file src="src/Internal/Workflow/Process/Process.php">
11451138
<MissingClosureParamType>
11461139
<code><![CDATA[$result]]></code>

psalm.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@
2121
<directory name="vendor" />
2222
</ignoreFiles>
2323
</projectFiles>
24+
<issueHandlers>
25+
<MissingOverrideAttribute errorLevel="suppress" />
26+
<ClassMustBeFinal errorLevel="suppress" />
27+
</issueHandlers>
2428
</psalm>

src/Internal/Marshaller/Type/DurationJsonType.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public function parse($value, $current): CarbonInterval
8181
}
8282

8383
if ($value === null) {
84-
return CarbonInterval::create();
84+
return CarbonInterval::create(0);
8585
}
8686

8787
return DateInterval::parse($value, $this->fallbackFormat);

src/Internal/Support/DateInterval.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
/**
1818
* @psalm-type DateIntervalFormat = DateInterval::FORMAT_*
19-
* @psalm-type DateIntervalValue = string | int | float | \DateInterval | Duration
19+
* @psalm-type DateIntervalValue = string | int | float | \DateInterval | Duration | null
2020
*/
2121
final class DateInterval
2222
{
@@ -115,6 +115,10 @@ public static function parse($interval, string $format = self::FORMAT_MILLISECON
115115
$interval->getSeconds() * 1e6 + $interval->getNanos() / 1e3,
116116
self::FORMAT_MICROSECONDS,
117117
);
118+
119+
case $interval === null:
120+
return CarbonInterval::create(0);
121+
118122
default:
119123
throw new \InvalidArgumentException(self::ERROR_INVALID_DATETIME);
120124
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Temporal\Tests\Acceptance\Extra\Workflow\WorkflowA;
6+
7+
use PHPUnit\Framework\Attributes\Test;
8+
use Temporal\Client\WorkflowStubInterface;
9+
use Temporal\Tests\Acceptance\App\Attribute\Stub;
10+
use Temporal\Tests\Acceptance\App\TestCase;
11+
use Temporal\Workflow\WorkflowInterface;
12+
use Temporal\Workflow\WorkflowMethod;
13+
14+
class WorkflowATest extends TestCase
15+
{
16+
#[Test]
17+
public function sendEmpty(
18+
#[Stub(type: 'Workflow')]
19+
WorkflowStubInterface $stub,
20+
): void {
21+
$this->assertSame(42, $stub->getResult());
22+
}
23+
}
24+
25+
#[WorkflowInterface]
26+
class TestWorkflow
27+
{
28+
#[WorkflowMethod(name: "Workflow")]
29+
public function handle()
30+
{
31+
return 42;
32+
}
33+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Temporal\Tests\Acceptance\Extra\Workflow\WorkflowB;
6+
7+
use PHPUnit\Framework\Attributes\CoversFunction;
8+
use PHPUnit\Framework\Attributes\Test;
9+
use Temporal\Client\WorkflowStubInterface;
10+
use Temporal\Tests\Acceptance\App\Attribute\Stub;
11+
use Temporal\Tests\Acceptance\App\TestCase;
12+
use Temporal\Workflow;
13+
use Temporal\Workflow\WorkflowInterface;
14+
use Temporal\Workflow\WorkflowMethod;
15+
16+
class WorkflowBTest extends TestCase
17+
{
18+
#[Test]
19+
public function sendEmpty(
20+
#[Stub(type: 'Workflow')]
21+
WorkflowStubInterface $stub,
22+
): void {
23+
$this->assertSame(24, $stub->getResult());
24+
}
25+
}
26+
27+
#[WorkflowInterface]
28+
class TestWorkflow
29+
{
30+
#[WorkflowMethod(name: "Workflow")]
31+
public function handle()
32+
{
33+
return 24;
34+
}
35+
}

tests/Acceptance/Harness/ContinueAsNew/ContinueAsSameTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static function check(
2727
args: [INPUT_DATA],
2828
memo: [MEMO_KEY => MEMO_VALUE],
2929
)]
30-
WorkflowStubInterface $stub
30+
WorkflowStubInterface $stub,
3131
): void {
3232
self::assertSame(INPUT_DATA, $stub->getResult());
3333
# Workflow ID does not change after continue as new

tests/Unit/Internal/Support/DateIntervalTestCase.php

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,31 @@
1212
#[CoversClass(DateInterval::class)]
1313
final class DateIntervalTestCase extends TestCase
1414
{
15+
public static function provideValuesToParse(): iterable
16+
{
17+
yield [1, DateInterval::FORMAT_MICROSECONDS, 1, '0/0/0/0'];
18+
yield [1, DateInterval::FORMAT_MILLISECONDS, 1_000, '0/0/0/0'];
19+
yield [0.25, DateInterval::FORMAT_SECONDS, 250_000, '0/0/0/0'];
20+
yield [1, DateInterval::FORMAT_SECONDS, 1_000_000, '0/0/0/1'];
21+
yield [1.25, DateInterval::FORMAT_SECONDS, 1_250_000, '0/0/0/1'];
22+
yield [1.8, DateInterval::FORMAT_SECONDS, 1_800_000, '0/0/0/1'];
23+
yield [1, DateInterval::FORMAT_MINUTES, 60_000_000, '0/0/1/0'];
24+
yield [1.5, DateInterval::FORMAT_MINUTES, 90_000_000, '0/0/1/30'];
25+
yield [1, DateInterval::FORMAT_HOURS, 3_600_000_000, '0/1/0/0'];
26+
yield [1, DateInterval::FORMAT_DAYS, 86_400_000_000, '1/0/0/0'];
27+
yield [1, DateInterval::FORMAT_WEEKS, 604_800_000_000, '7/0/0/0'];
28+
yield [(0.1 + 0.7) * 10.0, DateInterval::FORMAT_SECONDS, 8_000_000, '0/0/0/8'];
29+
yield [(0.1 + 0.7) * 10.0, DateInterval::FORMAT_DAYS, 691200000000, '8/0/0/0'];
30+
yield [(0.1 + 0.7) * 10.0, DateInterval::FORMAT_WEEKS, 4838400000000, '56/0/0/0'];
31+
yield [null, DateInterval::FORMAT_MILLISECONDS, 0, '0/0/0/0'];
32+
}
33+
1534
#[DataProvider('provideValuesToParse')]
1635
public function testParse(mixed $value, string $format, int $microseconds, string $formatted): void
1736
{
1837
$i = DateInterval::parse($value, $format);
1938

20-
self::assertSame($microseconds, (int)$i->totalMicroseconds);
39+
self::assertSame($microseconds, (int) $i->totalMicroseconds);
2140
self::assertSame($formatted, $i->format('%d/%h/%i/%s'));
2241
if ($i->totalMicroseconds > 1_000_000) {
2342
self::assertGreaterThan(0, $i->totalSeconds);
@@ -28,7 +47,7 @@ public function testParseAndFormat(): void
2847
{
2948
$i = DateInterval::parse(6_200, DateInterval::FORMAT_MILLISECONDS);
3049

31-
$this->assertSame(6_200_000, (int)$i->totalMicroseconds);
50+
$this->assertSame(6_200_000, (int) $i->totalMicroseconds);
3251
self::assertSame('0/0/0/6', $i->format('%y/%h/%i/%s'));
3352
}
3453

@@ -40,25 +59,7 @@ public function testParseFromDuration(): void
4059

4160
$i = DateInterval::parse($duration);
4261

43-
self::assertSame(5124, (int)$i->totalSeconds);
62+
self::assertSame(5124, (int) $i->totalSeconds);
4463
self::assertSame(123_456, $i->microseconds);
4564
}
46-
47-
public static function provideValuesToParse(): iterable
48-
{
49-
yield [1, DateInterval::FORMAT_MICROSECONDS, 1, '0/0/0/0'];
50-
yield [1, DateInterval::FORMAT_MILLISECONDS, 1_000, '0/0/0/0'];
51-
yield [0.25, DateInterval::FORMAT_SECONDS, 250_000, '0/0/0/0'];
52-
yield [1, DateInterval::FORMAT_SECONDS, 1_000_000, '0/0/0/1'];
53-
yield [1.25, DateInterval::FORMAT_SECONDS, 1_250_000, '0/0/0/1'];
54-
yield [1.8, DateInterval::FORMAT_SECONDS, 1_800_000, '0/0/0/1'];
55-
yield [1, DateInterval::FORMAT_MINUTES, 60_000_000, '0/0/1/0'];
56-
yield [1.5, DateInterval::FORMAT_MINUTES, 90_000_000, '0/0/1/30'];
57-
yield [1, DateInterval::FORMAT_HOURS, 3_600_000_000, '0/1/0/0'];
58-
yield [1, DateInterval::FORMAT_DAYS, 86_400_000_000, '1/0/0/0'];
59-
yield [1, DateInterval::FORMAT_WEEKS, 604_800_000_000, '7/0/0/0'];
60-
yield [(0.1 + 0.7) * 10.0, DateInterval::FORMAT_SECONDS, 8_000_000, '0/0/0/8'];
61-
yield [(0.1 + 0.7) * 10.0, DateInterval::FORMAT_DAYS, 691200000000, '8/0/0/0'];
62-
yield [(0.1 + 0.7) * 10.0, DateInterval::FORMAT_WEEKS, 4838400000000, '56/0/0/0'];
63-
}
6465
}

0 commit comments

Comments
 (0)