1 package org.apidesign.apifest08.test;
3 import java.math.BigDecimal;
4 import java.math.RoundingMode;
6 import junit.framework.TestCase;
7 import org.apidesign.apifest08.currency.Convertor;
8 import static org.apidesign.apifest08.test.Currencies.*;
10 /** The exchange rates are not always the same. They are changing. Day by day,
11 * hour by hour, minute by minute. For every bank it is important to always
12 * have the actual exchange rate available in the system. That is why let's
13 * create a pluggable convertor that will always have up to date value of its
16 * The quest for today is to allow 3rd party developer to write a convertor
17 * that adjusts its exchange rate everytime it is queried. This convertor is
18 * written by independent vendor, the vendor knows only your Convertor API,
19 * he does not know how the whole system looks and how the convertor is supposed
22 public class Task3Test extends TestCase {
23 public Task3Test(String testName) {
28 protected void setUp() throws Exception {
32 protected void tearDown() throws Exception {
35 // Backward compatibly enhance your existing API to support following
40 /** Without knowing anything about the surrounding system, write an
41 * implementation of convertor that will return different rates everytime
42 * it is queried. Convert USD to CZK and vice versa. Start with the rate of
43 * 1USD = 16CZK and adjust it in favor of CZK by 0.01 CZK with every query.
44 * As soon as you reach 1USD = 15CZK adjust it by 0.01 CZK in favor of USD
45 * until you reach 1USD = 16CZK
47 * @return new instance of "online" USD and CZK convertor starting with rate 1USD = 16CZK
49 public static Convertor createOnlineCZKUSDConvertor() {
50 Convertor.RateProvider rateProvider = new Convertor.RateProvider() {
51 private BigDecimal seed = new BigDecimal("16.01").setScale(2);
54 public BigDecimal getRate() {
55 if(seed.equals(new BigDecimal("15").setScale(2))) {
56 seed = seed.add(new BigDecimal("0.01")).setScale(2);
58 seed = seed.subtract(new BigDecimal("0.01")).setScale(2);
65 // initial rate: 1USD = 16CZK
66 // 2nd query 1USD = 15.99CZK
67 // 3rd query 1USD = 15.98CZK
68 // until 1USD = 15.00CZK
69 // then 1USD = 15.01CZK
70 // then 1USD = 15.02CZK
71 // and so on and on up to 1USD = 16CZK
72 // and then another round to 15, etc.
73 return new Convertor(rateProvider, USD, CZK);
76 public void testFewQueriesForOnlineConvertor() {
77 Convertor c = createOnlineCZKUSDConvertor();
78 doFewQueriesForOnlineConvertor(c);
81 static void doFewQueriesForOnlineConvertor(Convertor c) {
82 // convert $5 to CZK using c:
83 assertEquals("Result is 80 CZK",80 ,c.convert(new BigDecimal(5), USD, CZK).getValue().intValue());
85 // convert $8 to CZK using c:
86 assertEquals("Result is 127.92 CZK", 127.92d , c.convert(new BigDecimal(8), USD, CZK).getValue().doubleValue());
88 // convert $1 to CZK using c:
89 assertEquals("Result is 15.98 CZK", 15.98d, c.convert(new BigDecimal(1), USD, CZK).getValue().doubleValue());
91 // convert 15.97CZK to USD using c:
92 assertEquals("Result is 1$", 1, c.convert(new BigDecimal("15.97").setScale(2), CZK, USD).getValue().intValue());
95 /** Join the convertors and show they behave sane.
97 public void testOnlineConvertorComposition() throws Exception {
98 Convertor c = Task2Test.merge(
99 createOnlineCZKUSDConvertor(),
100 Task1Test.createSKKtoCZK()
103 // convert 16CZK to SKK using c:
104 assertEquals("Result is 20 SKK", 20, c.convert(new BigDecimal(16), CZK, SKK).getValue().intValue());
106 // convert 500SKK to CZK using c:
107 assertEquals("Result is 400 CZK", 400, c.convert(new BigDecimal(500), SKK, CZK).getValue().intValue());
109 doFewQueriesForOnlineConvertor(c);