From: David S. <ds...@us...> - 2006-02-15 22:55:42
|
Update of /cvsroot/junit/junit/junit4.0/junit/samples/money In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13390/junit4.0/junit/samples/money Added Files: MoneyTest.java Money.java MoneyBag.java IMoney.java Log Message: Merged with branch, Kent will make final changes and launch. --- NEW FILE: MoneyTest.java --- package junit.samples.money; import junit.framework.TestCase; public class MoneyTest extends TestCase { private Money f12CHF; private Money f14CHF; private Money f7USD; private Money f21USD; private IMoney fMB1; private IMoney fMB2; public static void main(String args[]) { junit.textui.TestRunner.run(MoneyTest.class); } @Override protected void setUp() { f12CHF= new Money(12, "CHF"); f14CHF= new Money(14, "CHF"); f7USD= new Money( 7, "USD"); f21USD= new Money(21, "USD"); fMB1= MoneyBag.create(f12CHF, f7USD); fMB2= MoneyBag.create(f14CHF, f21USD); } public void testBagMultiply() { // {[12 CHF][7 USD]} *2 == {[24 CHF][14 USD]} IMoney expected= MoneyBag.create(new Money(24, "CHF"), new Money(14, "USD")); assertEquals(expected, fMB1.multiply(2)); assertEquals(fMB1, fMB1.multiply(1)); assertTrue(fMB1.multiply(0).isZero()); } public void testBagNegate() { // {[12 CHF][7 USD]} negate == {[-12 CHF][-7 USD]} IMoney expected= MoneyBag.create(new Money(-12, "CHF"), new Money(-7, "USD")); assertEquals(expected, fMB1.negate()); } public void testBagSimpleAdd() { // {[12 CHF][7 USD]} + [14 CHF] == {[26 CHF][7 USD]} IMoney expected= MoneyBag.create(new Money(26, "CHF"), new Money(7, "USD")); assertEquals(expected, fMB1.add(f14CHF)); } public void testBagSubtract() { // {[12 CHF][7 USD]} - {[14 CHF][21 USD] == {[-2 CHF][-14 USD]} IMoney expected= MoneyBag.create(new Money(-2, "CHF"), new Money(-14, "USD")); assertEquals(expected, fMB1.subtract(fMB2)); } public void testBagSumAdd() { // {[12 CHF][7 USD]} + {[14 CHF][21 USD]} == {[26 CHF][28 USD]} IMoney expected= MoneyBag.create(new Money(26, "CHF"), new Money(28, "USD")); assertEquals(expected, fMB1.add(fMB2)); } public void testIsZero() { assertTrue(fMB1.subtract(fMB1).isZero()); assertTrue(MoneyBag.create(new Money (0, "CHF"), new Money (0, "USD")).isZero()); } public void testMixedSimpleAdd() { // [12 CHF] + [7 USD] == {[12 CHF][7 USD]} IMoney expected= MoneyBag.create(f12CHF, f7USD); assertEquals(expected, f12CHF.add(f7USD)); } public void testBagNotEquals() { IMoney bag= MoneyBag.create(f12CHF, f7USD); assertFalse(bag.equals(new Money(12, "DEM").add(f7USD))); } public void testMoneyBagEquals() { assertTrue(!fMB1.equals(null)); assertEquals(fMB1, fMB1); IMoney equal= MoneyBag.create(new Money(12, "CHF"), new Money(7, "USD")); assertTrue(fMB1.equals(equal)); assertTrue(!fMB1.equals(f12CHF)); assertTrue(!f12CHF.equals(fMB1)); assertTrue(!fMB1.equals(fMB2)); } public void testMoneyBagHash() { IMoney equal= MoneyBag.create(new Money(12, "CHF"), new Money(7, "USD")); assertEquals(fMB1.hashCode(), equal.hashCode()); } public void testMoneyEquals() { assertTrue(!f12CHF.equals(null)); Money equalMoney= new Money(12, "CHF"); assertEquals(f12CHF, f12CHF); assertEquals(f12CHF, equalMoney); assertEquals(f12CHF.hashCode(), equalMoney.hashCode()); assertTrue(!f12CHF.equals(f14CHF)); } public void testMoneyHash() { assertTrue(!f12CHF.equals(null)); Money equal= new Money(12, "CHF"); assertEquals(f12CHF.hashCode(), equal.hashCode()); } public void testSimplify() { IMoney money= MoneyBag.create(new Money(26, "CHF"), new Money(28, "CHF")); assertEquals(new Money(54, "CHF"), money); } public void testNormalize2() { // {[12 CHF][7 USD]} - [12 CHF] == [7 USD] Money expected= new Money(7, "USD"); assertEquals(expected, fMB1.subtract(f12CHF)); } public void testNormalize3() { // {[12 CHF][7 USD]} - {[12 CHF][3 USD]} == [4 USD] IMoney ms1= MoneyBag.create(new Money(12, "CHF"), new Money(3, "USD")); Money expected= new Money(4, "USD"); assertEquals(expected, fMB1.subtract(ms1)); } public void testNormalize4() { // [12 CHF] - {[12 CHF][3 USD]} == [-3 USD] IMoney ms1= MoneyBag.create(new Money(12, "CHF"), new Money(3, "USD")); Money expected= new Money(-3, "USD"); assertEquals(expected, f12CHF.subtract(ms1)); } public void testPrint() { assertEquals("[12 CHF]", f12CHF.toString()); } public void testSimpleAdd() { // [12 CHF] + [14 CHF] == [26 CHF] Money expected= new Money(26, "CHF"); assertEquals(expected, f12CHF.add(f14CHF)); } public void testSimpleBagAdd() { // [14 CHF] + {[12 CHF][7 USD]} == {[26 CHF][7 USD]} IMoney expected= MoneyBag.create(new Money(26, "CHF"), new Money(7, "USD")); assertEquals(expected, f14CHF.add(fMB1)); } public void testSimpleMultiply() { // [14 CHF] *2 == [28 CHF] Money expected= new Money(28, "CHF"); assertEquals(expected, f14CHF.multiply(2)); } public void testSimpleNegate() { // [14 CHF] negate == [-14 CHF] Money expected= new Money(-14, "CHF"); assertEquals(expected, f14CHF.negate()); } public void testSimpleSubtract() { // [14 CHF] - [12 CHF] == [2 CHF] Money expected= new Money(2, "CHF"); assertEquals(expected, f14CHF.subtract(f12CHF)); } } --- NEW FILE: Money.java --- package junit.samples.money; /** * A simple Money. * */ public class Money implements IMoney { private int fAmount; private String fCurrency; /** * Constructs a money from the given amount and currency. */ public Money(int amount, String currency) { fAmount= amount; fCurrency= currency; } /** * Adds a money to this money. Forwards the request to the addMoney helper. */ public IMoney add(IMoney m) { return m.addMoney(this); } public IMoney addMoney(Money m) { if (m.currency().equals(currency()) ) return new Money(amount()+m.amount(), currency()); return MoneyBag.create(this, m); } public IMoney addMoneyBag(MoneyBag s) { return s.addMoney(this); } public int amount() { return fAmount; } public String currency() { return fCurrency; } @Override public boolean equals(Object anObject) { if (isZero()) if (anObject instanceof IMoney) return ((IMoney)anObject).isZero(); if (anObject instanceof Money) { Money aMoney= (Money)anObject; return aMoney.currency().equals(currency()) && amount() == aMoney.amount(); } return false; } @Override public int hashCode() { if (fAmount == 0) return 0; return fCurrency.hashCode()+fAmount; } public boolean isZero() { return amount() == 0; } public IMoney multiply(int factor) { return new Money(amount()*factor, currency()); } public IMoney negate() { return new Money(-amount(), currency()); } public IMoney subtract(IMoney m) { return add(m.negate()); } @Override public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("["+amount()+" "+currency()+"]"); return buffer.toString(); } public /*this makes no sense*/ void appendTo(MoneyBag m) { m.appendMoney(this); } } --- NEW FILE: MoneyBag.java --- package junit.samples.money; import java.util.ArrayList; import java.util.List; /** * A MoneyBag defers exchange rate conversions. For example adding * 12 Swiss Francs to 14 US Dollars is represented as a bag * containing the two Monies 12 CHF and 14 USD. Adding another * 10 Swiss francs gives a bag with 22 CHF and 14 USD. Due to * the deferred exchange rate conversion we can later value a * MoneyBag with different exchange rates. * * A MoneyBag is represented as a list of Monies and provides * different constructors to create a MoneyBag. */ public class MoneyBag implements IMoney { private List<Money> fMonies= new ArrayList<Money>(5); public static IMoney create(IMoney m1, IMoney m2) { MoneyBag result= new MoneyBag(); m1.appendTo(result); m2.appendTo(result); return result.simplify(); } public IMoney add(IMoney m) { return m.addMoneyBag(this); } public IMoney addMoney(Money m) { return MoneyBag.create(m, this); } public IMoney addMoneyBag(MoneyBag s) { return MoneyBag.create(s, this); } void appendBag(MoneyBag aBag) { for (Money each : aBag.fMonies) appendMoney(each); } void appendMoney(Money aMoney) { if (aMoney.isZero()) return; IMoney old= findMoney(aMoney.currency()); if (old == null) { fMonies.add(aMoney); return; } fMonies.remove(old); Money sum= (Money) old.add(aMoney); if (sum.isZero()) return; fMonies.add(sum); } @Override public boolean equals(Object anObject) { if (isZero()) if (anObject instanceof IMoney) return ((IMoney)anObject).isZero(); if (anObject instanceof MoneyBag) { MoneyBag aMoneyBag= (MoneyBag)anObject; if (aMoneyBag.fMonies.size() != fMonies.size()) return false; for (Money each : fMonies) if (! aMoneyBag.contains(each)) return false; return true; } return false; } private Money findMoney(String currency) { for (Money each : fMonies) if (each.currency().equals(currency)) return each; return null; } private boolean contains(Money m) { Money found= findMoney(m.currency()); if (found == null) return false; return found.amount() == m.amount(); } @Override public int hashCode() { int hash= 0; for (Money each : fMonies) hash^= each.hashCode(); return hash; } public boolean isZero() { return fMonies.size() == 0; } public IMoney multiply(int factor) { MoneyBag result= new MoneyBag(); if (factor != 0) for (Money each : fMonies) result.appendMoney((Money) each.multiply(factor)); return result; } public IMoney negate() { MoneyBag result= new MoneyBag(); for (Money each : fMonies) result.appendMoney((Money) each.negate()); return result; } private IMoney simplify() { if (fMonies.size() == 1) return fMonies.iterator().next(); return this; } public IMoney subtract(IMoney m) { return add(m.negate()); } @Override public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("{"); for (Money each : fMonies) buffer.append(each); buffer.append("}"); return buffer.toString(); } public void appendTo(MoneyBag m) { m.appendBag(this); } } --- NEW FILE: IMoney.java --- package junit.samples.money; /** * The common interface for simple Monies and MoneyBags * */ public interface IMoney { /** * Adds a money to this money. */ public abstract IMoney add(IMoney m); /** * Adds a simple Money to this money. This is a helper method for * implementing double dispatch */ public abstract IMoney addMoney(Money m); /** * Adds a MoneyBag to this money. This is a helper method for * implementing double dispatch */ public abstract IMoney addMoneyBag(MoneyBag s); /** * Tests whether this money is zero */ public abstract boolean isZero(); /** * Multiplies a money by the given factor. */ public abstract IMoney multiply(int factor); /** * Negates this money. */ public abstract IMoney negate(); /** * Subtracts a money from this money. */ public abstract IMoney subtract(IMoney m); /** * Append this to a MoneyBag m. * appendTo() needs to be public because it is used * polymorphically, but it should not be used by clients * because it modifies the argument m. */ public abstract void appendTo(MoneyBag m); } |