task4/solution11/test/org/apidesign/apifest08/test/Task4Test.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sat, 25 Oct 2008 20:53:00 +0200
changeset 84 2ae6e4aa7aef
parent 62 f711ecd374f3
permissions -rw-r--r--
Solutions by Petr Smid
jaroslav@60
     1
package org.apidesign.apifest08.test;
jaroslav@60
     2
jaroslav@66
     3
import java.util.Calendar;
jaroslav@60
     4
import java.util.Date;
jaroslav@66
     5
import java.util.GregorianCalendar;
jaroslav@66
     6
import java.util.TimeZone;
jaroslav@60
     7
import junit.framework.TestCase;
jaroslav@60
     8
import org.apidesign.apifest08.currency.Convertor;
jaroslav@66
     9
import org.apidesign.apifest08.currency.CurrencyValue;
jaroslav@66
    10
import org.apidesign.apifest08.currency.ExchangeRateValue;
jaroslav@60
    11
jaroslav@60
    12
/** The exchange rates are not always the same. They are changing. However
jaroslav@60
    13
 * as in order to predict the future, one needs to understand own past. That is
jaroslav@60
    14
 * why it is important to know the exchange rate as it was at any time during
jaroslav@60
    15
 * the past.
jaroslav@60
    16
 * <p>
jaroslav@60
    17
 * Today's quest is to enhance the convertor API to deal with dates.
jaroslav@60
    18
 * One shall be able to convert a currency at any date. Each currencies rate shall
jaroslav@60
    19
 * be associated with a range between two Date objects. In order
jaroslav@60
    20
 * to keep compatibility with old API that knew nothing about dates, the
jaroslav@60
    21
 * rates associated then are applicable "for eternity". Any use of existing
jaroslav@60
    22
 * convert methods that do not accept a Date argument, uses the current
jaroslav@60
    23
 * System.currentTimeMillis() as default date.
jaroslav@60
    24
 */
jaroslav@60
    25
