1 package org.apidesign.apifest08.test;
3 import junit.framework.TestCase;
4 import org.apidesign.apifest08.currency.Convertor;
5 import org.apidesign.apifest08.currency.CurrencyValue;
6 import org.apidesign.apifest08.currency.ExchangeRateDataSource;
7 import org.apidesign.apifest08.currency.ExchangeRateProvider;
8 import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateRequest;
9 import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateResponse;
10 import org.apidesign.apifest08.currency.ExchangeRateValue;
12 /** The exchange rates are not always the same. They are changing. Day by day,
13 * hour by hour, minute by minute. For every bank it is important to always
14 * have the actual exchange rate available in the system. That is why let's
15 * create a pluggable convertor that will always have up to date value of its
18 * The quest for today is to allow 3rd party developer to write a convertor
19 * that adjusts its exchange rate everytime it is queried. This convertor is
20 * written by independent vendor, the vendor knows only your Convertor API,
21 * he does not know how the whole system looks and how the convertor is supposed
24 public class Task3Test extends TestCase {
26 public Task3Test(String testName) {
31 protected void setUp() throws Exception {
35 protected void tearDown() throws Exception {
38 // Backward compatibly enhance your existing API to support following
41 /** Without knowing anything about the surrounding system, write an
42 * implementation of convertor that will return different rates everytime
43 * it is queried. Convert USD to CZK and vice versa. Start with the rate of
44 * 1USD = 16CZK and adjust it in favor of CZK by 0.01 CZK with every query.
45 * As soon as you reach 1USD = 15CZK adjust it by 0.01 CZK in favor of USD
46 * until you reach 1USD = 16CZK
48 * @return new instance of "online" USD and CZK convertor starting with rate 1USD = 16CZK
50 public static Convertor<Double, String> createOnlineCZKUSDConvertor() {
51 // initial rate: 1USD = 16CZK
52 // 2nd query 1USD = 15.99CZK
53 // 3rd query 1USD = 15.98CZK
54 // until 1USD = 15.00CZK
55 // then 1USD = 15.01CZK
56 // then 1USD = 15.02CZK
57 // and so on and on up to 1USD = 16CZK
58 // and then another round to 15, etc.
59 return Convertor.getConvertorDataSourceDoubleString(
60 ExchangeRateDataSource.getExchangeRateDataSource(
61 "USD", "CZK", new ExchangeRateProvider<Double, String>() {
63 double currentRate = 16d;
66 public void getExchangeRate(ExchangeRateRequest<Double, String> request,
67 ExchangeRateResponse<Double, String> response) {
68 if ((request.getCurrencyAIdentifier().equals("CZK") && request.getCurrencyBIdentifier().equals("USD")) ||
69 (request.getCurrencyAIdentifier().equals("USD") && request.getCurrencyBIdentifier().equals("CZK"))) {
70 response.setExchangeRate(ExchangeRateValue.getExchangeRate(
71 CurrencyValue.getCurrencyValue(1d, "USD"),
72 CurrencyValue.getCurrencyValue(currentRate, "CZK")));
74 if (currentRate == 16d) {
77 if (currentRate == 15d) {
82 throw new IllegalArgumentException("No exchange rate for requested currencies!");
88 public void testFewQueriesForOnlineConvertor() {
89 Convertor<Double, String> c = createOnlineCZKUSDConvertor();
90 doFewQueriesForOnlineConvertor(c);
93 static void doFewQueriesForOnlineConvertor(Convertor<Double, String> c) {
94 CurrencyValue<Double, String> result;
95 // convert $5 to CZK using c:
96 //assertEquals("Result is 80 CZK");
97 result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD"));
98 assertEquals(CurrencyValue.getCurrencyValue(80d, "CZK"), result);
100 // convert $8 to CZK using c:
101 //assertEquals("Result is 127.92 CZK");
102 result = c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD"));
103 assertEquals(CurrencyValue.getCurrencyValue(127.92d, "CZK"), result);
105 // convert $1 to CZK using c:
106 //assertEquals("Result is 15.98 CZK");
107 result = c.convert("CZK", CurrencyValue.getCurrencyValue(1d, "USD"));
108 assertEquals(CurrencyValue.getCurrencyValue(15.98d, "CZK"), result);
110 // convert 15.97CZK to USD using c:
111 //assertEquals("Result is 1$");
112 result = c.convert("USD", CurrencyValue.getCurrencyValue(15.97d, "CZK"));
113 assertEquals(CurrencyValue.getCurrencyValue(1d, "USD"), result);
116 /** Join the convertors and show they behave sane.
118 public void testOnlineConvertorComposition() throws Exception {
119 Convertor<Double, String> c = Task2Test.merge(
120 createOnlineCZKUSDConvertor(),
121 Task1Test.createSKKtoCZK());
123 CurrencyValue<Double, String> result;
124 // convert 16CZK to SKK using c:
125 // assertEquals("Result is 20 SKK");
126 result = c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK"));
127 assertEquals(CurrencyValue.getCurrencyValue(20d, "SKK"), result);
129 // convert 500SKK to CZK using c:
130 // assertEquals("Result is 400 CZK");
131 result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"));
132 assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result);
134 doFewQueriesForOnlineConvertor(c);