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