task4/solution14/test/org/apidesign/apifest08/test/Task4Test.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 17 Oct 2008 17:35:52 +0200
changeset 67 bf7622ec1713
parent 62 f711ecd374f3
permissions -rw-r--r--
Solution 14, task4
     1 package org.apidesign.apifest08.test;
     2 
     3 import java.util.Date;
     4 import java.util.GregorianCalendar;
     5 import junit.framework.TestCase;
     6 import org.apidesign.apifest08.currency.Convertor;
     7 import org.apidesign.apifest08.currency.ConvertorFactory;
     8 
     9 /** The exchange rates are not always the same. They are changing. However
    10  * as in order to predict the future, one needs to understand own past. That is
    11  * why it is important to know the exchange rate as it was at any time during
    12  * the past.
    13  * <p>
    14  * Today's quest is to enhance the convertor API to deal with dates.
    15  * One shall be able to convert a currency at any date. Each currencies rate shall
    16  * be associated with a range between two Date objects. In order
    17  * to keep compatibility with old API that knew nothing about dates, the
    18  * rates associated then are applicable "for eternity". Any use of existing
    19  * convert methods that do not accept a Date argument, uses the current
    20  * System.currentTimeMillis() as default date.
    21  */
    22 public class Task4Test extends TestCase {
    23     public Task4Test(String testName) {
    24         super(testName);
    25     }
    26 
    27     @Override
    28     protected void setUp() throws Exception {
    29     }
    30 
    31     @Override
    32     protected void tearDown() throws Exception {
    33     }
    34 
    35     // Backward compatibly enhance your existing API to support following
    36     // usecases:
    37     //
    38 
    39     /** Takes a convertor with any rates associated and creates new convertor
    40      * that returns the same values as the old one for time between from to till.
    41      * Otherwise it returns no results. This is just a helper method that
    42      * shall call some real one in the API.
    43      * 
    44      * @param old existing convertor
    45      * @param from initial date (inclusive)
    46      * @param till final date (exclusive)
    47      * @return new convertor
    48      */
    49     public static Convertor limitTo(Convertor old, Date from, Date till) {
    50         return ConvertorFactory.newInstance().limitConvertor(old, from, till);
    51     }
    52 
    53 
    54     public void testCompositionOfLimitedConvertors() throws Exception {
    55         Date d1 = (new GregorianCalendar(2008, 9, 1, 0, 0)).getTime(); // 2008-10-01 0:00 GMT
    56         Date d2 = (new GregorianCalendar(2008, 9, 2, 0, 0)).getTime(); // 2008-10-02 0:00 GMT
    57         Date d3 = (new GregorianCalendar(2008, 9, 3, 0, 0)).getTime(); // 2008-10-03 0:00 GMT
    58         
    59         Convertor c = Task2Test.merge(
    60             limitTo(Task1Test.createCZKtoUSD(), d1, d2),
    61             limitTo(Task1Test.createSKKtoCZK(), d2, d3)
    62         );
    63 
    64         // convert $5 to CZK using c:
    65         // cannot convert as no rate is applicable to current date
    66         try {
    67             c.convert("USD", "CZK", 5);
    68             fail();
    69         } catch (IllegalArgumentException e) {
    70             //ok
    71         }
    72 
    73         // convert $8 to CZK using c:
    74         // cannot convert as no rate is applicable to current date
    75         try {
    76             c.convert("USD", "CZK", 8);
    77             fail();
    78         } catch (IllegalArgumentException e) {
    79             //ok
    80         }
    81 
    82         // convert 1003CZK to USD using c:
    83         // cannot convert as no rate is applicable to current date
    84         try {
    85             c.convert("CZK", "USD", 1003);
    86             fail();
    87         } catch (IllegalArgumentException e) {
    88             //ok
    89         }
    90 
    91         // convert 16CZK using c:
    92         // cannot convert as no rate is applicable to current date
    93         try {
    94             c.convert("CZK", "USD", 16);
    95             fail();
    96         } catch (IllegalArgumentException e) {
    97             //ok
    98         }
    99 
   100         // convert 500SKK to CZK using c:
   101         // cannot convert as no rate is applicable to current date
   102         try {
   103             c.convert("SKK", "CZK", 500);
   104             fail();
   105         } catch (IllegalArgumentException e) {
   106             //ok
   107         }
   108 
   109         // convert $5 to CZK using c at 2008-10-01 6:00 GMT:
   110         // assertEquals("Result is 85 CZK");
   111         assertEquals("Result is 85 CZK", 85.0, c.convert("USD", "CZK", 5, (new GregorianCalendar(2008,9,1,6,0)).getTime()));
   112 
   113         // convert $8 to CZK using c at 2008-10-01 6:00 GMT:
   114         // assertEquals("Result is 136 CZK");
   115         assertEquals("Result is 136 CZK", 136.0, c.convert("USD", "CZK", 8, (new GregorianCalendar(2008,9,1,6,0)).getTime()));
   116 
   117         // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT:
   118         // assertEquals("Result is 59 USD");
   119         assertEquals("Result is 59 USD", 59.0, c.convert("CZK", "USD", 1003.0, (new GregorianCalendar(2008, 9, 1, 6, 0)).getTime()));
   120 
   121         // convert 16CZK using c at 2008-10-02 9:00 GMT:
   122         // assertEquals("Result is 20 SKK");
   123         assertEquals("Result is 20 SKK", 20.0, c.convert("CZK", "SKK", 16.0, (new GregorianCalendar(2008, 9, 2, 9, 0)).getTime()));
   124 
   125         // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
   126         // assertEquals("Result is 400 CZK");
   127         assertEquals("Result is 400 CZK", 400.0, c.convert("SKK", "CZK", 500.0, (new GregorianCalendar(2008, 9, 2, 9, 0)).getTime()));
   128 
   129         // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
   130         // cannot convert as no rate is applicable to current date
   131         try {
   132             c.convert("SKK", "CZK", 500.0, (new GregorianCalendar(2008, 9, 1, 6, 0)).getTime());
   133             fail();
   134         } catch (IllegalArgumentException e) {
   135             //ok
   136         }
   137     }
   138 
   139     /** Create convertor that understands two currencies, CZK and
   140      *  SKK. Make 100 SKK == 90 CZK.
   141      *
   142      * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
   143      */
   144     public static Convertor createSKKtoCZK2() {
   145         return ConvertorFactory.newInstance().createConvertor("SKK", "CZK", 100, 90);
   146     }
   147 
   148     public void testDateConvetorWithTwoDifferentRates() throws Exception {
   149         Date d1 = (new GregorianCalendar(2008,9,1,0,0)).getTime(); // 2008-10-01 0:00 GMT
   150         Date d2 = (new GregorianCalendar(2008,9,2,0,0)).getTime(); // 2008-10-02 0:00 GMT
   151         Date d3 = (new GregorianCalendar(2008,9,6,0,0)).getTime(); // 2008-10-03 0:00 GMT
   152 
   153         Convertor c = Task2Test.merge(
   154             limitTo(createSKKtoCZK2(), d1, d2),
   155             limitTo(Task1Test.createSKKtoCZK(), d2, d3)
   156         );
   157 
   158         // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
   159         // assertEquals("Result is 400 CZK");
   160         assertEquals("Result is 400 CZK", 400.0, c.convert("SKK", "CZK", 500.0, (new GregorianCalendar(2008, 9, 2, 9, 0)).getTime()));
   161 
   162         // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
   163         // assertEquals("Result is 450 CZK");
   164         assertEquals("Result is 450 CZK", 450.0, c.convert("SKK", "CZK", 500.0, (new GregorianCalendar(2008, 9, 1, 6, 0)).getTime()));
   165     }
   166 
   167 }