japod@35: package org.apidesign.apifest08.test; japod@35: japod@35: import java.math.BigDecimal; japod@35: import java.util.Currency; japod@35: import java.util.Set; japod@35: import junit.framework.TestCase; japod@35: import org.apidesign.apifest08.currency.Convertor; japod@35: import org.apidesign.apifest08.currency.ConvertorFactory; japod@35: import org.apidesign.apifest08.currency.InvalidConversionException; japod@35: japod@35: japod@35: /** There are many currencies around the world and many banks manipulate japod@35: * with more than one or two at the same time. As banks are usually the japod@35: * best paying clients, which is true even in case of your Convertor API, japod@35: * it is reasonable to listen to their requests. japod@35: *
japod@35: * The quest for today is to enhance your existing convertor API to hold
japod@35: * information about many currencies and allow conversions between any of them.
japod@35: * Also, as conversion rates for diferent currencies usually arise from various
japod@35: * bank departments, there is another important need. There is a need to
japod@35: * compose two convertors into one by merging all the information about
japod@35: * currencies they know about.
japod@35: */
japod@35: public class Task2Test extends TestCase
japod@35: {
japod@35: private final static Currency CZK;
japod@35: private final static Currency SKK;
japod@35: private final static Currency USD;
japod@35:
japod@35: static
japod@35: {
japod@35: CZK = Currency.getInstance("CZK");
japod@35: SKK = Currency.getInstance("SKK");
japod@35: USD = Currency.getInstance("USD");
japod@35: }
japod@35:
japod@35: public Task2Test(String testName)
japod@35: {
japod@35: super(testName);
japod@35: }
japod@35:
japod@35: @Override
japod@35: protected void setUp()
japod@35: throws Exception
japod@35: {
japod@35: }
japod@35:
japod@35: @Override
japod@35: protected void tearDown()
japod@35: throws Exception
japod@35: {
japod@35: }
japod@35:
japod@35: // As in Task1Test, keep in mind, that there are three parts
japod@35: // of the whole system:
japod@35: // 1. there is someone who knows the current exchange rate
japod@35: // 2. there is someone who wants to do the conversion
japod@35: // 3. there is the API between 1. and 2. which allows them to communicate
japod@35: //
japod@35: // Please backward compatibly enhance your existing API to support following
japod@35: // usecases:
japod@35: //
japod@35:
japod@35: /** Create convertor that understands two currencies, CZK and
japod@35: * SKK. Make 100 SKK == 75 CZK. This is method for the group of users that
japod@35: * knows the exchange rate, and needs to use the API to create objects
japod@35: * with the exchange rate. Anyone shall be ready to call this method without
japod@35: * any other method being called previously. The API itself shall know
japod@35: * nothing about any rates, before this method is called.
japod@35: */
japod@35: public static Convertor createTripleConvertor() {
japod@35: // Rates: 1USD = 15CZK
japod@35: // Rates: 1USD = 20SKK
japod@35: // Rates: 75CZK = 100SKK
japod@35: Convertor c = ConvertorFactory.mergeConvertors(
japod@35: ConvertorFactory.getConvertor(USD, BigDecimal.ONE, CZK, BigDecimal.valueOf(15.00)),
japod@35: ConvertorFactory.getConvertor(USD, BigDecimal.ONE, SKK, BigDecimal.valueOf(20.00))
japod@35: );
japod@35:
japod@35: return c;
japod@35: }
japod@35:
japod@35: /** Define convertor that understands three currencies. Use it.
japod@35: */
japod@35: public void testConvertorForUSDandCZKandSKK() throws Exception {
japod@35: Convertor c = createTripleConvertor();
japod@35:
japod@35: // convert $5 to CZK using c:
japod@35: // assertEquals("Result is 75 CZK");
japod@35: assertEquals(new BigDecimal("75.00"), c.convert(USD, CZK, BigDecimal.valueOf(5.00)));
japod@35:
japod@35: // convert $5 to SKK using c:
japod@35: // assertEquals("Result is 100 SKK");
japod@35: assertEquals(new BigDecimal("100.00"), c.convert(USD, SKK, BigDecimal.valueOf(5.00)));
japod@35:
japod@35: // convert 200SKK to CZK using c:
japod@35: // assertEquals("Result is 150 CZK");
japod@35: assertEquals(new BigDecimal("150.00"), c.convert(SKK, CZK, BigDecimal.valueOf(200.00)));
japod@35:
japod@35: // convert 200SKK to USK using c:
japod@35: // assertEquals("Result is 10 USD");
japod@35: assertEquals(new BigDecimal("10.00"), c.convert(SKK, USD, BigDecimal.valueOf(200.00)));
japod@35: }
japod@35:
japod@35: /** Merge all currency rates of convertor 1 with convertor 2.
japod@35: * Implement this using your API, preferably this method just delegates
japod@35: * into some API method which does the actual work, without requiring
japod@35: * API clients to code anything complex.
japod@35: */
japod@35: public static Convertor merge(Convertor one, Convertor two) {
japod@35: return ConvertorFactory.mergeConvertors(one, two);
japod@35: }
japod@35:
japod@35: /** Join the convertors from previous task, Task1Test and show that it
japod@35: * can be used to do reasonable conversions.
japod@35: */
japod@35: public void testConvertorComposition() throws Exception {
japod@35: Convertor c = merge(
japod@35: Task1Test.createCZKtoUSD(),
japod@35: Task1Test.createSKKtoCZK()
japod@35: );
japod@35:
japod@35: // convert $5 to CZK using c:
japod@35: // assertEquals("Result is 85 CZK");
japod@35: assertEquals(new BigDecimal("85.00"), c.convert(USD, CZK, BigDecimal.valueOf(5.00)));
japod@35:
japod@35: // convert $8 to CZK using c:
japod@35: // assertEquals("Result is 136 CZK");
japod@35: assertEquals(new BigDecimal("136.00"), c.convert(USD, CZK, BigDecimal.valueOf(8.00)));
japod@35:
japod@35: // convert 1003CZK to USD using c:
japod@35: // assertEquals("Result is 59 USD");
japod@35: assertEquals(new BigDecimal("59.00"), c.convert(CZK, USD, BigDecimal.valueOf(1003.00)));
japod@35:
japod@35: // convert 16CZK using c:
japod@35: // assertEquals("Result is 20 SKK");
japod@35: assertEquals(new BigDecimal("20.00"), c.convert(CZK, SKK, BigDecimal.valueOf(16.00)));
japod@35:
japod@35: // convert 500SKK to CZK using c:
japod@35: // assertEquals("Result is 400 CZK");
japod@35: assertEquals(new BigDecimal("400.00"), c.convert(SKK, CZK, BigDecimal.valueOf(500.00)));
japod@35: }
japod@35:
japod@35: public void testGetCurrencies()
japod@35: {
japod@35: Convertor c = merge(
japod@35: Task1Test.createCZKtoUSD(),
japod@35: Task1Test.createSKKtoCZK()
japod@35: );
japod@35: Set