# HG changeset patch # User japod@localhost # Date 1223669245 -7200 # Node ID a3144e7f9c9092571b1421e0ba1407a9a1fe6725 # Parent 14e78f48ac2b995e756b13a346792ecb76a4ebd0 solution02 task3 diff -r 14e78f48ac2b -r a3144e7f9c90 task3/solution02/src/org/apidesign/apifest08/currency/ConvertorFactory.java --- a/task3/solution02/src/org/apidesign/apifest08/currency/ConvertorFactory.java Fri Oct 10 22:05:15 2008 +0200 +++ b/task3/solution02/src/org/apidesign/apifest08/currency/ConvertorFactory.java Fri Oct 10 22:07:25 2008 +0200 @@ -17,7 +17,7 @@ * Creates {@link Convertor} that converts from sourceEquivalent.currency to destinationEquivalent.currency. * Exchange rate is set as equivalents. It means if you want to create USD to CZK convertor where USD1 = CZK17 * call createConvertor(new MoneyImpl(1, USD), new MoneyImpl(17, CZK)). Convertor created by this method - * rounds the result to two decimal places. + * rounds the result to two decimal places. Convertor created by this method is thread safe. * @param sourceEquivalent * @param destinationEquivalent * @return @@ -33,7 +33,7 @@ /** * Merges convertors. The resulting convertor has ability to do all conversions that its underlying * convertors could do. No consistency validation is done, inconsistent input will result in a convertor with - * inconsistent behavior. + * inconsistent behavior. Convertor created by this method is thread safe. * @param convertors * @return */ diff -r 14e78f48ac2b -r a3144e7f9c90 task3/solution02/test/org/apidesign/apifest08/test/OnlineConvertor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task3/solution02/test/org/apidesign/apifest08/test/OnlineConvertor.java Fri Oct 10 22:07:25 2008 +0200 @@ -0,0 +1,54 @@ +package org.apidesign.apifest08.test; + +import java.math.BigDecimal; +import java.util.Currency; + +import org.apidesign.apifest08.currency.ConvertorFactory; +import org.apidesign.apifest08.currency.ExtendedConvertor; +import org.apidesign.apifest08.currency.Money; +import org.apidesign.apifest08.currency.MoneyImpl; + +/** + * Third party implementation of the convertor. IT IS NOT THREAD SAFE. + * @author lukas + * + */ +class OnlineConvertor implements ExtendedConvertor { + + private static final BigDecimal LOWER_LIMIT = BigDecimal.valueOf(15); + private static final BigDecimal HIGHER_LIMIT = BigDecimal.valueOf(16); + + private static final Currency USD = Currency.getInstance("USD"); + private static final Currency CZK = Currency.getInstance("CZK"); + private static final MoneyImpl ONE_USD = new MoneyImpl(1,USD); + + private ExtendedConvertor wrappedConvertor = ConvertorFactory.createConvertor(ONE_USD, new MoneyImpl(16, CZK)); + + private BigDecimal increment = new BigDecimal("-0.01"); + + public boolean isConversionSupported(Currency from, Currency to) { + return wrappedConvertor.isConversionSupported(from, to); + } + + public Money convert(Money amount, Currency destinationCurrency) + throws IllegalArgumentException { + Money result = wrappedConvertor.convert(amount, destinationCurrency); + updateConvertor(); + return result; + } + + /** + * Prepares convertor for the next conversion. + */ + private void updateConvertor() { + BigDecimal currentRate = wrappedConvertor.convert(ONE_USD, CZK).getAmount(); + BigDecimal newRate = currentRate.add(increment); + + if (LOWER_LIMIT.compareTo(newRate)==0 || HIGHER_LIMIT.compareTo(newRate)==0) + { + increment = increment.negate(); + } + wrappedConvertor = ConvertorFactory.createConvertor(ONE_USD, new MoneyImpl(newRate, CZK)); + } + +} diff -r 14e78f48ac2b -r a3144e7f9c90 task3/solution02/test/org/apidesign/apifest08/test/OnlineConvertorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/task3/solution02/test/org/apidesign/apifest08/test/OnlineConvertorTest.java Fri Oct 10 22:07:25 2008 +0200 @@ -0,0 +1,44 @@ +package org.apidesign.apifest08.test; +import static junit.framework.Assert.assertEquals; +import static org.apidesign.apifest08.currency.MoneyImpl.money; +import static org.apidesign.apifest08.test.Task1Test.CZK; +import static org.apidesign.apifest08.test.Task1Test.USD; + +import java.math.BigDecimal; + +import org.apidesign.apifest08.currency.Convertor; +import org.apidesign.apifest08.currency.Money; +import org.junit.Test; + +public class OnlineConvertorTest { + private static final Money ONE_USD = money(1, USD); + + @Test + public void testBounce() + { + Convertor c = Task3Test.createOnlineCZKUSDConvertor(); + + doBounceTest(c); + doBounceTest(c); + + } + + private void doBounceTest(Convertor c) { + BigDecimal expectedRate = new BigDecimal(16); + BigDecimal increment = new BigDecimal("0.01"); + + for (int i=0;i<100;i++) + { + assertEquals(money(expectedRate,CZK), c.convert(ONE_USD, CZK)); + expectedRate = expectedRate.subtract(increment); + } + + assertEquals(money(15,CZK), c.convert(ONE_USD, CZK)); + + for (int i=0;i<99;i++) + { + expectedRate = expectedRate.add(increment); + assertEquals(money(expectedRate,CZK), c.convert(ONE_USD, CZK)); + } + } +} diff -r 14e78f48ac2b -r a3144e7f9c90 task3/solution02/test/org/apidesign/apifest08/test/Task3Test.java --- a/task3/solution02/test/org/apidesign/apifest08/test/Task3Test.java Fri Oct 10 22:05:15 2008 +0200 +++ b/task3/solution02/test/org/apidesign/apifest08/test/Task3Test.java Fri Oct 10 22:07:25 2008 +0200 @@ -1,6 +1,11 @@ package org.apidesign.apifest08.test; +import static org.apidesign.apifest08.currency.MoneyImpl.money; +import static org.apidesign.apifest08.test.Task1Test.CZK; +import static org.apidesign.apifest08.test.Task1Test.SKK; +import static org.apidesign.apifest08.test.Task1Test.USD; import junit.framework.TestCase; + import org.apidesign.apifest08.currency.Convertor; /** The exchange rates are not always the same. They are changing. Day by day, @@ -51,42 +56,33 @@ // then 1USD = 15.02CZK // and so on and on up to 1USD = 16CZK // and then another round to 15, etc. - return null; + return new OnlineConvertor(); } public void testFewQueriesForOnlineConvertor() { - if (Boolean.getBoolean("ignore.failing")) { - // implement me! - return; - } - Convertor c = createOnlineCZKUSDConvertor(); doFewQueriesForOnlineConvertor(c); } static void doFewQueriesForOnlineConvertor(Convertor c) { // convert $5 to CZK using c: - //assertEquals("Result is 80 CZK"); + assertEquals("Result is 80 CZK", money(80,CZK), c.convert(money(5,USD), CZK)); // convert $8 to CZK using c: - //assertEquals("Result is 127.92 CZK"); + assertEquals("Result is 127.92 CZK", money(127.92,CZK), c.convert(money(8,USD), CZK)); // convert $1 to CZK using c: - //assertEquals("Result is 15.98 CZK"); + assertEquals("Result is 15.98 CZK", money(15.98,CZK), c.convert(money(1,USD), CZK)); // convert 15.97CZK to USD using c: + assertEquals("Result is 1 USD", money(1,USD), c.convert(money(15.97,CZK), USD)); //assertEquals("Result is 1$"); - fail("Implement me!"); } /** Join the convertors and show they behave sane. */ public void testOnlineConvertorComposition() throws Exception { - if (Boolean.getBoolean("ignore.failing")) { - // implement me! - return; - } Convertor c = Task2Test.merge( createOnlineCZKUSDConvertor(), @@ -94,10 +90,10 @@ ); // convert 16CZK to SKK using c: - // assertEquals("Result is 20 SKK"); + assertEquals("Result is 20 SKK", money(20,SKK), c.convert(money(16,CZK), SKK)); // convert 500SKK to CZK using c: - // assertEquals("Result is 400 CZK"); + assertEquals("Result is 400 CZK", money(400,CZK), c.convert(money(500,SKK), CZK)); doFewQueriesForOnlineConvertor(c); }