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