Skip to content

Commit

Permalink
[TransactionalMessenger] Update to get attributes from parent classes
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalzombie committed Aug 20, 2022
1 parent 647b360 commit 9c4f1dc
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 56 deletions.
14 changes: 9 additions & 5 deletions Helper/AttributeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace FRZB\Component\TransactionalMessenger\Helper;

use Fp\Collections\ArrayList;
use Fp\Functional\Option\Option;
use JetBrains\PhpStorm\Immutable;

/** @internal */
Expand Down Expand Up @@ -59,10 +60,13 @@ public static function getAttributes(string|object $target, string $attributeCla
*/
public static function getReflectionAttributes(string|object $target, string $attributeClass): array
{
try {
return (new \ReflectionClass($target))->getAttributes($attributeClass);
} catch (\ReflectionException) {
return [];
}
return Option::fromNullable(ClassHelper::getReflectionClass($target))
->map(
static fn (\ReflectionClass $rClass) => Option::fromNullable(ClassHelper::getParentReflectionClass($rClass))
->map(static fn (\ReflectionClass $rClass) => [...ClassHelper::getReflectionAttributes($rClass, $attributeClass), ...self::getReflectionAttributes($rClass, $attributeClass)])
->getOrElse(ClassHelper::getReflectionAttributes($rClass, $attributeClass))
)
->getOrElse([])
;
}
}
40 changes: 38 additions & 2 deletions Helper/ClassHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,47 @@ private function __construct()
}

public static function getShortName(string|object $target): string
{
return self::getReflectionClass($target)?->getShortName() ?? self::DEFAULT_SHORT_NAME;
}

/**
* @template T
*
* @param class-string<T>|T $target
*
* @return null|\ReflectionClass<T>
*/
public static function getReflectionClass(string|object $target): ?\ReflectionClass
{
try {
return (new \ReflectionClass($target))->getShortName();
return $target instanceof \ReflectionClass ? $target : new \ReflectionClass($target);
} catch (\ReflectionException) {
return self::DEFAULT_SHORT_NAME;
return null;
}
}

/**
* @template T
*
* @param class-string<T>|T $target
*
* @return null|\ReflectionClass<T>
*/
public static function getParentReflectionClass(string|object $target): ?\ReflectionClass
{
return self::getReflectionClass($target)?->getParentClass() ?: null;
}

/**
* @template T
*
* @param class-string<T> $attributeClass
*
* @return \Iterator<\ReflectionAttribute<T>>
*/
public static function getReflectionAttributes(string|object $target, string $attributeClass): iterable
{
return self::getReflectionClass($target)?->getAttributes($attributeClass, \ReflectionAttribute::IS_INSTANCEOF) ?? [];
}
}
3 changes: 1 addition & 2 deletions Helper/TransactionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Fp\Collections\ArrayList;
use FRZB\Component\TransactionalMessenger\Attribute\Transactional;
use FRZB\Component\TransactionalMessenger\Enum\CommitType;
use FRZB\Component\TransactionalMessenger\ValueObject\PendingEnvelope;
use JetBrains\PhpStorm\Immutable;

/** @internal */
Expand All @@ -28,7 +27,7 @@ public static function getTransactional(string|object $target): array
return AttributeHelper::getAttributes($target, Transactional::class);
}

