From 6b67d4893958e1c4a4e20e85d1e1961589de08b8 Mon Sep 17 00:00:00 2001 From: Anatoliy Melnikov <5785276@gmail.com> Date: Wed, 12 Jun 2024 22:06:22 +0300 Subject: [PATCH] Move responsibility for key injection out of Registrar into CommentRegistrar --- src/ApplicationFactory.php | 2 ++ src/Dto/Comment/CommentPart.php | 18 ++++++++++ src/Dto/Registrar/Todo.php | 36 ++++++++++++++++++++ src/Service/CommentRegistrar.php | 7 ++-- src/Service/Registrar/JIRA/JiraRegistrar.php | 26 +++++++------- src/Service/Registrar/RegistrarInterface.php | 6 ++-- src/Service/TodoFactory.php | 21 ++++++++++++ tests/Unit/Service/CommentRegistrarTest.php | 20 +++++++---- 8 files changed, 111 insertions(+), 25 deletions(-) create mode 100644 src/Dto/Registrar/Todo.php create mode 100644 src/Service/TodoFactory.php diff --git a/src/ApplicationFactory.php b/src/ApplicationFactory.php index cbf3360..5774bca 100644 --- a/src/ApplicationFactory.php +++ b/src/ApplicationFactory.php @@ -12,6 +12,7 @@ use Aeliot\TodoRegistrar\Service\FileProcessor; use Aeliot\TodoRegistrar\Service\Registrar\RegistrarFactory; use Aeliot\TodoRegistrar\Service\Registrar\RegistrarInterface; +use Aeliot\TodoRegistrar\Service\TodoFactory; class ApplicationFactory { @@ -33,6 +34,7 @@ private function createCommentRegistrar(RegistrarInterface $registrar): CommentR new Detector(), new Extractor(), $registrar, + new TodoFactory(), ); } diff --git a/src/Dto/Comment/CommentPart.php b/src/Dto/Comment/CommentPart.php index d054904..5994c32 100644 --- a/src/Dto/Comment/CommentPart.php +++ b/src/Dto/Comment/CommentPart.php @@ -25,6 +25,18 @@ public function addLine(string $line): void $this->lines[] = $line; } + public function getDescription(): string + { + if (!$this->lines) { + throw new NoLineException('Cannot get description till added one line'); + } + + $prefixLength = (int) $this->tagMetadata?->getPrefixLength(); + $lines = array_map(static fn(string $line): string => substr($line, $prefixLength), $this->lines); + + return implode('', $lines); + } + public function getFirstLine(): string { if (!$this->lines) { @@ -44,9 +56,15 @@ public function getLines(): array public function getPrefixLength(): ?int { + // THINK: throw exception when there is no prefix return $this->tagMetadata?->getPrefixLength(); } + public function getSummary(): string + { + return trim(substr($this->getFirstLine(), $this->getPrefixLength())); + } + public function getTag(): ?string { return $this->tagMetadata?->getTag(); diff --git a/src/Dto/Registrar/Todo.php b/src/Dto/Registrar/Todo.php new file mode 100644 index 0000000..4772fd9 --- /dev/null +++ b/src/Dto/Registrar/Todo.php @@ -0,0 +1,36 @@ +assignee; + } + + public function getDescription(): string + { + return $this->description; + } + + public function getSummary(): string + { + return $this->summary; + } + + public function getTag(): string + { + return $this->tag; + } +} \ No newline at end of file diff --git a/src/Service/CommentRegistrar.php b/src/Service/CommentRegistrar.php index e5b1da0..eabbf96 100644 --- a/src/Service/CommentRegistrar.php +++ b/src/Service/CommentRegistrar.php @@ -14,6 +14,7 @@ public function __construct( private CommentDetector $commentDetector, private CommentExtractor $commentExtractor, private RegistrarInterface $registrar, + private TodoFactory $todoFactory, ) { } @@ -39,10 +40,12 @@ private function registerTodos(array $tokens): bool foreach ($tokens as $token) { $commentParts = $this->commentExtractor->extract($token->text); foreach ($commentParts->getTodos() as $commentPart) { - if ($this->registrar->isRegistered($commentPart)) { + $todo = $this->todoFactory->create($commentPart); + if ($this->registrar->isRegistered($todo)) { continue; } - $this->registrar->register($commentPart); + $key = $this->registrar->register($todo); + $commentPart->injectKey($key); $hasNewTodo = true; } diff --git a/src/Service/Registrar/JIRA/JiraRegistrar.php b/src/Service/Registrar/JIRA/JiraRegistrar.php index 0a6b03b..ea127ee 100644 --- a/src/Service/Registrar/JIRA/JiraRegistrar.php +++ b/src/Service/Registrar/JIRA/JiraRegistrar.php @@ -4,7 +4,7 @@ namespace Aeliot\TodoRegistrar\Service\Registrar\JIRA; -use Aeliot\TodoRegistrar\Dto\Comment\CommentPart; +use Aeliot\TodoRegistrar\Dto\Registrar\Todo; use Aeliot\TodoRegistrar\Service\Registrar\RegistrarInterface; use JiraRestApi\Issue\IssueField; use JiraRestApi\Issue\IssueService; @@ -17,38 +17,36 @@ public function __construct( ) { } - public function isRegistered(CommentPart $commentPart): bool + public function isRegistered(Todo $todo): bool { - $lineWithoutPrefix = substr($commentPart->getFirstLine(), $commentPart->getPrefixLength()); - - return preg_match('/^\\s*\\b[A-Z]+-\\d+\\b/i', $lineWithoutPrefix); + return preg_match('/^\\s*\\b[A-Z]+-\\d+\\b/i', $todo->getSummary()); } - public function register(CommentPart $commentPart): void + public function register(Todo $todo): string { - $issueField = $this->createIssueField($commentPart); - $issue = $this->issueService->create($issueField); - $commentPart->injectKey($issue->key); + $issueField = $this->createIssueField($todo); + + return $this->issueService->create($issueField)->key; } - private function createIssueField(CommentPart $commentPart): IssueField + private function createIssueField(Todo $todo): IssueField { $issueField = new IssueField(); $issueField ->setProjectKey($this->issueConfig->getProjectKey()) ->setIssueTypeAsString($this->issueConfig->getIssueType()) - ->setSummary($commentPart->getFirstLine()) - ->setDescription($commentPart->getContent()) + ->setSummary($todo->getSummary()) + ->setDescription($todo->getDescription()) ->addComponentsAsArray($this->issueConfig->getComponents()); - $assignee = $commentPart->getTagMetadata()?->getAssignee(); + $assignee = $todo->getAssignee(); if ($assignee) { $issueField->setAssigneeNameAsString($assignee); } $labels = $this->issueConfig->getLabels(); if ($this->issueConfig->addTagToLabels()) { - $labels[] = strtolower(sprintf('%s%s', $this->issueConfig->getTagPrefix(), $commentPart->getTag())); + $labels[] = strtolower(sprintf('%s%s', $this->issueConfig->getTagPrefix(), $todo->getTag())); } foreach ($labels as $label) { diff --git a/src/Service/Registrar/RegistrarInterface.php b/src/Service/Registrar/RegistrarInterface.php index a5a290f..94dd03b 100644 --- a/src/Service/Registrar/RegistrarInterface.php +++ b/src/Service/Registrar/RegistrarInterface.php @@ -4,11 +4,11 @@ namespace Aeliot\TodoRegistrar\Service\Registrar; -use Aeliot\TodoRegistrar\Dto\Comment\CommentPart; +use Aeliot\TodoRegistrar\Dto\Registrar\Todo; interface RegistrarInterface { - public function isRegistered(CommentPart $commentPart): bool; + public function isRegistered(Todo $todo): bool; - public function register(CommentPart $commentPart): void; + public function register(Todo $todo): string; } \ No newline at end of file diff --git a/src/Service/TodoFactory.php b/src/Service/TodoFactory.php new file mode 100644 index 0000000..76e84e8 --- /dev/null +++ b/src/Service/TodoFactory.php @@ -0,0 +1,21 @@ +getTag(), + $commentPart->getFirstLine(), + $commentPart->getContent(), + $commentPart->getTagMetadata()?->getAssignee(), + ); + } +} \ No newline at end of file diff --git a/tests/Unit/Service/CommentRegistrarTest.php b/tests/Unit/Service/CommentRegistrarTest.php index fbd19f6..69668b5 100644 --- a/tests/Unit/Service/CommentRegistrarTest.php +++ b/tests/Unit/Service/CommentRegistrarTest.php @@ -6,11 +6,13 @@ use Aeliot\TodoRegistrar\Dto\Comment\CommentPart; use Aeliot\TodoRegistrar\Dto\Comment\CommentParts; +use Aeliot\TodoRegistrar\Dto\Registrar\Todo; use Aeliot\TodoRegistrar\Dto\Tag\TagMetadata; use Aeliot\TodoRegistrar\Service\Comment\Detector as CommentDetector; use Aeliot\TodoRegistrar\Service\Comment\Extractor as CommentExtractor; use Aeliot\TodoRegistrar\Service\CommentRegistrar; use Aeliot\TodoRegistrar\Service\Registrar\RegistrarInterface; +use Aeliot\TodoRegistrar\Service\TodoFactory; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -25,7 +27,8 @@ public function testDontRegisterTwice(): void $commentParts = $this->createCommentParts(); $commentExtractor = $this->mockCommentExtractor($commentParts); - $todo = $commentParts->getTodos()[0]; + $todoFactory = new TodoFactory(); + $todo = $todoFactory->create($commentParts->getTodos()[0]); $registrar = $this->mockRegistrar($todo, true); $registrar @@ -33,7 +36,7 @@ public function testDontRegisterTwice(): void ->method('register') ->with($todo); - $commentRegistrar = new CommentRegistrar($commentDetector, $commentExtractor, $registrar); + $commentRegistrar = new CommentRegistrar($commentDetector, $commentExtractor, $registrar, $todoFactory); $commentRegistrar->register($tokens); } @@ -44,16 +47,21 @@ public function testRegisterNewTodos(): void $commentParts = $this->createCommentParts(); $commentExtractor = $this->mockCommentExtractor($commentParts); - $todo = $commentParts->getTodos()[0]; + $token = $commentParts->getTodos()[0]; + $todoFactory = new TodoFactory(); + $todo = $todoFactory->create($token); $registrar = $this->mockRegistrar($todo, false); $registrar ->expects($this->once()) ->method('register') - ->with($todo); + ->with($todo) + ->willReturn('X-001'); - $commentRegistrar = new CommentRegistrar($commentDetector, $commentExtractor, $registrar); + $commentRegistrar = new CommentRegistrar($commentDetector, $commentExtractor, $registrar, $todoFactory); $commentRegistrar->register($tokens); + + self::assertSame('// TODO X-001 single line comment', $tokens[2]->text); } public function createCommentParts(): CommentParts @@ -108,7 +116,7 @@ private function mockCommentExtractor(CommentParts $commentParts): CommentExtrac return $commentExtractor; } - public function mockRegistrar(CommentPart $todo, bool $isRegistered): RegistrarInterface&MockObject + public function mockRegistrar(Todo $todo, bool $isRegistered): RegistrarInterface&MockObject { $registrar = $this->createMock(RegistrarInterface::class); $registrar