Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: channel attribute extraction #22

Merged
merged 2 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ ferror_asyncapi_doc_bundle_html:
```php
use Ferror\AsyncapiDocBundle\Attribute\Message;
use Ferror\AsyncapiDocBundle\Attribute\Channel;

#[Message(name: 'ProductCreated', channel: 'product.created')]
#[Message(name: 'ProductCreated')]
#[Channel(name: 'product.created')] // optional
final readonly class ProductCreated
{
public function __construct(
Expand All @@ -81,7 +83,8 @@ use Ferror\AsyncapiDocBundle\Attribute as AA;
use Ferror\AsyncapiDocBundle\Schema\Format;
use Ferror\AsyncapiDocBundle\Schema\PropertyType;

#[AA\Message(name: 'ProductCreated', channel: 'product.created')]
#[AA\Message(name: 'ProductCreated')]
#[AA\Channel(name: 'product.created')] // optional
final readonly class ProductCreated
{
public function __construct(
Expand Down
4 changes: 3 additions & 1 deletion example/src/ProductCreated.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
namespace App;

use DateTime;
use Ferror\AsyncapiDocBundle\Attribute\Channel;
use Ferror\AsyncapiDocBundle\Attribute\Message;
use Ferror\AsyncapiDocBundle\Attribute\Property;
use Ferror\AsyncapiDocBundle\Attribute\PropertyArray;
use Ferror\AsyncapiDocBundle\Schema\Format;
use Ferror\AsyncapiDocBundle\Schema\PropertyType;

#[Message(name: 'ProductCreated', channel: 'product.created')]
#[Message(name: 'ProductCreated')]
#[Channel(name: 'product.created')]
final readonly class ProductCreated
{
/**
Expand Down
4 changes: 3 additions & 1 deletion example/src/UserSignedUp.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

namespace App;

use Ferror\AsyncapiDocBundle\Attribute\Channel;
use Ferror\AsyncapiDocBundle\Attribute\Message;

#[Message(name: 'UserSignedUp', channel: 'user_signed_up')]
#[Message(name: 'UserSignedUp')]
#[Channel(name: 'user_signed_up')]
final readonly class UserSignedUp
{
public function __construct(
Expand Down
3 changes: 3 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<testsuite name="all">
<directory>tests</directory>
</testsuite>
<testsuite name="unit">
<directory>tests/Unit</directory>
</testsuite>
</testsuites>

<php>
Expand Down
26 changes: 26 additions & 0 deletions src/Attribute/Channel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Ferror\AsyncapiDocBundle\Attribute;

use Attribute;
use Ferror\AsyncapiDocBundle\Schema\V2\ChannelType;

#[Attribute(Attribute::TARGET_CLASS)]
readonly class Channel
{
public function __construct(
public string $name,
public ChannelType $type = ChannelType::SUBSCRIBE,
) {
}

public function toArray(): array
{
return [
'name' => $this->name,
'type' => $this->type->value,
];
}
}
13 changes: 8 additions & 5 deletions src/Attribute/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,27 @@
namespace Ferror\AsyncapiDocBundle\Attribute;

use Attribute;
use Ferror\AsyncapiDocBundle\Schema\V2\ChannelType;

#[Attribute(Attribute::TARGET_CLASS)]
class Message
{
/**
* @param array<Property|PropertyArray|PropertyEnum|PropertyObject|PropertyArrayObject> $properties
* @param Channel[] $channels
*/
public function __construct(
public readonly string $name,
public readonly string $channel,
public array $properties = [],
public readonly ChannelType $channelType = ChannelType::SUBSCRIBE,
public array $channels = [],
) {
}

public function toArray(): array
{
return [
'name' => $this->name,
'channel' => $this->channel,
'properties' => array_map(static fn(PropertyInterface $property) => $property->toArray(), $this->properties),
'channelType' => $this->channelType->value,
'channels' => array_map(static fn(Channel $channel) => $channel->toArray(), $this->channels),
];
}

Expand All @@ -36,6 +34,11 @@ public function addProperty(Property|PropertyArray|PropertyEnum|PropertyObject|P
$this->properties[] = $property;
}

public function addChannel(Channel $channel): void
{
$this->channels[] = $channel;
}

public function enrich(self $self): self
{
// UPDATE EXISTING
Expand Down
9 changes: 9 additions & 0 deletions src/DocumentationStrategy/AttributeDocumentationStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Ferror\AsyncapiDocBundle\DocumentationStrategy;

use Ferror\AsyncapiDocBundle\Attribute\Channel;
use Ferror\AsyncapiDocBundle\Attribute\Message;
use ReflectionAttribute;
use ReflectionClass;
Expand Down Expand Up @@ -41,6 +42,14 @@ public function document(string $class): Message
$message->addProperty($property);
}

// Channels are optional as it's possible to document just Messages.
/** @var ReflectionAttribute<Channel>[] $messageAttributes */
$channelAttributes = $reflection->getAttributes(Channel::class);

foreach ($channelAttributes as $channelAttribute) {
$message->addChannel($channelAttribute->newInstance());
}

return $message;
}
}
18 changes: 11 additions & 7 deletions src/Schema/V2/ChannelRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ class ChannelRenderer
{
public function render(array $document): array
{
$channel[$document['channel']] = [
$document['channelType'] => [
'message' => [
'$ref' => '#/components/messages/' . $document['name'],
$channels = [];

foreach ($document['channels'] as $channel) {
$channels[$channel['name']] = [
$channel['type'] => [
'message' => [
'$ref' => '#/components/messages/' . $document['name'],
],
],
],
];
];
}

return $channel;
return $channels;
}
}
4 changes: 3 additions & 1 deletion tests/Examples/PaymentExecuted.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

namespace Ferror\AsyncapiDocBundle\Tests\Examples;

use Ferror\AsyncapiDocBundle\Attribute\Channel;
use Ferror\AsyncapiDocBundle\Attribute\Message;

/**
* This class represents an example of documenting by ReflectionStrategy
*/
#[Message(name: 'PaymentExecuted', channel: 'payment_executed')]
#[Message(name: 'PaymentExecuted')]
#[Channel(name: 'payment_executed')]
final readonly class PaymentExecuted
{
public function __construct(
Expand Down
4 changes: 3 additions & 1 deletion tests/Examples/ProductCreated.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Ferror\AsyncapiDocBundle\Tests\Examples;

use DateTime;
use Ferror\AsyncapiDocBundle\Attribute\Channel;
use Ferror\AsyncapiDocBundle\Attribute\Message;
use Ferror\AsyncapiDocBundle\Attribute\Property;
use Ferror\AsyncapiDocBundle\Attribute\PropertyArray;
Expand All @@ -17,7 +18,8 @@
/**
* This class represents an example of documenting by AttributeStrategy. It contains all types.
*/
#[Message(name: 'ProductCreated', channel: 'product.created')]
#[Message(name: 'ProductCreated')]
#[Channel(name: 'product.created')]
final readonly class ProductCreated
{
/**
Expand Down
3 changes: 2 additions & 1 deletion tests/Examples/ProductUpdated.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Ferror\AsyncapiDocBundle\Tests\Examples;

use DateTime;
use Ferror\AsyncapiDocBundle\Attribute\Channel;
use Ferror\AsyncapiDocBundle\Attribute\Message;
use Ferror\AsyncapiDocBundle\Attribute\Property;
use Ferror\AsyncapiDocBundle\Attribute\PropertyArray;
Expand All @@ -19,7 +20,6 @@
*/
#[Message(
name: 'ProductUpdated',
channel: 'product.updated',
properties: [
new Property(name: 'id', type: PropertyType::INTEGER),
new Property(name: 'amount', type: PropertyType::FLOAT),
Expand All @@ -32,6 +32,7 @@
new PropertyArray(name: 'tags', itemsType: PropertyType::STRING),
],
)]
#[Channel(name: 'product.updated')]
final readonly class ProductUpdated
{
/**
Expand Down
4 changes: 3 additions & 1 deletion tests/Examples/UserSignedUp.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Ferror\AsyncapiDocBundle\Tests\Examples;

use Ferror\AsyncapiDocBundle\Attribute\Channel;
use Ferror\AsyncapiDocBundle\Attribute\Message;
use Ferror\AsyncapiDocBundle\Attribute\Property;
use Ferror\AsyncapiDocBundle\Schema\Format;
Expand All @@ -12,7 +13,8 @@
/**
* This class represents a SIMPLE example of documenting by AttributeStrategy.
*/
#[Message(name: 'UserSignedUp', channel: 'user_signed_up')]
#[Message(name: 'UserSignedUp')]
#[Channel(name: 'user_signed_up')]
final readonly class UserSignedUp
{
public function __construct(
Expand Down
8 changes: 4 additions & 4 deletions tests/Unit/Attribute/MessageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ final class MessageTest extends TestCase
{
public function testEnrichAddsProperty(): void
{
$message = new Message('name', 'channel');
$message = new Message('name');

$message->enrich(new Message('name', 'channel', [new Property('name')]));
$message->enrich(new Message('name', [new Property('name')]));

$this->assertCount(1, $message->properties);
}

public function testEnrichUpdatesProperty(): void
{
$message = new Message('name', 'channel', [new Property('name')]);
$message = new Message('name', [new Property('name')]);

$message->enrich(new Message('name', 'channel', [new Property('name', 'Nice Description')]));
$message->enrich(new Message('name', [new Property('name', 'Nice Description')]));

$this->assertEquals('Nice Description', $message->properties[0]->description);
}
Expand Down
3 changes: 1 addition & 2 deletions tests/Unit/DocumentationEditorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ public function testDocument(): void

$expected = [
'name' => 'PaymentExecuted',
'channel' => 'payment_executed',
'channelType' => 'subscribe',
'properties' => [
[
'name' => 'amount',
Expand All @@ -44,6 +42,7 @@ public function testDocument(): void
'example' => null,
],
],
'channels' => [],
];

$this->assertEquals($expected, $actual);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ public function testUserSignedUp(): void

$expected = [
'name' => 'UserSignedUp',
'channel' => 'user_signed_up',
'channelType' => 'subscribe',
'properties' => [
[
'name' => 'name',
Expand Down Expand Up @@ -56,6 +54,12 @@ public function testUserSignedUp(): void
'required' => true,
],
],
'channels' => [
[
'name' => 'user_signed_up',
'type' => 'subscribe',
],
],
];

$this->assertEquals($expected, $actual);
Expand All @@ -69,8 +73,6 @@ public function testProductCreated(): void

$expected = [
'name' => 'ProductCreated',
'channel' => 'product.created',
'channelType' => 'subscribe',
'properties' => [
[
'name' => 'id',
Expand Down Expand Up @@ -146,6 +148,12 @@ public function testProductCreated(): void
'required' => true,
],
],
'channels' => [
[
'name' => 'product.created',
'type' => 'subscribe',
],
],
];

$this->assertEquals($expected, $actual);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ public function test(): void

$expected = [
'name' => 'UserSignedUp',
'channel' => 'user_signed_up',
'channelType' => 'subscribe',
'properties' => [
[
'name' => 'name',
Expand Down Expand Up @@ -53,6 +51,7 @@ public function test(): void
'example' => null,
],
],
'channels' => [],
];

$this->assertEquals($expected, $documentation->document(UserSignedUp::class)->toArray());
Expand All @@ -64,8 +63,6 @@ public function testEnum(): void

$expected = [
'name' => 'ProductCreated',
'channel' => 'product.created',
'channelType' => 'subscribe',
'properties' => [
[
'name' => 'id',
Expand Down Expand Up @@ -100,6 +97,7 @@ public function testEnum(): void
'example' => null
],
],
'channels' => [],
];


Expand Down
Loading
Loading