public static function isDispatchAllowed(string|object $target, CommitType ...$commitTypes): bool
public static function isDispatchable(string|object $target, CommitType ...$commitTypes): bool
{
return ArrayList::collect(self::getTransactional($target))
->map(static fn (Transactional $t) => $t->commitTypes)
Expand Down
2 changes: 1 addition & 1 deletion MessageBus/TransactionalMessageBus.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private function dispatchPendingEnvelopes(CommitType ...$commitTypes): void
$notAllowedForDispatchEnvelopes = new StorageImpl();

while ($pendingEnvelope = $this->pendingStorage->next()) {
TransactionHelper::isDispatchAllowed($pendingEnvelope->getMessageClass(), ...$commitTypes)
TransactionHelper::isDispatchable($pendingEnvelope->getMessageClass(), ...$commitTypes)
? $this->dispatchEnvelope($pendingEnvelope->envelope)
: $notAllowedForDispatchEnvelopes->prepend($pendingEnvelope)
;
Expand Down
14 changes: 14 additions & 0 deletions Tests/Stub/Message/AbstractTransactionalMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace FRZB\Component\TransactionalMessenger\Tests\Stub\Message;

use FRZB\Component\TransactionalMessenger\Attribute\Transactional;
use FRZB\Component\TransactionalMessenger\Enum\CommitType;

/** @internal */
#[Transactional(CommitType::OnTerminate)]
abstract class AbstractTransactionalMessage
{
}
9 changes: 9 additions & 0 deletions Tests/Stub/Message/ExtendedTransactionalMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace FRZB\Component\TransactionalMessenger\Tests\Stub\Message;

class ExtendedTransactionalMessage extends AbstractTransactionalMessage
{
}
49 changes: 39 additions & 10 deletions Tests/Unit/Helper/AttributeHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

declare(strict_types=1);


namespace FRZB\Component\TransactionalMessenger\Tests\Unit\Helper;

use FRZB\Component\TransactionalMessenger\Enum\CommitType;
use FRZB\Component\TransactionalMessenger\Attribute\Transactional;
use FRZB\Component\TransactionalMessenger\Helper\AttributeHelper;
use FRZB\Component\TransactionalMessenger\Helper\ClassHelper;
use FRZB\Component\TransactionalMessenger\Helper\TransactionHelper;
use FRZB\Component\TransactionalMessenger\Tests\Stub\Message\ExtendedTransactionalMessage;
use FRZB\Component\TransactionalMessenger\Tests\Stub\Message\NonTransactionalMessage;
use FRZB\Component\TransactionalMessenger\Tests\Stub\Message\TransactionalOnHandledMessage;
use FRZB\Component\TransactionalMessenger\Tests\Stub\Message\TransactionalOnResponseMessage;
Expand All @@ -21,36 +21,65 @@
final class AttributeHelperTest extends TestCase
{
#[DataProvider('dataProvider')]
public function testGetShortNameMethod(string $className, string $shortClassName): void
public function testGetAttributesMethod(string $className, bool $hasAttributes): void
{
$hasAttributes
? self::assertNotEmpty(AttributeHelper::getAttributes($className, Transactional::class))
: self::assertEmpty(AttributeHelper::getAttributes($className, Transactional::class));
}

#[DataProvider('dataProvider')]
public function testGetAttributeMethod(string $className, bool $hasAttributes): void
{
self::assertSame($shortClassName, ClassHelper::getShortName($className));
$hasAttributes
? self::assertNotNull(AttributeHelper::getAttribute($className, Transactional::class))
: self::assertNull(AttributeHelper::getAttribute($className, Transactional::class));
}

#[DataProvider('dataProvider')]
public function testGetReflectionAttributesMethod(string $className, bool $hasAttributes): void
{
$hasAttributes
? self::assertNotEmpty(AttributeHelper::getReflectionAttributes($className, Transactional::class))
: self::assertEmpty(AttributeHelper::getReflectionAttributes($className, Transactional::class));
}

#[DataProvider('dataProvider')]
public function testHasAttributeMethod(string $className, bool $hasAttributes): void
{
self::assertSame($hasAttributes, AttributeHelper::hasAttribute($className, Transactional::class));
}

public function dataProvider(): iterable
{
yield sprintf('%s', ClassHelper::getShortName(TransactionalOnTerminateMessage::class)) => [
'class_name' => TransactionalOnTerminateMessage::class,
'short_class_name' => 'TransactionalOnTerminateMessage',
'has_attributes' => true,
];

yield sprintf('%s', ClassHelper::getShortName(TransactionalOnResponseMessage::class)) => [
'class_name' => TransactionalOnResponseMessage::class,
'short_class_name' => 'TransactionalOnResponseMessage',
'has_attributes' => true,
];

yield sprintf('%s', ClassHelper::getShortName(TransactionalOnHandledMessage::class)) => [
'class_name' => TransactionalOnHandledMessage::class,
'short_class_name' => 'TransactionalOnHandledMessage',
'has_attributes' => true,
];

yield sprintf('%s', ClassHelper::getShortName(ExtendedTransactionalMessage::class)) => [
'class_name' => ExtendedTransactionalMessage::class,
'has_attributes' => true,
];

yield sprintf('%s', ClassHelper::getShortName(NonTransactionalMessage::class)) => [
'class_name' => NonTransactionalMessage::class,
'short_class_name' => 'NonTransactionalMessage',
'has_attributes' => false,
];

yield 'InvalidClassName' => [
'class_name' => 'InvalidClassName',
'short_class_name' => 'InvalidClassName',
'has_attributes' => false,
];
}
}

0 comments on commit 9c4f1dc

Please sign in to comment.