Skip to content

Commit

Permalink
Merge pull request #6 from bavix/develop
Browse files Browse the repository at this point in the history
exceptions
  • Loading branch information
rez1dent3 authored Nov 26, 2021
2 parents 08ed477 + 2b36433 commit 5d7162d
Show file tree
Hide file tree
Showing 14 changed files with 291 additions and 27 deletions.
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ parameters:
- Illuminate\Database\Eloquent\Model

# php exceptions
- Exception
- LogicException
- RuntimeException
- UnderflowException
Expand Down
67 changes: 67 additions & 0 deletions src/CurrencyService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

namespace Bavix\WalletSwap;

use Bavix\WalletSwap\Exception\CacheException;
use Bavix\WalletSwap\Exception\NonBreakingInvalidArgumentException;
use Bavix\WalletSwap\Exception\SwapException;
use Bavix\WalletSwap\Exception\SwapRuntimeException;
use Bavix\WalletSwap\Exception\UnsupportedCurrencyPairException;
use Bavix\WalletSwap\Exception\UnsupportedDateException;
use Bavix\WalletSwap\Exception\UnsupportedExchangeQueryException;
use Exchanger\Exception\CacheException as ExchangerCacheException;
use Exchanger\Exception\Exception as ExchangerException;
use Exchanger\Exception\NonBreakingInvalidArgumentException as ExchangerNonBreakingInvalidArgumentException;
use Exchanger\Exception\UnsupportedCurrencyPairException as ExchangerUnsupportedCurrencyPairException;
use Exchanger\Exception\UnsupportedDateException as ExchangerUnsupportedDateException;
use Exchanger\Exception\UnsupportedExchangeQueryException as ExchangerUnsupportedExchangeQueryException;
use Swap\Swap;

final class CurrencyService implements CurrencyServiceInterface
{
private Swap $swapService;

public function __construct(Swap $swapService)
{
$this->swapService = $swapService;
}

/**
* @throws CacheException
* @throws NonBreakingInvalidArgumentException
* @throws UnsupportedExchangeQueryException
* @throws UnsupportedCurrencyPairException
* @throws UnsupportedDateException
* @throws SwapException
* @throws SwapRuntimeException
*/
public function rate(string $fromCurrency, string $toCurrency): string
{
if ($fromCurrency === $toCurrency) {
return '1';
}

try {
return (string) $this->swapService
->latest($fromCurrency.'/'.$toCurrency)
->getValue()
;
} catch (ExchangerCacheException $exception) {
throw new CacheException($exception->getMessage(), $exception->getCode(), $exception);
} catch (ExchangerNonBreakingInvalidArgumentException $exception) {
throw new NonBreakingInvalidArgumentException($exception->getMessage(), $exception->getCode(), $exception);
} catch (ExchangerUnsupportedExchangeQueryException $exception) {
throw new UnsupportedExchangeQueryException($exception->getMessage(), $exception->getCode(), $exception);
} catch (ExchangerUnsupportedCurrencyPairException $exception) {
throw new UnsupportedCurrencyPairException($exception->getMessage(), $exception->getCode(), $exception);
} catch (ExchangerUnsupportedDateException $exception) {
throw new UnsupportedDateException($exception->getMessage(), $exception->getCode(), $exception);
} catch (ExchangerException $exception) {
throw new SwapException($exception->getMessage(), $exception->getCode(), $exception);
} catch (\Throwable $exception) {
throw new SwapRuntimeException($exception->getMessage(), $exception->getCode(), $exception);
}
}
}
27 changes: 27 additions & 0 deletions src/CurrencyServiceInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Bavix\WalletSwap;

use Bavix\WalletSwap\Exception\CacheException;
use Bavix\WalletSwap\Exception\NonBreakingInvalidArgumentException;
use Bavix\WalletSwap\Exception\SwapException;
use Bavix\WalletSwap\Exception\SwapRuntimeException;
use Bavix\WalletSwap\Exception\UnsupportedCurrencyPairException;
use Bavix\WalletSwap\Exception\UnsupportedDateException;
use Bavix\WalletSwap\Exception\UnsupportedExchangeQueryException;

