Skip to content

Commit

Permalink
First Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Renato Dehnhardt committed Sep 12, 2017
1 parent 8f57a84 commit 2cde810
Show file tree
Hide file tree
Showing 11 changed files with 354 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
vendor
composer.lock
.idea
31 changes: 31 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "rdehnhardt/excahnge-rate",
"description": "Performs currency conversion automatically based on api fixer.io",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Renato Dehnhardt",
"email": "[email protected]"
}
],
"require": {
"guzzlehttp/guzzle": "~6.0"
},
"require-dev": {
"phpunit/phpunit": "^6.3"
},
"autoload": {
"psr-4": {
"Rdehnhardt\\ExchangeRate\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"test": "vendor/bin/phpunit"
}
}
18 changes: 18 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false">
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
25 changes: 25 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Exchange Rate

Performs currency conversion automatically based on api fixer.io

### Instalation

```
composer require rdehnhardt/exchange-rate
```

### How to use (automatically)
```
use Rdehnhardt\ExchangeRate\Exchange;
$exchange = new Exchange();
$exchange->rate(10, 'EUR', 'USD'); // 11,933 - at 2017-09-12
```

### How to use (manually)
```
use Rdehnhardt\ExchangeRate\Exchange;
$exchange = new Exchange();
$exchange->rate(10, 'EUR', 'USD', 1.2987); // 12,987
```
9 changes: 9 additions & 0 deletions src/Exceptions/NotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Rdehnhardt\ExchangeRate\Excaptions;

use InvalidArgumentException as Exception;

class NotFoundException extends Exception
{
}
41 changes: 41 additions & 0 deletions src/Exchange.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Rdehnhardt\ExchangeRate;

class Exchange
{
/**
* @var Fixer
*/
private $fixer;

/**
* Exchange constructor.
* @param Fixer $fixer
*/
public function __construct(Fixer $fixer = null)
{
if ($fixer === null) {
$fixer = new Fixer();
}

$this->fixer = $fixer;
}

/**
* @param $amount
* @param $from
* @param $to
* @param null $rate
* @return int
* @throws \Rdehnhardt\ExchangeRate\Excaptions\NotFoundException
*/
public function rate($amount, $from, $to, $rate = null)
{
if ($rate === null) {
$rate = $this->fixer->get($from, $to);
}

return $amount * $rate;
}
}
50 changes: 50 additions & 0 deletions src/Fixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Rdehnhardt\ExchangeRate;

use GuzzleHttp\Client;
use Rdehnhardt\ExchangeRate\Excaptions\NotFoundException;

class Fixer
{
/**
* @var array
*/
private $rates;

/**
* @param string $from
* @param string $to
* @return mixed
*/
public function get($from, $to)
{
$this->getRates($from);

if (!array_key_exists(strtoupper($to), $this->rates[$from])) {
throw new NotFoundException("Exchange rate '$to' not found.");
}

return $this->rates[$from][strtoupper($to)];
}

/**
* @param string $from
*/
private function getRates($from)
{
if (!$this->rates[$from]) {
$response = (new Client())->get("http://api.fixer.io/latest?base={$from}");
$this->rates[$from] = json_decode($response->getBody(), true)['rates'];
}
}

/**
* @param string $from
* @param array $rates
*/
public function setRates($from, $rates)
{
$this->rates[$from] = $rates;
}
}
61 changes: 61 additions & 0 deletions tests/ExchangeRate/ExchangeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Tests\ExchangeRate;

use Rdehnhardt\ExchangeRate\Exchange;
use Tests\TestCase;