public class Task4Test extends TestCase {
jaroslav@60
    26
    public Task4Test(String testName) {
jaroslav@60
    27
        super(testName);
jaroslav@60
    28
    }
jaroslav@60
    29
jaroslav@60
    30
    @Override
jaroslav@60
    31
    protected void setUp() throws Exception {
jaroslav@60
    32
    }
jaroslav@60
    33
jaroslav@60
    34
    @Override
jaroslav@60
    35
    protected void tearDown() throws Exception {
jaroslav@60
    36
    }
jaroslav@60
    37
jaroslav@60
    38
    // Backward compatibly enhance your existing API to support following
jaroslav@60
    39
    // usecases:
jaroslav@60
    40
    //
jaroslav@60
    41
jaroslav@60
    42
    /** Takes a convertor with any rates associated and creates new convertor
jaroslav@60
    43
     * that returns the same values as the old one for time between from to till.
jaroslav@60
    44
     * Otherwise it returns no results. This is just a helper method that
jaroslav@60
    45
     * shall call some real one in the API.
jaroslav@60
    46
     * 
jaroslav@60
    47
     * @param old existing convertor
jaroslav@60
    48
     * @param from initial date (inclusive)
jaroslav@60
    49
     * @param till final date (exclusive)
jaroslav@60
    50
     * @return new convertor
jaroslav@60
    51
     */
jaroslav@66
    52
    public static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> limitTo(Convertor<AmountType, IdentifierType> old, Date from, Date till) {
jaroslav@66
    53
        return old.limitConvertor(from, till);
jaroslav@60
    54
    }
jaroslav@60
    55
jaroslav@60
    56
jaroslav@60
    57
    public void testCompositionOfLimitedConvertors() throws Exception {
jaroslav@66
    58
        Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
jaroslav@66
    59
        cal.clear();
jaroslav@66
    60
        cal.set(2008, 9, 1, 0, 0);
jaroslav@66
    61
        Date d1 = cal.getTime(); // 2008-10-01 0:00 GMT
jaroslav@66
    62
        cal.set(2008, 9, 2, 0, 0);
jaroslav@66
    63
        Date d2 = cal.getTime(); // 2008-10-02 0:00 GMT
jaroslav@66
    64
        cal.set(2008, 9, 3, 0, 0);
jaroslav@66
    65
        Date d3 = cal.getTime(); // 2008-10-03 0:00 GMT
jaroslav@60
    66
        
jaroslav@66
    67
        Convertor<Double, String> c = Task2Test.merge(
jaroslav@60
    68
            limitTo(Task1Test.createCZKtoUSD(), d1, d2),
jaroslav@60
    69
            limitTo(Task1Test.createSKKtoCZK(), d2, d3)
jaroslav@60
    70
        );
jaroslav@60
    71
jaroslav@66
    72
        CurrencyValue<Double, String> result;
jaroslav@60
    73
        // convert $5 to CZK using c:
jaroslav@60
    74
        // cannot convert as no rate is applicable to current date
jaroslav@66
    75
        try {
jaroslav@66
    76
            c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD"));
jaroslav@66
    77
            fail("Should not convert");
jaroslav@66
    78
        } catch (Exception e) {
jaroslav@66
    79
        }
jaroslav@66
    80
        
jaroslav@60
    81
        // convert $8 to CZK using c:
jaroslav@60
    82
        // cannot convert as no rate is applicable to current date
jaroslav@66
    83
        try {
jaroslav@66
    84
            c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD"));
jaroslav@66
    85
            fail("Should not convert");
jaroslav@66
    86
        } catch (Exception e) {
jaroslav@66
    87
        }
jaroslav@60
    88
jaroslav@60
    89
        // convert 1003CZK to USD using c:
jaroslav@60
    90
        // cannot convert as no rate is applicable to current date
jaroslav@66
    91
        try {
jaroslav@66
    92
            c.convert("USD", CurrencyValue.getCurrencyValue(1003d, "CZK"));
jaroslav@66
    93
            fail("Should not convert");
jaroslav@66
    94
        } catch (Exception e) {
jaroslav@66
    95
        }
jaroslav@60
    96
jaroslav@60
    97
        // convert 16CZK using c:
jaroslav@60
    98
        // cannot convert as no rate is applicable to current date
jaroslav@66
    99
        try {
jaroslav@66
   100
            c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK"));
jaroslav@66
   101
            fail("Should not convert");
jaroslav@66
   102
        } catch (Exception e) {
jaroslav@66
   103
        }
jaroslav@60
   104
jaroslav@60
   105
        // convert 500SKK to CZK using c:
jaroslav@60
   106
        // cannot convert as no rate is applicable to current date
jaroslav@66
   107
        try {
jaroslav@66
   108
            c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"));
jaroslav@66
   109
            fail("Should not convert");
jaroslav@66
   110
        } catch (Exception e) {
jaroslav@66
   111
        }
jaroslav@60
   112
jaroslav@60
   113
        // convert $5 to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@60
   114
        // assertEquals("Result is 85 CZK");
jaroslav@66
   115
        cal.set(2008, 9, 1, 6, 0);
jaroslav@66
   116
        result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD"), cal.getTime());
jaroslav@66
   117
        assertEquals(CurrencyValue.getCurrencyValue(85d, "CZK"), result);
jaroslav@60
   118
jaroslav@60
   119
        // convert $8 to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@60
   120
        // assertEquals("Result is 136 CZK");
jaroslav@66
   121
        cal.set(2008, 9, 1, 6, 0);
jaroslav@66
   122
        result = c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD"), cal.getTime());
jaroslav@66
   123
        assertEquals(CurrencyValue.getCurrencyValue(136d, "CZK"), result);
jaroslav@60
   124
jaroslav@60
   125
        // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT:
jaroslav@60
   126
        // assertEquals("Result is 59 USD");
jaroslav@66
   127
        cal.set(2008, 9, 1, 6, 0);
jaroslav@66
   128
        result = c.convert("USD", CurrencyValue.getCurrencyValue(1003d, "CZK"), cal.getTime());
jaroslav@66
   129
        assertEquals(CurrencyValue.getCurrencyValue(59d, "USD"), result);
jaroslav@60
   130
jaroslav@60
   131
        // convert 16CZK using c at 2008-10-02 9:00 GMT:
jaroslav@60
   132
        // assertEquals("Result is 20 SKK");
jaroslav@66
   133
        cal.set(2008, 9, 2, 9, 0);
jaroslav@66
   134
        result = c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK"), cal.getTime());
jaroslav@66
   135
        assertEquals(CurrencyValue.getCurrencyValue(20d, "SKK"), result);
jaroslav@60
   136
jaroslav@60
   137
        // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
jaroslav@60
   138
        // assertEquals("Result is 400 CZK");
jaroslav@66
   139
        cal.set(2008, 9, 2, 9, 0);
jaroslav@66
   140
        result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"), cal.getTime());
jaroslav@66
   141
        assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result);
jaroslav@60
   142
jaroslav@60
   143
        // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@60
   144
        // cannot convert as no rate is applicable to current date
jaroslav@66
   145
        cal.set(2008, 9, 1, 6, 0);
jaroslav@66
   146
        try {
jaroslav@66
   147
            result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"), cal.getTime());
jaroslav@66
   148
            fail("Should not convert");
jaroslav@66
   149
        } catch (Exception e) {
jaroslav@66
   150
        }
jaroslav@60
   151
    }
