diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 6c163ee3..bbb87795 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -874,6 +874,12 @@
+
+
+
+
+
+
diff --git a/src/Internal/Support/DateInterval.php b/src/Internal/Support/DateInterval.php
index f23eb4e5..2d4d762e 100644
--- a/src/Internal/Support/DateInterval.php
+++ b/src/Internal/Support/DateInterval.php
@@ -20,8 +20,12 @@
*/
final class DateInterval
{
+ /** @deprecated Use days instead */
public const FORMAT_YEARS = 'years';
+
+ /** @deprecated Use days instead */
public const FORMAT_MONTHS = 'months';
+
public const FORMAT_WEEKS = 'weeks';
public const FORMAT_DAYS = 'days';
public const FORMAT_HOURS = 'hours';
@@ -73,11 +77,17 @@ public static function parse($interval, string $format = self::FORMAT_MILLISECON
default => $fraction > 0 ? match ($format) {
self::FORMAT_SECONDS => $fraction * 1_000_000,
self::FORMAT_MINUTES => $fraction * 60_000_000,
+ self::FORMAT_HOURS => $fraction * 3_600_000_000,
+ self::FORMAT_DAYS => $fraction * 86_400_000_000,
+ self::FORMAT_WEEKS => $fraction * 604_800_000_000,
default => 0,
} : 0,
};
+ $micros = (int) \round($micros);
+ $seconds = (int) \floor($micros / 1_000_000);
+ $micros = $micros - ($seconds * 1_000_000);
- $seconds = \floor($micros / 1_000_000) + \floor(match ($format) {
+ $seconds += \floor(match ($format) {
self::FORMAT_SECONDS => $int,
self::FORMAT_MINUTES => $int * 60,
self::FORMAT_HOURS => $int * 3600,
@@ -97,7 +107,7 @@ public static function parse($interval, string $format = self::FORMAT_MILLISECON
hours: $hours % 24,
minutes: $minutes % 60,
seconds: $seconds % 60,
- microseconds: $micros % 1000_000,
+ microseconds: $micros,
);
case $interval instanceof Duration:
diff --git a/testing/src/Environment.php b/testing/src/Environment.php
index 6687b600..3c74441b 100644
--- a/testing/src/Environment.php
+++ b/testing/src/Environment.php
@@ -9,6 +9,7 @@
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\Process\Process;
+use Temporal\Common\SearchAttributes\ValueType;
final class Environment
{
@@ -52,11 +53,41 @@ public function start(?string $rrCommand = null, int $commandTimeout = 10, array
/**
* @param list $parameters
+ * @param array $searchAttributes Key is the name of the search
+ * attribute, value is the type of the search attribute. Expected values from {@see ValueType}.
*/
- public function startTemporalServer(int $commandTimeout = 10, array $parameters = []): void
- {
+ public function startTemporalServer(
+ int $commandTimeout = 10,
+ array $parameters = [],
+ array $searchAttributes = [],
+ ): void {
$temporalPort = \parse_url(\getenv('TEMPORAL_ADDRESS') ?: '127.0.0.1:7233', PHP_URL_PORT);
+ // Add search attributes
+ foreach ($searchAttributes as $name => $type) {
+ $type = \is_string($type) ? ValueType::tryFrom($type) : $type;
+ if (!$type instanceof ValueType) {
+ \trigger_error('Invalid search attribute type: ' . \get_debug_type($type), E_USER_WARNING);
+ continue;
+ }
+
+ if (\preg_match('/^[a-zA-Z0-9_-]+$/', $name) !== 1) {
+ \trigger_error('Invalid search attribute name: ' . $name, E_USER_WARNING);
+ continue;
+ }
+
+ $parameters[] = '--search-attribute';
+ $parameters[] = $name . '=' . match ($type) {
+ ValueType::Bool => 'bool',
+ ValueType::Float => 'double',
+ ValueType::Int => 'int',
+ ValueType::Keyword => 'keyword',
+ ValueType::KeywordList => 'keywordList',
+ ValueType::String => 'text',
+ ValueType::Datetime => 'datetime',
+ };
+ }
+
$this->output->write('Starting Temporal test server... ');
$this->temporalServerProcess = new Process(
[
diff --git a/tests/Acceptance/App/Runtime/TemporalStarter.php b/tests/Acceptance/App/Runtime/TemporalStarter.php
index 3f61fe13..44df7840 100644
--- a/tests/Acceptance/App/Runtime/TemporalStarter.php
+++ b/tests/Acceptance/App/Runtime/TemporalStarter.php
@@ -4,6 +4,7 @@
namespace Temporal\Tests\Acceptance\App\Runtime;
+use Temporal\Common\SearchAttributes\ValueType;
use Temporal\Testing\Environment;
final class TemporalStarter
@@ -23,16 +24,16 @@ public function start(): void
return;
}
- $this->environment->startTemporalServer(parameters: [
- '--search-attribute', 'foo=text',
- '--search-attribute', 'bar=int',
- '--search-attribute', 'testBool=bool',
- '--search-attribute', 'testInt=int',
- '--search-attribute', 'testFloat=double',
- '--search-attribute', 'testString=text',
- '--search-attribute', 'testKeyword=keyword',
- '--search-attribute', 'testKeywordList=keywordList',
- '--search-attribute', 'testDatetime=datetime',
+ $this->environment->startTemporalServer(searchAttributes: [
+ 'foo' => ValueType::String->value,
+ 'bar' => ValueType::Int->value,
+ 'testBool' => ValueType::Bool,
+ 'testInt' => ValueType::Int,
+ 'testFloat' => ValueType::Float,
+ 'testString' => ValueType::String,
+ 'testKeyword' => ValueType::Keyword,
+ 'testKeywordList' => ValueType::KeywordList,
+ 'testDatetime' => ValueType::Datetime,
]);
$this->started = true;
}
diff --git a/tests/Unit/Internal/Support/DateIntervalTestCase.php b/tests/Unit/Internal/Support/DateIntervalTestCase.php
index 5ec7dfda..dddb809b 100644
--- a/tests/Unit/Internal/Support/DateIntervalTestCase.php
+++ b/tests/Unit/Internal/Support/DateIntervalTestCase.php
@@ -57,5 +57,8 @@ public static function provideValuesToParse(): iterable
yield [1, DateInterval::FORMAT_HOURS, 3_600_000_000, '0/1/0/0'];
yield [1, DateInterval::FORMAT_DAYS, 86_400_000_000, '1/0/0/0'];
yield [1, DateInterval::FORMAT_WEEKS, 604_800_000_000, '7/0/0/0'];
+ yield [(0.1 + 0.7) * 10.0, DateInterval::FORMAT_SECONDS, 8_000_000, '0/0/0/8'];
+ yield [(0.1 + 0.7) * 10.0, DateInterval::FORMAT_DAYS, 691200000000, '8/0/0/0'];
+ yield [(0.1 + 0.7) * 10.0, DateInterval::FORMAT_WEEKS, 4838400000000, '56/0/0/0'];
}
}