interface CurrencyServiceInterface
{
/**
* @throws CacheException
* @throws NonBreakingInvalidArgumentException
* @throws UnsupportedExchangeQueryException
* @throws UnsupportedCurrencyPairException
* @throws UnsupportedDateException
* @throws SwapException
* @throws SwapRuntimeException
*/
public function rate(string $fromCurrency, string $toCurrency): string;
}
12 changes: 12 additions & 0 deletions src/Exception/CacheException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Bavix\WalletSwap\Exception;

use Bavix\Wallet\Internal\Exceptions\ExceptionInterface;
use Exception;

final class CacheException extends Exception implements ExceptionInterface
{
}
12 changes: 12 additions & 0 deletions src/Exception/NonBreakingInvalidArgumentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Bavix\WalletSwap\Exception;

use Bavix\Wallet\Internal\Exceptions\ExceptionInterface;
use InvalidArgumentException;

final class NonBreakingInvalidArgumentException extends InvalidArgumentException implements ExceptionInterface
{
}
12 changes: 12 additions & 0 deletions src/Exception/SwapException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Bavix\WalletSwap\Exception;

use Bavix\Wallet\Internal\Exceptions\ExceptionInterface;
use Exception;

final class SwapException extends Exception implements ExceptionInterface
{
}
12 changes: 12 additions & 0 deletions src/Exception/SwapRuntimeException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Bavix\WalletSwap\Exception;

use Bavix\Wallet\Internal\Exceptions\ExceptionInterface;
use RuntimeException;

final class SwapRuntimeException extends RuntimeException implements ExceptionInterface
{
}
12 changes: 12 additions & 0 deletions src/Exception/UnsupportedCurrencyPairException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Bavix\WalletSwap\Exception;

use Bavix\Wallet\Internal\Exceptions\ExceptionInterface;
use Exception;

final class UnsupportedCurrencyPairException extends Exception implements ExceptionInterface
{
}
12 changes: 12 additions & 0 deletions src/Exception/UnsupportedDateException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Bavix\WalletSwap\Exception;

use Bavix\Wallet\Internal\Exceptions\ExceptionInterface;
use Exception;

final class UnsupportedDateException extends Exception implements ExceptionInterface
{
}
12 changes: 12 additions & 0 deletions src/Exception/UnsupportedExchangeQueryException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Bavix\WalletSwap\Exception;

use Bavix\Wallet\Internal\Exceptions\ExceptionInterface;
use Exception;

final class UnsupportedExchangeQueryException extends Exception implements ExceptionInterface
{
}
44 changes: 23 additions & 21 deletions src/SwapExchangeService.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,40 @@

use Bavix\Wallet\Internal\Service\MathServiceInterface;
use Bavix\Wallet\Services\ExchangeServiceInterface;
use Exchanger\CurrencyPair;
use Swap\Swap;
use Bavix\WalletSwap\Exception\CacheException;
use Bavix\WalletSwap\Exception\NonBreakingInvalidArgumentException;
use Bavix\WalletSwap\Exception\SwapException;
use Bavix\WalletSwap\Exception\SwapRuntimeException;
use Bavix\WalletSwap\Exception\UnsupportedCurrencyPairException;
use Bavix\WalletSwap\Exception\UnsupportedDateException;
use Bavix\WalletSwap\Exception\UnsupportedExchangeQueryException;

final class SwapExchangeService implements ExchangeServiceInterface
{
private CurrencyServiceInterface $currencyService;
private MathServiceInterface $mathService;
private Swap $swapService;

public function __construct(
MathServiceInterface $mathService,
Swap $swapService
CurrencyServiceInterface $currencyService,
MathServiceInterface $mathService
) {
$this->currencyService = $currencyService;
$this->mathService = $mathService;
$this->swapService = $swapService;
}

/** @param float|int|string $amount */
/**
* @param float|int|string $amount
*
* @throws CacheException
* @throws NonBreakingInvalidArgumentException
* @throws UnsupportedExchangeQueryException
* @throws UnsupportedCurrencyPairException
* @throws UnsupportedDateException
* @throws SwapException
* @throws SwapRuntimeException
*/
public function convertTo(string $fromCurrency, string $toCurrency, $amount): string
{
return $this->mathService->mul(
$amount,
$this->rate($fromCurrency, $toCurrency)
);
}

private function rate(string $fromCurrency, string $toCurrency): string
{
$pair = new CurrencyPair($fromCurrency, $toCurrency);
if (!$pair->isIdentical()) {
return (string) $this->swapService->latest((string) $pair)->getValue();
}

return '1';
return $this->mathService->mul($this->currencyService->rate($fromCurrency, $toCurrency), $amount);
}
}
6 changes: 1 addition & 5 deletions src/WalletSwapServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@

