task4/solution04/test/org/apidesign/apifest08/test/Task2Test.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 11 Oct 2008 23:38:46 +0200
changeset 61 58ec6da75f6f
parent 45 task3/solution04/test/org/apidesign/apifest08/test/Task2Test.java@251d0ed461fb
permissions -rw-r--r--
Copying structure for task4
japod@35
     1
package org.apidesign.apifest08.test;
japod@35
     2
japod@35
     3
import java.math.BigDecimal;
japod@35
     4
import java.util.Currency;
japod@35
     5
import java.util.Set;
japod@35
     6
import junit.framework.TestCase;
japod@35
     7
import org.apidesign.apifest08.currency.Convertor;
japod@35
     8
import org.apidesign.apifest08.currency.ConvertorFactory;
japod@35
     9
import org.apidesign.apifest08.currency.InvalidConversionException;
japod@35
    10
japod@35
    11
japod@35
    12
/** There are many currencies around the world and many banks manipulate
japod@35
    13
 * with more than one or two at the same time. As banks are usually the
japod@35
    14
 * best paying clients, which is true even in case of your Convertor API,
japod@35
    15
 * it is reasonable to listen to their requests.
japod@35
    16
 * <p>
japod@35
    17
 * The quest for today is to enhance your existing convertor API to hold
japod@35
    18
 * information about many currencies and allow conversions between any of them.
japod@35
    19
 * Also, as conversion rates for diferent currencies usually arise from various
japod@35
    20
 * bank departments, there is another important need. There is a need to
japod@35
    21
 * compose two convertors into one by merging all the information about
japod@35
    22
 * currencies they know about.
japod@35
    23
 */
japod@35
    24