jaroslav@60
   152
jaroslav@60
   153
    /** Create convertor that understands two currencies, CZK and
jaroslav@60
   154
     *  SKK. Make 100 SKK == 90 CZK.
jaroslav@60
   155
     *
jaroslav@60
   156
     * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
jaroslav@60
   157
     */
jaroslav@66
   158
    public static Convertor<Double, String> createSKKtoCZK2() {
jaroslav@66
   159
        return Convertor.getConvertorDoubleString(
jaroslav@66
   160
                ExchangeRateValue.getExchangeRate(
jaroslav@66
   161
                    CurrencyValue.getCurrencyValue(100d, "SKK"),
jaroslav@66
   162
                    CurrencyValue.getCurrencyValue(90d, "CZK")));
jaroslav@60
   163
    }
jaroslav@60
   164
jaroslav@60
   165
    public void testDateConvetorWithTwoDifferentRates() throws Exception {
jaroslav@66
   166
        Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
jaroslav@66
   167
        cal.clear();
jaroslav@66
   168
        cal.set(2008, 9, 1, 0, 0);
jaroslav@66
   169
        Date d1 = cal.getTime(); // 2008-10-01 0:00 GMT
jaroslav@66
   170
        cal.set(2008, 9, 2, 0, 0);
jaroslav@66
   171
        Date d2 = cal.getTime(); // 2008-10-02 0:00 GMT
jaroslav@66
   172
        cal.set(2008, 9, 3, 0, 0);
jaroslav@66
   173
        Date d3 = cal.getTime(); // 2008-10-03 0:00 GMT
jaroslav@60
   174
jaroslav@66
   175
        Convertor<Double, String> c = Task2Test.merge(
jaroslav@60
   176
            limitTo(createSKKtoCZK2(), d1, d2),
jaroslav@60
   177
            limitTo(Task1Test.createSKKtoCZK(), d2, d3)
jaroslav@60
   178
        );
jaroslav@60
   179
jaroslav@66
   180
        CurrencyValue<Double, String> result;
jaroslav@60
   181
        // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
jaroslav@60
   182
        // assertEquals("Result is 400 CZK");
jaroslav@66
   183
        cal.set(2008, 9, 2, 9, 0);
jaroslav@66
   184
        result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"), cal.getTime());
jaroslav@66
   185
        assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result);
jaroslav@60
   186
jaroslav@60
   187
        // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@60
   188
        // assertEquals("Result is 450 CZK");
jaroslav@66
   189
        cal.set(2008, 9, 1, 6, 0);
jaroslav@66
   190
        result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"), cal.getTime());
jaroslav@66
   191
        assertEquals(CurrencyValue.getCurrencyValue(450d, "CZK"), result);
jaroslav@60
   192
    }
jaroslav@60
   193
jaroslav@60
   194
}