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 // if (Boolean.getBoolean("ignore.failing")) {
71 // // implement me! then delete this if statement
76 Date d1 = df.parse("2008-10-01 0:00 GMT");
77 Date d2 = df.parse("2008-10-02 0:00 GMT");
78 Date d3 = df.parse("2008-10-03 0:00 GMT");
80 Convertor c = Task2Test.merge(
81 limitTo(Task1Test.createCZKtoUSD(), d1, d2),
82 limitTo(Task1Test.createSKKtoCZK(), d2, d3)
85 // convert $5 to CZK using c:
86 // cannot convert as no rate is applicable to current date
88 c.convert(USD, CZK, new BigDecimal(5));
90 } catch (ConversionNotSupportedException e) {
94 // convert $8 to CZK using c:
95 // cannot convert as no rate is applicable to current date
97 c.convert(USD, CZK, new BigDecimal(8));
99 } catch (ConversionNotSupportedException e) {
104 // convert 1003CZK to USD using c:
105 // cannot convert as no rate is applicable to current date
107 c.convert(CZK, USD, new BigDecimal(1003));
109 } catch (ConversionNotSupportedException e) {
113 // convert 16CZK using c:
114 // cannot convert as no rate is applicable to current date
117 c.convert(CZK, USD, new BigDecimal(16));
119 } catch (ConversionNotSupportedException e) {
123 // convert 500SKK to CZK using c:
124 // cannot convert as no rate is applicable to current date
126 c.convert(SKK, CZK, new BigDecimal(500));
128 } catch (ConversionNotSupportedException e) {
133 // convert $5 to CZK using c at 2008-10-01 6:00 GMT:
134 // assertEquals("Result is 85 CZK");
135 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());
137 // convert $8 to CZK using c at 2008-10-01 6:00 GMT:
138 // assertEquals("Result is 136 CZK");
139 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());
141 // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT:
142 // assertEquals("Result is 59 USD");
143 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());
145 // convert 16CZK using c at 2008-10-02 9:00 GMT:
146 // assertEquals("Result is 20 SKK");
147 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());
149 // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
150 // assertEquals("Result is 400 CZK");
151 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());
153 // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
154 // cannot convert as no rate is applicable to current date
156 c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-01 6:00 GMT")).getConverted();
158 } catch (ConversionNotSupportedException e) {
164 /** Create convertor that understands two currencies, CZK and
165 * SKK. Make 100 SKK == 90 CZK.
167 * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
169 public static Convertor createSKKtoCZK2() {
170 ExchangeRateProvider exchangeRateProvider = ExchangeRateProvider.createExchangeRateProvider();
171 exchangeRateProvider.addFixedCurencyRate(SKK, new BigDecimal("100.00"), CZK, new BigDecimal("90.00"));
172 Convertor c = Convertor.createConvertor(exchangeRateProvider);
176 public void testDateConvetorWithTwoDifferentRates() throws Exception {
178 Date d1 = df.parse("2008-10-01 0:00 GMT");
179 Date d2 = df.parse("2008-10-02 0:00 GMT");
180 Date d3 = df.parse("2008-10-03 0:00 GMT");
182 Convertor c = Task2Test.merge(
183 limitTo(createSKKtoCZK2(), d1, d2),
184 limitTo(Task1Test.createSKKtoCZK(), d2, d3)
187 // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
188 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());
190 // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
191 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());