task4/solution13/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 63 20d332739f60
permissions -rw-r--r--
Solutions by Petr Smid
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
        Date d1 = df.parse("2008-10-01 0:00 GMT");
jaroslav@63
    71
        Date d2 = df.parse("2008-10-02 0:00 GMT");
jaroslav@63
    72
        Date d3 = df.parse("2008-10-03 0:00 GMT");
jaroslav@60
    73
        
jaroslav@60
    74
        Convertor c = Task2Test.merge(
jaroslav@60
    75
            limitTo(Task1Test.createCZKtoUSD(), d1, d2),
jaroslav@60
    76
            limitTo(Task1Test.createSKKtoCZK(), d2, d3)
jaroslav@60
    77
        );
jaroslav@60
    78
jaroslav@60
    79
        // convert $5 to CZK using c:
jaroslav@60
    80
        // cannot convert as no rate is applicable to current date
jaroslav@63
    81
        try {
jaroslav@63
    82
          c.convert(USD, CZK, new BigDecimal(5));
jaroslav@63
    83
          fail();        
jaroslav@63
    84
        } catch (ConversionNotSupportedException e) {
jaroslav@63
    85
            //exception expected
jaroslav@63
    86
        }
jaroslav@60
    87
jaroslav@60
    88
        // convert $8 to CZK using c:
jaroslav@60
    89
        // cannot convert as no rate is applicable to current date
jaroslav@63
    90
        try {
jaroslav@63
    91
          c.convert(USD, CZK, new BigDecimal(8));
jaroslav@63
    92
          fail();        
jaroslav@63
    93
        } catch (ConversionNotSupportedException e) {
jaroslav@63
    94
            //exception expected
jaroslav@63
    95
        }
jaroslav@63
    96
        
jaroslav@60
    97
jaroslav@60
    98
        // convert 1003CZK to USD using c:
jaroslav@60
    99
        // cannot convert as no rate is applicable to current date
jaroslav@63
   100
        try {
jaroslav@63
   101
          c.convert(CZK, USD, new BigDecimal(1003));
jaroslav@63
   102
          fail();        
jaroslav@63
   103
        } catch (ConversionNotSupportedException e) {
jaroslav@63
   104
            //exception expected
jaroslav@63
   105
        }
jaroslav@60
   106
jaroslav@60
   107
        // convert 16CZK using c:
jaroslav@60
   108
        // cannot convert as no rate is applicable to current date
jaroslav@63
   109
        // ???
jaroslav@63
   110
        try {
jaroslav@63
   111
          c.convert(CZK, USD, new BigDecimal(16));
jaroslav@63
   112
          fail();        
jaroslav@63
   113
        } catch (ConversionNotSupportedException e) {
jaroslav@63
   114
            //exception expected
jaroslav@63
   115
        }
jaroslav@60
   116
jaroslav@60
   117
        // convert 500SKK to CZK using c:
jaroslav@60
   118
        // cannot convert as no rate is applicable to current date
jaroslav@63
   119
        try {
jaroslav@63
   120
          c.convert(SKK, CZK, new BigDecimal(500));
jaroslav@63
   121
          fail();        
jaroslav@63
   122
        } catch (ConversionNotSupportedException e) {
jaroslav@63
   123
            //exception expected
jaroslav@63
   124
        }
jaroslav@63
   125
        
jaroslav@60
   126
jaroslav@60
   127
        // convert $5 to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@60
   128
        // assertEquals("Result is 85 CZK");
jaroslav@63
   129
        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
   130
jaroslav@60
   131
        // convert $8 to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@60
   132
        // assertEquals("Result is 136 CZK");
jaroslav@63
   133
        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
   134
jaroslav@60
   135
        // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT:
jaroslav@60
   136
        // assertEquals("Result is 59 USD");
jaroslav@63
   137
        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
   138
jaroslav@60
   139
        // convert 16CZK using c at 2008-10-02 9:00 GMT:
jaroslav@60
   140
        // assertEquals("Result is 20 SKK");
jaroslav@63
   141
        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
   142
jaroslav@60
   143
        // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
jaroslav@60
   144
        // assertEquals("Result is 400 CZK");
jaroslav@63
   145
        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
   146
jaroslav@60
   147
        // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@60
   148
        // cannot convert as no rate is applicable to current date
jaroslav@63
   149
        try {
jaroslav@63
   150
          c.convertWithReversibleRates(SKK, CZK , new BigDecimal("500"),df.parse("2008-10-01 6:00 GMT")).getConverted();        
jaroslav@63
   151
          fail();        
jaroslav@63
   152
        } catch (ConversionNotSupportedException e) {
jaroslav@63
   153
            //exception expected
jaroslav@63
   154
        }
jaroslav@63
   155
jaroslav@60
   156
    }
jaroslav@60
   157
jaroslav@60
   158
    /** Create convertor that understands two currencies, CZK and
jaroslav@60
   159
     *  SKK. Make 100 SKK == 90 CZK.
jaroslav@60
   160
     *
jaroslav@60
   161
     * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
jaroslav@60
   162
     */
jaroslav@60
   163
    public static Convertor createSKKtoCZK2() {
jaroslav@63
   164
        ExchangeRateProvider exchangeRateProvider = ExchangeRateProvider.createExchangeRateProvider();
jaroslav@63
   165
        exchangeRateProvider.addFixedCurencyRate(SKK, new BigDecimal("100.00"), CZK, new BigDecimal("90.00"));
jaroslav@63
   166
        Convertor c  = Convertor.createConvertor(exchangeRateProvider);
jaroslav@63
   167
        return c;
jaroslav@60
   168
    }
jaroslav@60
   169
jaroslav@60
   170
    public void testDateConvetorWithTwoDifferentRates() throws Exception {
jaroslav@60
   171
jaroslav@63
   172
        Date d1 = df.parse("2008-10-01 0:00 GMT");
jaroslav@63
   173
        Date d2 = df.parse("2008-10-02 0:00 GMT");
jaroslav@63
   174
        Date d3 = df.parse("2008-10-03 0:00 GMT");
jaroslav@60
   175
jaroslav@60
   176
        Convertor c = Task2Test.merge(
jaroslav@60
   177
            limitTo(createSKKtoCZK2(), d1, d2),
jaroslav@60
   178
            limitTo(Task1Test.createSKKtoCZK(), d2, d3)
jaroslav@60
   179
        );
jaroslav@60
   180
jaroslav@60
   181
        // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
jaroslav@63
   182
        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
   183
jaroslav@60
   184
        // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
jaroslav@63
   185
        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
   186
    }
jaroslav@60
   187
jaroslav@60
   188
}