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
     1 package org.apidesign.apifest08.test;
     2 
     3 import java.util.Calendar;
     4 import java.util.Date;
     5 import java.util.GregorianCalendar;
     6 import java.util.TimeZone;
     7 import junit.framework.TestCase;
     8 import org.apidesign.apifest08.currency.Convertor;
     9 import org.apidesign.apifest08.currency.CurrencyValue;
    10 import org.apidesign.apifest08.currency.ExchangeRateValue;
    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     public Task4Test(String testName) {
    27         super(testName);
    28     }
    29 
    30     @Override
    31     protected void setUp() throws Exception {
    32     }
    33 
    34     @Override
    35     protected void tearDown() throws Exception {
    36     }
    37 
    38     // Backward compatibly enhance your existing API to support following
    39     // usecases:
    40     //
    41 
    42     /** Takes a convertor with any rates associated and creates new convertor
    43      * that returns the same values as the old one for time between from to till.
    44      * Otherwise it returns no results. This is just a helper method that
    45      * shall call some real one in the API.
    46      * 
    47      * @param old existing convertor
    48      * @param from initial date (inclusive)
    49      * @param till final date (exclusive)
    50      * @return new convertor
    51      */
    52     public static <AmountType, IdentifierType> Convertor<AmountType, IdentifierType> limitTo(Convertor<AmountType, IdentifierType> old, Date from, Date till) {
    53         return old.limitConvertor(from, till);
    54     }
    55 
    56 
    57     public void testCompositionOfLimitedConvertors() throws Exception {
    58         Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    59         cal.clear();
    60         cal.set(2008, 9, 1, 0, 0);
    61         Date d1 = cal.getTime(); // 2008-10-01 0:00 GMT
    62         cal.set(2008, 9, 2, 0, 0);
    63         Date d2 = cal.getTime(); // 2008-10-02 0:00 GMT
    64         cal.set(2008, 9, 3, 0, 0);
    65         Date d3 = cal.getTime(); // 2008-10-03 0:00 GMT
    66         
    67         Convertor<Double, String> c = Task2Test.merge(
    68             limitTo(Task1Test.createCZKtoUSD(), d1, d2),
    69             limitTo(Task1Test.createSKKtoCZK(), d2, d3)
    70         );
    71 
    72         CurrencyValue<Double, String> result;
    73         // convert $5 to CZK using c:
    74         // cannot convert as no rate is applicable to current date
    75         try {
    76             c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD"));
    77             fail("Should not convert");
    78         } catch (Exception e) {
    79         }
    80         
    81         // convert $8 to CZK using c:
    82         // cannot convert as no rate is applicable to current date
    83         try {
    84             c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD"));
    85             fail("Should not convert");
    86         } catch (Exception e) {
    87         }
    88 
    89         // convert 1003CZK to USD using c:
    90         // cannot convert as no rate is applicable to current date
    91         try {
    92             c.convert("USD", CurrencyValue.getCurrencyValue(1003d, "CZK"));
    93             fail("Should not convert");
    94         } catch (Exception e) {
    95         }
    96 
    97         // convert 16CZK using c:
    98         // cannot convert as no rate is applicable to current date
    99         try {
   100             c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK"));
   101             fail("Should not convert");
   102         } catch (Exception e) {
   103         }
   104 
   105         // convert 500SKK to CZK using c:
   106         // cannot convert as no rate is applicable to current date
   107         try {
   108             c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"));
   109             fail("Should not convert");
   110         } catch (Exception e) {
   111         }
   112 
   113         // convert $5 to CZK using c at 2008-10-01 6:00 GMT:
   114         // assertEquals("Result is 85 CZK");
   115         cal.set(2008, 9, 1, 6, 0);
   116         result = c.convert("CZK", CurrencyValue.getCurrencyValue(5d, "USD"), cal.getTime());
   117         assertEquals(CurrencyValue.getCurrencyValue(85d, "CZK"), result);
   118 
   119         // convert $8 to CZK using c at 2008-10-01 6:00 GMT:
   120         // assertEquals("Result is 136 CZK");
   121         cal.set(2008, 9, 1, 6, 0);
   122         result = c.convert("CZK", CurrencyValue.getCurrencyValue(8d, "USD"), cal.getTime());
   123         assertEquals(CurrencyValue.getCurrencyValue(136d, "CZK"), result);
   124 
   125         // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT:
   126         // assertEquals("Result is 59 USD");
   127         cal.set(2008, 9, 1, 6, 0);
   128         result = c.convert("USD", CurrencyValue.getCurrencyValue(1003d, "CZK"), cal.getTime());
   129         assertEquals(CurrencyValue.getCurrencyValue(59d, "USD"), result);
   130 
   131         // convert 16CZK using c at 2008-10-02 9:00 GMT:
   132         // assertEquals("Result is 20 SKK");
   133         cal.set(2008, 9, 2, 9, 0);
   134         result = c.convert("SKK", CurrencyValue.getCurrencyValue(16d, "CZK"), cal.getTime());
   135         assertEquals(CurrencyValue.getCurrencyValue(20d, "SKK"), result);
   136 
   137         // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
   138         // assertEquals("Result is 400 CZK");
   139         cal.set(2008, 9, 2, 9, 0);
   140         result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"), cal.getTime());
   141         assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result);
   142 
   143         // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
   144         // cannot convert as no rate is applicable to current date
   145         cal.set(2008, 9, 1, 6, 0);
   146         try {
   147             result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"), cal.getTime());
   148             fail("Should not convert");
   149         } catch (Exception e) {
   150         }
   151     }
   152 
   153     /** Create convertor that understands two currencies, CZK and
   154      *  SKK. Make 100 SKK == 90 CZK.
   155      *
   156      * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
   157      */
   158     public static Convertor<Double, String> createSKKtoCZK2() {
   159         return Convertor.getConvertorDoubleString(
   160                 ExchangeRateValue.getExchangeRate(
   161                     CurrencyValue.getCurrencyValue(100d, "SKK"),
   162                     CurrencyValue.getCurrencyValue(90d, "CZK")));
   163     }
   164 
   165     public void testDateConvetorWithTwoDifferentRates() throws Exception {
   166         Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
   167         cal.clear();
   168         cal.set(2008, 9, 1, 0, 0);
   169         Date d1 = cal.getTime(); // 2008-10-01 0:00 GMT
   170         cal.set(2008, 9, 2, 0, 0);
   171         Date d2 = cal.getTime(); // 2008-10-02 0:00 GMT
   172         cal.set(2008, 9, 3, 0, 0);
   173         Date d3 = cal.getTime(); // 2008-10-03 0:00 GMT
   174 
   175         Convertor<Double, String> c = Task2Test.merge(
   176             limitTo(createSKKtoCZK2(), d1, d2),
   177             limitTo(Task1Test.createSKKtoCZK(), d2, d3)
   178         );
   179 
   180         CurrencyValue<Double, String> result;
   181         // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
   182         // assertEquals("Result is 400 CZK");
   183         cal.set(2008, 9, 2, 9, 0);
   184         result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"), cal.getTime());
   185         assertEquals(CurrencyValue.getCurrencyValue(400d, "CZK"), result);
   186 
   187         // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
   188         // assertEquals("Result is 450 CZK");
   189         cal.set(2008, 9, 1, 6, 0);
   190         result = c.convert("CZK", CurrencyValue.getCurrencyValue(500d, "SKK"), cal.getTime());
   191         assertEquals(CurrencyValue.getCurrencyValue(450d, "CZK"), result);
   192     }
   193 
   194 }