1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/task2/solution02/src/org/apidesign/apifest08/currency/CompositeConvertor.java Tue Oct 07 00:19:37 2008 +0200
1.3 @@ -0,0 +1,75 @@
1.4 +package org.apidesign.apifest08.currency;
1.5 +
1.6 +import java.io.Serializable;
1.7 +import java.util.Arrays;
1.8 +import java.util.Currency;
1.9 +
1.10 +/**
1.11 + * Convertor that is composed from other convertors.
1.12 + * @author lukas
1.13 + *
1.14 + */
1.15 +class CompositeConvertor implements ExtendedConvertor, Serializable {
1.16 +
1.17 + private static final long serialVersionUID = -2702026568249130055L;
1.18 +
1.19 + private final ExtendedConvertor[] convertors;
1.20 +
1.21 +
1.22 + public CompositeConvertor(ExtendedConvertor... convertors) {
1.23 + this.convertors = convertors.clone();
1.24 + for (ExtendedConvertor convertor: this.convertors)
1.25 + {
1.26 + if (convertor==null)
1.27 + {
1.28 + throw new NullPointerException("One of the convertors to be merged is null");
1.29 + }
1.30 + }
1.31 + }
1.32 +
1.33 + /**
1.34 + * Returns true if the composite contains convertor that supports given conversion.
1.35 + */
1.36 + public boolean isConversionSupported(Currency from, Currency to) {
1.37 + return findConvertorFor(from, to)!=null;
1.38 + }
1.39 +
1.40 +
1.41 + /**
1.42 + * If the composite contains convertor that supports given conversion, delegates to its convert method.
1.43 + * Throws {@link IllegalArgumentException} convertor supporting given conversion is not found.
1.44 + */
1.45 + public Money convert(Money amount, Currency destinationCurrency) throws IllegalArgumentException {
1.46 + ExtendedConvertor convertor = findConvertorFor(amount.getCurrency(), destinationCurrency);
1.47 + if (convertor!=null)
1.48 + {
1.49 + return convertor.convert(amount, destinationCurrency);
1.50 + }
1.51 + throw new IllegalArgumentException("Conversion not supported. Can not convert to "+destinationCurrency+".");
1.52 + }
1.53 +
1.54 + /**
1.55 + * Finds convertor for given currencies. If not found, returns null.
1.56 + * @param from
1.57 + * @param to
1.58 + * @return
1.59 + */
1.60 + ExtendedConvertor findConvertorFor(Currency from, Currency to) {
1.61 + //does linear search, in the future can cache the results.
1.62 + for (ExtendedConvertor convertor:convertors)
1.63 + {
1.64 + if (convertor.isConversionSupported(from, to))
1.65 + {
1.66 + return convertor;
1.67 + }
1.68 + }
1.69 + return null;
1.70 + }
1.71 +
1.72 +
1.73 + @Override
1.74 + public String toString() {
1.75 + return getClass().getName()+" converts "+Arrays.toString(convertors);
1.76 + }
1.77 +
1.78 +}
2.1 --- a/task2/solution02/src/org/apidesign/apifest08/currency/ConvertorFactory.java Tue Oct 07 00:17:07 2008 +0200
2.2 +++ b/task2/solution02/src/org/apidesign/apifest08/currency/ConvertorFactory.java Tue Oct 07 00:19:37 2008 +0200
2.3 @@ -22,9 +22,24 @@
2.4 * @param destinationEquivalent
2.5 * @return
2.6 */
2.7 - public static final Convertor createConvertor(Money sourceEquivalent, Money destinationEquivalent)
2.8 + public static final ExtendedConvertor createConvertor(Money sourceEquivalent, Money destinationEquivalent)
2.9 {
2.10 - return new DefaultConvertor(sourceEquivalent.getAmount(), destinationEquivalent.getAmount(), sourceEquivalent.getCurrency(), destinationEquivalent.getCurrency());
2.11 + return mergeConvertors(
2.12 + new DefaultConvertor(sourceEquivalent, destinationEquivalent),
2.13 + new DefaultConvertor(destinationEquivalent ,sourceEquivalent)
2.14 + );
2.15 + }
2.16 +
2.17 + /**
2.18 + * Merges convertors. The resulting convertor has ability to do all conversions that its underlying
2.19 + * convertors could do. No consistency validation is done, inconsistent input will result in a convertor with
2.20 + * inconsistent behavior.
2.21 + * @param convertors
2.22 + * @return
2.23 + */
2.24 + public static final ExtendedConvertor mergeConvertors(ExtendedConvertor... convertors)
2.25 + {
2.26 + return new CompositeConvertor(convertors);
2.27 }
2.28
2.29
3.1 --- a/task2/solution02/src/org/apidesign/apifest08/currency/DefaultConvertor.java Tue Oct 07 00:17:07 2008 +0200
3.2 +++ b/task2/solution02/src/org/apidesign/apifest08/currency/DefaultConvertor.java Tue Oct 07 00:19:37 2008 +0200
3.3 @@ -11,9 +11,9 @@
3.4 * @author lukas
3.5 *
3.6 */
3.7 -class DefaultConvertor implements Convertor, Serializable {
3.8 +class DefaultConvertor implements ExtendedConvertor, Serializable {
3.9
3.10 - private static final long serialVersionUID = -1754789142402148099L;
3.11 + private static final long serialVersionUID = 6660014633685135034L;
3.12
3.13 /**
3.14 * Equivalent in source currency.
3.15 @@ -29,20 +29,20 @@
3.16
3.17 private final Currency destinationCurrency;
3.18
3.19 - public DefaultConvertor(BigDecimal sourceEquivalent, BigDecimal destinationEquivalent, Currency sourceCurrency, Currency destinationCurrency) {
3.20 + public DefaultConvertor(Money sourceEquivalent, Money destinationEquivalent) {
3.21 super();
3.22 - if (BigDecimal.ZERO.compareTo(sourceEquivalent)==0)
3.23 + if (BigDecimal.ZERO.compareTo(sourceEquivalent.getAmount())==0)
3.24 {
3.25 throw new IllegalArgumentException("Source equivalent amount can not be 0.");
3.26 }
3.27 - if (BigDecimal.ZERO.compareTo(destinationEquivalent)==0)
3.28 + if (BigDecimal.ZERO.compareTo(destinationEquivalent.getAmount())==0)
3.29 {
3.30 throw new IllegalArgumentException("Destination equivalent amount can not be 0.");
3.31 }
3.32 - this.sourceEquivalent = sourceEquivalent;
3.33 - this.destinationEquivalent = destinationEquivalent;
3.34 - this.sourceCurrency = sourceCurrency;
3.35 - this.destinationCurrency = destinationCurrency;
3.36 + this.sourceEquivalent = sourceEquivalent.getAmount();
3.37 + this.destinationEquivalent = destinationEquivalent.getAmount();
3.38 + this.sourceCurrency = sourceEquivalent.getCurrency();
3.39 + this.destinationCurrency = destinationEquivalent.getCurrency();
3.40 }
3.41
3.42 public Money convert(Money amount, Currency destinationCurrency) {
3.43 @@ -54,10 +54,6 @@
3.44 {
3.45 throw new NullPointerException("destionationCurrency is null");
3.46 }
3.47 - if (isConversionInOpositeDirection(amount, destinationCurrency))
3.48 - {
3.49 - return revert().convert(amount, destinationCurrency);
3.50 - }
3.51 if (!amount.getCurrency().equals(getSourceCurrency()))
3.52 {
3.53 throw new IllegalArgumentException("Can not convert from "+amount.getCurrency()+". Converts between "+getSourceCurrency()+" and "+getDestinationCurrency());
3.54 @@ -70,20 +66,9 @@
3.55 BigDecimal destinationAmount = sourceAmount.multiply(destinationEquivalent).divide(sourceEquivalent, 2, RoundingMode.HALF_UP);
3.56 return new MoneyImpl(destinationAmount, getDestinationCurrency());
3.57 }
3.58 -
3.59 - /**
3.60 - * Returns true, if the conversion is in oposit direction.
3.61 - * @param amount
3.62 - * @param destinationCurrency
3.63 - * @return
3.64 - */
3.65 - private boolean isConversionInOpositeDirection(Money amount, Currency destinationCurrency) {
3.66 - return amount.getCurrency().equals(getDestinationCurrency()) && destinationCurrency.equals(getSourceCurrency());
3.67 - }
3.68 -
3.69 -
3.70 - public Convertor revert() {
3.71 - return new DefaultConvertor(destinationEquivalent, sourceEquivalent, destinationCurrency, sourceCurrency);
3.72 +
3.73 + public boolean isConversionSupported(Currency from, Currency to) {
3.74 + return sourceCurrency.equals(from) && destinationCurrency.equals(to);
3.75 }
3.76
3.77 public BigDecimal getSourceEquivalent() {
3.78 @@ -107,58 +92,4 @@
3.79 return getClass().getName()+" converts "+getSourceCurrency()+" to "+getDestinationCurrency()+" "
3.80 +getSourceCurrency()+getSourceEquivalent()+"="+getDestinationCurrency()+getDestinationEquivalent();
3.81 }
3.82 -
3.83 - @Override
3.84 - public int hashCode() {
3.85 - final int prime = 31;
3.86 - int result = 1;
3.87 - result = prime
3.88 - * result
3.89 - + ((destinationCurrency == null) ? 0 : destinationCurrency
3.90 - .hashCode());
3.91 - result = prime
3.92 - * result
3.93 - + ((destinationEquivalent == null) ? 0 : destinationEquivalent
3.94 - .hashCode());
3.95 - result = prime * result
3.96 - + ((sourceCurrency == null) ? 0 : sourceCurrency.hashCode());
3.97 - result = prime
3.98 - * result
3.99 - + ((sourceEquivalent == null) ? 0 : sourceEquivalent.hashCode());
3.100 - return result;
3.101 - }
3.102 -
3.103 - @Override
3.104 - public boolean equals(Object obj) {
3.105 - if (this == obj)
3.106 - return true;
3.107 - if (obj == null)
3.108 - return false;
3.109 - if (!(obj instanceof DefaultConvertor))
3.110 - return false;
3.111 - DefaultConvertor other = (DefaultConvertor) obj;
3.112 - if (destinationCurrency == null) {
3.113 - if (other.destinationCurrency != null)
3.114 - return false;
3.115 - } else if (!destinationCurrency.equals(other.destinationCurrency))
3.116 - return false;
3.117 - if (destinationEquivalent == null) {
3.118 - if (other.destinationEquivalent != null)
3.119 - return false;
3.120 - } else if (!destinationEquivalent.equals(other.destinationEquivalent))
3.121 - return false;
3.122 - if (sourceCurrency == null) {
3.123 - if (other.sourceCurrency != null)
3.124 - return false;
3.125 - } else if (!sourceCurrency.equals(other.sourceCurrency))
3.126 - return false;
3.127 - if (sourceEquivalent == null) {
3.128 - if (other.sourceEquivalent != null)
3.129 - return false;
3.130 - } else if (!sourceEquivalent.equals(other.sourceEquivalent))
3.131 - return false;
3.132 - return true;
3.133 - }
3.134 -
3.135 -
3.136 }
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/task2/solution02/src/org/apidesign/apifest08/currency/ExtendedConvertor.java Tue Oct 07 00:19:37 2008 +0200
4.3 @@ -0,0 +1,18 @@
4.4 +package org.apidesign.apifest08.currency;
4.5 +
4.6 +import java.util.Currency;
4.7 +
4.8 +/**
4.9 + * Extended convertor interface.
4.10 + * @author lukas
4.11 + *
4.12 + */
4.13 +public interface ExtendedConvertor extends Convertor {
4.14 + /**
4.15 + * Returns true if given conversion is supported.
4.16 + * @param from
4.17 + * @param to
4.18 + * @return
4.19 + */
4.20 + public boolean isConversionSupported(Currency from, Currency to);
4.21 +}
5.1 --- a/task2/solution02/src/org/apidesign/apifest08/currency/MoneyImpl.java Tue Oct 07 00:17:07 2008 +0200
5.2 +++ b/task2/solution02/src/org/apidesign/apifest08/currency/MoneyImpl.java Tue Oct 07 00:19:37 2008 +0200
5.3 @@ -15,7 +15,7 @@
5.4 private final BigDecimal amount;
5.5
5.6 private final Currency currency;
5.7 -
5.8 +
5.9 public MoneyImpl(BigDecimal amount, Currency currency) {
5.10 if (amount==null) throw new NullPointerException("Amount is null");
5.11 if (currency==null) throw new NullPointerException("Currency is null"+currency);
5.12 @@ -23,6 +23,8 @@
5.13 this.currency = currency;
5.14 }
5.15
5.16 +
5.17 +
5.18 public MoneyImpl(long amount, Currency currency) {
5.19 this(BigDecimal.valueOf(amount), currency);
5.20 }
5.21 @@ -30,6 +32,37 @@
5.22 public MoneyImpl(double amount, Currency currency) {
5.23 this(BigDecimal.valueOf(amount), currency);
5.24 }
5.25 +
5.26 + /**
5.27 + * Factory method.
5.28 + * @param amount
5.29 + * @param currency
5.30 + * @return
5.31 + */
5.32 + public static final Money money(BigDecimal amount, Currency currency)
5.33 + {
5.34 + return new MoneyImpl(amount, currency);
5.35 + }
5.36 + /**
5.37 + * Factory method.
5.38 + * @param amount
5.39 + * @param currency
5.40 + * @return
5.41 + */
5.42 + public static final Money money(long amount, Currency currency)
5.43 + {
5.44 + return new MoneyImpl(amount, currency);
5.45 + }
5.46 + /**
5.47 + * Factory method.
5.48 + * @param amount
5.49 + * @param currency
5.50 + * @return
5.51 + */
5.52 + public static final Money money(double amount, Currency currency)
5.53 + {
5.54 + return new MoneyImpl(amount, currency);
5.55 + }
5.56
5.57 /**
5.58 * Returns amount.
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/task2/solution02/test/org/apidesign/apifest08/currency/CompositeConvertorTest.java Tue Oct 07 00:19:37 2008 +0200
6.3 @@ -0,0 +1,56 @@
6.4 +package org.apidesign.apifest08.currency;
6.5 +
6.6 +import static junit.framework.Assert.assertEquals;
6.7 +import static junit.framework.Assert.assertFalse;
6.8 +import static junit.framework.Assert.assertTrue;
6.9 +import static junit.framework.Assert.fail;
6.10 +import static org.apidesign.apifest08.test.Task1Test.CZK;
6.11 +import static org.apidesign.apifest08.test.Task1Test.SKK;
6.12 +import static org.apidesign.apifest08.test.Task1Test.USD;
6.13 +
6.14 +import org.junit.Test;
6.15 +
6.16 +public class CompositeConvertorTest {
6.17 + private static final ExtendedConvertor USD_CZK_CONVERTOR = ConvertorFactory.createConvertor(new MoneyImpl(1,USD), new MoneyImpl(17,CZK));
6.18 + private static final ExtendedConvertor SKK_CZK_CONVERTOR = ConvertorFactory.createConvertor(new MoneyImpl(100,SKK), new MoneyImpl(80,CZK));
6.19 +
6.20 + @Test
6.21 + public void testCompose()
6.22 + {
6.23 + ExtendedConvertor convertor = new CompositeConvertor(USD_CZK_CONVERTOR, SKK_CZK_CONVERTOR);
6.24 + assertTrue(convertor.isConversionSupported(CZK, SKK));
6.25 + assertTrue(convertor.isConversionSupported(CZK, USD));
6.26 + assertFalse(convertor.isConversionSupported(SKK, USD));
6.27 + assertEquals(new MoneyImpl(10,SKK), convertor.convert(new MoneyImpl(8,CZK), SKK));
6.28 + assertEquals(new MoneyImpl(2,USD), convertor.convert(new MoneyImpl(34,CZK), USD));
6.29 + try
6.30 + {
6.31 + convertor.convert(new MoneyImpl(34,SKK), USD);
6.32 + fail("Exception expected");
6.33 + }
6.34 + catch(IllegalArgumentException e)
6.35 + {
6.36 + assertTrue("Ok", true);
6.37 + }
6.38 + }
6.39 + @Test
6.40 + public void testEmpty()
6.41 + {
6.42 + ExtendedConvertor convertor = new CompositeConvertor();
6.43 + assertFalse(convertor.isConversionSupported(SKK, USD));
6.44 + try
6.45 + {
6.46 + convertor.convert(new MoneyImpl(34,SKK), USD);
6.47 + fail("Exception expected");
6.48 + }
6.49 + catch(IllegalArgumentException e)
6.50 + {
6.51 + assertTrue("Ok", true);
6.52 + }
6.53 + }
6.54 + @Test(expected=NullPointerException.class)
6.55 + public void testCreateNull()
6.56 + {
6.57 + new CompositeConvertor(USD_CZK_CONVERTOR, null);
6.58 + }
6.59 +}
7.1 --- a/task2/solution02/test/org/apidesign/apifest08/test/ConvertorTest.java Tue Oct 07 00:17:07 2008 +0200
7.2 +++ b/task2/solution02/test/org/apidesign/apifest08/test/ConvertorTest.java Tue Oct 07 00:19:37 2008 +0200
7.3 @@ -1,13 +1,16 @@
7.4 package org.apidesign.apifest08.test;
7.5
7.6 +import static junit.framework.Assert.assertEquals;
7.7 +import static junit.framework.Assert.assertFalse;
7.8 +import static junit.framework.Assert.assertTrue;
7.9 import static org.apidesign.apifest08.test.Task1Test.CZK;
7.10 +import static org.apidesign.apifest08.test.Task1Test.SKK;
7.11 import static org.apidesign.apifest08.test.Task1Test.USD;
7.12 -import static org.junit.Assert.assertEquals;
7.13
7.14 import java.math.BigDecimal;
7.15
7.16 -import org.apidesign.apifest08.currency.Convertor;
7.17 import org.apidesign.apifest08.currency.ConvertorFactory;
7.18 +import org.apidesign.apifest08.currency.ExtendedConvertor;
7.19 import org.apidesign.apifest08.currency.Money;
7.20 import org.apidesign.apifest08.currency.MoneyImpl;
7.21 import org.junit.Test;
7.22 @@ -15,7 +18,7 @@
7.23
7.24 public class ConvertorTest {
7.25
7.26 - private static final Convertor CZK_TO_USD_CONVERTOR = ConvertorFactory.createConvertor(new MoneyImpl(17,CZK), new MoneyImpl(1,USD));
7.27 + private static final ExtendedConvertor CZK_TO_USD_CONVERTOR = ConvertorFactory.createConvertor(new MoneyImpl(17,CZK), new MoneyImpl(1,USD));
7.28 @Test
7.29 public void testConvertSmall()
7.30 {
7.31 @@ -29,4 +32,13 @@
7.32 Money converted = CZK_TO_USD_CONVERTOR.convert(new MoneyImpl(0.01,USD),CZK);
7.33 assertEquals(new MoneyImpl(new BigDecimal("0.17"),CZK),converted);
7.34 }
7.35 + @Test
7.36 + public void testSupports()
7.37 + {
7.38 + assertTrue(CZK_TO_USD_CONVERTOR.isConversionSupported(USD,CZK));
7.39 + assertTrue(CZK_TO_USD_CONVERTOR.isConversionSupported(CZK,USD));
7.40 + assertFalse(CZK_TO_USD_CONVERTOR.isConversionSupported(CZK,CZK));
7.41 + assertFalse(CZK_TO_USD_CONVERTOR.isConversionSupported(CZK,SKK));
7.42 +
7.43 + }
7.44 }
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/task2/solution02/test/org/apidesign/apifest08/test/Task2Test.java Tue Oct 07 00:19:37 2008 +0200
8.3 @@ -0,0 +1,119 @@
8.4 +package org.apidesign.apifest08.test;
8.5 +
8.6 +import static org.apidesign.apifest08.currency.ConvertorFactory.createConvertor;
8.7 +import static org.apidesign.apifest08.currency.ConvertorFactory.mergeConvertors;
8.8 +import static org.apidesign.apifest08.currency.MoneyImpl.money;
8.9 +import static org.apidesign.apifest08.test.Task1Test.CZK;
8.10 +import static org.apidesign.apifest08.test.Task1Test.SKK;
8.11 +import static org.apidesign.apifest08.test.Task1Test.USD;
8.12 +import junit.framework.TestCase;
8.13 +
8.14 +import org.apidesign.apifest08.currency.Convertor;
8.15 +import org.apidesign.apifest08.currency.ExtendedConvertor;
8.16 +
8.17 +/** There are many currencies around the world and many banks manipulate
8.18 + * with more than one or two at the same time. As banks are usually the
8.19 + * best paying clients, which is true even in case of your Convertor API,
8.20 + * it is reasonable to listen to their requests.
8.21 + * <p>
8.22 + * The quest for today is to enhance your existing convertor API to hold
8.23 + * information about many currencies and allow conversions between any of them.
8.24 + * Also, as conversion rates for diferent currencies usually arise from various
8.25 + * bank departments, there is another important need. There is a need to
8.26 + * compose two convertors into one by merging all the information about
8.27 + * currencies they know about.
8.28 + */
8.29 +public class Task2Test extends TestCase {
8.30 + public Task2Test(String testName) {
8.31 + super(testName);
8.32 + }
8.33 +
8.34 + @Override
8.35 + protected void setUp() throws Exception {
8.36 + }
8.37 +
8.38 + @Override
8.39 + protected void tearDown() throws Exception {
8.40 + }
8.41 +
8.42 + // As in Task1Test, keep in mind, that there are three parts
8.43 + // of the whole system:
8.44 + // 1. there is someone who knows the current exchange rate
8.45 + // 2. there is someone who wants to do the conversion
8.46 + // 3. there is the API between 1. and 2. which allows them to communicate
8.47 + //
8.48 + // Please backward compatibly enhance your existing API to support following
8.49 + // usecases:
8.50 + //
8.51 +
8.52 + /** Create convertor that understands two currencies, CZK and
8.53 + * SKK. Make 100 SKK == 75 CZK. This is method for the group of users that
8.54 + * knows the exchange rate, and needs to use the API to create objects
8.55 + * with the exchange rate. Anyone shall be ready to call this method without
8.56 + * any other method being called previously. The API itself shall know
8.57 + * nothing about any rates, before this method is called.
8.58 + */
8.59 + public static Convertor createTripleConvertor() {
8.60 + // Rates: 1USD = 15CZK
8.61 + // Rates: 1USD = 20SKK
8.62 + // Rates: 75CZK = 100SKK
8.63 + return mergeConvertors(
8.64 + createConvertor(money(1, USD), money(15, CZK)),
8.65 + createConvertor(money(1, USD), money(20, SKK)),
8.66 + createConvertor(money(75, CZK), money(100, SKK))
8.67 + );
8.68 + }
8.69 +
8.70 + /** Define convertor that understands three currencies. Use it.
8.71 + */
8.72 + public void testConvertorForUSDandCZKandSKK() throws Exception {
8.73 + Convertor c = createTripleConvertor();
8.74 +
8.75 + // convert $5 to CZK using c:
8.76 + assertEquals("Result is 75 CZK", money(75, CZK),c.convert(money(5,USD), CZK));
8.77 +
8.78 + // convert $5 to SKK using c:
8.79 + assertEquals("Result is 100 SKK", money(100, SKK),c.convert(money(5,USD), SKK));
8.80 +
8.81 + // convert 200SKK to CZK using c:
8.82 + assertEquals("Result is 150 CZK", money(150, CZK),c.convert(money(200,SKK), CZK));
8.83 +
8.84 + // convert 200SKK to USK using c:
8.85 + assertEquals("Result is 10 USD", money(10, USD),c.convert(money(200,SKK), USD));
8.86 + }
8.87 +
8.88 + /** Merge all currency rates of convertor 1 with convertor 2.
8.89 + * Implement this using your API, preferably this method just delegates
8.90 + * into some API method which does the actual work, without requiring
8.91 + * API clients to code anything complex.
8.92 + */
8.93 + public static Convertor merge(Convertor one, Convertor two) {
8.94 + return mergeConvertors((ExtendedConvertor)one, (ExtendedConvertor)two);
8.95 + }
8.96 +
8.97 + /** Join the convertors from previous task, Task1Test and show that it
8.98 + * can be used to do reasonable conversions.
8.99 + */
8.100 + public void testConvertorComposition() throws Exception {
8.101 + Convertor c = merge(
8.102 + Task1Test.createCZKtoUSD(),
8.103 + Task1Test.createSKKtoCZK()
8.104 + );
8.105 +
8.106 + // convert $5 to CZK using c:
8.107 + assertEquals("Result is 85 CZK", money(85, CZK),c.convert(money(5,USD), CZK));
8.108 +
8.109 + // convert $8 to CZK using c:
8.110 + assertEquals("Result is 136 CZK", money(136, CZK),c.convert(money(8,USD), CZK));
8.111 +
8.112 + // convert 1003CZK to USD using c:
8.113 + assertEquals("Result is 59 USD", money(59, USD),c.convert(money(1003,CZK), USD));
8.114 +
8.115 + // convert 16CZK using c:
8.116 + assertEquals("Result is 20 SKK", money(20, SKK),c.convert(money(16,CZK), SKK));
8.117 +
8.118 + // convert 500SKK to CZK using c:
8.119 + assertEquals("Result is 400 CZK", money(400, CZK),c.convert(money(500,SKK), CZK));
8.120 +
8.121 + }
8.122 +}