1 package org.apidesign.apifest08.test;
3 import java.math.BigDecimal;
4 import java.util.Currency;
6 import junit.framework.TestCase;
7 import org.apidesign.apifest08.currency.Convertor;
8 import org.apidesign.apifest08.currency.ConvertorFactory;
9 import org.apidesign.apifest08.currency.InvalidConversionException;
12 /** There are many currencies around the world and many banks manipulate
13 * with more than one or two at the same time. As banks are usually the
14 * best paying clients, which is true even in case of your Convertor API,
15 * it is reasonable to listen to their requests.
17 * The quest for today is to enhance your existing convertor API to hold
18 * information about many currencies and allow conversions between any of them.
19 * Also, as conversion rates for diferent currencies usually arise from various
20 * bank departments, there is another important need. There is a need to
21 * compose two convertors into one by merging all the information about
22 * currencies they know about.
24 public class Task2Test extends TestCase
26 private final static Currency CZK;
27 private final static Currency SKK;
28 private final static Currency USD;
32 CZK = Currency.getInstance("CZK");
33 SKK = Currency.getInstance("SKK");
34 USD = Currency.getInstance("USD");
37 public Task2Test(String testName)
43 protected void setUp()
49 protected void tearDown()
54 // As in Task1Test, keep in mind, that there are three parts
55 // of the whole system:
56 // 1. there is someone who knows the current exchange rate
57 // 2. there is someone who wants to do the conversion
58 // 3. there is the API between 1. and 2. which allows them to communicate
60 // Please backward compatibly enhance your existing API to support following
64 /** Create convertor that understands two currencies, CZK and
65 * SKK. Make 100 SKK == 75 CZK. This is method for the group of users that
66 * knows the exchange rate, and needs to use the API to create objects
67 * with the exchange rate. Anyone shall be ready to call this method without
68 * any other method being called previously. The API itself shall know
69 * nothing about any rates, before this method is called.
71 public static Convertor createTripleConvertor() {
72 // Rates: 1USD = 15CZK
73 // Rates: 1USD = 20SKK
74 // Rates: 75CZK = 100SKK
75 Convertor c = ConvertorFactory.mergeConvertors(
76 ConvertorFactory.getConvertor(USD, BigDecimal.ONE, CZK, BigDecimal.valueOf(15.00)),
77 ConvertorFactory.getConvertor(USD, BigDecimal.ONE, SKK, BigDecimal.valueOf(20.00))
83 /** Define convertor that understands three currencies. Use it.
85 public void testConvertorForUSDandCZKandSKK() throws Exception {
86 Convertor c = createTripleConvertor();
88 // convert $5 to CZK using c:
89 // assertEquals("Result is 75 CZK");
90 assertEquals(new BigDecimal("75.00"), c.convert(USD, CZK, BigDecimal.valueOf(5.00)));
92 // convert $5 to SKK using c:
93 // assertEquals("Result is 100 SKK");
94 assertEquals(new BigDecimal("100.00"), c.convert(USD, SKK, BigDecimal.valueOf(5.00)));
96 // convert 200SKK to CZK using c:
97 // assertEquals("Result is 150 CZK");
98 assertEquals(new BigDecimal("150.00"), c.convert(SKK, CZK, BigDecimal.valueOf(200.00)));
100 // convert 200SKK to USK using c:
101 // assertEquals("Result is 10 USD");
102 assertEquals(new BigDecimal("10.00"), c.convert(SKK, USD, BigDecimal.valueOf(200.00)));
105 /** Merge all currency rates of convertor 1 with convertor 2.
106 * Implement this using your API, preferably this method just delegates
107 * into some API method which does the actual work, without requiring
108 * API clients to code anything complex.
110 public static Convertor merge(Convertor one, Convertor two) {
111 return ConvertorFactory.mergeConvertors(one, two);
114 /** Join the convertors from previous task, Task1Test and show that it
115 * can be used to do reasonable conversions.
117 public void testConvertorComposition() throws Exception {
119 Task1Test.createCZKtoUSD(),
120 Task1Test.createSKKtoCZK()
123 // convert $5 to CZK using c:
124 // assertEquals("Result is 85 CZK");
125 assertEquals(new BigDecimal("85.00"), c.convert(USD, CZK, BigDecimal.valueOf(5.00)));
127 // convert $8 to CZK using c:
128 // assertEquals("Result is 136 CZK");
129 assertEquals(new BigDecimal("136.00"), c.convert(USD, CZK, BigDecimal.valueOf(8.00)));
131 // convert 1003CZK to USD using c:
132 // assertEquals("Result is 59 USD");
133 assertEquals(new BigDecimal("59.00"), c.convert(CZK, USD, BigDecimal.valueOf(1003.00)));
135 // convert 16CZK using c:
136 // assertEquals("Result is 20 SKK");
137 assertEquals(new BigDecimal("20.00"), c.convert(CZK, SKK, BigDecimal.valueOf(16.00)));
139 // convert 500SKK to CZK using c:
140 // assertEquals("Result is 400 CZK");
141 assertEquals(new BigDecimal("400.00"), c.convert(SKK, CZK, BigDecimal.valueOf(500.00)));
144 public void testGetCurrencies()
147 Task1Test.createCZKtoUSD(),
148 Task1Test.createSKKtoCZK()
150 Set<Currency> currencies;
152 currencies = c.getCurrencies();
153 assertEquals(3, currencies.size());
154 assertTrue(currencies.contains(Currency.getInstance("SKK")));
155 assertTrue(currencies.contains(Currency.getInstance("CZK")));
156 assertTrue(currencies.contains(Currency.getInstance("USD")));
159 public void testGetConverstionRate()
160 throws InvalidConversionException
163 Task1Test.createCZKtoUSD(),
164 Task1Test.createSKKtoCZK()
167 assertEquals(1.0, c.getConversionRate(USD, USD).doubleValue(), 0.0000000000000001);
168 assertEquals(17.0, c.getConversionRate(USD, CZK).doubleValue(), 0.0000000000000001);
169 assertEquals(21.25, c.getConversionRate(USD, SKK).doubleValue(), 0.0000000000000001);
171 assertEquals(1.0 / 17.0, c.getConversionRate(CZK, USD).doubleValue(), 0.0000000000000001);
172 assertEquals(1.0, c.getConversionRate(CZK, CZK).doubleValue(), 0.0000000000000001);
173 assertEquals(1.25, c.getConversionRate(CZK, SKK).doubleValue(), 0.0000000000000001);
175 assertEquals(0.04705882352941176, c.getConversionRate(SKK, USD).doubleValue(), 0.0000000000000001);
176 assertEquals(0.8, c.getConversionRate(SKK, CZK).doubleValue(), 0.0000000000000001);
177 assertEquals(1.0, c.getConversionRate(SKK, SKK).doubleValue(), 0.0000000000000001);