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