1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/task4/solution11/test/org/apidesign/apifest08/test/Task3Test.java Sat Oct 11 23:38:46 2008 +0200
1.3 @@ -0,0 +1,136 @@
1.4 +package org.apidesign.apifest08.test;
1.5 +
1.6 +import junit.framework.TestCase;
1.7 +import org.apidesign.apifest08.currency.Convertor;
1.8 +import org.apidesign.apifest08.currency.CurrencyValue;
1.9 +import org.apidesign.apifest08.currency.ExchangeRateDataSource;
1.10 +import org.apidesign.apifest08.currency.ExchangeRateProvider;
1.11 +import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateRequest;
1.12 +import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateResponse;
1.13 +import org.apidesign.apifest08.currency.ExchangeRateValue;
1.14 +
1.15 +/** The exchange rates are not always the same. They are changing. Day by day,
1.16 + * hour by hour, minute by minute. For every bank it is important to always
1.17 + * have the actual exchange rate available in the system. That is why let's
1.18 + * create a pluggable convertor that will always have up to date value of its
1.19 + * exchange rate.
1.20 + * <p>
1.21 + * The quest for today is to allow 3rd party developer to write a convertor
1.22 + * that adjusts its exchange rate everytime it is queried. This convertor is
1.23 + * written by independent vendor, the vendor knows only your Convertor API,
1.24 + * he does not know how the whole system looks and how the convertor is supposed
1.25 + * to be used.
1.26 + */
1.27 +public class Task3Test extends TestCase {
1.28 +
1.29 + public Task3Test(String testName) {
1.30 + super(testName);
1.31 + }
1.32 +
1.33 + @Override
1.34 + protected void setUp() throws Exception {
1.35 + }
1.36 +
1.37 + @Override
1.38 + protected void tearDown() throws Exception {
1.39 + }
1.40 +
1.41 + // Backward compatibly enhance your existing API to support following
1.42 + // usecases:
1.43 + //
1.44 + /** Without knowing anything about the surrounding system, write an
1.45 + * implementation of convertor that will return different rates everytime
1.46 + * it is queried. Convert USD to CZK and vice versa. Start with the rate of
1.47 + * 1USD = 16CZK and adjust it in favor of CZK by 0.01 CZK with every query.
1.48 + * As soon as you reach 1USD = 15CZK adjust it by 0.01 CZK in favor of USD
1.49 + * until you reach 1USD = 16CZK
1.50 + *
1.51 + * @return new instance of "online" USD and CZK convertor starting with rate 1USD = 16CZK
1.52 + */
1.53 + public static Convertor<Double, String> createOnlineCZKUSDConvertor() {
1.54 + // initial rate: 1USD = 16CZK
1.55 + // 2nd query 1USD = 15.99CZK
1.56 + // 3rd query 1USD = 15.98CZK
1.57 + // until 1USD = 15.00CZK
1.58 + // then 1USD = 15.01CZK
1.59 + // then 1USD = 15.02CZK
1.60 + // and so on and on up to 1USD = 16CZK
1.61 + // and then another round to 15, etc.
1.62 + return Convertor.getConvertorDataSourceDoubleString(
1.63 + ExchangeRateDataSource.getExchangeRateDataSource(
1.64 + "USD", "CZK", new ExchangeRateProvider<Double, String>() {
1.65 +
1.66 + double currentRate = 16d;
1.67 + double step;
1.68 +
1.69 + public void getExchangeRate(ExchangeRateRequest<Double, String> request,
1.70 + ExchangeRateResponse<Double, String> response) {
1.71 + if ((request.getCurrencyAIdentifier().equals("CZK") && request.getCurrencyBIdentifier().equals("USD")) ||
1.72 + (request.getCurrencyAIdentifier().equals("USD") && request.getCurrencyBIdentifier().equals("CZK"))) {
1.73 + response.setExchangeRate(ExchangeRateValue.getExchangeRate(
1.74 + CurrencyValue.getCurrencyValue(1d, "USD"),
1.75 + CurrencyValue.getCurrencyValue(currentRate, "CZK")));
1.76 +
1.77 + if (currentRate == 16d) {
1.78 + step = -0.01;
1.79 + }
1.80 + if (currentRate == 15d) {
1.81 + step = 0.01;
1.82 + }
1.83 + currentRate += step;
1.84 + } else {
1.85 + throw new IllegalArgumentException("No exchange rate for requested currencies!");
1.86 + }
1.87 + }
1.88 + }));
1.89 + }
1.90 +
1.91 + public void testFewQueriesForOnlineConvertor() {
1.92 + Convertor<Double, String> c = createOnlineCZKUSDConvertor();
1.93 + doFewQueriesForOnlineConvertor(c);
1.94 + }
1.95 +
1.96 + static void doFewQueriesForOnlineConvertor(Convertor<Double, String> c) {
1.97 + CurrencyValue<Double, String> result;
1.98 + // convert $5 to CZK using c:
1.99 + //assertEquals("Result is 80 CZK");
1.100 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD"));
1.101 + assertEquals(CurrencyValue.getCurrencyValue(80d, "CZK"), result);
1.102 +
1.103 + // convert $8 to CZK using c:
1.104 + //assertEquals("Result is 127.92 CZK");
1.105 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD"));
1.106 + assertEquals(CurrencyValue.getCurrencyValue(127.92d, "CZK"), result);
1.107 +
1.108 + // convert $1 to CZK using c:
1.109 + //assertEquals("Result is 15.98 CZK");
1.110 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(1d, "USD"));
1.111 + assertEquals(CurrencyValue.getCurrencyValue(15.98d, "CZK"), result);
1.112 +
1.113 + // convert 15.97CZK to USD using c:
1.114 + //assertEquals("Result is 1$");
1.115 + result = c.convert("USD", CurrencyValue.getCurrencyValue(15.97d, "CZK"));
1.116 + assertEquals(CurrencyValue.getCurrencyValue(1d, "USD"), result);
1.117 + }
1.118 +
1.119 + /** Join the convertors and show they behave sane.
1.120 + */
1.121 + public void testOnlineConvertorComposition() throws Exception {
1.122 + Convertor<Double, String> c = Task2Test.merge(
1.123 + createOnlineCZKUSDConvertor(),
1.124 + Task1Test.createSKKtoCZK());
1.125 +
1.126 + CurrencyValue<Double, String> result;
1.127 + // convert 16CZK to SKK using c:
1.128 + // assertEquals("Result is 20 SKK");
1.129 + result = c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK"));
1.130 + assertEquals(CurrencyValue.getCurrencyValue(20d, "SKK"), result);
1.131 +
1.132 + // convert 500SKK to CZK using c:
1.133 + // assertEquals("Result is 400 CZK");
1.134 + result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"));
1.135 + assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result);
1.136 +
1.137 + doFewQueriesForOnlineConvertor(c);
1.138 + }
1.139 +}