solution02 task3
authorjapod@localhost
Fri, 10 Oct 2008 22:07:25 +0200
changeset 56a3144e7f9c90
parent 55 14e78f48ac2b
child 57 be49855c7fa2
solution02 task3
task3/solution02/src/org/apidesign/apifest08/currency/ConvertorFactory.java
task3/solution02/test/org/apidesign/apifest08/test/OnlineConvertor.java
task3/solution02/test/org/apidesign/apifest08/test/OnlineConvertorTest.java
task3/solution02/test/org/apidesign/apifest08/test/Task3Test.java
     1.1 --- a/task3/solution02/src/org/apidesign/apifest08/currency/ConvertorFactory.java	Fri Oct 10 22:05:15 2008 +0200
     1.2 +++ b/task3/solution02/src/org/apidesign/apifest08/currency/ConvertorFactory.java	Fri Oct 10 22:07:25 2008 +0200
     1.3 @@ -17,7 +17,7 @@
     1.4  	 * Creates {@link Convertor} that converts from sourceEquivalent.currency to destinationEquivalent.currency. 
     1.5  	 * Exchange rate is set as equivalents. It means if you want to create USD to CZK convertor where USD1 = CZK17 
     1.6       * call createConvertor(new MoneyImpl(1, USD), new MoneyImpl(17, CZK)). Convertor created by this method 
     1.7 -     * rounds the result to two decimal places.
     1.8 +     * rounds the result to two decimal places. Convertor created by this method is thread safe.
     1.9  	 * @param sourceEquivalent
    1.10  	 * @param destinationEquivalent
    1.11  	 * @return
    1.12 @@ -33,7 +33,7 @@
    1.13  	/**
    1.14  	 * Merges convertors. The resulting convertor has ability to do all conversions that its underlying 
    1.15  	 * convertors could do. No consistency validation is done, inconsistent input will result in a convertor with
    1.16 -	 * inconsistent behavior.
    1.17 +	 * inconsistent behavior. Convertor created by this method is thread safe.
    1.18  	 * @param convertors
    1.19  	 * @return
    1.20  	 */
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/task3/solution02/test/org/apidesign/apifest08/test/OnlineConvertor.java	Fri Oct 10 22:07:25 2008 +0200
     2.3 @@ -0,0 +1,54 @@
     2.4 +package org.apidesign.apifest08.test;
     2.5 +
     2.6 +import java.math.BigDecimal;
     2.7 +import java.util.Currency;
     2.8 +
     2.9 +import org.apidesign.apifest08.currency.ConvertorFactory;
    2.10 +import org.apidesign.apifest08.currency.ExtendedConvertor;
    2.11 +import org.apidesign.apifest08.currency.Money;
    2.12 +import org.apidesign.apifest08.currency.MoneyImpl;
    2.13 +
    2.14 +/**
    2.15 + * Third party implementation of the convertor. IT IS NOT THREAD SAFE.
    2.16 + * @author lukas
    2.17 + *
    2.18 + */
    2.19 +class OnlineConvertor implements ExtendedConvertor {
    2.20 +	
    2.21 +	private static final BigDecimal LOWER_LIMIT = BigDecimal.valueOf(15);
    2.22 +	private static final BigDecimal HIGHER_LIMIT = BigDecimal.valueOf(16);
    2.23 +	
    2.24 +	private static final Currency USD = Currency.getInstance("USD");
    2.25 +	private static final Currency CZK = Currency.getInstance("CZK");
    2.26 +	private static final MoneyImpl ONE_USD = new MoneyImpl(1,USD);
    2.27 +	
    2.28 +	private ExtendedConvertor wrappedConvertor = ConvertorFactory.createConvertor(ONE_USD, new MoneyImpl(16, CZK));
    2.29 +	
    2.30 +	private BigDecimal increment = new BigDecimal("-0.01");
    2.31 +	
    2.32 +	public boolean isConversionSupported(Currency from, Currency to) {
    2.33 +		return wrappedConvertor.isConversionSupported(from, to);
    2.34 +	}
    2.35 +
    2.36 +	public Money convert(Money amount, Currency destinationCurrency)
    2.37 +			throws IllegalArgumentException {
    2.38 +		Money result = wrappedConvertor.convert(amount, destinationCurrency);
    2.39 +		updateConvertor();
    2.40 +		return result;
    2.41 +	}
    2.42 +
    2.43 +	/**
    2.44 +	 * Prepares convertor for the next conversion.
    2.45 +	 */
    2.46 +	private void updateConvertor() {
    2.47 +		BigDecimal currentRate = wrappedConvertor.convert(ONE_USD, CZK).getAmount();
    2.48 +		BigDecimal newRate = currentRate.add(increment);
    2.49 +		
    2.50 +		if (LOWER_LIMIT.compareTo(newRate)==0 || HIGHER_LIMIT.compareTo(newRate)==0)
    2.51 +		{
    2.52 +			increment = increment.negate();
    2.53 +		}
    2.54 +		wrappedConvertor = ConvertorFactory.createConvertor(ONE_USD, new MoneyImpl(newRate, CZK));
    2.55 +	}
    2.56 +
    2.57 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/task3/solution02/test/org/apidesign/apifest08/test/OnlineConvertorTest.java	Fri Oct 10 22:07:25 2008 +0200
     3.3 @@ -0,0 +1,44 @@
     3.4 +package org.apidesign.apifest08.test;
     3.5 +import static junit.framework.Assert.assertEquals;
     3.6 +import static org.apidesign.apifest08.currency.MoneyImpl.money;
     3.7 +import static org.apidesign.apifest08.test.Task1Test.CZK;
     3.8 +import static org.apidesign.apifest08.test.Task1Test.USD;
     3.9 +
    3.10 +import java.math.BigDecimal;
    3.11 +
    3.12 +import org.apidesign.apifest08.currency.Convertor;
    3.13 +import org.apidesign.apifest08.currency.Money;
    3.14 +import org.junit.Test;
    3.15 +
    3.16 +public class OnlineConvertorTest {
    3.17 +	private static final Money ONE_USD = money(1, USD);
    3.18 +
    3.19 +	@Test
    3.20 +	public void testBounce()
    3.21 +	{
    3.22 +		Convertor c = Task3Test.createOnlineCZKUSDConvertor();
    3.23 +		
    3.24 +		doBounceTest(c);
    3.25 +		doBounceTest(c);
    3.26 +	
    3.27 +	}
    3.28 +
    3.29 +	private void doBounceTest(Convertor c) {
    3.30 +		BigDecimal expectedRate = new BigDecimal(16);
    3.31 +		BigDecimal increment = new BigDecimal("0.01");
    3.32 +		
    3.33 +		for (int i=0;i<100;i++)
    3.34 +		{
    3.35 +			assertEquals(money(expectedRate,CZK), c.convert(ONE_USD, CZK));
    3.36 +			expectedRate = expectedRate.subtract(increment);
    3.37 +		}
    3.38 +		
    3.39 +		assertEquals(money(15,CZK), c.convert(ONE_USD, CZK));
    3.40 +		
    3.41 +		for (int i=0;i<99;i++)
    3.42 +		{
    3.43 +			expectedRate = expectedRate.add(increment);
    3.44 +			assertEquals(money(expectedRate,CZK), c.convert(ONE_USD, CZK));
    3.45 +		}
    3.46 +	}
    3.47 +}
     4.1 --- a/task3/solution02/test/org/apidesign/apifest08/test/Task3Test.java	Fri Oct 10 22:05:15 2008 +0200
     4.2 +++ b/task3/solution02/test/org/apidesign/apifest08/test/Task3Test.java	Fri Oct 10 22:07:25 2008 +0200
     4.3 @@ -1,6 +1,11 @@
     4.4  package org.apidesign.apifest08.test;
     4.5  
     4.6 +import static org.apidesign.apifest08.currency.MoneyImpl.money;
     4.7 +import static org.apidesign.apifest08.test.Task1Test.CZK;
     4.8 +import static org.apidesign.apifest08.test.Task1Test.SKK;
     4.9 +import static org.apidesign.apifest08.test.Task1Test.USD;
    4.10  import junit.framework.TestCase;
    4.11 +
    4.12  import org.apidesign.apifest08.currency.Convertor;
    4.13  
    4.14  /** The exchange rates are not always the same. They are changing. Day by day,
    4.15 @@ -51,42 +56,33 @@
    4.16          // then 1USD = 15.02CZK
    4.17          // and so on and on up to 1USD = 16CZK
    4.18          // and then another round to 15, etc.
    4.19 -        return null;
    4.20 +        return new OnlineConvertor();
    4.21      }
    4.22  
    4.23      public void testFewQueriesForOnlineConvertor() {
    4.24 -        if (Boolean.getBoolean("ignore.failing")) {
    4.25 -            // implement me!
    4.26 -            return;
    4.27 -        }
    4.28 -
    4.29          Convertor c = createOnlineCZKUSDConvertor();
    4.30          doFewQueriesForOnlineConvertor(c);
    4.31      }
    4.32  
    4.33      static void doFewQueriesForOnlineConvertor(Convertor c) {
    4.34          // convert $5 to CZK using c:
    4.35 -        //assertEquals("Result is 80 CZK");
    4.36 +        assertEquals("Result is 80 CZK", money(80,CZK), c.convert(money(5,USD), CZK));
    4.37  
    4.38          // convert $8 to CZK using c:
    4.39 -        //assertEquals("Result is 127.92 CZK");
    4.40 +        assertEquals("Result is 127.92 CZK", money(127.92,CZK), c.convert(money(8,USD), CZK));
    4.41  
    4.42          // convert $1 to CZK using c:
    4.43 -        //assertEquals("Result is 15.98 CZK");
    4.44 +        assertEquals("Result is 15.98 CZK", money(15.98,CZK), c.convert(money(1,USD), CZK));
    4.45  
    4.46          // convert 15.97CZK to USD using c:
    4.47 +        assertEquals("Result is 1 USD", money(1,USD), c.convert(money(15.97,CZK), USD));
    4.48          //assertEquals("Result is 1$");
    4.49  
    4.50 -        fail("Implement me!");
    4.51      }
    4.52  
    4.53      /** Join the convertors and show they behave sane.
    4.54       */
    4.55      public void testOnlineConvertorComposition() throws Exception {
    4.56 -        if (Boolean.getBoolean("ignore.failing")) {
    4.57 -            // implement me!
    4.58 -            return;
    4.59 -        }
    4.60          
    4.61          Convertor c = Task2Test.merge(
    4.62              createOnlineCZKUSDConvertor(),
    4.63 @@ -94,10 +90,10 @@
    4.64          );
    4.65  
    4.66          // convert 16CZK to SKK using c:
    4.67 -        // assertEquals("Result is 20 SKK");
    4.68 +        assertEquals("Result is 20 SKK", money(20,SKK), c.convert(money(16,CZK), SKK));
    4.69  
    4.70          // convert 500SKK to CZK using c:
    4.71 -        // assertEquals("Result is 400 CZK");
    4.72 +        assertEquals("Result is 400 CZK", money(400,CZK), c.convert(money(500,SKK), CZK));
    4.73  
    4.74          doFewQueriesForOnlineConvertor(c);
    4.75      }