task4/solution11/test/org/apidesign/apifest08/test/Task3Test.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 11 Oct 2008 23:38:46 +0200
changeset 61 58ec6da75f6f
parent 53 task3/solution11/test/org/apidesign/apifest08/test/Task3Test.java@09d690bb97f6
permissions -rw-r--r--
Copying structure for task4
jaroslav@43
     1
package org.apidesign.apifest08.test;
jaroslav@43
     2
jaroslav@43
     3
import junit.framework.TestCase;
jaroslav@43
     4
import org.apidesign.apifest08.currency.Convertor;
japod@53
     5
import org.apidesign.apifest08.currency.CurrencyValue;
japod@53
     6
import org.apidesign.apifest08.currency.ExchangeRateDataSource;
japod@53
     7
import org.apidesign.apifest08.currency.ExchangeRateProvider;
japod@53
     8
import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateRequest;
japod@53
     9
import org.apidesign.apifest08.currency.ExchangeRateProvider.ExchangeRateResponse;
japod@53
    10
import org.apidesign.apifest08.currency.ExchangeRateValue;
jaroslav@43
    11
jaroslav@43
    12
/** The exchange rates are not always the same. They are changing. Day by day,
jaroslav@43
    13
 * hour by hour, minute by minute. For every bank it is important to always
jaroslav@43
    14
 * have the actual exchange rate available in the system. That is why let's
jaroslav@43
    15
 * create a pluggable convertor that will always have up to date value of its
jaroslav@43
    16
 * exchange rate.
jaroslav@43
    17
 * <p>
jaroslav@43
    18
 * The quest for today is to allow 3rd party developer to write a convertor
jaroslav@43
    19
 * that adjusts its exchange rate everytime it is queried. This convertor is
jaroslav@43
    20
 * written by independent vendor, the vendor knows only your Convertor API,
jaroslav@43
    21
 * he does not know how the whole system looks and how the convertor is supposed
jaroslav@43
    22
 * to be used.
jaroslav@43
    23
 */
jaroslav@43
    24
