1 package org.apidesign.apifest08.test;
3 import java.math.BigDecimal;
4 import junit.framework.TestCase;
5 import org.apidesign.apifest08.currency.Convertor;
6 import org.apidesign.apifest08.currency.ConvertorCurrency;
7 import org.apidesign.apifest08.currency.ExchangeRateProvider;
9 /** There are many currencies around the world and many banks manipulate
10 * with more than one or two at the same time. As banks are usually the
11 * best paying clients, which is true even in case of your Convertor API,
12 * it is reasonable to listen to their requests.
14 * The quest for today is to enhance your existing convertor API to hold
15 * information about many currencies and allow conversions between any of them.
16 * Also, as conversion rates for diferent currencies usually arise from various
17 * bank departments, there is another important need. There is a need to
18 * compose two convertors into one by merging all the information about
19 * currencies they know about.
21 public class Task2Test extends TestCase {
22 private static ConvertorCurrency currencyCZK = ConvertorCurrency.getInstance("CZK");
23 private static ConvertorCurrency currencySKK = ConvertorCurrency.getInstance("SKK");
24 private static ConvertorCurrency currencyUSD = ConvertorCurrency.getInstance("USD");
26 public Task2Test(String testName) {
31 protected void setUp() throws Exception {
36 protected void tearDown() throws Exception {
39 public static Convertor createUsdToSkkConvertor() {
40 ConvertorCurrency fromCurrency = currencyUSD;
41 ConvertorCurrency toCurrency = currencySKK;
42 ExchangeRateProvider exchangeRateProvider = new ExchangeRateProvider(new BigDecimal(1), fromCurrency, new BigDecimal(20), toCurrency);
44 return Convertor.createConvertor(exchangeRateProvider);
48 // As in Task1Test, keep in mind, that there are three parts
49 // of the whole system:
50 // 1. there is someone who knows the current exchange rate
51 // 2. there is someone who wants to do the conversion
52 // 3. there is the API between 1. and 2. which allows them to communicate
54 // Please backward compatibly enhance your existing API to support following
58 /** Create convertor that understands two currencies, CZK and
59 * SKK. Make 100 SKK == 75 CZK. This is method for the group of users that
60 * knows the exchange rate, and needs to use the API to create objects
61 * with the exchange rate. Anyone shall be ready to call this method without
62 * any other method being called previously. The API itself shall know
63 * nothing about any rates, before this method is called.
65 public static Convertor createTripleConvertor() {
66 ExchangeRateProvider exRateProvider = ExchangeRateProvider.createExchangeRateProvider();
68 // Rates: 1USD = 15CZK
69 exRateProvider.addFixedCurencyRate(currencyUSD, new BigDecimal(1),currencyCZK, new BigDecimal(15));
71 // Rates: 1USD = 20SKK
72 exRateProvider.addFixedCurencyRate(currencyUSD, new BigDecimal(1), currencySKK, new BigDecimal(20));
74 // Rates: 75CZK = 100SKK
75 exRateProvider.addFixedCurencyRate(currencyCZK, new BigDecimal(75), currencySKK, new BigDecimal(100));
77 Convertor c = Convertor.createConvertor(exRateProvider);
82 /** Define convertor that understands three currencies. Use it.
84 public void testConvertorForUSDandCZKandSKK() throws Exception {
85 Convertor c = createTripleConvertor();
87 // convert $5 to CZK using c:
88 assertEquals("Result is 75 CZK",new BigDecimal("75.00"),c.convertWithReversibleRates(currencyUSD, currencyCZK, new BigDecimal(5)).getConverted());
91 // convert $5 to SKK using c:
92 assertEquals("Result is 100 SKK",new BigDecimal("100.00"),c.convertWithReversibleRates(currencyUSD, currencySKK, new BigDecimal(5)).getConverted());
94 // convert 200SKK to CZK using c:
95 assertEquals("Result is 150 CZK",new BigDecimal("150.00"),c.convertWithReversibleRates(currencySKK, currencyCZK, new BigDecimal(200)).getConverted());
97 // convert 200SKK to USK using c:
98 // assertEquals("Result is 10 USD");
101 /** Merge all currency rates of convertor 1 with convertor 2.
102 * Implement this using your API, preferably this method just delegates
103 * into some API method which does the actual work, without requiring
104 * API clients to code anything complex.
106 public static Convertor merge(Convertor one, Convertor two) {
107 return Convertor.createConvertorAsMerge(new Convertor[]{one, two});
110 /** Join the convertors from previous task, Task1Test and show that it
111 * can be used to do reasonable conversions.
113 public void testConvertorComposition() throws Exception {
115 Task1Test.createCZKtoUSD(),
116 Task1Test.createSKKtoCZK()
119 // convert $5 to CZK using c:
120 assertEquals("Result is 85 CZK",new BigDecimal("85.00"),c.convertWithReversibleRates(currencyUSD, currencyCZK, new BigDecimal(5)).getConverted());
122 // convert $8 to CZK using c:
123 // assertEquals("Result is 136 CZK");
124 assertEquals("Result is 136 CZK",new BigDecimal("136.00"),c.convertWithReversibleRates(currencyUSD, currencyCZK, new BigDecimal(8)).getConverted());
126 // convert 1003CZK to USD using c:
127 assertEquals("Result is 59 USD",new BigDecimal("59.00"),c.convertWithReversibleRates(currencyCZK, currencyUSD, new BigDecimal(1003)).getConverted());
129 // convert 16CZK using c:
130 assertEquals("Result is 20 SKK",new BigDecimal("20.00"),c.convertWithReversibleRates(currencyCZK, currencySKK, new BigDecimal(16)).getConverted());
132 // convert 500SKK to CZK using c:
133 assertEquals("Result is 400 CZK",new BigDecimal("400.00"),c.convertWithReversibleRates(currencySKK, currencyCZK, new BigDecimal(500)).getConverted());