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