1 package org.apidesign.apifest08.test;
3 import java.math.BigDecimal;
4 import java.util.Calendar;
6 import java.util.TimeZone;
7 import junit.framework.TestCase;
8 import org.apidesign.apifest08.currency.Convertor;
9 import org.apidesign.apifest08.currency.ConvertorFactory;
10 import org.apidesign.apifest08.currency.ExchangeRate;
11 import org.apidesign.apifest08.currency.InvalidConversionException;
12 import org.apidesign.apifest08.currency.TimedConvertor;
14 /** The exchange rates are not always the same. They are changing. However
15 * as in order to predict the future, one needs to understand own past. That is
16 * why it is important to know the exchange rate as it was at any time during
19 * Today's quest is to enhance the convertor API to deal with dates.
20 * One shall be able to convert a currency at any date. Each currencies rate shall
21 * be associated with a range between two Date objects. In order
22 * to keep compatibility with old API that knew nothing about dates, the
23 * rates associated then are applicable "for eternity". Any use of existing
24 * convert methods that do not accept a Date argument, uses the current
25 * System.currentTimeMillis() as default date.
27 public class Task4Test extends TestCase {
28 public Task4Test(String testName) {
32 private Calendar gmtCalendar;
35 protected void setUp() throws Exception {
36 gmtCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
40 protected void tearDown() throws Exception {
43 // Backward compatibly enhance your existing API to support following
47 /** Takes a convertor with any rates associated and creates new convertor
48 * that returns the same values as the old one for time between from to till.
49 * Otherwise it returns no results. This is just a helper method that
50 * shall call some real one in the API.
52 * @param old existing convertor
53 * @param from initial date (inclusive)
54 * @param till final date (exclusive)
55 * @return new convertor
57 public static Convertor limitTo(Convertor old, Date from, Date till) {
58 final Convertor convertor;
60 convertor = ConvertorFactory.getConvertor(from, till, old);
66 public void testCompositionOfLimitedConvertors() throws Exception {
68 gmtCalendar.set(2008, Calendar.OCTOBER, 1, 0, 0, 0);
69 Date d1 = gmtCalendar.getTime(); // 2008-10-01 0:00 GMT
70 gmtCalendar.set(2008, Calendar.OCTOBER, 2, 0, 0, 0);
71 Date d2 = gmtCalendar.getTime(); // 2008-10-02 0:00 GMT
72 gmtCalendar.set(2008, Calendar.OCTOBER, 3, 0, 0, 0);
73 Date d3 = gmtCalendar.getTime(); // 2008-10-03 0:00 GMT
75 Convertor c = Task2Test.merge(
76 limitTo(Task1Test.createCZKtoUSD(), d1, d2),
77 limitTo(Task1Test.createSKKtoCZK(), d2, d3)
83 // convert $5 to CZK using c:
84 // cannot convert as no rate is applicable to current date
87 c.convert(Task1Test.USD, Task1Test.CZK, new BigDecimal("5.00"));
90 catch(final InvalidConversionException ex)
94 // convert $8 to CZK using c:
95 // cannot convert as no rate is applicable to current date
98 c.convert(Task1Test.USD, Task1Test.CZK, new BigDecimal("8.00"));
101 catch(final InvalidConversionException ex)
105 // convert 1003CZK to USD using c:
106 // cannot convert as no rate is applicable to current date
109 c.convert(Task1Test.CZK, Task1Test.USD, new BigDecimal("1003.00"));
112 catch(final InvalidConversionException ex)
116 // convert 16CZK using c:
117 // cannot convert as no rate is applicable to current date
120 c.convert(Task1Test.CZK, Task1Test.USD, new BigDecimal("16.00"));
123 catch(final InvalidConversionException ex)
127 // convert 500SKK to CZK using c:
128 // cannot convert as no rate is applicable to current date
131 c.convert(Task1Test.SKK, Task1Test.CZK, new BigDecimal("500.00"));
134 catch(final InvalidConversionException ex)
138 // convert $5 to CZK using c at 2008-10-01 6:00 GMT:
139 // assertEquals("Result is 85 CZK");
140 gmtCalendar.set(2008, Calendar.OCTOBER, 1, 6, 0, 0);
141 date = gmtCalendar.getTime();
142 amount = ((TimedConvertor)c).convert(Task1Test.USD, Task1Test.CZK, new BigDecimal("5.00"), date);
143 assertEquals(new BigDecimal("85.00"), amount);
145 // convert $8 to CZK using c at 2008-10-01 6:00 GMT:
146 // assertEquals("Result is 136 CZK");
147 gmtCalendar.set(2008, Calendar.OCTOBER, 1, 6, 0, 0);
148 date = gmtCalendar.getTime();
149 amount = ((TimedConvertor)c).convert(Task1Test.USD, Task1Test.CZK, new BigDecimal("8.00"), date);
150 assertEquals(new BigDecimal("136.00"), amount);
152 // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT:
153 // assertEquals("Result is 59 USD");
154 gmtCalendar.set(2008, Calendar.OCTOBER, 1, 6, 0, 0);
155 date = gmtCalendar.getTime();
156 amount = ((TimedConvertor)c).convert(Task1Test.CZK, Task1Test.USD, new BigDecimal("1003.00"), date);
157 assertEquals(new BigDecimal("59.00"), amount);
159 // convert 16CZK using c at 2008-10-02 9:00 GMT:
160 // assertEquals("Result is 20 SKK");
161 gmtCalendar.set(2008, Calendar.OCTOBER, 2, 9, 0, 0);
162 date = gmtCalendar.getTime();
163 amount = ((TimedConvertor)c).convert(Task1Test.CZK, Task1Test.SKK, new BigDecimal("16.00"), date);
164 assertEquals(new BigDecimal("20.00"), amount);
166 // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
167 // assertEquals("Result is 400 CZK");
168 gmtCalendar.set(2008, Calendar.OCTOBER, 2, 9, 0, 0);
169 date = gmtCalendar.getTime();
170 amount = ((TimedConvertor)c).convert(Task1Test.SKK, Task1Test.CZK, new BigDecimal("500.00"), date);
171 assertEquals(new BigDecimal("400.00"), amount);
173 // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
174 // cannot convert as no rate is applicable to current date
177 gmtCalendar.set(2008, Calendar.OCTOBER, 1, 6, 0, 0);
178 date = gmtCalendar.getTime();
179 ((TimedConvertor)c).convert(Task1Test.SKK, Task1Test.CZK, new BigDecimal("500.00"), date);
182 catch(final InvalidConversionException ex)
187 /** Create convertor that understands two currencies, CZK and
188 * SKK. Make 100 SKK == 90 CZK.
190 * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
192 public static Convertor createSKKtoCZK2()
194 final ExchangeRate rate;
195 final Convertor convertor;
197 rate = ExchangeRate.getExchangeRate(Task1Test.SKK,
199 new BigDecimal("100.00"),
200 new BigDecimal("90.00"));
201 convertor = ConvertorFactory.getConvertor(rate);
206 public void testDateConvetorWithTwoDifferentRates() throws Exception {
207 gmtCalendar.set(2008, Calendar.OCTOBER, 1, 0, 0, 0);
208 Date d1 = gmtCalendar.getTime(); // 2008-10-01 0:00 GMT
209 gmtCalendar.set(2008, Calendar.OCTOBER, 2, 0, 0, 0);
210 Date d2 = gmtCalendar.getTime(); // 2008-10-02 0:00 GMT
211 gmtCalendar.set(2008, Calendar.OCTOBER, 3, 0, 0, 0);
212 Date d3 = gmtCalendar.getTime(); // 2008-10-03 0:00 GMT
214 Convertor c = Task2Test.merge(
215 limitTo(createSKKtoCZK2(), d1, d2),
216 limitTo(Task1Test.createSKKtoCZK(), d2, d3)
222 // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
223 // assertEquals("Result is 400 CZK");
224 gmtCalendar.set(2008, Calendar.OCTOBER, 2, 6, 0, 0);
225 date = gmtCalendar.getTime();
226 amount = ((TimedConvertor)c).convert(Task1Test.SKK, Task1Test.CZK, new BigDecimal("500.00"), date);
227 assertEquals(new BigDecimal("400.00"), amount);
229 // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
230 // assertEquals("Result is 450 CZK");
231 gmtCalendar.set(2008, Calendar.OCTOBER, 1, 6, 0, 0);
232 date = gmtCalendar.getTime();
233 amount = ((TimedConvertor)c).convert(Task1Test.SKK, Task1Test.CZK, new BigDecimal("500.00"), date);
234 assertEquals(new BigDecimal("450.00"), amount);