task4/solution13/test/org/apidesign/apifest08/test/Task4Test.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 17 Oct 2008 17:31:48 +0200
changeset 63 20d332739f60
parent 62 f711ecd374f3
child 71 978f6a78c22e
permissions -rw-r--r--
Solution 13 for task4
jaroslav@60
     1
package org.apidesign.apifest08.test;
jaroslav@60
     2
jaroslav@63
     3
import java.math.BigDecimal;
jaroslav@63
     4
import java.text.SimpleDateFormat;
jaroslav@60
     5
import java.util.Date;
jaroslav@60
     6
import junit.framework.TestCase;
jaroslav@63
     7
import org.apidesign.apifest08.currency.ConversionNotSupportedException;
jaroslav@60
     8
import org.apidesign.apifest08.currency.Convertor;
jaroslav@63
     9
import org.apidesign.apifest08.currency.ConvertorCurrency;
jaroslav@63
    10
import org.apidesign.apifest08.currency.ExchangeRateProvider;
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@63
    26
    private static ConvertorCurrency CZK = ConvertorCurrency.getInstance("CZK");
jaroslav@63
    27
    private static ConvertorCurrency SKK = ConvertorCurrency.getInstance("SKK");
jaroslav@63
    28
    private static ConvertorCurrency USD = ConvertorCurrency.getInstance("USD");
jaroslav@63
    29
    private SimpleDateFormat df;
jaroslav@63
    30
    
jaroslav@63
    31
    
jaroslav@60
    32
    public Task4Test(String testName) {
jaroslav@60
    33
        super(testName);
jaroslav@60
    34
    }
jaroslav@60
    35
jaroslav@60
    36
    @Override
jaroslav@60
    37
    protected void setUp() throws Exception {
jaroslav@63
    38
        super.setUp();
jaroslav@63
    39
        df = new SimpleDateFormat("yyyy-MM-dd HH:mm zzzz");
jaroslav@60
    40
    }
jaroslav@60
    41
jaroslav@60
    42
    @Override
jaroslav@60
    43
    protected void tearDown() throws Exception {
jaroslav@63
    44
        super.tearDown();
jaroslav@63
    45
        df = null;
jaroslav@60
    46
    }
jaroslav@60
    47
jaroslav@60
    48
    // Backward compatibly enhance your existing API to support following
jaroslav@60
    49
    // usecases:
jaroslav@60
    50
    //
jaroslav@60
    51
jaroslav@60
    52
    /** Takes a convertor with any rates associated and creates new convertor
jaroslav@60
    53
     * that returns the same values as the old one for time between from to till.
jaroslav@60
    54
     * Otherwise it returns no results. This is just a helper method that
jaroslav@60
    55
     * shall call some real one in the API.
jaroslav@60
    56
     * 
jaroslav@60
    57
     * @param old existing convertor
jaroslav@60
    58
     * @param from initial date (inclusive)
jaroslav@60
    59
     * @param till final date (exclusive)
jaroslav@60
    60
     * @return new convertor
jaroslav@60
    61
     */
jaroslav@60
    62
    public static Convertor limitTo(Convertor old, Date from, Date till) {
jaroslav@63
    63
        Convertor c = Convertor.createConvertorAsMerge(new Convertor[]{old});
jaroslav@63
    64
        c.limitAllowedDates(from, till);
jaroslav@63
    65
        return c;
jaroslav@60
    66
    }
jaroslav@60
    67
jaroslav@60
    68
