diff --git a/phpunit.xml b/phpunit.xml
index 82ce746..1fba752 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -19,6 +19,9 @@
tests/Unit
+
+ tests/Integration
+
diff --git a/src/Attribute/Message.php b/src/Attribute/Message.php
index 73f8d98..793ceb6 100644
--- a/src/Attribute/Message.php
+++ b/src/Attribute/Message.php
@@ -17,6 +17,7 @@ public function __construct(
public readonly string $name,
public array $properties = [],
public array $channels = [],
+ public array $operations = [],
) {
}
@@ -26,6 +27,7 @@ public function toArray(): array
'name' => $this->name,
'properties' => array_map(static fn(PropertyInterface $property) => $property->toArray(), $this->properties),
'channels' => array_map(static fn(Channel $channel) => $channel->toArray(), $this->channels),
+ 'operations' => array_map(static fn(Operation $operation) => $operation->toArray(), $this->operations),
];
}
@@ -39,6 +41,11 @@ public function addChannel(Channel $channel): void
$this->channels[] = $channel;
}
+ public function addOperation(Operation $operation): void
+ {
+ $this->operations[] = $operation;
+ }
+
public function enrich(self $self): self
{
// UPDATE EXISTING
diff --git a/src/Attribute/Operation.php b/src/Attribute/Operation.php
new file mode 100644
index 0000000..f52fcdb
--- /dev/null
+++ b/src/Attribute/Operation.php
@@ -0,0 +1,36 @@
+ $this->name,
+ 'type' => $this->type->value,
+ 'channels' => array_map(
+ static fn (Channel $channel) => $channel->toArray(),
+ $this->channels
+ ),
+ ];
+ }
+
+ public function addChannel(Channel $channel): void
+ {
+ $this->channels[] = $channel;
+ }
+}
diff --git a/src/DocumentationStrategy/AttributeDocumentationStrategy.php b/src/DocumentationStrategy/AttributeDocumentationStrategy.php
index d3fe12b..9978569 100644
--- a/src/DocumentationStrategy/AttributeDocumentationStrategy.php
+++ b/src/DocumentationStrategy/AttributeDocumentationStrategy.php
@@ -6,6 +6,7 @@
use Ferror\AsyncapiDocBundle\Attribute\Channel;
use Ferror\AsyncapiDocBundle\Attribute\Message;
+use Ferror\AsyncapiDocBundle\Attribute\Operation;
use ReflectionAttribute;
use ReflectionClass;
use ReflectionException;
@@ -50,6 +51,14 @@ public function document(string $class): Message
$message->addChannel($channelAttribute->newInstance());
}
+ // Channels are optional as it's possible to document just Messages.
+ /** @var ReflectionAttribute[] $operationAttributes */
+ $operationAttributes = $reflection->getAttributes(Operation::class);
+
+ foreach ($operationAttributes as $operationAttribute) {
+ $message->addOperation($operationAttribute->newInstance());
+ }
+
return $message;
}
}
diff --git a/src/Schema/V3/OperationRenderer.php b/src/Schema/V3/OperationRenderer.php
new file mode 100644
index 0000000..ac86384
--- /dev/null
+++ b/src/Schema/V3/OperationRenderer.php
@@ -0,0 +1,26 @@
+ $operation['type'],
+ 'channel' => [
+ '$ref' => '#/channels/' . $channel['name'],
+ ],
+ ];
+ }
+ }
+
+ return $operations;
+ }
+}
diff --git a/src/Schema/V3/OperationType.php b/src/Schema/V3/OperationType.php
new file mode 100644
index 0000000..2f6e302
--- /dev/null
+++ b/src/Schema/V3/OperationType.php
@@ -0,0 +1,12 @@
+assertEquals($expectedDisplay, $display);
}
- public function testExecuteYaml(): void
+ public function testExecuteYamlV2(): void
{
+ if ($this->isV3()) {
+ $this->markTestSkipped('Skipping schema V2 test on V3 variable');
+ }
+
$kernel = self::bootKernel();
$application = new Application($kernel);
@@ -195,6 +199,141 @@ public function testExecuteYaml(): void
}
}
+ public function testExecuteYamlV3(): void
+ {
+ if (false === $this->isV3()) {
+ $this->markTestSkipped('Skipping schema V3 test on V2 variable');
+ }
+
+ $kernel = self::bootKernel();
+ $application = new Application($kernel);
+
+ $command = $application->find('ferror:asyncapi:dump');
+ $commandTester = new CommandTester($command);
+ $commandTester->execute(['format' => 'yaml']);
+
+ $commandTester->assertCommandIsSuccessful();
+
+ $display = $commandTester->getDisplay();
+
+ $expectedDisplay = <<assertEquals($expectedDisplay, $display);
+
+ mkdir(dirname(__DIR__) . '/../var/' . $this->getSchemaVersion());
+
+ $content = file_put_contents(dirname(__DIR__) . '/../var/' . $this->getSchemaVersion() . '/asyncapi.yaml', $display);
+
+ if (false === $content) {
+ throw new RuntimeException('Schema file was not save');
+ }
+ }
+
public function testExecuteJson(): void
{
$kernel = self::bootKernel();
diff --git a/tests/Unit/DocumentationEditorTest.php b/tests/Unit/DocumentationEditorTest.php
index b75b995..c08dfac 100644
--- a/tests/Unit/DocumentationEditorTest.php
+++ b/tests/Unit/DocumentationEditorTest.php
@@ -43,6 +43,7 @@ public function testDocument(): void
],
],
'channels' => [],
+ 'operations' => [],
];
$this->assertEquals($expected, $actual);
diff --git a/tests/Unit/DocumentationStrategy/AttributeDocumentationStrategyTest.php b/tests/Unit/DocumentationStrategy/AttributeDocumentationStrategyTest.php
index 3f723da..6e00d7c 100644
--- a/tests/Unit/DocumentationStrategy/AttributeDocumentationStrategyTest.php
+++ b/tests/Unit/DocumentationStrategy/AttributeDocumentationStrategyTest.php
@@ -60,6 +60,7 @@ public function testUserSignedUp(): void
'type' => 'subscribe',
],
],
+ 'operations' => [],
];
$this->assertEquals($expected, $actual);
@@ -154,6 +155,7 @@ public function testProductCreated(): void
'type' => 'subscribe',
],
],
+ 'operations' => [],
];
$this->assertEquals($expected, $actual);
diff --git a/tests/Unit/DocumentationStrategy/ReflectionDocumentationStrategyTest.php b/tests/Unit/DocumentationStrategy/ReflectionDocumentationStrategyTest.php
index daf47b6..5c18bc2 100644
--- a/tests/Unit/DocumentationStrategy/ReflectionDocumentationStrategyTest.php
+++ b/tests/Unit/DocumentationStrategy/ReflectionDocumentationStrategyTest.php
@@ -52,6 +52,7 @@ public function test(): void
],
],
'channels' => [],
+ 'operations' => [],
];
$this->assertEquals($expected, $documentation->document(UserSignedUp::class)->toArray());
@@ -98,9 +99,9 @@ public function testEnum(): void
],
],
'channels' => [],
+ 'operations' => [],
];
-
$actual = $documentation->document(ProductCreated::class)->toArray();
$this->assertEquals($expected, $actual);
diff --git a/tests/Unit/Schema/V3/OperationRendererTest.php b/tests/Unit/Schema/V3/OperationRendererTest.php
new file mode 100644
index 0000000..ddc835f
--- /dev/null
+++ b/tests/Unit/Schema/V3/OperationRendererTest.php
@@ -0,0 +1,82 @@
+ 'UserSignedUp',
+ 'properties' => [],
+ 'operations' => [
+ [
+ 'name' => 'UserSignedUpOperation',
+ 'type' => 'send',
+ 'channels' => [
+ [
+ 'name' => 'UserSignedUpChannel',
+ 'type' => 'subscribe',
+ ]
+ ],
+ ]
+ ],
+ ];
+
+ $actual = $renderer->render($document);
+
+ $expected = [
+ 'UserSignedUpOperation' => [
+ 'action' => 'send',
+ 'channel' => [
+ '$ref' => '#/channels/UserSignedUpChannel',
+ ]
+ ]
+ ];
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testItRendersReceiveAction(): void
+ {
+ $renderer = new OperationRenderer();
+
+ $document = [
+ 'name' => 'UserSignedUp',
+ 'properties' => [],
+ 'operations' => [
+ [
+ 'name' => 'UserSignedUpOperation',
+ 'type' => 'receive',
+ 'channels' => [
+ [
+ 'name' => 'UserSignedUpChannel',
+ 'type' => 'subscribe',
+ ]
+ ],
+ ]
+ ],
+ ];
+
+ $actual = $renderer->render($document);
+
+ $expected = [
+ 'UserSignedUpOperation' => [
+ 'action' => 'receive',
+ 'channel' => [
+ '$ref' => '#/channels/UserSignedUpChannel',
+ ]
+ ]
+ ];
+
+ $this->assertEquals($expected, $actual);
+ }
+}