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']; } }