Skip to content

Commit

Permalink
add criteria object
Browse files Browse the repository at this point in the history
  • Loading branch information
roman.dykyi committed May 13, 2021
1 parent e1d9635 commit 85ca691
Show file tree
Hide file tree
Showing 19 changed files with 124 additions and 32 deletions.
2 changes: 1 addition & 1 deletion README.md
@@ -1,6 +1,6 @@
Crossword game
=======
![Build Status](https://travis-ci.com/dykyi-roman/crossword.svg?branch=master)
[![Build Status](https://scrutinizer-ci.com/g/dykyi-roman/crossword/badges/build.png?b=master)](https://scrutinizer-ci.com/g/dykyi-roman/crossword/build-status/master)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/dykyi-roman/crossword/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/dykyi-roman/crossword/?branch=master)
[![Code Intelligence Status](https://scrutinizer-ci.com/g/dykyi-roman/crossword/badges/code-intelligence.svg?b=master)](https://scrutinizer-ci.com/code-intelligence)
[![Code Coverage](https://scrutinizer-ci.com/g/dykyi-roman/crossword/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/dykyi-roman/crossword/?branch=master)
Expand Down
4 changes: 1 addition & 3 deletions code/src/Crossword/Application/Service/CrosswordReceiver.php
Expand Up @@ -23,11 +23,9 @@ public function __construct(ReadCrosswordRepositoryInterface $readCrosswordRepos
/**
* @throws ReceiveCrosswordException
*/
public function receive(string $type, string $language, int $wordCount): array
public function receive(string $key): array
{
try {
$key = sprintf('%s-%s-%d', $language, $type, $wordCount);

return $this->readCrosswordRepository->get($key);
} catch (Throwable $exception) {
$this->logger->error($exception->getMessage());
Expand Down
27 changes: 27 additions & 0 deletions code/src/Crossword/Domain/Criteria/WordSearchCriteria.php
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace App\Crossword\Domain\Criteria;

final class WordSearchCriteria
{
private string $mask;
private string $language;

public function __construct(string $language, string $mask)
{
$this->language = $language;
$this->mask = $mask;
}

public function mask(): string
{
return $this->mask;
}

public function language(): string
{
return $this->language;
}
}
3 changes: 2 additions & 1 deletion code/src/Crossword/Domain/Port/DictionaryInterface.php
Expand Up @@ -4,6 +4,7 @@

namespace App\Crossword\Domain\Port;

use App\Crossword\Domain\Criteria\WordSearchCriteria;
use App\Crossword\Domain\Dto\DictionaryLanguagesDto;
use App\Crossword\Domain\Dto\DictionaryWordDto;
use App\Crossword\Domain\Exception\ApiClientException;
Expand All @@ -18,5 +19,5 @@ public function supportedLanguages(): DictionaryLanguagesDto;
/**
* @throws ApiClientException
*/
public function searchWord(string $language, string $mask): DictionaryWordDto;
public function searchWord(WordSearchCriteria $criteria): DictionaryWordDto;
}
Expand Up @@ -4,6 +4,7 @@

namespace App\Crossword\Domain\Service\Constructor\Normal;

use App\Crossword\Domain\Criteria\WordSearchCriteria;
use App\Crossword\Domain\Exception\WordFoundException;
use App\Crossword\Domain\Service\WordFinder;
use App\SharedKernel\Domain\Model\Mask;
Expand All @@ -30,7 +31,7 @@ public function find(string $language, Mask $mask, int $attempt = self::ATTEMPT)

do {
try {
return $this->wordFinder->find($language, (string) $template);
return $this->wordFinder->search(new WordSearchCriteria($language, (string) $template));
} catch (WordFoundException) {
$counter++;
$template = $template->shiftLeft();
Expand Down
5 changes: 3 additions & 2 deletions code/src/Crossword/Domain/Service/WordFinder.php
Expand Up @@ -4,6 +4,7 @@

namespace App\Crossword\Domain\Service;

use App\Crossword\Domain\Criteria\WordSearchCriteria;
use App\Crossword\Domain\Exception\ApiClientException;
use App\Crossword\Domain\Exception\WordFoundException;
use App\Crossword\Domain\Port\DictionaryInterface;
Expand All @@ -21,10 +22,10 @@ public function __construct(DictionaryInterface $dictionary, LoggerInterface $lo
$this->dictionary = $dictionary;
}

public function find(string $language, string $mask): Word
public function search(WordSearchCriteria $criteria): Word
{
try {
$searchWordDto = $this->dictionary->searchWord($language, $mask);
$searchWordDto = $this->dictionary->searchWord($criteria);
if ($searchWordDto->count()) {
return new Word($searchWordDto->word(), $searchWordDto->definition());
}
Expand Down
Expand Up @@ -4,6 +4,7 @@

namespace App\Crossword\Infrastructure\Adapter\Dictionary;

use App\Crossword\Domain\Criteria\WordSearchCriteria;
use App\Crossword\Domain\Dto\DictionaryLanguagesDto;
use App\Crossword\Domain\Dto\DictionaryWordDto;
use App\Crossword\Domain\Exception\ApiClientException;
Expand Down Expand Up @@ -41,9 +42,15 @@ public function supportedLanguages(): DictionaryLanguagesDto
}
}

public function searchWord(string $language, string $mask): DictionaryWordDto
public function searchWord(WordSearchCriteria $criteria): DictionaryWordDto
{
$uri = sprintf('%s/words/%s/?mask=%s', $this->dictionaryApiHost, $language, $mask);
$uri = sprintf(
'%s/words/%s/?mask=%s',
$this->dictionaryApiHost,
$criteria->language(),
$criteria->mask()
);

try {
$response = $this->client->sendRequest(new Request('GET', $uri));

Expand Down
Expand Up @@ -4,6 +4,7 @@

namespace App\Crossword\Infrastructure\Adapter\Dictionary;

use App\Crossword\Domain\Criteria\WordSearchCriteria;
use App\Crossword\Domain\Dto\DictionaryLanguagesDto;
use App\Crossword\Domain\Dto\DictionaryWordDto;
use App\Crossword\Domain\Port\DictionaryInterface;
Expand Down Expand Up @@ -32,9 +33,14 @@ public function supportedLanguages(): DictionaryLanguagesDto
return new DictionaryLanguagesDto($data->body());
}

public function searchWord(string $language, string $mask): DictionaryWordDto
public function searchWord(WordSearchCriteria $criteria): DictionaryWordDto
{
$words = $this->wordsFinder->find($language, new Mask($mask), self::LIMIT);
$words = $this->wordsFinder->find(
$criteria->language(),
new Mask($criteria->mask()),
self::LIMIT
);

$data = new SuccessApiResponse($words->jsonSerialize());

return new DictionaryWordDto($data->body());
Expand Down
Expand Up @@ -4,6 +4,7 @@

namespace App\Crossword\Infrastructure\Adapter\Dictionary;

use App\Crossword\Domain\Criteria\WordSearchCriteria;
use App\Crossword\Domain\Dto\DictionaryLanguagesDto;
use App\Crossword\Domain\Dto\DictionaryWordDto;
use App\Crossword\Domain\Exception\ApiClientException;
Expand All @@ -29,7 +30,7 @@ public function supportedLanguages(): DictionaryLanguagesDto
return $this->languagesDto;
}

public function searchWord(string $language, string $mask): DictionaryWordDto
public function searchWord(WordSearchCriteria $criteria): DictionaryWordDto
{
if (null === $this->wordDto) {
throw ApiClientException::badRequest('test error message');
Expand Down
5 changes: 3 additions & 2 deletions code/src/Crossword/UI/API/ConstructAction.php
Expand Up @@ -53,10 +53,11 @@ final class ConstructAction
* )
*/
#[Route('/api/crossword/construct/{language}/{type}/{words}', name: 'crossword.api.construct', methods: ['GET'])]
public function __invoke(ConstructRequest $request, CrosswordReceiver $constructor): ResponseInterface
public function __invoke(ConstructRequest $request, CrosswordReceiver $crosswordReceiver): ResponseInterface
{
try {
$crossword = $constructor->receive($request->type(), $request->language(), $request->wordCount());
$key = sprintf('%s-%s-%d', $request->language(), $request->type(), $request->wordCount());
$crossword = $crosswordReceiver->receive($key);

return new SuccessApiResponse($crossword);
} catch (ReceiveCrosswordException) {
Expand Down
3 changes: 2 additions & 1 deletion code/src/Game/Application/Service/GamePlay.php
Expand Up @@ -5,6 +5,7 @@
namespace App\Game\Application\Service;

use App\Game\Application\Dto\GameDto;
use App\Game\Domain\Criteria\CrosswordCriteria;
use App\Game\Domain\Model\Grid;
use App\Game\Domain\Service\CrosswordConstructor;

Expand All @@ -19,7 +20,7 @@ public function __construct(CrosswordConstructor $constructor)

public function new(string $language, string $type, int $wordCount): GameDto
{
$crossword = $this->constructor->construct($language, $type, $wordCount);
$crossword = $this->constructor->construct(new CrosswordCriteria($language, $type, $wordCount));
$grid = new Grid($crossword);
$definitions = array_map(static fn (array $item) => $item['word']['definition'], $crossword);
foreach ($crossword as $index => $line) {
Expand Down
34 changes: 34 additions & 0 deletions code/src/Game/Domain/Criteria/CrosswordCriteria.php
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace App\Game\Domain\Criteria;

final class CrosswordCriteria
{
private string $type;
private int $wordCount;
private string $language;

public function __construct(string $language, string $type, int $wordCount)
{
$this->type = $type;
$this->language = $language;
$this->wordCount = $wordCount;
}

public function language(): string
{
return $this->language;
}

public function type(): string
{
return $this->type;
}

public function wordCount(): int
{
return $this->wordCount;
}
}
3 changes: 2 additions & 1 deletion code/src/Game/Domain/Port/CrosswordInterface.php
Expand Up @@ -4,6 +4,7 @@

namespace App\Game\Domain\Port;

use App\Game\Domain\Criteria\CrosswordCriteria;
use App\Game\Domain\Dto\CrosswordDto;
use App\Game\Domain\Dto\LanguagesDto;
use App\Game\Domain\Exception\ApiClientException;
Expand All @@ -13,7 +14,7 @@ interface CrosswordInterface
/**
* @throws ApiClientException
*/
public function construct(string $language, string $type, int $wordCount): CrosswordDto;
public function construct(CrosswordCriteria $criteria): CrosswordDto;

/**
* @throws ApiClientException
Expand Down
5 changes: 3 additions & 2 deletions code/src/Game/Domain/Service/CrosswordConstructor.php
Expand Up @@ -4,6 +4,7 @@

namespace App\Game\Domain\Service;

use App\Game\Domain\Criteria\CrosswordCriteria;
use App\Game\Domain\Exception\ApiClientException;
use App\Game\Domain\Exception\CrosswordNotConstructedException;
use App\Game\Domain\Port\CrosswordInterface;
Expand All @@ -23,10 +24,10 @@ public function __construct(CrosswordInterface $crossword, LoggerInterface $logg
/**
* @throws CrosswordNotConstructedException
*/
public function construct(string $language, string $type, int $wordCount): array
public function construct(CrosswordCriteria $criteria): array
{
try {
$crosswordDto = $this->crossword->construct($language, $type, $wordCount);
$crosswordDto = $this->crossword->construct($criteria);

return $crosswordDto->count() ? $crosswordDto->crossword() : [];
} catch (ApiClientException $exception) {
Expand Down
Expand Up @@ -4,6 +4,7 @@

namespace App\Game\Infrastructure\Adapter\Crossword;

use App\Game\Domain\Criteria\CrosswordCriteria;
use App\Game\Domain\Dto\CrosswordDto;
use App\Game\Domain\Dto\LanguagesDto;
use App\Game\Domain\Exception\ApiClientException;
Expand All @@ -29,9 +30,16 @@ public function __construct(
$this->responseDataExtractor = $responseDataExtractor;
}

public function construct(string $language, string $type, int $wordCount): CrosswordDto
public function construct(CrosswordCriteria $criteria): CrosswordDto
{
$uri = sprintf('%s/construct/%s/%s/%d', $this->crosswordApiHost, $language, $type, $wordCount);
$uri = sprintf(
'%s/construct/%s/%s/%d',
$this->crosswordApiHost,
$criteria->language(),
$criteria->type(),
$criteria->wordCount()
);

try {
$response = $this->client->sendRequest(new Request('GET', $uri));

Expand Down
Expand Up @@ -6,6 +6,7 @@

use App\Crossword\Application\Service\CrosswordReceiver;
use App\Crossword\Application\Service\SupportedLanguages;
use App\Game\Domain\Criteria\CrosswordCriteria;
use App\Game\Domain\Dto\CrosswordDto;
use App\Game\Domain\Dto\LanguagesDto;
use App\Game\Domain\Port\CrosswordInterface;
Expand All @@ -22,9 +23,10 @@ public function __construct(CrosswordReceiver $crosswordReceiver, SupportedLangu
$this->supportedLanguages = $supportedLanguages;
}

public function construct(string $language, string $type, int $wordCount): CrosswordDto
public function construct(CrosswordCriteria $criteria): CrosswordDto
{
$data = $this->crosswordReceiver->receive($type, $language, $wordCount);
$key = sprintf('%s-%s-%d', $criteria->language(), $criteria->type(), $criteria->wordCount());
$data = $this->crosswordReceiver->receive($key);
$response = new SuccessApiResponse($data);

return new CrosswordDto($response->body());
Expand Down
Expand Up @@ -4,6 +4,7 @@

namespace App\Game\Infrastructure\Adapter\Crossword;

use App\Game\Domain\Criteria\CrosswordCriteria;
use App\Game\Domain\Dto\CrosswordDto;
use App\Game\Domain\Dto\LanguagesDto;
use App\Game\Domain\Exception\ApiClientException;
Expand All @@ -20,7 +21,7 @@ public function __construct(null | CrosswordDto $crosswordDto, null | LanguagesD
$this->languagesDto = $languagesDto;
}

public function construct(string $language, string $type, int $wordCount): CrosswordDto
public function construct(CrosswordCriteria $criteria): CrosswordDto
{
if (null === $this->crosswordDto) {
throw ApiClientException::badRequest('test error message');
Expand Down
Expand Up @@ -28,7 +28,7 @@ public function testSuccessfullyReceived(): void
$cache->save(new CacheItem('ua-normal-3', [time() => json_encode(['data' => 'value'], JSON_THROW_ON_ERROR)]));

$crosswordReceiver = new CrosswordReceiver(new ReadCrosswordRepository($cache), new NullLogger());
$crossword = $crosswordReceiver->receive(Type::NORMAL, 'ua', 3);
$crossword = $crosswordReceiver->receive(sprintf('%s-%s-%d', 'ua', Type::NORMAL, 3));

self::assertSame($crossword, $data);
}
Expand All @@ -41,6 +41,6 @@ public function testThrowExceptionWhenCrosswordNotFoundInTheStorage(): void
$this->expectException(ReceiveCrosswordException::class);

$crosswordReceiver = new CrosswordReceiver(new ReadCrosswordRepository(new InMemoryClient()), new NullLogger());
$crosswordReceiver->receive(Type::NORMAL, 'ua', 3);
$crosswordReceiver->receive(sprintf('%s-%s-%d', 'ua', Type::NORMAL, 3));
}
}

0 comments on commit 85ca691

Please sign in to comment.