Commit 4ce189d2 authored by Mathias Verraes's avatar Mathias Verraes
Browse files

removed Currency subtypes

add GBP, JPY
parent e52583cd
......@@ -23,7 +23,7 @@ Creation
All amounts are represented in the smallest unit (eg. cents), so USD 5.00 is written as
<?php
$fiver = new Money(500, new USD);
$fiver = new Money(500, new Currency('USD'));
// or shorter:
$fiver = Money::USD(500);
......
......@@ -10,15 +10,37 @@
namespace Verraes\Money;
interface Currency
class Currency
{
/** @var string */
private $name;
const EUR = 'EUR';
const USD = 'USD';
const GBP = 'GBP';
const JPY = 'JPY';
public function __construct($name)
{
if(!defined("self::$name")) {
throw new UnknownCurrencyException($name);
}
$this->name = $name;
}
/**
* @return string
*/
public function getName();
public function getName()
{
return $this->name;
}
/**
* @return bool
*/
public function equals(Currency $currency);
public function equals(Currency $other)
{
return $this->name === $other->name;
}
}
\ No newline at end of file
......@@ -10,8 +10,6 @@
namespace Verraes\Money;
use Verraes\Money\InvalidArgumentException;
class Money
{
const ROUND_HALF_UP = PHP_ROUND_HALF_UP;
......@@ -38,17 +36,18 @@ class Money
if(!is_int($units)) {
throw new InvalidArgumentException("The first parameter of Money must be an integer");
}
$this->units = $units;
$this->units = $units; // #todo rename to amount
$this->currency = $currency;
}
/**
* @todo make generic using __callstatic?
* Convenience factory method for an amount in EURO
* @return Money
*/
public static function EUR($units)
{
return new Money($units, new EUR);
return new Money($units, new Currency('EUR'));
}
/**
......@@ -57,7 +56,25 @@ class Money
*/
public static function USD($units)
{
return new Money($units, new USD);
return new Money($units, new Currency('USD'));
}
/**
* Convenience factory method for an amount in GBP
* @return Money
*/
public static function GBP($units)
{
return new Money($units, new Currency('GBP'));
}
/**
* Convenience factory method for an amount in JPY
* @return Money
*/
public static function JPY($units)
{
return new Money($units, new Currency('JPY'));
}
private function isSameCurrency(Money $other)
......@@ -148,7 +165,7 @@ class Money
private function assertRoundingMode($rounding_mode)
{
if(!in_array($rounding_mode, array(self::ROUND_HALF_DOWN, self::ROUND_HALF_EVEN, self::ROUND_HALF_ODD, self::ROUND_HALF_UP))) {
throw new InvalidArgumentException('Operand should be an integer or a float');
throw new InvalidArgumentException('Rounding mode should be Money::ROUND_HALF_DOWN | Money::ROUND_HALF_EVEN | Money::ROUND_HALF_ODD | Money::ROUND_HALF_UP');
}
}
......
<?php
/**
* This file is part of the Verraes\Money library
*
* Copyright (c) 2011 Mathias Verraes
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Verraes\Money;
class USD implements Currency
{
/**
* @return string
*/
public function getName()
{
return 'USD';
}
/**
* @return bool
*/
public function equals(Currency $currency)
{
return $this->getName() == $currency->getName();
}
}
......@@ -10,21 +10,6 @@
namespace Verraes\Money;
class EUR implements Currency
class UnknownCurrencyException extends \Exception implements Exception
{
/**
* @return string
*/
public function getName()
{
return 'EUR';
}
/**
* @return bool
*/
public function equals(Currency $currency)
{
return $this->getName() == $currency->getName();
}
}
......@@ -18,10 +18,10 @@ class CurrencyTest extends PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->euro1 = new EUR;
$this->euro2 = new EUR;
$this->usd1 = new USD;
$this->usd2 = new USD;
$this->euro1 = new Currency('EUR');
$this->euro2 = new Currency('EUR');
$this->usd1 = new Currency('USD');
$this->usd2 = new Currency('USD');
}
public function testDifferentInstancesAreEqual()
......@@ -40,4 +40,13 @@ class CurrencyTest extends PHPUnit_Framework_TestCase
$this->euro1->equals($this->usd1)
);
}
/**
* @test
* @expectedException Verraes\Money\UnknownCurrencyException
*/
public function testCantInstantiateUnknownCurrency()
{
new Currency('unknonw');
}
}
\ No newline at end of file
......@@ -46,7 +46,7 @@ class MoneyTest extends PHPUnit_Framework_TestCase
public function testGetters()
{
$m = new Money(100, $euro = new EUR);
$m = new Money(100, $euro = new Currency('EUR'));
$this->assertEquals(100, $m->getUnits());
$this->assertEquals($euro, $m->getCurrency());
}
......@@ -56,7 +56,7 @@ class MoneyTest extends PHPUnit_Framework_TestCase
*/
public function testDecimalsThrowException()
{
$money = new Money(0.01, new EUR);
$money = new Money(0.01, new Currency('EUR'));
}
/**
......@@ -64,15 +64,15 @@ class MoneyTest extends PHPUnit_Framework_TestCase
*/
public function testStringThrowsException()
{
$money = new Money('100', new EUR);
$money = new Money('100', new Currency('EUR'));
}
public function testEquality()
{
$m1 = new Money(100, new EUR);
$m2 = new Money(100, new EUR);
$m3 = new Money(100, new USD);
$m4 = new Money(50, new EUR);
$m1 = new Money(100, new Currency('EUR'));
$m2 = new Money(100, new Currency('EUR'));
$m3 = new Money(100, new Currency('USD'));
$m4 = new Money(50, new Currency('EUR'));
$this->assertTrue($m1->equals($m2));
$this->assertFalse($m1->equals($m3));
......@@ -81,10 +81,10 @@ class MoneyTest extends PHPUnit_Framework_TestCase
public function testAddition()
{
$m1 = new Money(100, new EUR);
$m2 = new Money(100, new EUR);
$m1 = new Money(100, new Currency('EUR'));
$m2 = new Money(100, new Currency('EUR'));
$sum = $m1->add($m2);
$expected = new Money(200, new EUR);
$expected = new Money(200, new Currency('EUR'));
$this->assertMoneyEquals($expected, $sum);
......@@ -98,17 +98,17 @@ class MoneyTest extends PHPUnit_Framework_TestCase
*/
public function testDifferentCurrenciesCannotBeAdded()
{
$m1 = new Money(100, new EUR);
$m2 = new Money(100, new USD);
$m1 = new Money(100, new Currency('EUR'));
$m2 = new Money(100, new Currency('USD'));
$m1->add($m2);
}
public function testSubtraction()
{
$m1 = new Money(100, new EUR);
$m2 = new Money(200, new EUR);
$m1 = new Money(100, new Currency('EUR'));
$m2 = new Money(200, new Currency('EUR'));
$diff = $m1->subtract($m2);
$expected = new Money(-100, new EUR);
$expected = new Money(-100, new Currency('EUR'));
$this->assertMoneyEquals($expected, $diff);
......@@ -122,20 +122,20 @@ class MoneyTest extends PHPUnit_Framework_TestCase
*/
public function testDifferentCurrenciesCannotBeSubtracted()
{
$m1 = new Money(100, new EUR);
$m2 = new Money(100, new USD);
$m1 = new Money(100, new Currency('EUR'));
$m2 = new Money(100, new Currency('USD'));
$m1->subtract($m2);
}
public function testMultiplication()
{
$m = new Money(1, new EUR);
$m = new Money(1, new Currency('EUR'));
$this->assertMoneyEquals(
new Money(2, new EUR),
new Money(2, new Currency('EUR')),
$m->multiply(1.5)
);
$this->assertMoneyEquals(
new Money(1, new EUR),
new Money(1, new Currency('EUR')),
$m->multiply(1.5, Money::ROUND_HALF_DOWN)
);
......@@ -144,17 +144,17 @@ class MoneyTest extends PHPUnit_Framework_TestCase
public function testDivision()
{
$m = new Money(10, new EUR);
$m = new Money(10, new Currency('EUR'));
$this->assertMoneyEquals(
new Money(3, new EUR),
new Money(3, new Currency('EUR')),
$m->divide(3)
);
$this->assertMoneyEquals(
new Money(2, new EUR),
new Money(2, new Currency('EUR')),
$m->divide(4, Money::ROUND_HALF_EVEN)
);
$this->assertMoneyEquals(
new Money(3, new EUR),
new Money(3, new Currency('EUR')),
$m->divide(3, Money::ROUND_HALF_ODD)
);
......@@ -163,9 +163,9 @@ class MoneyTest extends PHPUnit_Framework_TestCase
public function testComparison()
{
$euro1 = new Money(1, new EUR);
$euro2 = new Money(2, new EUR);
$usd = new Money(1, new USD);
$euro1 = new Money(1, new Currency('EUR'));
$euro2 = new Money(2, new Currency('EUR'));
$usd = new Money(1, new Currency('USD'));
$this->assertTrue($euro2->greaterThan($euro1));
$this->assertFalse($euro1->greaterThan($euro2));
......@@ -187,31 +187,31 @@ class MoneyTest extends PHPUnit_Framework_TestCase
public function testAllocation()
{
$m = new Money(100, new EUR);
$m = new Money(100, new Currency('EUR'));
list($part1, $part2, $part3) = $m->allocate(array(1, 1, 1));
$this->assertMoneyEquals(new Money(34, new EUR), $part1);
$this->assertMoneyEquals(new Money(33, new EUR), $part2);
$this->assertMoneyEquals(new Money(33, new EUR), $part3);
$this->assertMoneyEquals(new Money(34, new Currency('EUR')), $part1);
$this->assertMoneyEquals(new Money(33, new Currency('EUR')), $part2);
$this->assertMoneyEquals(new Money(33, new Currency('EUR')), $part3);
$m = new Money(101, new EUR);
$m = new Money(101, new Currency('EUR'));
list($part1, $part2, $part3) = $m->allocate(array(1, 1, 1));
$this->assertMoneyEquals(new Money(34, new EUR), $part1);
$this->assertMoneyEquals(new Money(34, new EUR), $part2);
$this->assertMoneyEquals(new Money(33, new EUR), $part3);
$this->assertMoneyEquals(new Money(34, new Currency('EUR')), $part1);
$this->assertMoneyEquals(new Money(34, new Currency('EUR')), $part2);
$this->assertMoneyEquals(new Money(33, new Currency('EUR')), $part3);
}
public function testAllocationOrderIsImportant()
{
$m = new Money(5, new EUR);
$m = new Money(5, new Currency('EUR'));
list($part1, $part2) = $m->allocate(array(3, 7));
$this->assertMoneyEquals(new Money(2, new EUR), $part1);
$this->assertMoneyEquals(new Money(3, new EUR), $part2);
$this->assertMoneyEquals(new Money(2, new Currency('EUR')), $part1);
$this->assertMoneyEquals(new Money(3, new Currency('EUR')), $part2);
$m = new Money(5, new EUR);
$m = new Money(5, new Currency('EUR'));
list($part1, $part2) = $m->allocate(array(7, 3));
$this->assertMoneyEquals(new Money(4, new EUR), $part1);
$this->assertMoneyEquals(new Money(1, new EUR), $part2);
$this->assertMoneyEquals(new Money(4, new Currency('EUR')), $part1);
$this->assertMoneyEquals(new Money(1, new Currency('EUR')), $part2);
}
}
\ No newline at end of file
......@@ -10,8 +10,7 @@
require_once 'PHPUnit/Framework/TestCase.php';
require_once __DIR__.'/../lib/Verraes/Money/Currency.php';
require_once __DIR__.'/../lib/Verraes/Money/EUR.php';
require_once __DIR__.'/../lib/Verraes/Money/Exception.php';
require_once __DIR__.'/../lib/Verraes/Money/InvalidArgumentException.php';
require_once __DIR__.'/../lib/Verraes/Money/UnknownCurrencyException.php';
require_once __DIR__.'/../lib/Verraes/Money/Money.php';
require_once __DIR__.'/../lib/Verraes/Money/USD.php';
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment