task4/solution07/test/org/apidesign/apifest08/test/Task1Test.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 11 Oct 2008 23:38:46 +0200
changeset 61 58ec6da75f6f
parent 45 task3/solution07/test/org/apidesign/apifest08/test/Task1Test.java@251d0ed461fb
permissions -rw-r--r--
Copying structure for task4
japod@6
     1
package org.apidesign.apifest08.test;
japod@6
     2
japod@6
     3
import java.util.Currency;
japod@6
     4
import junit.framework.TestCase;
japod@6
     5
import org.apidesign.apifest08.currency.ConversionRate;
japod@6
     6
import org.apidesign.apifest08.currency.Convertor;
japod@6
     7
import org.apidesign.apifest08.currency.MonetaryAmount;
japod@6
     8
import org.apidesign.apifest08.currency.TableConvertor;
japod@6
     9
japod@6
    10
/** Finish the Convertor API, and then write bodies of methods inside
japod@6
    11
 * of this class to match the given tasks. To fullfil your task, use the
japod@6
    12
 * API define in the <code>org.apidesign.apifest08.currency</code> package.
japod@6
    13
 * Do not you reflection, or other hacks as your code
japod@6
    14
 * shall run without any runtime permissions.
japod@6
    15
 */
japod@6
    16
public class Task1Test extends TestCase {
japod@6
    17
    public Task1Test(String testName) {
japod@6
    18
        super(testName);
japod@6
    19
    }
japod@6
    20
japod@6
    21
    @Override
japod@6
    22
    protected void setUp() throws Exception {
japod@6
    23
    }
japod@6
    24
japod@6
    25
    @Override
japod@6
    26
    protected void tearDown() throws Exception {
japod@6
    27
    }
japod@6
    28
japod@18
    29
    //
japod@18
    30
    // Imagine that there are three parts of the whole system:
japod@18
    31
    // 1. there is someone who knows the current exchange rate
japod@18
    32
    // 2. there is someone who wants to do the conversion
japod@18
    33
    // 3. there is the API between 1. and 2. which allows them to communicate
japod@18
    34
    // Please design such API
japod@18
    35
    //
japod@18
    36
japod@6
    37
    protected static final Currency CZK = Currency.getInstance( "CZK" );
japod@6
    38
    protected static final Currency SKK = Currency.getInstance( "SKK" );
japod@6
    39
    protected static final Currency USD = Currency.getInstance( "USD" );
japod@6
    40
    
japod@6
    41
    /** Create convertor that understands two currencies, CZK and
japod@6
    42
     *  USD. Make 1 USD == 17 CZK.
japod@18
    43
     *  USD. Make 1 USD == 17 CZK. This is a method provided for #1 group -
japod@18
    44
     *  e.g. those that know the exchange rate. They somehow need to create
japod@18
    45
     *  the objects from the API and tell them the exchange rate. The API itself
japod@18
    46
     *  knows nothing about any rates, before the createCZKtoUSD method is called.
japod@6
    47
     *
japod@6
    48
     * Creation of the convertor shall not require subclassing of any class
japod@6
    49
     * or interface on the client side.
japod@6
    50
     *
japod@6
    51
     * @return prepared convertor ready for converting USD to CZK and CZK to USD
japod@6
    52
     */
japod@6
    53
    public static Convertor createCZKtoUSD() {
japod@6
    54
        final TableConvertor convertor = new TableConvertor();
japod@6
    55
        final MonetaryAmount amountInCZK = new MonetaryAmount( 17, CZK );
japod@6
    56
        final MonetaryAmount amountInUSD = new MonetaryAmount( 1, USD );
japod@6
    57
        convertor.putIntoTable( new ConversionRate( amountInCZK, amountInUSD ) );
japod@6
    58
        convertor.putIntoTable( new ConversionRate( amountInUSD, amountInCZK ) );
japod@6
    59
        return new ContractImposingDelegatingConvertor( convertor ).test();
japod@6
    60
    }
japod@6
    61
japod@6
    62
    /** Create convertor that understands two currencies, CZK and
japod@18
    63
     *  SKK. Make 100 SKK == 80 CZK. Again this is method for the #1 group -
japod@18
    64
     *  it knows the exchange rate, and needs to use the API to create objects
japod@18
    65
     *  with the exchange rate. Anyone shall be ready to call this method without
japod@18
    66
     *  any other method being called previously. The API itself shall know
japod@18
    67
     *  nothing about any rates, before this method is called.
japod@6
    68
     *
japod@6
    69
     * Creation of the convertor shall not require subclassing of any class
japod@6
    70
     * or interface on the client side.
japod@6
    71
     * 
japod@6
    72
     * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
japod@6
    73
     */
japod@6
    74
    public static Convertor createSKKtoCZK() {
japod@6
    75
        final TableConvertor convertor = new TableConvertor();
japod@6
    76
        final MonetaryAmount amountInSKK = new MonetaryAmount( 100, SKK );
japod@6
    77
        final MonetaryAmount amountInCZK = new MonetaryAmount( 80, CZK );
japod@6
    78
        convertor.putIntoTable( new ConversionRate( amountInSKK, amountInCZK ) );
japod@6
    79
        convertor.putIntoTable( new ConversionRate( amountInCZK, amountInSKK ) );
japod@6
    80
        return new ContractImposingDelegatingConvertor( convertor ).test();
japod@6
    81
    }
japod@6
    82
japod@18
    83
    //
japod@18
    84
    // now the methods for group #2 follow:
japod@18
    85
    // this group knows nothing about exchange rates, but knows how to use
japod@18
    86
    // the API to do conversions. It somehow (by calling one of the factory
japod@18
    87
    // methods) gets objects from the API and uses them to do the conversions.
japod@18
    88
    //
japod@18
    89
japod@6
    90
    /** Use the convertor from <code>createCZKtoUSD</code> method and do few conversions
japod@6
    91
     * with it.
japod@6
    92
     */
japod@6
    93
    public void testCurrencyCZKUSD() throws Exception {
japod@6
    94
        final Convertor c = createCZKtoUSD();
japod@6
    95
        
japod@6
    96
        // convert $5 to CZK using c:
japod@6
    97
        final Convertor.ConversionResult r1 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 5, USD ), CZK ) );
japod@6
    98
        final MonetaryAmount a1 = r1.getNetAmount();
japod@6
    99
        // assertEquals("Result is 85 CZK");
japod@6
   100
        assertNotNull( a1 );
japod@6
   101
        assertEquals( 85.0, a1.getAmount().doubleValue() );
japod@6
   102
        assertEquals( CZK, a1.getCurrency() );
japod@6
   103
japod@6
   104
        // convert $8 to CZK
japod@6
   105
        final Convertor.ConversionResult r2 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 8, USD ), CZK ) );
japod@6
   106
        final MonetaryAmount a2 = r2.getNetAmount();
japod@6
   107
        // assertEquals("Result is 136 CZK");
japod@6
   108
        assertNotNull( a2 );
japod@6
   109
        assertEquals( 136.0, a2.getAmount().doubleValue() );
japod@6
   110
        assertEquals( CZK, a2.getCurrency() );
japod@6
   111
japod@6
   112
        // convert 1003CZK to USD
japod@6
   113
        final Convertor.ConversionResult r3 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 1003, CZK ), USD ) );
japod@6
   114
        final MonetaryAmount a3 = r3.getNetAmount();
japod@6
   115
        // assertEquals("Result is 59 USD");
japod@6
   116
        assertNotNull( a3 );
japod@6
   117
        assertEquals( 59.0, a3.getAmount().doubleValue() );
japod@6
   118
        assertEquals( USD, a3.getCurrency() );
japod@6
   119
    }
japod@6
   120
japod@6
   121
    /** Use the convertor from <code>createSKKtoCZK</code> method and do few conversions
japod@6
   122
     * with it.
japod@6
   123
     */
japod@6
   124
    public void testCurrencySKKCZK() throws Exception {
japod@6
   125
        final Convertor c = createSKKtoCZK();
japod@6
   126
        
japod@6
   127
        // convert 16CZK using c:
japod@6
   128
        final Convertor.ConversionResult r1 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 16, CZK ), SKK ) );
japod@6
   129
        final MonetaryAmount a1 = r1.getNetAmount();
japod@6
   130
        // assertEquals("Result is 20 SKK");
japod@6
   131
        assertNotNull( a1 );
japod@6
   132
        assertEquals( 20.0, a1.getAmount().doubleValue() );
japod@6
   133
        assertEquals( SKK, a1.getCurrency() );
japod@6
   134
        
japod@6
   135
        // convert 500SKK to CZK
japod@6
   136
        final Convertor.ConversionResult r2 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 500, SKK ), CZK ) );
japod@6
   137
        final MonetaryAmount a2 = r2.getNetAmount();
japod@6
   138
        // assertEquals("Result is 400 CZK");
japod@6
   139
        assertNotNull( a2 );
japod@6
   140
        assertEquals( 400.0, a2.getAmount().doubleValue() );
japod@6
   141
        assertEquals( CZK, a2.getCurrency() );
japod@6
   142
    }
japod@6
   143
japod@18
   144
    /** Verify that the CZK to USD convertor knows nothing about SKK.
japod@18
   145
    */
japod@18
   146
    public void testCannotConvertToSKKwithCZKUSDConvertor() throws Exception {
japod@18
   147
        final Convertor c = createCZKtoUSD();
japod@18
   148
        
japod@18
   149
        // convert $5 to SKK, the API shall say this is not possible
japod@18
   150
        final Convertor.ConversionResult r1 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 5, USD ), SKK ) );
japod@18
   151
        final MonetaryAmount a1 = r1.getNetAmount();
japod@18
   152
        assertNull( a1 );
japod@18
   153
japod@18
   154
        // convert 500 SKK to CZK, the API shall say this is not possible
japod@18
   155
        final Convertor.ConversionResult r2 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 5, SKK ), CZK ) );
japod@18
   156
        final MonetaryAmount a2 = r2.getNetAmount();
japod@18
   157
        assertNull( a2 );
japod@18
   158
    }
japod@18
   159
japod@18
   160
    /** Verify that the CZK to SKK convertor knows nothing about USD.
japod@18
   161
    */
japod@18
   162
    public void testCannotConvertToUSDwithCZKSKKConvertor() throws Exception {
japod@18
   163
        final Convertor c = createSKKtoCZK();
japod@18
   164
        
japod@18
   165
        // convert $5 to SKK, the API shall say this is not possible
japod@18
   166
        final Convertor.ConversionResult r1 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 5, USD ), SKK ) );
japod@18
   167
        final MonetaryAmount a1 = r1.getNetAmount();
japod@18
   168
        assertNull( a1 );
japod@18
   169
        
japod@18
   170
        // convert 500 CZK to USD, the API shall say this is not possible
japod@18
   171
        final Convertor.ConversionResult r2 = c.convert( new Convertor.ConversionRequest( new MonetaryAmount( 5, CZK ), USD ) );
japod@18
   172
        final MonetaryAmount a2 = r2.getNetAmount();
japod@18
   173
        assertNull( a2 );
japod@18
   174
    }
japod@18
   175
japod@6
   176
}
japod@6
   177