final class WalletSwapServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @codeCoverageIgnore
*/
public function register(): void
{
$this->app->singleton(CurrencyServiceInterface::class, CurrencyService::class);
$this->app->singleton(ExchangeServiceInterface::class, SwapExchangeService::class);
}
}
87 changes: 87 additions & 0 deletions tests/CurrencyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

declare(strict_types=1);

namespace Bavix\WalletSwap\Test;

use Bavix\WalletSwap\CurrencyService;
use Bavix\WalletSwap\Exception\CacheException;
use Bavix\WalletSwap\Exception\NonBreakingInvalidArgumentException;
use Bavix\WalletSwap\Exception\SwapException;
use Bavix\WalletSwap\Exception\SwapRuntimeException;
use Bavix\WalletSwap\Exception\UnsupportedCurrencyPairException;
use Bavix\WalletSwap\Exception\UnsupportedDateException;
use Bavix\WalletSwap\Exception\UnsupportedExchangeQueryException;
use DateTimeImmutable;
use Exchanger\CurrencyPair;
use Exchanger\Exception\CacheException as ExchangerCacheException;
use Exchanger\Exception\ChainException;
use Exchanger\Exception\Exception as ExchangerException;
use Exchanger\Exception\NonBreakingInvalidArgumentException as ExchangerNonBreakingInvalidArgumentException;
use Exchanger\Exception\UnsupportedCurrencyPairException as ExchangerUnsupportedCurrencyPairException;
use Exchanger\Exception\UnsupportedDateException as ExchangerUnsupportedDateException;
use Exchanger\Exception\UnsupportedExchangeQueryException as ExchangerUnsupportedExchangeQueryException;
use Exchanger\ExchangeRateQuery;
use Exchanger\Service\PhpArray;
use RuntimeException;
use Swap\Swap;
use Throwable;

/**
* @internal
*/
final class CurrencyTest extends TestCase
{
/**
* @dataProvider exceptionDataProvider
*/
public function testExceptions(string $expect, Throwable $throwable): void
{
$this->expectException($expect);

$mockSwapService = $this->createMock(Swap::class);
$mockSwapService->method('latest')->willThrowException($throwable);

$currencyService = new CurrencyService($mockSwapService);
$currencyService->rate('USD', 'RUB');
}

public function exceptionDataProvider(): iterable
{
$currencyPair = new CurrencyPair('USD', 'EUR');
$service = new PhpArray([]);

yield [CacheException::class, new ExchangerCacheException()];
yield [NonBreakingInvalidArgumentException::class, new ExchangerNonBreakingInvalidArgumentException()];

yield [
UnsupportedExchangeQueryException::class,
new ExchangerUnsupportedExchangeQueryException(new ExchangeRateQuery($currencyPair), $service),
];

yield [
UnsupportedCurrencyPairException::class,
new ExchangerUnsupportedCurrencyPairException($currencyPair, $service),
];

yield [
UnsupportedDateException::class,
new ExchangerUnsupportedDateException(new DateTimeImmutable(), $service),
];

yield [
SwapException::class,
new ExchangerException(),
];

yield [
SwapException::class,
new ChainException([]),
];

yield [
SwapRuntimeException::class,
new RuntimeException(),
];
}
}
2 changes: 1 addition & 1 deletion tests/SwapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/**
* @internal
*/
class SwapTest extends TestCase
final class SwapTest extends TestCase
{
public function testSimple(): void
{
Expand Down

0 comments on commit 5d7162d

Please sign in to comment.