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