public class Task3Test extends TestCase {
japod@53
    25
jaroslav@43
    26
    public Task3Test(String testName) {
jaroslav@43
    27
        super(testName);
jaroslav@43
    28
    }
jaroslav@43
    29
jaroslav@43
    30
    @Override
jaroslav@43
    31
    protected void setUp() throws Exception {
jaroslav@43
    32
    }
jaroslav@43
    33
jaroslav@43
    34
    @Override
jaroslav@43
    35
    protected void tearDown() throws Exception {
jaroslav@43
    36
    }
jaroslav@43
    37
jaroslav@43
    38
    // Backward compatibly enhance your existing API to support following
jaroslav@43
    39
    // usecases:
jaroslav@43
    40
    //
jaroslav@43
    41
    /** Without knowing anything about the surrounding system, write an
jaroslav@43
    42
     * implementation of convertor that will return different rates everytime
jaroslav@43
    43
     * it is queried. Convert USD to CZK and vice versa. Start with the rate of
jaroslav@43
    44
     * 1USD = 16CZK and adjust it in favor of CZK by 0.01 CZK with every query.
jaroslav@43
    45
     * As soon as you reach 1USD = 15CZK adjust it by 0.01 CZK in favor of USD
jaroslav@43
    46
     * until you reach 1USD = 16CZK
jaroslav@43
    47
     *
jaroslav@43
    48
     * @return new instance of "online" USD and CZK convertor starting with rate 1USD = 16CZK
jaroslav@43
    49
     */
japod@53
    50
    public static Convertor<Double, String> createOnlineCZKUSDConvertor() {
jaroslav@43
    51
        // initial rate: 1USD = 16CZK
jaroslav@43
    52
        // 2nd query 1USD = 15.99CZK
jaroslav@43
    53
        // 3rd query 1USD = 15.98CZK
jaroslav@43
    54
        // until 1USD = 15.00CZK
jaroslav@43
    55
        // then 1USD = 15.01CZK
jaroslav@43
    56
        // then 1USD = 15.02CZK
jaroslav@43
    57
        // and so on and on up to 1USD = 16CZK
jaroslav@43
    58
        // and then another round to 15, etc.
japod@53
    59
        return Convertor.getConvertorDataSourceDoubleString(
japod@53
    60
                ExchangeRateDataSource.getExchangeRateDataSource(
japod@53
    61
                "USD", "CZK", new ExchangeRateProvider<Double, String>() {
japod@53
    62
japod@53
    63
            double currentRate = 16d;
japod@53
    64
            double step;
japod@53
    65
japod@53
    66
            public void getExchangeRate(ExchangeRateRequest<Double, String> request,
japod@53
    67
                    ExchangeRateResponse<Double, String> response) {
japod@53
    68
                if ((request.getCurrencyAIdentifier().equals("CZK") && request.getCurrencyBIdentifier().equals("USD")) ||
japod@53
    69
                        (request.getCurrencyAIdentifier().equals("USD") && request.getCurrencyBIdentifier().equals("CZK"))) {
japod@53
    70
                    response.setExchangeRate(ExchangeRateValue.getExchangeRate(
japod@53
    71
                            CurrencyValue.getCurrencyValue(1d, "USD"),
japod@53
    72
                            CurrencyValue.getCurrencyValue(currentRate, "CZK")));
japod@53
    73
japod@53
    74
                    if (currentRate == 16d) {
japod@53
    75
                        step = -0.01;
japod@53
    76
                    }
japod@53
    77
                    if (currentRate == 15d) {
japod@53
    78
                        step = 0.01;
japod@53
    79
                    }
japod@53
    80
                    currentRate += step;
japod@53
    81
                } else {
japod@53
    82
                    throw new IllegalArgumentException("No exchange rate for requested currencies!");
japod@53
    83
                }
japod@53
    84
            }
japod@53
    85
        }));
jaroslav@43
    86
    }
jaroslav@43
    87
jaroslav@43
    88
    public void testFewQueriesForOnlineConvertor() {
japod@53
    89
        Convertor<Double, String> c = createOnlineCZKUSDConvertor();
jaroslav@43
    90
        doFewQueriesForOnlineConvertor(c);
jaroslav@43
    91
    }
jaroslav@43
    92
japod@53
    93
    static void doFewQueriesForOnlineConvertor(Convertor<Double, String> c) {
japod@53
    94
        CurrencyValue<Double, String> result;
jaroslav@43
    95
        // convert $5 to CZK using c:
jaroslav@43
    96
        //assertEquals("Result is 80 CZK");
japod@53
    97
        result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD"));
japod@53
    98
        assertEquals(CurrencyValue.getCurrencyValue(80d, "CZK"), result);
jaroslav@43
    99
jaroslav@43
   100
        // convert $8 to CZK using c:
jaroslav@43
   101
        //assertEquals("Result is 127.92 CZK");
japod@53
   102
        result = c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD"));
japod@53
   103
        assertEquals(CurrencyValue.getCurrencyValue(127.92d, "CZK"), result);
jaroslav@43
   104
jaroslav@43
   105
        // convert $1 to CZK using c:
jaroslav@43
   106
        //assertEquals("Result is 15.98 CZK");
japod@53
   107
        result = c.convert("CZK", CurrencyValue.getCurrencyValue(1d, "USD"));
japod@53
   108
        assertEquals(CurrencyValue.getCurrencyValue(15.98d, "CZK"), result);
jaroslav@43
   109
jaroslav@43
   110
        // convert 15.97CZK to USD using c:
jaroslav@43
   111
        //assertEquals("Result is 1$");
japod@53
   112
        result = c.convert("USD", CurrencyValue.getCurrencyValue(15.97d, "CZK"));
japod@53
   113
        assertEquals(CurrencyValue.getCurrencyValue(1d, "USD"), result);
jaroslav@43
   114
    }
jaroslav@43
   115
jaroslav@43
   116
    /** Join the convertors and show they behave sane.
jaroslav@43
   117
     */
jaroslav@43
   118
    public void testOnlineConvertorComposition() throws Exception {
japod@53
   119
        Convertor<Double, String> c = Task2Test.merge(
japod@53
   120
                createOnlineCZKUSDConvertor(),
japod@53
   121
                Task1Test.createSKKtoCZK());
jaroslav@43
   122
japod@53
   123
        CurrencyValue<Double, String> result;
jaroslav@43
   124
        // convert 16CZK to SKK using c:
jaroslav@43
   125
        // assertEquals("Result is 20 SKK");
japod@53
   126
        result = c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK"));
japod@53
   127
        assertEquals(CurrencyValue.getCurrencyValue(20d, "SKK"), result);
jaroslav@43
   128
jaroslav@43
   129
        // convert 500SKK to CZK using c:
jaroslav@43
   130
        // assertEquals("Result is 400 CZK");
japod@53
   131
        result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"));
japod@53
   132
        assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result);
jaroslav@43
   133
jaroslav@43
   134
        doFewQueriesForOnlineConvertor(c);
jaroslav@43
   135
    }
jaroslav@43
   136
}