class ExchangeTest extends TestCase
{
/**
* @dataProvider getData
* @param $from
* @param $to
* @param $amount
* @param $rate
* @param $expected
*/
public function testExchangeRate($amount, $from, $to, $rate, $expected)
{
$exchange = new Exchange($this->fixer($from));

$this->assertEquals($expected, $exchange->rate($amount, $from, $to, $rate));
}

public function getData()
{
return [
[1, 'EUR', 'AUD', null, 1.4915],
[1, 'EUR', 'BGN', 1.9558, 1.9558],
[1, 'EUR', 'BRL', null, 3.7057],
[1, 'EUR', 'CAD', 1.4477, 1.4477],
[1, 'EUR', 'CHF', 1.1444, 1.1444],
[1, 'EUR', 'CNY', 7.8024, 7.8024],
[1, 'EUR', 'CZK', 26.105, 26.105],
[1, 'EUR', 'DKK', null, 7.4397],
[1, 'EUR', 'GBP', 0.89878, 0.89878],
[1, 'EUR', 'HKD', 9.3235, 9.3235],
[1, 'EUR', 'HRK', 7.4513, 7.4513],
[1, 'EUR', 'HUF', 307.11, 307.11],
[1, 'EUR', 'IDR', null, 15791.0],
[1, 'EUR', 'ILS', 4.2197, 4.2197],
[1, 'EUR', 'INR', 76.438, 76.438],
[1, 'EUR', 'JPY', 130.93, 130.93],
[1, 'EUR', 'KRW', 1346.0, 1346.0],
[1, 'EUR', 'MXN', null, 21.214],
[1, 'EUR', 'MYR', null, 5.0357],
[1, 'EUR', 'NOK', 9.3593, 9.3593],
[1, 'EUR', 'NZD', 1.6343, 1.6343],
[1, 'EUR', 'PHP', null, 60.99],
[1, 'EUR', 'PLN', 4.2549, 4.2549],
[1, 'EUR', 'RON', 4.6018, 4.6018],
[1, 'EUR', 'RUB', 68.384, 68.384],
[1, 'EUR', 'SEK', null, 9.5705],
[1, 'EUR', 'SGD', 1.6074, 1.6074],
[1, 'EUR', 'THB', 39.522, 39.522],
[1, 'EUR', 'TRY', 4.0948, 4.0948],
[1, 'EUR', 'USD', 1.1933, 1.1933],
[1, 'EUR', 'ZAR', null, 15.514],
];
}
}
34 changes: 34 additions & 0 deletions tests/ExchangeRate/FixerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Tests\ExchangeRate;

use Tests\TestCase;

class FixerTest extends TestCase
{
/**
* @dataProvider dataForTests
* @param $from
* @param $to
* @param $expected
*/
public function testGetExchangeRate($from, $to, $expected)
{
$this->assertEquals($expected, $this->fixer($from)->get($from, $to));
}

/**
* @return array
*/
public function dataForTests()
{
$content = $this->getContent();
$output = [];

foreach ($content['rates'] as $rate => $amount) {
$output[] = [$content['base'], $rate, $amount];
}

return $output;
}
}
45 changes: 45 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Tests;

use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use PHPUnit\Framework\TestCase as PHPUnitTestCase;
use Rdehnhardt\ExchangeRate\Fixer;

abstract class TestCase extends PHPUnitTestCase
{
/**
* @return Client
*/
public function client()
{
$mock = new MockHandler([
new Response(200, [], file_get_contents(__DIR__ . '/response.json'))
]);

return new Client(['handler' => HandlerStack::create($mock)]);
}

/**
* @return array
*/
public function getContent()
{
return json_decode($this->client()->get('/')->getBody()->getContents(), true);
}

/**
* @param $from
* @return Fixer
*/
public function fixer($from)
{
$fixer = new Fixer();
$fixer->setRates($from, $this->getContent()['rates']);

return $fixer;
}
}
37 changes: 37 additions & 0 deletions tests/response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"base": "EUR",
"date": "0000-00-00",
"rates": {
"AUD": 1.4915,
"BGN": 1.9558,
"BRL": 3.7057,
"CAD": 1.4541,
"CHF": 1.1404,
"CNY": 7.8329,
"CZK": 26.077,
"DKK": 7.4397,
"GBP": 0.90775,
"HKD": 9.3731,
"HRK": 7.4282,
"HUF": 306.28,
"IDR": 15791.0,
"ILS": 4.2255,
"INR": 76.674,
"JPY": 130.38,
"KRW": 1357.8,
"MXN": 21.214,
"MYR": 5.0357,
"NOK": 9.371,
"NZD": 1.6502,
"PHP": 60.99,
"PLN": 4.244,
"RON": 4.5987,
"RUB": 68.619,
"SEK": 9.5705,
"SGD": 1.6129,
"THB": 39.746,
"TRY": 4.0779,
"USD": 1.1997,
"ZAR": 15.514
}
}

0 comments on commit 2cde810

Please sign in to comment.