1 package org.apidesign.apifest08.test;
3 import java.math.BigDecimal;
4 import java.text.SimpleDateFormat;
6 import junit.framework.TestCase;
7 import org.apidesign.apifest08.currency.ConversionNotSupportedException;
8 import org.apidesign.apifest08.currency.Convertor;
9 import org.apidesign.apifest08.currency.ConvertorCurrency;
10 import org.apidesign.apifest08.currency.ExchangeRateProvider;
12 /** The exchange rates are not always the same. They are changing. However
13 * as in order to predict the future, one needs to understand own past. That is
14 * why it is important to know the exchange rate as it was at any time during
17 * Today's quest is to enhance the convertor API to deal with dates.
18 * One shall be able to convert a currency at any date. Each currencies rate shall
19 * be associated with a range between two Date objects. In order
20 * to keep compatibility with old API that knew nothing about dates, the
21 * rates associated then are applicable "for eternity". Any use of existing
22 * convert methods that do not accept a Date argument, uses the current
23 * System.currentTimeMillis() as default date.
25 public class Task4Test extends TestCase {
26 private static ConvertorCurrency CZK = ConvertorCurrency.getInstance("CZK");
27 private static ConvertorCurrency SKK = ConvertorCurrency.getInstance("SKK");
28 private static ConvertorCurrency USD = ConvertorCurrency.getInstance("USD");
29 private SimpleDateFormat df;
32 public Task4Test(String testName) {
37 protected void setUp() throws Exception {
39 df = new SimpleDateFormat("yyyy-MM-dd HH:mm zzzz");
43 protected void tearDown() throws Exception {
48 // Backward compatibly enhance your existing API to support following
52 /** Takes a convertor with any rates associated and creates new convertor
53 * that returns the same values as the old one for time between from to till.
54 * Otherwise it returns no results. This is just a helper method that
55 * shall call some real one in the API.
57 * @param old existing convertor
58 * @param from initial date (inclusive)
59 * @param till final date (exclusive)
60 * @return new convertor
62 public static Convertor limitTo(Convertor old, Date from, Date till) {
63 Convertor c = Convertor.createConvertorAsMerge(new Convertor[]{old});
64 c.limitAllowedDates(from, till);
69 public void testCompositionOfLimitedConvertors() throws Exception {
70 Date d1 = df.parse("2008-10-01 0:00 GMT");
71 Date d2 = df.parse("2008-10-02 0:00 GMT");
72 Date d3 = df.parse("2008-10-03 0:00 GMT");
74 Convertor c = Task2Test.merge(
75 limitTo(Task1Test.createCZKtoUSD(), d1, d2),
76 limitTo(Task1Test.createSKKtoCZK(), d2, d3)
79 // convert $5 to CZK using c:
80 // cannot convert as no rate is applicable to current date
82 c.convert(USD, CZK, new BigDecimal(5));
84 } catch (ConversionNotSupportedException e) {
88 // convert $8 to CZK using c:
89 // cannot convert as no rate is applicable to current date
91 c.convert(USD, CZK, new BigDecimal(8));
93 } catch (ConversionNotSupportedException e) {
98 // convert 1003CZK to USD using c:
99 // cannot convert as no rate is applicable to current date
101 c.convert(CZK, USD, new BigDecimal(1003));
103 } catch (ConversionNotSupportedException e) {
107 // convert 16CZK using c:
108 // cannot convert as no rate is applicable to current date
111 c.convert(CZK, USD, new BigDecimal(16));
113 } catch (ConversionNotSupportedException e) {
117 // convert 500SKK to CZK using c:
118 // cannot convert as no rate is applicable to current date
120 c.convert(SKK, CZK, new BigDecimal(500));
122 } catch (ConversionNotSupportedException e) {
127 // convert $5 to CZK using c at 2008-10-01 6:00 GMT:
128 // assertEquals("Result is 85 CZK");
129 assertEquals("Result is 85 CZK", new BigDecimal("85.00"), c.convertWithReversibleRates(USD, CZK , new BigDecimal("5"),df.parse("2008-10-01 6:00 GMT")).getConverted());
131 // convert $8 to CZK using c at 2008-10-01 6:00 GMT:
132 // assertEquals("Result is 136 CZK");
133 assertEquals("Result is 136 CZK", new BigDecimal("136.00"), c.convertWithReversibleRates(USD, CZK , new BigDecimal("8"),df.parse("2008-10-01 6:00 GMT")).getConverted());
135 // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT:
136 // assertEquals("Result is 59 USD");
137 assertEquals("Result is 59 USD", new BigDecimal("59.00"), c.convertWithReversibleRates(CZK, USD , new BigDecimal("1003"),df.parse("2008-10-01 6:00 GMT")).getConverted());
139 // convert 16CZK using c at 2008-10-02 9:00 GMT:
140 // assertEquals("Result is 20 SKK");
141 assertEquals("Result is 20 SKK", new BigDecimal("20.00"), c.convertWithReversibleRates(CZK, SKK , new BigDecimal("16"),df.parse("2008-10-02 9:00 GMT")).getConverted());
143 // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
144 // assertEquals("Result is 400 CZK");
145 assertEquals("Result is 400 SKK", new BigDecimal("400.00"), c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-02 9:00 GMT")).getConverted());
147 // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
148 // cannot convert as no rate is applicable to current date
150 c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-01 6:00 GMT")).getConverted();
152 } catch (ConversionNotSupportedException e) {
158 /** Create convertor that understands two currencies, CZK and
159 * SKK. Make 100 SKK == 90 CZK.
161 * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
163 public static Convertor createSKKtoCZK2() {
164 ExchangeRateProvider exchangeRateProvider = ExchangeRateProvider.createExchangeRateProvider();
165 exchangeRateProvider.addFixedCurencyRate(SKK, new BigDecimal("100.00"), CZK, new BigDecimal("90.00"));
166 Convertor c = Convertor.createConvertor(exchangeRateProvider);
170 public void testDateConvetorWithTwoDifferentRates() throws Exception {
172 Date d1 = df.parse("2008-10-01 0:00 GMT");
173 Date d2 = df.parse("2008-10-02 0:00 GMT");
174 Date d3 = df.parse("2008-10-03 0:00 GMT");
176 Convertor c = Task2Test.merge(
177 limitTo(createSKKtoCZK2(), d1, d2),
178 limitTo(Task1Test.createSKKtoCZK(), d2, d3)
181 // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
182 assertEquals("Result is 400 CZK", new BigDecimal("400.00"), c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-02 9:00 GMT")).getConverted());
184 // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
185 assertEquals("Result is 450 CZK", new BigDecimal("450.00"), c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-01 9:00 GMT")).getConverted());