1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/task3/solution04/test/org/apidesign/apifest08/test/Task2Test.java Tue Oct 07 11:05:34 2008 +0200
1.3 @@ -0,0 +1,179 @@
1.4 +package org.apidesign.apifest08.test;
1.5 +
1.6 +import java.math.BigDecimal;
1.7 +import java.util.Currency;
1.8 +import java.util.Set;
1.9 +import junit.framework.TestCase;
1.10 +import org.apidesign.apifest08.currency.Convertor;
1.11 +import org.apidesign.apifest08.currency.ConvertorFactory;
1.12 +import org.apidesign.apifest08.currency.InvalidConversionException;
1.13 +
1.14 +
1.15 +/** There are many currencies around the world and many banks manipulate
1.16 + * with more than one or two at the same time. As banks are usually the
1.17 + * best paying clients, which is true even in case of your Convertor API,
1.18 + * it is reasonable to listen to their requests.
1.19 + * <p>
1.20 + * The quest for today is to enhance your existing convertor API to hold
1.21 + * information about many currencies and allow conversions between any of them.
1.22 + * Also, as conversion rates for diferent currencies usually arise from various
1.23 + * bank departments, there is another important need. There is a need to
1.24 + * compose two convertors into one by merging all the information about
1.25 + * currencies they know about.
1.26 + */
1.27 +public class Task2Test extends TestCase
1.28 +{
1.29 + private final static Currency CZK;
1.30 + private final static Currency SKK;
1.31 + private final static Currency USD;
1.32 +
1.33 + static
1.34 + {
1.35 + CZK = Currency.getInstance("CZK");
1.36 + SKK = Currency.getInstance("SKK");
1.37 + USD = Currency.getInstance("USD");
1.38 + }
1.39 +
1.40 + public Task2Test(String testName)
1.41 + {
1.42 + super(testName);
1.43 + }
1.44 +
1.45 + @Override
1.46 + protected void setUp()
1.47 + throws Exception
1.48 + {
1.49 + }
1.50 +
1.51 + @Override
1.52 + protected void tearDown()
1.53 + throws Exception
1.54 + {
1.55 + }
1.56 +
1.57 + // As in Task1Test, keep in mind, that there are three parts
1.58 + // of the whole system:
1.59 + // 1. there is someone who knows the current exchange rate
1.60 + // 2. there is someone who wants to do the conversion
1.61 + // 3. there is the API between 1. and 2. which allows them to communicate
1.62 + //
1.63 + // Please backward compatibly enhance your existing API to support following
1.64 + // usecases:
1.65 + //
1.66 +
1.67 + /** Create convertor that understands two currencies, CZK and
1.68 + * SKK. Make 100 SKK == 75 CZK. This is method for the group of users that
1.69 + * knows the exchange rate, and needs to use the API to create objects
1.70 + * with the exchange rate. Anyone shall be ready to call this method without
1.71 + * any other method being called previously. The API itself shall know
1.72 + * nothing about any rates, before this method is called.
1.73 + */
1.74 + public static Convertor createTripleConvertor() {
1.75 + // Rates: 1USD = 15CZK
1.76 + // Rates: 1USD = 20SKK
1.77 + // Rates: 75CZK = 100SKK
1.78 + Convertor c = ConvertorFactory.mergeConvertors(
1.79 + ConvertorFactory.getConvertor(USD, BigDecimal.ONE, CZK, BigDecimal.valueOf(15.00)),
1.80 + ConvertorFactory.getConvertor(USD, BigDecimal.ONE, SKK, BigDecimal.valueOf(20.00))
1.81 + );
1.82 +
1.83 + return c;
1.84 + }
1.85 +
1.86 + /** Define convertor that understands three currencies. Use it.
1.87 + */
1.88 + public void testConvertorForUSDandCZKandSKK() throws Exception {
1.89 + Convertor c = createTripleConvertor();
1.90 +
1.91 + // convert $5 to CZK using c:
1.92 + // assertEquals("Result is 75 CZK");
1.93 + assertEquals(new BigDecimal("75.00"), c.convert(USD, CZK, BigDecimal.valueOf(5.00)));
1.94 +
1.95 + // convert $5 to SKK using c:
1.96 + // assertEquals("Result is 100 SKK");
1.97 + assertEquals(new BigDecimal("100.00"), c.convert(USD, SKK, BigDecimal.valueOf(5.00)));
1.98 +
1.99 + // convert 200SKK to CZK using c:
1.100 + // assertEquals("Result is 150 CZK");
1.101 + assertEquals(new BigDecimal("150.00"), c.convert(SKK, CZK, BigDecimal.valueOf(200.00)));
1.102 +
1.103 + // convert 200SKK to USK using c:
1.104 + // assertEquals("Result is 10 USD");
1.105 + assertEquals(new BigDecimal("10.00"), c.convert(SKK, USD, BigDecimal.valueOf(200.00)));
1.106 + }
1.107 +
1.108 + /** Merge all currency rates of convertor 1 with convertor 2.
1.109 + * Implement this using your API, preferably this method just delegates
1.110 + * into some API method which does the actual work, without requiring
1.111 + * API clients to code anything complex.
1.112 + */
1.113 + public static Convertor merge(Convertor one, Convertor two) {
1.114 + return ConvertorFactory.mergeConvertors(one, two);
1.115 + }
1.116 +
1.117 + /** Join the convertors from previous task, Task1Test and show that it
1.118 + * can be used to do reasonable conversions.
1.119 + */
1.120 + public void testConvertorComposition() throws Exception {
1.121 + Convertor c = merge(
1.122 + Task1Test.createCZKtoUSD(),
1.123 + Task1Test.createSKKtoCZK()
1.124 + );
1.125 +
1.126 + // convert $5 to CZK using c:
1.127 + // assertEquals("Result is 85 CZK");
1.128 + assertEquals(new BigDecimal("85.00"), c.convert(USD, CZK, BigDecimal.valueOf(5.00)));
1.129 +
1.130 + // convert $8 to CZK using c:
1.131 + // assertEquals("Result is 136 CZK");
1.132 + assertEquals(new BigDecimal("136.00"), c.convert(USD, CZK, BigDecimal.valueOf(8.00)));
1.133 +
1.134 + // convert 1003CZK to USD using c:
1.135 + // assertEquals("Result is 59 USD");
1.136 + assertEquals(new BigDecimal("59.00"), c.convert(CZK, USD, BigDecimal.valueOf(1003.00)));
1.137 +
1.138 + // convert 16CZK using c:
1.139 + // assertEquals("Result is 20 SKK");
1.140 + assertEquals(new BigDecimal("20.00"), c.convert(CZK, SKK, BigDecimal.valueOf(16.00)));
1.141 +
1.142 + // convert 500SKK to CZK using c:
1.143 + // assertEquals("Result is 400 CZK");
1.144 + assertEquals(new BigDecimal("400.00"), c.convert(SKK, CZK, BigDecimal.valueOf(500.00)));
1.145 + }
1.146 +
1.147 + public void testGetCurrencies()
1.148 + {
1.149 + Convertor c = merge(
1.150 + Task1Test.createCZKtoUSD(),
1.151 + Task1Test.createSKKtoCZK()
1.152 + );
1.153 + Set<Currency> currencies;
1.154 +
1.155 + currencies = c.getCurrencies();
1.156 + assertEquals(3, currencies.size());
1.157 + assertTrue(currencies.contains(Currency.getInstance("SKK")));
1.158 + assertTrue(currencies.contains(Currency.getInstance("CZK")));
1.159 + assertTrue(currencies.contains(Currency.getInstance("USD")));
1.160 + }
1.161 +
1.162 + public void testGetConverstionRate()
1.163 + throws InvalidConversionException
1.164 + {
1.165 + Convertor c = merge(
1.166 + Task1Test.createCZKtoUSD(),
1.167 + Task1Test.createSKKtoCZK()
1.168 + );
1.169 +
1.170 + assertEquals(1.0, c.getConversionRate(USD, USD).doubleValue(), 0.0000000000000001);
1.171 + assertEquals(17.0, c.getConversionRate(USD, CZK).doubleValue(), 0.0000000000000001);
1.172 + assertEquals(21.25, c.getConversionRate(USD, SKK).doubleValue(), 0.0000000000000001);
1.173 +
1.174 + assertEquals(1.0 / 17.0, c.getConversionRate(CZK, USD).doubleValue(), 0.0000000000000001);
1.175 + assertEquals(1.0, c.getConversionRate(CZK, CZK).doubleValue(), 0.0000000000000001);
1.176 + assertEquals(1.25, c.getConversionRate(CZK, SKK).doubleValue(), 0.0000000000000001);
1.177 +
1.178 + assertEquals(0.04705882352941176, c.getConversionRate(SKK, USD).doubleValue(), 0.0000000000000001);
1.179 + assertEquals(0.8, c.getConversionRate(SKK, CZK).doubleValue(), 0.0000000000000001);
1.180 + assertEquals(1.0, c.getConversionRate(SKK, SKK).doubleValue(), 0.0000000000000001);
1.181 + }
1.182 +}