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 }