task4/solution06/test/org/apidesign/apifest08/test/Task4Test.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 17 Oct 2008 17:54:38 +0200
changeset 71 978f6a78c22e
parent 64 51f7b894eba6
permissions -rw-r--r--
removing 'ignore.failing' messages
     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.Convertor;
     8 import org.apidesign.apifest08.currency.UnsupportedConversionException;
     9 
    10 import static org.apidesign.apifest08.test.Currencies.*;
    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 Convertor limitTo(Convertor old, Date from, Date till) {
    53         return new Convertor(old, from, till);
    54     }
    55 
    56 
    57     public void testCompositionOfLimitedConvertors() throws Exception {
    58         SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm zzzz");
    59         
    60         Date d1 = df.parse("2008-10-01 0:00 GMT"); 
    61         Date d2 = df.parse("2008-10-02 0:00 GMT"); 
    62         Date d3 = df.parse("2008-10-03 0:00 GMT");
    63         
    64         Convertor c = Task2Test.merge(
    65             limitTo(Task1Test.createCZKtoUSD(), d1, d2),
    66             limitTo(Task1Test.createSKKtoCZK(), d2, d3)
    67         );
    68 
    69         // convert $5 to CZK using c:
    70         try {
    71         	c.convert(new BigDecimal(5), USD , CZK);
    72         	fail("cannot convert as no rate is applicable to current date");
    73         } catch(UnsupportedConversionException e) {
    74         	//expected
    75         }
    76 
    77         // convert $8 to CZK using c:
    78         try {
    79         	c.convert(new BigDecimal(8), USD , CZK);
    80         	fail("cannot convert as no rate is applicable to current date");
    81         } catch(UnsupportedConversionException e) {
    82         	//expected
    83         }
    84 
    85         // convert 1003CZK to USD using c:
    86         try {
    87         	c.convert(new BigDecimal(1003), CZK, USD);
    88         	fail("cannot convert as no rate is applicable to current date");
    89         } catch(UnsupportedConversionException e) {
    90         	//expected
    91         }
    92 
    93         // convert 16CZK using c:
    94         try {
    95         	c.convert(new BigDecimal(16), CZK, USD);
    96         	fail("cannot convert as no rate is applicable to current date");
    97         } catch(UnsupportedConversionException e) {
    98         	//expected
    99         }
   100 
   101         // convert 500SKK to CZK using c:
   102         try {
   103         	c.convert(new BigDecimal(500), SKK, CZK);
   104         	fail("cannot convert as no rate is applicable to current date");
   105         } catch(UnsupportedConversionException e) {
   106         	//expected
   107         }
   108 
   109         // convert $5 to CZK using c at 2008-10-01 6:00 GMT:         
   110         assertEquals("Result is 85 CZK", 85, c.convert(new BigDecimal(5), USD, CZK, df.parse("2008-10-01 6:00 GMT")).getValue().intValue());
   111 
   112         // convert $8 to CZK using c at 2008-10-01 6:00 GMT:
   113         assertEquals("Result is 136 CZK", 136, c.convert(new BigDecimal(8), USD, CZK, df.parse("2008-10-01 6:00 GMT")).getValue().intValue());
   114      
   115         // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT:
   116         assertEquals("Result is 59 USD", 59, c.convert(new BigDecimal(1003), CZK, USD, df.parse("2008-10-01 6:00 GMT")).getValue().intValue());
   117 
   118         // convert 16CZK using c at 2008-10-02 9:00 GMT:
   119         assertEquals("Result is 20 SKK", 20, c.convert(new BigDecimal(16), CZK, SKK, df.parse("2008-10-02 9:00 GMT")).getValue().intValue());
   120 
   121         // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
   122         assertEquals("Result is 400 CZK", 400, c.convert(new BigDecimal(500), SKK, CZK, df.parse("2008-10-02 9:00 GMT")).getValue().intValue());
   123 
   124         // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
   125         try {
   126         	c.convert(new BigDecimal(500), SKK, CZK, df.parse("2008-10-01 6:00 GMT"));
   127         	fail("cannot convert as no rate is applicable to current date");
   128         } catch(UnsupportedConversionException e) {
   129         	//expected
   130         }
   131     }
   132 
   133     /** Create convertor that understands two currencies, CZK and
   134      *  SKK. Make 100 SKK == 90 CZK.
   135      *
   136      * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
   137      */
   138     public static Convertor createSKKtoCZK2() {
   139     	return new Convertor(new BigDecimal("0.9"), SKK, CZK);
   140     }
   141 
   142     public void testDateConvetorWithTwoDifferentRates() throws Exception {
   143         SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm zzzz");
   144         
   145         Date d1 = df.parse("2008-10-01 0:00 GMT"); 
   146         Date d2 = df.parse("2008-10-02 0:00 GMT"); 
   147         Date d3 = df.parse("2008-10-03 0:00 GMT");
   148 
   149         Convertor c = Task2Test.merge(
   150             limitTo(createSKKtoCZK2(), d1, d2),
   151             limitTo(Task1Test.createSKKtoCZK(), d2, d3)
   152         );
   153 
   154         // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
   155         assertEquals("Result is 400 CZK", 400, c.convert(new BigDecimal(500), SKK, CZK, df.parse("2008-10-02 9:00 GMT")).getValue().intValue());
   156 
   157         // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
   158         assertEquals("Result is 450 CZK", 450, c.convert(new BigDecimal(500), SKK, CZK, df.parse("2008-10-01 6:00 GMT")).getValue().intValue());
   159     }
   160 
   161 }