public class Task2Test extends TestCase
japod@35
    25
{
japod@35
    26
    private final static Currency CZK;
japod@35
    27
    private final static Currency SKK;
japod@35
    28
    private final static Currency USD;
japod@35
    29
japod@35
    30
    static
japod@35
    31
    {
japod@35
    32
        CZK = Currency.getInstance("CZK");
japod@35
    33
        SKK = Currency.getInstance("SKK");
japod@35
    34
        USD = Currency.getInstance("USD");
japod@35
    35
    }
japod@35
    36
japod@35
    37
    public Task2Test(String testName)
japod@35
    38
    {
japod@35
    39
        super(testName);
japod@35
    40
    }
japod@35
    41
japod@35
    42
    @Override
japod@35
    43
    protected void setUp() 
japod@35
    44
        throws Exception
japod@35
    45
    {
japod@35
    46
    }
japod@35
    47
japod@35
    48
    @Override
japod@35
    49
    protected void tearDown() 
japod@35
    50
        throws Exception
japod@35
    51
    {
japod@35
    52
    }
japod@35
    53
japod@35
    54
    // As in Task1Test, keep in mind, that there are three parts
japod@35
    55
    // of the whole system:
japod@35
    56
    // 1. there is someone who knows the current exchange rate
japod@35
    57
    // 2. there is someone who wants to do the conversion
japod@35
    58
    // 3. there is the API between 1. and 2. which allows them to communicate
japod@35
    59
    // 
japod@35
    60
    // Please backward compatibly enhance your existing API to support following
japod@35
    61
    // usecases:
japod@35
    62
    //
japod@35
    63
    
japod@35
    64
    /** Create convertor that understands two currencies, CZK and
japod@35
    65
     *  SKK. Make 100 SKK == 75 CZK. This is method for the group of users that
japod@35
    66
     *  knows the exchange rate, and needs to use the API to create objects
japod@35
    67
     *  with the exchange rate. Anyone shall be ready to call this method without
japod@35
    68
     *  any other method being called previously. The API itself shall know
japod@35
    69
     *  nothing about any rates, before this method is called.
japod@35
    70
     */
japod@35
    71
    public static Convertor createTripleConvertor() {
japod@35
    72
        // Rates: 1USD = 15CZK
japod@35
    73
        // Rates: 1USD = 20SKK
japod@35
    74
        // Rates: 75CZK = 100SKK
japod@35
    75
        Convertor c = ConvertorFactory.mergeConvertors(
japod@35
    76
            ConvertorFactory.getConvertor(USD, BigDecimal.ONE, CZK, BigDecimal.valueOf(15.00)),
japod@35
    77
            ConvertorFactory.getConvertor(USD, BigDecimal.ONE, SKK, BigDecimal.valueOf(20.00))
japod@35
    78
        );
japod@35
    79
        
japod@35
    80
        return c;
japod@35
    81
    }
japod@35
    82
japod@35
    83
    /** Define convertor that understands three currencies. Use it.
japod@35
    84
     */
japod@35
    85
    public void testConvertorForUSDandCZKandSKK() throws Exception {
japod@35
    86
        Convertor c = createTripleConvertor();
japod@35
    87
japod@35
    88
        // convert $5 to CZK using c:
japod@35
    89
        // assertEquals("Result is 75 CZK");
japod@35
    90
        assertEquals(new BigDecimal("75.00"), c.convert(USD, CZK, BigDecimal.valueOf(5.00)));
japod@35
    91
japod@35
    92
        // convert $5 to SKK using c:
japod@35
    93
        // assertEquals("Result is 100 SKK");
japod@35
    94
        assertEquals(new BigDecimal("100.00"), c.convert(USD, SKK, BigDecimal.valueOf(5.00)));
japod@35
    95
japod@35
    96
        // convert 200SKK to CZK using c:
japod@35
    97
        // assertEquals("Result is 150 CZK");
japod@35
    98
        assertEquals(new BigDecimal("150.00"), c.convert(SKK, CZK, BigDecimal.valueOf(200.00)));
japod@35
    99
japod@35
   100
        // convert 200SKK to USK using c:
japod@35
   101
        // assertEquals("Result is 10 USD");
japod@35
   102
        assertEquals(new BigDecimal("10.00"), c.convert(SKK, USD, BigDecimal.valueOf(200.00)));
japod@35
   103
    }
japod@35
   104
japod@35
   105
    /** Merge all currency rates of convertor 1 with convertor 2.
japod@35
   106
     * Implement this using your API, preferably this method just delegates
japod@35
   107
     * into some API method which does the actual work, without requiring
japod@35
   108
     * API clients to code anything complex.
japod@35
   109
     */
japod@35
   110
    public static Convertor merge(Convertor one, Convertor two) {
japod@35
   111
        return ConvertorFactory.mergeConvertors(one, two);
japod@35
   112
    }
japod@35
   113
japod@35
   114
    /** Join the convertors from previous task, Task1Test and show that it
japod@35
   115
     * can be used to do reasonable conversions.
japod@35
   116
     */
japod@35
   117
    public void testConvertorComposition() throws Exception {
japod@35
   118
        Convertor c = merge(
japod@35
   119
            Task1Test.createCZKtoUSD(),
japod@35
   120
            Task1Test.createSKKtoCZK()
japod@35
   121
        );
japod@35
   122
japod@35
   123
        // convert $5 to CZK using c:
japod@35
   124
        // assertEquals("Result is 85 CZK");
japod@35
   125
        assertEquals(new BigDecimal("85.00"), c.convert(USD, CZK, BigDecimal.valueOf(5.00)));
japod@35
   126
japod@35
   127
        // convert $8 to CZK using c:
japod@35
   128
        // assertEquals("Result is 136 CZK");
japod@35
   129
        assertEquals(new BigDecimal("136.00"), c.convert(USD, CZK, BigDecimal.valueOf(8.00)));
japod@35
   130
japod@35
   131
        // convert 1003CZK to USD using c:
japod@35
   132
        // assertEquals("Result is 59 USD");
japod@35
   133
        assertEquals(new BigDecimal("59.00"), c.convert(CZK, USD, BigDecimal.valueOf(1003.00)));
japod@35
   134
japod@35
   135
        // convert 16CZK using c:
japod@35
   136
        // assertEquals("Result is 20 SKK");
japod@35
   137
        assertEquals(new BigDecimal("20.00"), c.convert(CZK, SKK, BigDecimal.valueOf(16.00)));
japod@35
   138
japod@35
   139
        // convert 500SKK to CZK using c:
japod@35
   140
        // assertEquals("Result is 400 CZK");
japod@35
   141
        assertEquals(new BigDecimal("400.00"), c.convert(SKK, CZK, BigDecimal.valueOf(500.00)));
japod@35
   142
    }
japod@35
   143
    
japod@35
   144
    public void testGetCurrencies()
japod@35
   145
    {
japod@35
   146
        Convertor c = merge(
japod@35
   147
            Task1Test.createCZKtoUSD(),
japod@35
   148
            Task1Test.createSKKtoCZK()
japod@35
   149
        );
japod@35
   150
        Set<Currency> currencies;
japod@35
   151
        
japod@35
   152
        currencies = c.getCurrencies();        
japod@35
   153
        assertEquals(3, currencies.size());
japod@35
   154
        assertTrue(currencies.contains(Currency.getInstance("SKK")));
japod@35
   155
        assertTrue(currencies.contains(Currency.getInstance("CZK")));
japod@35
   156
        assertTrue(currencies.contains(Currency.getInstance("USD")));
japod@35
   157
    }
japod@35
   158
    
japod@35
   159
    public void testGetConverstionRate()
japod@35
   160
        throws InvalidConversionException
japod@35
   161
    {
japod@35
   162
        Convertor c = merge(
japod@35
   163
            Task1Test.createCZKtoUSD(),
japod@35
   164
            Task1Test.createSKKtoCZK()
japod@35
   165
        );
japod@35
   166
japod@35
   167
        assertEquals(1.0,        c.getConversionRate(USD, USD).doubleValue(), 0.0000000000000001);
japod@35
   168
        assertEquals(17.0,       c.getConversionRate(USD, CZK).doubleValue(), 0.0000000000000001);
japod@35
   169
        assertEquals(21.25,      c.getConversionRate(USD, SKK).doubleValue(), 0.0000000000000001);
japod@35
   170
japod@35
   171
        assertEquals(1.0 / 17.0, c.getConversionRate(CZK, USD).doubleValue(), 0.0000000000000001);
japod@35
   172
        assertEquals(1.0,        c.getConversionRate(CZK, CZK).doubleValue(), 0.0000000000000001);
japod@35
   173
        assertEquals(1.25,       c.getConversionRate(CZK, SKK).doubleValue(), 0.0000000000000001);
japod@35
   174
japod@35
   175
        assertEquals(0.04705882352941176, c.getConversionRate(SKK, USD).doubleValue(), 0.0000000000000001);
japod@35
   176
        assertEquals(0.8,                 c.getConversionRate(SKK, CZK).doubleValue(), 0.0000000000000001);
japod@35
   177
        assertEquals(1.0,                 c.getConversionRate(SKK, SKK).doubleValue(), 0.0000000000000001);
japod@35
   178
    }
japod@35
   179
}