From 91562d76d527a9eb93e465a779ea7dc71e410085 Mon Sep 17 00:00:00 2001 From: Ferror Date: Sat, 3 Feb 2024 22:02:02 +0100 Subject: [PATCH] feat: schema V3 --- src/Attribute/Message.php | 1 - src/Attribute/Operation.php | 36 -------- .../AttributeDocumentationStrategy.php | 11 --- src/Schema/V3/InfoRenderer.php | 15 +++- src/Schema/V3/OperationRenderer.php | 26 ------ src/Schema/V3/OperationType.php | 12 --- src/Schema/V3/SchemaRenderer.php | 6 -- .../Console/DumpSpecificationConsole.php | 1 + src/Symfony/Extension.php | 47 +++++++---- tests/Unit/Schema/V3/ChannelRendererTest.php | 3 - tests/Unit/Schema/V3/InfoRendererTest.php | 10 +-- .../Unit/Schema/V3/OperationRendererTest.php | 82 ------------------- tests/Unit/Schema/V3/SchemaRendererTest.php | 42 +++++----- 13 files changed, 68 insertions(+), 224 deletions(-) delete mode 100644 src/Attribute/Operation.php delete mode 100644 src/Schema/V3/OperationRenderer.php delete mode 100644 src/Schema/V3/OperationType.php delete mode 100644 tests/Unit/Schema/V3/OperationRendererTest.php diff --git a/src/Attribute/Message.php b/src/Attribute/Message.php index daf7faf..73f8d98 100644 --- a/src/Attribute/Message.php +++ b/src/Attribute/Message.php @@ -17,7 +17,6 @@ public function __construct( public readonly string $name, public array $properties = [], public array $channels = [], - public array $operations = [], ) { } diff --git a/src/Attribute/Operation.php b/src/Attribute/Operation.php deleted file mode 100644 index f52fcdb..0000000 --- a/src/Attribute/Operation.php +++ /dev/null @@ -1,36 +0,0 @@ - $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 931f7e9..d3fe12b 100644 --- a/src/DocumentationStrategy/AttributeDocumentationStrategy.php +++ b/src/DocumentationStrategy/AttributeDocumentationStrategy.php @@ -6,7 +6,6 @@ use Ferror\AsyncapiDocBundle\Attribute\Channel; use Ferror\AsyncapiDocBundle\Attribute\Message; -use Ferror\AsyncapiDocBundle\Attribute\Operation; use ReflectionAttribute; use ReflectionClass; use ReflectionException; @@ -37,17 +36,7 @@ public function document(string $class): Message throw new DocumentationStrategyException('Error: class ' . $class . ' must have at least ' . Message::class . ' attribute.'); } - /** @var ReflectionAttribute[] $operationAttributes */ - $operationAttributes = $reflection->getAttributes(Operation::class); - - /** @var ReflectionAttribute[] $channelAttributes */ - $channelAttributes = $reflection->getAttributes(Channel::class); - $message = $messageAttributes[0]->newInstance(); - $operation = $operationAttributes[0]->newInstance(); - $channel = $channelAttributes[0]->newInstance(); - - $operation->addChannel($channel); foreach ($this->propertyExtractor->extract($class) as $property) { $message->addProperty($property); diff --git a/src/Schema/V3/InfoRenderer.php b/src/Schema/V3/InfoRenderer.php index 9a0c4be..e04b0c5 100644 --- a/src/Schema/V3/InfoRenderer.php +++ b/src/Schema/V3/InfoRenderer.php @@ -6,12 +6,19 @@ final readonly class InfoRenderer { - public function render(array $document): array + public function __construct( + public string $title, + public string $description, + public string $version, + ) { + } + + public function render(): array { return [ - 'title' => $document['title'], - 'version' => $document['version'], - 'description' => $document['description'], + 'title' => $this->title, + 'version' => $this->version, + 'description' => $this->description, ]; } } diff --git a/src/Schema/V3/OperationRenderer.php b/src/Schema/V3/OperationRenderer.php deleted file mode 100644 index ac86384..0000000 --- a/src/Schema/V3/OperationRenderer.php +++ /dev/null @@ -1,26 +0,0 @@ - $operation['type'], - 'channel' => [ - '$ref' => '#/channels/' . $channel['name'], - ], - ]; - } - } - - return $operations; - } -} diff --git a/src/Schema/V3/OperationType.php b/src/Schema/V3/OperationType.php deleted file mode 100644 index 2f6e302..0000000 --- a/src/Schema/V3/OperationType.php +++ /dev/null @@ -1,12 +0,0 @@ -documentationEditor->document($class); @@ -36,22 +34,18 @@ public function generate(): array $channel = $this->channelRenderer->render($document); $message = $this->messageRenderer->render($document); - $operation = $this->operationRenderer->render($document); $channelKey = key($channel); $messageKey = key($message); - $operationKey = key($operation); $channels[$channelKey] = $channel[$channelKey]; $messages[$messageKey] = $message[$messageKey]; - $operations[$operationKey] = $operation[$operationKey]; } $schema = [ 'asyncapi' => $this->schemaVersion, 'info' => $this->infoRenderer->render(), 'channels' => $channels, - 'operations' => $operations, 'components' => [ 'messages' => $messages, ], diff --git a/src/Symfony/Console/DumpSpecificationConsole.php b/src/Symfony/Console/DumpSpecificationConsole.php index 6fefaac..11d54bd 100644 --- a/src/Symfony/Console/DumpSpecificationConsole.php +++ b/src/Symfony/Console/DumpSpecificationConsole.php @@ -9,6 +9,7 @@ use Ferror\AsyncapiDocBundle\DocumentationStrategy\DocumentationStrategyInterface; use Ferror\AsyncapiDocBundle\Generator\GeneratorFactory; use Ferror\AsyncapiDocBundle\Schema\V2\MessageRenderer; +use Ferror\AsyncapiDocBundle\SchemaRendererInterface; use Ferror\AsyncapiDocBundle\Tests\Examples\UserSignedUp; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; diff --git a/src/Symfony/Extension.php b/src/Symfony/Extension.php index 8fb7858..b768e9f 100644 --- a/src/Symfony/Extension.php +++ b/src/Symfony/Extension.php @@ -12,9 +12,12 @@ use Ferror\AsyncapiDocBundle\Generator\JsonGenerator; use Ferror\AsyncapiDocBundle\Generator\YamlGenerator; use Ferror\AsyncapiDocBundle\Schema\SchemaGeneratorFactory; -use Ferror\AsyncapiDocBundle\Schema\V2\ChannelRenderer; -use Ferror\AsyncapiDocBundle\Schema\V2\InfoRenderer; -use Ferror\AsyncapiDocBundle\Schema\V2\MessageRenderer; +use Ferror\AsyncapiDocBundle\Schema\V2\ChannelRenderer as ChannelV2Renderer; +use Ferror\AsyncapiDocBundle\Schema\V3\ChannelRenderer as ChannelV3Renderer; +use Ferror\AsyncapiDocBundle\Schema\V2\InfoRenderer as InfoV2Renderer; +use Ferror\AsyncapiDocBundle\Schema\V3\InfoRenderer as InfoV3Renderer; +use Ferror\AsyncapiDocBundle\Schema\V2\MessageRenderer as MessageV2Renderer; +use Ferror\AsyncapiDocBundle\Schema\V3\MessageRenderer as MessageV3Renderer; use Ferror\AsyncapiDocBundle\Schema\V2\SchemaRenderer as SchemaV2Renderer; use Ferror\AsyncapiDocBundle\Schema\V3\SchemaRenderer as SchemaV3Renderer; use Ferror\AsyncapiDocBundle\SchemaRendererInterface; @@ -54,34 +57,50 @@ public function load(array $configs, ContainerBuilder $container): void ->addTag('ferror.asyncapi_doc_bundle.documentation-strategy') ; + $container + ->register(DocumentationEditor::class) + ; + // Async API v2 - $container->register(ChannelRenderer::class); - $container->register(MessageRenderer::class); + $container->register(ChannelV2Renderer::class); + $container->register(MessageV2Renderer::class); $container - ->register(InfoRenderer::class) + ->register(InfoV2Renderer::class) ->addArgument($config['title']) ->addArgument($config['description']) ->addArgument($config['version']) ; - $container - ->register(DocumentationEditor::class) - ; - $container ->register(SchemaV2Renderer::class) ->addArgument(new Reference('ferror.asyncapi_doc_bundle.class_finder.manual')) ->addArgument(new Reference(DocumentationEditor::class)) - ->addArgument(new Reference(ChannelRenderer::class)) - ->addArgument(new Reference(MessageRenderer::class)) - ->addArgument(new Reference(InfoRenderer::class)) + ->addArgument(new Reference(ChannelV2Renderer::class)) + ->addArgument(new Reference(MessageV2Renderer::class)) + ->addArgument(new Reference(InfoV2Renderer::class)) ->addArgument($config['servers']) ->addArgument($config['asyncapi_version']) ; // Async API v3 + $container->register(ChannelV3Renderer::class); + $container->register(MessageV3Renderer::class); + $container + ->register(InfoV3Renderer::class) + ->addArgument($config['title']) + ->addArgument($config['description']) + ->addArgument($config['version']) + ; + $container ->register(SchemaV3Renderer::class) + ->addArgument(new Reference('ferror.asyncapi_doc_bundle.class_finder.manual')) + ->addArgument(new Reference(DocumentationEditor::class)) + ->addArgument(new Reference(InfoV3Renderer::class)) + ->addArgument(new Reference(MessageV3Renderer::class)) + ->addArgument(new Reference(ChannelV3Renderer::class)) + ->addArgument($config['servers']) + ->addArgument($config['asyncapi_version']) ; // Version Agnostic @@ -134,7 +153,7 @@ public function load(array $configs, ContainerBuilder $container): void ->register('ferror.asyncapi_doc_bundle.console', DumpSpecificationConsole::class) ->addArgument(new Reference('ferror.asyncapi_doc_bundle.generator-factory')) ->addArgument(new Reference('ferror.asyncapi_doc_bundle.documentation.attributes')) - ->addArgument(new Reference(MessageRenderer::class)) + ->addArgument(new Reference(MessageV2Renderer::class)) ->addTag('console.command') ; } diff --git a/tests/Unit/Schema/V3/ChannelRendererTest.php b/tests/Unit/Schema/V3/ChannelRendererTest.php index d5b2bc2..4f3e457 100644 --- a/tests/Unit/Schema/V3/ChannelRendererTest.php +++ b/tests/Unit/Schema/V3/ChannelRendererTest.php @@ -16,9 +16,6 @@ public function testItRenders(): void $document = [ 'name' => 'UserSignedUp', 'properties' => [], - 'operations' => [ - 'UserSignedUpOperation' - ], 'channels' => [ [ 'name' => 'UserSignedUpChannel', diff --git a/tests/Unit/Schema/V3/InfoRendererTest.php b/tests/Unit/Schema/V3/InfoRendererTest.php index dfe7d0b..9a28789 100644 --- a/tests/Unit/Schema/V3/InfoRendererTest.php +++ b/tests/Unit/Schema/V3/InfoRendererTest.php @@ -11,15 +11,9 @@ final class InfoRendererTest extends TestCase { public function testItRenders(): void { - $renderer = new InfoRenderer(); + $renderer = new InfoRenderer('Async API Title', 'Async API Description', '2.6.0'); - $document = [ - 'version' => '2.6.0', - 'title' => 'Async API Title', - 'description' => 'Async API Description', - ]; - - $actual = $renderer->render($document); + $actual = $renderer->render(); $expected = [ 'version' => '2.6.0', diff --git a/tests/Unit/Schema/V3/OperationRendererTest.php b/tests/Unit/Schema/V3/OperationRendererTest.php deleted file mode 100644 index ddc835f..0000000 --- a/tests/Unit/Schema/V3/OperationRendererTest.php +++ /dev/null @@ -1,82 +0,0 @@ - '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); - } -} diff --git a/tests/Unit/Schema/V3/SchemaRendererTest.php b/tests/Unit/Schema/V3/SchemaRendererTest.php index fb7774b..c5edb7b 100644 --- a/tests/Unit/Schema/V3/SchemaRendererTest.php +++ b/tests/Unit/Schema/V3/SchemaRendererTest.php @@ -12,7 +12,6 @@ use Ferror\AsyncapiDocBundle\Schema\V3\ChannelRenderer; use Ferror\AsyncapiDocBundle\Schema\V3\InfoRenderer; use Ferror\AsyncapiDocBundle\Schema\V3\MessageRenderer; -use Ferror\AsyncapiDocBundle\Schema\V3\OperationRenderer; use Ferror\AsyncapiDocBundle\Schema\V3\SchemaRenderer; use Ferror\AsyncapiDocBundle\Tests\Examples\UserSignedUp; use PHPUnit\Framework\TestCase; @@ -29,9 +28,8 @@ public function testItRenders(): void new AttributeDocumentationStrategy(new PropertyExtractor()), new ReflectionDocumentationStrategy(), ]), - new InfoRenderer(), + new InfoRenderer('Service Example API', 'This service is in charge of processing user signups', '1.0.0'), new MessageRenderer(), - new OperationRenderer(), new ChannelRenderer(), [], '3.0.0', @@ -42,12 +40,12 @@ public function testItRenders(): void $expected = [ 'asyncapi' => '3.0.0', 'info' => [ - 'title' => 'Account Service', + 'title' => 'Service Example API', 'version' => '1.0.0', 'description' => 'This service is in charge of processing user signups', ], 'channels' => [ - 'userSignedUpChannel' => [ + 'user_signed_up' => [ 'messages' => [ 'UserSignedUp' => [ '$ref' => '#/components/messages/UserSignedUp', @@ -55,36 +53,38 @@ public function testItRenders(): void ], ], ], - 'operations' => [ - 'sendUserSignedUpOperation' => [ - 'action' => 'send', - 'channel' => [ - '$ref' => '#/channels/userSignedUpChannel', - ], - ], - 'receiveUserSignedUpOperation' => [ - 'action' => 'receive', - 'channel' => [ - '$ref' => '#/channels/userSignedUpChannel', - ], - ], - ], 'components' => [ 'messages' => [ 'UserSignedUp' => [ 'payload' => [ 'type' => 'object', 'properties' => [ - 'displayName' => [ + 'name' => [ 'type' => 'string', 'description' => 'Name of the user', + 'format' => 'string', + 'example' => 'John', ], 'email' => [ 'type' => 'string', - 'format' => 'email', 'description' => 'Email of the user', + 'format' => 'email', + 'example' => 'john@example.com', + ], + 'age' => [ + 'type' => 'integer', + 'description' => 'Age of the user', + 'format' => 'int32', + 'example' => 18, + ], + 'isCitizen' => [ + 'type' => 'boolean', + 'description' => 'Is user a citizen', + 'format' => 'boolean', + 'example' => true, ], ], + 'required' => ['name', 'email', 'age', 'isCitizen'], ], ], ],