From ee6320c127f8fc700fe1a052dbf8873577a0993e Mon Sep 17 00:00:00 2001 From: viktorprogger Date: Wed, 18 Sep 2024 20:04:44 +0500 Subject: [PATCH 1/3] Ability to find an envelope instance from the given stack --- src/Message/EnvelopeInterface.php | 13 ++++ src/Message/EnvelopeTrait.php | 36 +++++++++++ src/Message/NotEnvelopInterfaceException.php | 22 +++++++ tests/Unit/Message/EnvelopeTraitTest.php | 65 ++++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 src/Message/NotEnvelopInterfaceException.php create mode 100644 tests/Unit/Message/EnvelopeTraitTest.php diff --git a/src/Message/EnvelopeInterface.php b/src/Message/EnvelopeInterface.php index 7c58daa1..0fd61f8b 100644 --- a/src/Message/EnvelopeInterface.php +++ b/src/Message/EnvelopeInterface.php @@ -17,4 +17,17 @@ public static function fromMessage(MessageInterface $message): self; public function getMessage(): MessageInterface; public function withMessage(MessageInterface $message): self; + + /** + * Finds an envelope in the current envelope stack or creates a new one from the message. + * + * @template T + * + * @psalm-param T> $className + * @throws NotEnvelopInterfaceException Implementation MUST throw this exception if the given class does not + * implement {@see EnvelopeInterface}. + * + * @psalm-return T + */ + public function getEnvelopeFromStack(string $className): EnvelopeInterface; } diff --git a/src/Message/EnvelopeTrait.php b/src/Message/EnvelopeTrait.php index cc52cf15..e408e87e 100644 --- a/src/Message/EnvelopeTrait.php +++ b/src/Message/EnvelopeTrait.php @@ -45,6 +45,42 @@ public function getMetadata(): array ); } + /** + * Finds an envelope in the current envelope stack or creates a new one from the message. + * + * @template T + * + * @psalm-param T> $className + * @throws NotEnvelopInterfaceException is thrown if the given class does not implement {@see EnvelopeInterface}. + * + * @psalm-return T + */ + public function getEnvelopeFromStack(string $className): EnvelopeInterface + { + if (!is_a($className, EnvelopeInterface::class, true)) { + throw new NotEnvelopInterfaceException($className); + } + + if (get_class($this) === $className) { + return $this; + } + + if ($this->message instanceof EnvelopeInterface) { + return $this->message->getEnvelopeFromStack($className); + } + + return $className::fromMessage($this->message); + } + + public static function getEnvelopeFromMessage(MessageInterface $message): EnvelopeInterface + { + if ($message instanceof EnvelopeInterface) { + return $message->getEnvelopeFromStack(static::class); + } + + return static::fromMessage($message); + } + public function getEnvelopeMetadata(): array { return []; diff --git a/src/Message/NotEnvelopInterfaceException.php b/src/Message/NotEnvelopInterfaceException.php new file mode 100644 index 00000000..f1e251c1 --- /dev/null +++ b/src/Message/NotEnvelopInterfaceException.php @@ -0,0 +1,22 @@ + true]); + $result = $envelope->getEnvelopeFromStack(IdEnvelope::class); + + $this->assertInstanceOf(IdEnvelope::class, $result); + $this->assertEquals('id value', $result->getId()); + } + + public function testGetEnvelopeFromStackNotInStack(): void + { + $message = new Message('handler', 'data', [IdEnvelope::MESSAGE_ID_KEY => 'id value']); + $envelope = new FailureEnvelope($message, ['fail' => true]); + $result = $envelope->getEnvelopeFromStack(IdEnvelope::class); + + $this->assertInstanceOf(IdEnvelope::class, $result); + $this->assertEquals('id value', $result->getId()); + } + + public function testGetEnvelopeFromStackNotEnvelope(): void + { + $this->expectException(NotEnvelopInterfaceException::class); + $interface = EnvelopeInterface::class; + $this->expectExceptionMessage("The given class \"foo\" does not implement \"$interface\"."); + + $message = new Message('handler', 'data', [IdEnvelope::MESSAGE_ID_KEY => 'id value']); + $envelope = new FailureEnvelope($message, ['fail' => true]); + $envelope->getEnvelopeFromStack('foo'); + } + + public function testGetEnvelopeFromMessage(): void + { + $message = new Message('handler', 'data'); + $envelope = new FailureEnvelope(new IdEnvelope($message, 'id value'), ['fail' => true]); + $result = IdEnvelope::getEnvelopeFromMessage($envelope); + + $this->assertInstanceOf(IdEnvelope::class, $result); + $this->assertEquals('id value', $result->getId()); + } + + public function testGetEnvelopeFromMessageNotInStack(): void + { + $message = new Message('handler', 'data', [IdEnvelope::MESSAGE_ID_KEY => 'id value']); + $result = IdEnvelope::getEnvelopeFromMessage($message); + + $this->assertInstanceOf(IdEnvelope::class, $result); + $this->assertEquals('id value', $result->getId()); + } +} From 4b2b56d1dda7ffd4ebd5e3a72f3b80d222eb0156 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Wed, 18 Sep 2024 15:05:32 +0000 Subject: [PATCH 2/3] Apply fixes from StyleCI --- src/Message/EnvelopeInterface.php | 2 +- src/Message/EnvelopeTrait.php | 2 +- src/Message/NotEnvelopInterfaceException.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Message/EnvelopeInterface.php b/src/Message/EnvelopeInterface.php index 0fd61f8b..e1873bcb 100644 --- a/src/Message/EnvelopeInterface.php +++ b/src/Message/EnvelopeInterface.php @@ -29,5 +29,5 @@ public function withMessage(MessageInterface $message): self; * * @psalm-return T */ - public function getEnvelopeFromStack(string $className): EnvelopeInterface; + public function getEnvelopeFromStack(string $className): self; } diff --git a/src/Message/EnvelopeTrait.php b/src/Message/EnvelopeTrait.php index e408e87e..1dab866d 100644 --- a/src/Message/EnvelopeTrait.php +++ b/src/Message/EnvelopeTrait.php @@ -61,7 +61,7 @@ public function getEnvelopeFromStack(string $className): EnvelopeInterface throw new NotEnvelopInterfaceException($className); } - if (get_class($this) === $className) { + if (static::class === $className) { return $this; } diff --git a/src/Message/NotEnvelopInterfaceException.php b/src/Message/NotEnvelopInterfaceException.php index f1e251c1..f0461df4 100644 --- a/src/Message/NotEnvelopInterfaceException.php +++ b/src/Message/NotEnvelopInterfaceException.php @@ -9,7 +9,7 @@ final class NotEnvelopInterfaceException extends InvalidArgumentException { - public function __construct(string $className = "", int $code = 0, ?Throwable $previous = null) + public function __construct(string $className = '', int $code = 0, ?Throwable $previous = null) { $message = sprintf( 'The given class "%s" does not implement "%s".', From 760edee8cb2e2ca621ee588346b5df1103e2cef4 Mon Sep 17 00:00:00 2001 From: viktorprogger Date: Wed, 18 Sep 2024 20:18:10 +0500 Subject: [PATCH 3/3] Fix some psalm errors --- src/Message/EnvelopeInterface.php | 4 ++-- src/Message/EnvelopeTrait.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Message/EnvelopeInterface.php b/src/Message/EnvelopeInterface.php index e1873bcb..5c8266c3 100644 --- a/src/Message/EnvelopeInterface.php +++ b/src/Message/EnvelopeInterface.php @@ -21,9 +21,9 @@ public function withMessage(MessageInterface $message): self; /** * Finds an envelope in the current envelope stack or creates a new one from the message. * - * @template T + * @template T of EnvelopeInterface * - * @psalm-param T> $className + * @psalm-param class-string $className * @throws NotEnvelopInterfaceException Implementation MUST throw this exception if the given class does not * implement {@see EnvelopeInterface}. * diff --git a/src/Message/EnvelopeTrait.php b/src/Message/EnvelopeTrait.php index 1dab866d..51f4440f 100644 --- a/src/Message/EnvelopeTrait.php +++ b/src/Message/EnvelopeTrait.php @@ -48,9 +48,9 @@ public function getMetadata(): array /** * Finds an envelope in the current envelope stack or creates a new one from the message. * - * @template T + * @template T of EnvelopeInterface * - * @psalm-param T> $className + * @psalm-param class-string $className * @throws NotEnvelopInterfaceException is thrown if the given class does not implement {@see EnvelopeInterface}. * * @psalm-return T