jaroslav@60
    69
    public void testCompositionOfLimitedConvertors() throws Exception {
jaroslav@63
    70
//        if (Boolean.getBoolean("ignore.failing")) {
jaroslav@63
    71
//            // implement me! then delete this if statement
jaroslav@63
    72
//            return;
jaroslav@63
    73
//        }
jaroslav@63
    74
        
jaroslav@60
    75
jaroslav@63
    76
        Date d1 = df.parse("2008-10-01 0:00 GMT");
jaroslav@63
    77
        Date d2 = df.parse("2008-10-02 0:00 GMT");
jaroslav@63
    78
        Date d3 = df.parse("2008-10-03 0:00 GMT");
jaroslav@60
    79
        
jaroslav@60
    80
        Convertor c = Task2Test.merge(
jaroslav@60
    81
            limitTo(Task1Test.createCZKtoUSD(), d1, d2),
jaroslav@60
    82
            limitTo(Task1Test.createSKKtoCZK(), d2, d3)
jaroslav@60
    83
        );
jaroslav@60
    84
jaroslav@60
    85
        // convert $5 to CZK using c:
jaroslav@60
    86
        // cannot convert as no rate is applicable to current date
jaroslav@63
    87
        try {
jaroslav@63
    88
          c.convert(USD, CZK, new BigDecimal(5));
jaroslav@63
    89
          fail();        
jaroslav@63
    90
        } catch (ConversionNotSupportedException e) {
jaroslav@63
    91
            //exception expected
jaroslav@63
    92
        }
jaroslav@60
    93
jaroslav@60
    94
        // convert $8 to CZK using c:
jaroslav@60
    95
        // cannot convert as no rate is applicable to current date
jaroslav@63
    96
        try {
jaroslav@63
    97
          c.convert(USD, CZK, new BigDecimal(8));
jaroslav@63
    98
          fail();        
jaroslav@63
    99
        } catch (ConversionNotSupportedException e) {
jaroslav@63
   100
            //exception expected
jaroslav@63
   101
        }
jaroslav@63
   102
        
jaroslav@60
   103
jaroslav@60
   104
        // convert 1003CZK to USD using c:
jaroslav@60
   105
        // cannot convert as no rate is applicable to current date
jaroslav@63
   106
        try {
jaroslav@63
   107
          c.convert(CZK, USD, new BigDecimal(1003));
jaroslav@63
   108
          fail();        
jaroslav@63
   109
        } catch (ConversionNotSupportedException e) {
jaroslav@63
   110
            //exception expected
jaroslav@63
   111
        }
jaroslav@60
   112
jaroslav@60
   113
        // convert 16CZK using c:
jaroslav@60
   114
        // cannot convert as no rate is applicable to current date
jaroslav@63
   115
        // ???
jaroslav@63
   116
        try {
jaroslav@63
   117
          c.convert(CZK, USD, new BigDecimal(16));
jaroslav@63
   118
          fail();        
jaroslav@63
   119
        } catch (ConversionNotSupportedException e) {
jaroslav@63
   120
            //exception expected
jaroslav@63
   121
        }
jaroslav@60
   122
jaroslav@60
   123
        // convert 500SKK to CZK using c:
jaroslav@60
   124
        // cannot convert as no rate is applicable to current date
jaroslav@63
   125
        try {
jaroslav@63
   126
          c.convert(SKK, CZK, new BigDecimal(500));
jaroslav@63
   127
          fail();        
jaroslav@63
   128
        } catch (ConversionNotSupportedException e) {
jaroslav@63
   129
            //exception expected
jaroslav@63
   130
        }
jaroslav@63
   131
        
jaroslav@60
   132
jaroslav@60
   133
        // convert $5 to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@60
   134
        // assertEquals("Result is 85 CZK");
jaroslav@63
   135
        assertEquals("Result is 85 CZK", new BigDecimal("85.00"), c.convertWithReversibleRates(USD, CZK , new BigDecimal("5"),df.parse("2008-10-01 6:00 GMT")).getConverted());        
jaroslav@60
   136
jaroslav@60
   137
        // convert $8 to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@60
   138
        // assertEquals("Result is 136 CZK");
jaroslav@63
   139
        assertEquals("Result is 136 CZK", new BigDecimal("136.00"), c.convertWithReversibleRates(USD, CZK , new BigDecimal("8"),df.parse("2008-10-01 6:00 GMT")).getConverted());        
jaroslav@60
   140
jaroslav@60
   141
        // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT:
jaroslav@60
   142
        // assertEquals("Result is 59 USD");
jaroslav@63
   143
        assertEquals("Result is 59 USD", new BigDecimal("59.00"), c.convertWithReversibleRates(CZK, USD , new BigDecimal("1003"),df.parse("2008-10-01 6:00 GMT")).getConverted());        
jaroslav@60
   144
jaroslav@60
   145
        // convert 16CZK using c at 2008-10-02 9:00 GMT:
jaroslav@60
   146
        // assertEquals("Result is 20 SKK");
jaroslav@63
   147
        assertEquals("Result is 20 SKK", new BigDecimal("20.00"), c.convertWithReversibleRates(CZK, SKK , new BigDecimal("16"),df.parse("2008-10-02 9:00 GMT")).getConverted());        
jaroslav@60
   148
jaroslav@60
   149
        // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
jaroslav@60
   150
        // assertEquals("Result is 400 CZK");
jaroslav@63
   151
        assertEquals("Result is 400 SKK", new BigDecimal("400.00"), c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-02 9:00 GMT")).getConverted());        
jaroslav@60
   152
jaroslav@60
   153
        // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@60
   154
        // cannot convert as no rate is applicable to current date
jaroslav@63
   155
        try {
jaroslav@63
   156
          c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-01 6:00 GMT")).getConverted();        
jaroslav@63
   157
          fail();        
jaroslav@63
   158
        } catch (ConversionNotSupportedException e) {
jaroslav@63
   159
            //exception expected
jaroslav@63
   160
        }
jaroslav@63
   161
jaroslav@60
   162
    }
jaroslav@60
   163
jaroslav@60
   164
    /** Create convertor that understands two currencies, CZK and
jaroslav@60
   165
     *  SKK. Make 100 SKK == 90 CZK.
jaroslav@60
   166
     *
jaroslav@60
   167
     * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
jaroslav@60
   168
     */
jaroslav@60
   169
    public static Convertor createSKKtoCZK2() {
jaroslav@63
   170
        ExchangeRateProvider exchangeRateProvider = ExchangeRateProvider.createExchangeRateProvider();
jaroslav@63
   171
        exchangeRateProvider.addFixedCurencyRate(SKK, new BigDecimal("100.00"), CZK, new BigDecimal("90.00"));
jaroslav@63
   172
        Convertor c  = Convertor.createConvertor(exchangeRateProvider);
jaroslav@63
   173
        return c;
jaroslav@60
   174
    }
jaroslav@60
   175
jaroslav@60
   176
    public void testDateConvetorWithTwoDifferentRates() throws Exception {
jaroslav@60
   177
jaroslav@63
   178
        Date d1 = df.parse("2008-10-01 0:00 GMT");
jaroslav@63
   179
        Date d2 = df.parse("2008-10-02 0:00 GMT");
jaroslav@63
   180
        Date d3 = df.parse("2008-10-03 0:00 GMT");
jaroslav@60
   181
jaroslav@60
   182
        Convertor c = Task2Test.merge(
jaroslav@60
   183
            limitTo(createSKKtoCZK2(), d1, d2),
jaroslav@60
   184
            limitTo(Task1Test.createSKKtoCZK(), d2, d3)
jaroslav@60
   185
        );
jaroslav@60
   186
jaroslav@60
   187
        // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
jaroslav@63
   188
        assertEquals("Result is 400 CZK", new BigDecimal("400.00"), c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-02 9:00 GMT")).getConverted());        
jaroslav@60
   189
jaroslav@60
   190
        // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@63
   191
        assertEquals("Result is 450 CZK", new BigDecimal("450.00"), c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-01 9:00 GMT")).getConverted());        
jaroslav@60
   192
    }
jaroslav@60
   193
jaroslav@60
   194
}