diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index caff662..18a5eae 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -14,7 +14,5 @@ jobs: extensions: sockets, grpc os: >- ['ubuntu-latest'] - php: >- - ['8.1', '8.2'] stability: >- ['prefer-stable'] diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml index df570fa..e6940e4 100644 --- a/.github/workflows/psalm.yml +++ b/.github/workflows/psalm.yml @@ -13,5 +13,3 @@ jobs: with: os: >- ['ubuntu-latest'] - php: >- - ['8.1'] diff --git a/composer.json b/composer.json index a7c158f..393d0d9 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "require-dev": { "spiral/framework": "^3.0", "spiral/testing": "^2.0", - "vimeo/psalm": "^4.9" + "vimeo/psalm": "^5.17" }, "autoload": { "psr-4": { diff --git a/psalm.xml b/psalm.xml index 7c6aaae..0200c83 100644 --- a/psalm.xml +++ b/psalm.xml @@ -4,6 +4,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" + findUnusedBaselineEntry="true" + findUnusedCode="false" > diff --git a/src/Attribute/AssignWorker.php b/src/Attribute/AssignWorker.php index bb73dea..b7f8028 100644 --- a/src/Attribute/AssignWorker.php +++ b/src/Attribute/AssignWorker.php @@ -6,6 +6,9 @@ use Spiral\Attributes\NamedArgumentConstructor; +/** + * @psalm-suppress DeprecatedClass + */ #[\Attribute(\Attribute::TARGET_CLASS), NamedArgumentConstructor] final class AssignWorker { diff --git a/src/Dispatcher.php b/src/Dispatcher.php index ee2328a..b6db7fa 100644 --- a/src/Dispatcher.php +++ b/src/Dispatcher.php @@ -42,6 +42,7 @@ public function serve(): void $factory = $this->container->get(WorkerFactoryInterface::class); $registry = $this->container->get(WorkersRegistryInterface::class); + $hasDeclarations = false; foreach ($declarations as $type => $declaration) { // Worker that listens on a task queue and hosts both workflow and activity implementations. $queueName = $this->resolveQueueName($declaration) ?? $this->config->getDefaultWorker(); @@ -60,6 +61,11 @@ public function serve(): void fn(ReflectionClass $class): object => $this->container->make($class->getName()), ); } + $hasDeclarations = true; + } + + if (!$hasDeclarations) { + $registry->get(WorkerFactoryInterface::DEFAULT_TASK_QUEUE); } // start primary loop diff --git a/src/Generator/Utils.php b/src/Generator/Utils.php index f2f3c43..be1efc8 100644 --- a/src/Generator/Utils.php +++ b/src/Generator/Utils.php @@ -25,6 +25,7 @@ public static function generateWorkflowSignalMethods(array $signalMethods, Class foreach ($signalMethods as $method) { $params = null; if (\str_contains($method, ',')) { + /** @psalm-suppress PossiblyUndefinedArrayOffset */ [$method, $params] = \explode(',', $method, 2); } @@ -70,10 +71,12 @@ public static function parseMethods(array $methods): array foreach ($methods as $method) { $params = ''; if (\str_contains($method, ',')) { + /** @psalm-suppress PossiblyUndefinedArrayOffset */ [$method, $params] = \explode(',', $method, 2); } if (\str_contains($method, ':')) { + /** @psalm-suppress PossiblyUndefinedArrayOffset */ [$method, $type] = \explode(':', $method, 2); } @@ -100,6 +103,7 @@ public static function parseParameters(array $parameters): array foreach ($parameters as $param) { $type = null; if (\str_contains($param, ':')) { + /** @psalm-suppress PossiblyUndefinedArrayOffset */ [$param, $type] = \explode(':', $param, 2); } diff --git a/tests/src/Commands/MakePresetCommandTest.php b/tests/src/Commands/MakePresetCommandTest.php index 390f424..ffa10da 100644 --- a/tests/src/Commands/MakePresetCommandTest.php +++ b/tests/src/Commands/MakePresetCommandTest.php @@ -16,7 +16,7 @@ final class MakePresetCommandTest extends TestCase public function testNotFoundPresetShouldShowErrorMessage(): void { $this->expectException(PresetNotFoundException::class); - $this->expectErrorMessage('Preset with given name [foo] is not defined.'); + $this->expectExceptionMessage('Preset with given name [foo] is not defined.'); $this->runCommand('temporal:make-preset', ['preset' => 'foo', 'name' => ' bar']); } diff --git a/tests/src/DispatcherTest.php b/tests/src/DispatcherTest.php index 9851571..75f33b6 100644 --- a/tests/src/DispatcherTest.php +++ b/tests/src/DispatcherTest.php @@ -8,7 +8,13 @@ use Spiral\RoadRunnerBridge\RoadRunnerMode; use Spiral\TemporalBridge\Attribute\AssignWorker; use Spiral\TemporalBridge\Config\TemporalConfig; +use Spiral\TemporalBridge\DeclarationLocatorInterface; use Spiral\TemporalBridge\Dispatcher; +use Spiral\TemporalBridge\Tests\App\SomeWorkflow; +use Spiral\TemporalBridge\WorkersRegistryInterface; +use Temporal\Worker\WorkerFactoryInterface; +use Temporal\Worker\WorkerInterface; +use Temporal\Workflow\WorkflowInterface; final class DispatcherTest extends TestCase { @@ -60,6 +66,58 @@ public function testResolvingQueueNameWithoutAttribute(): void $this->assertNull($queue); } + + public function testServeWithoutDeclarations(): void + { + $dispatcher = new Dispatcher( + RoadRunnerMode::Temporal, + new AttributeReader(), + new TemporalConfig(), + $this->getContainer(), + ); + + $locator = $this->mockContainer(DeclarationLocatorInterface::class); + $locator->shouldReceive('getDeclarations')->once()->andReturn([]); + + $registry = $this->mockContainer(WorkersRegistryInterface::class); + $registry + ->shouldReceive('get') + ->once() + ->with(WorkerFactoryInterface::DEFAULT_TASK_QUEUE) + ->andReturn($this->createMock(WorkerInterface::class)); + + $factory = $this->mockContainer(WorkerFactoryInterface::class); + $factory->shouldReceive('run')->once(); + + $dispatcher->serve(); + } + + public function testServeWithDeclarations(): void + { + $dispatcher = new Dispatcher( + RoadRunnerMode::Temporal, + new AttributeReader(), + new TemporalConfig(), + $this->getContainer(), + ); + + $locator = $this->mockContainer(DeclarationLocatorInterface::class); + $locator->shouldReceive('getDeclarations')->once()->andReturn([ + WorkflowInterface::class => new \ReflectionClass(SomeWorkflow::class), + ]); + + $registry = $this->mockContainer(WorkersRegistryInterface::class); + $registry + ->shouldReceive('get') + ->once() + ->with('worker2') + ->andReturn($this->createMock(WorkerInterface::class)); + + $factory = $this->mockContainer(WorkerFactoryInterface::class); + $factory->shouldReceive('run')->once(); + + $dispatcher->serve(); + } } #[AssignWorker(name: 'worker1')] diff --git a/tests/src/Generator/PhpCodePrinterTest.php b/tests/src/Generator/PhpCodePrinterTest.php index 16dafa6..37e4155 100644 --- a/tests/src/Generator/PhpCodePrinterTest.php +++ b/tests/src/Generator/PhpCodePrinterTest.php @@ -14,8 +14,11 @@ final class PhpCodePrinterTest extends TestCase { public function testPrint(): void { + $namespace = new PhpNamespace('Foo\\Bar'); + $namespace->addClass('Baz'); + $printer = new PhpCodePrinter( - new PhpNamespace('Foo\\Bar'), + $namespace, new Context('src/app/', 'App//Foo', 'Bar') ); @@ -28,6 +31,9 @@ public function testPrint(): void namespace Foo\Bar; +class Baz +{ +} CODE , null, true); diff --git a/tests/src/Preset/PresetRegistryTest.php b/tests/src/Preset/PresetRegistryTest.php index 9de2db6..c498c17 100644 --- a/tests/src/Preset/PresetRegistryTest.php +++ b/tests/src/Preset/PresetRegistryTest.php @@ -27,7 +27,7 @@ public function testRegister(): void public function testNotFoundPresetShouldThrowAnException(): void { $this->expectException(PresetNotFoundException::class); - $this->expectErrorMessage('Preset with given name [foo] is not defined.'); + $this->expectExceptionMessage('Preset with given name [foo] is not defined.'); $registry = new PresetRegistry(); diff --git a/tests/src/WorkersRegistryTest.php b/tests/src/WorkersRegistryTest.php index 1b5879a..e725998 100644 --- a/tests/src/WorkersRegistryTest.php +++ b/tests/src/WorkersRegistryTest.php @@ -40,7 +40,7 @@ public function testRegisterWorker(): void public function testRegisterWorkerWithExistsName(): void { $this->expectException(WorkersRegistryException::class); - $this->expectErrorMessage('Temporal worker with given name `foo` has already been registered.'); + $this->expectExceptionMessage('Temporal worker with given name `foo` has already been registered.'); $registry = new WorkersRegistry( $this->createMock(WorkerFactoryInterface::class),