1.1 --- a/task2/solution14/src/org/apidesign/apifest08/currency/Convertor.java Tue Oct 07 11:19:36 2008 +0200
1.2 +++ b/task2/solution14/src/org/apidesign/apifest08/currency/Convertor.java Wed Oct 08 12:51:52 2008 +0200
1.3 @@ -1,5 +1,12 @@
1.4 package org.apidesign.apifest08.currency;
1.5
1.6 +import java.util.ArrayList;
1.7 +import java.util.Collection;
1.8 +import java.util.Collections;
1.9 +import java.util.HashSet;
1.10 +import java.util.List;
1.11 +import java.util.Set;
1.12 +
1.13 /** This is the skeleton class for your API. You need to make it public, so
1.14 * it is accessible to your client code (currently in Task1Test.java) file.
1.15 * <p>
1.16 @@ -8,12 +15,21 @@
1.17 * to other packages.
1.18 */
1.19 public final class Convertor {
1.20 - private String currency1;
1.21 - private String currency2;
1.22 - private Rate rate;
1.23 -
1.24 + //version 1 fields
1.25 +
1.26 + private String currency1 = null;
1.27 + private String currency2 = null;
1.28 + private Rate rate = null;
1.29 +
1.30 + //version 2 field
1.31 + private List<CurrencyRate> currencyRates = null;
1.32 +
1.33 + //version - for compatible mode
1.34 + private int instanceVersion = 0; //compatible mode because of problem with empty currency and CZE -> CZE (1:2) rate
1.35 +
1.36 Convertor(String currency1, String currency2, Rate rate) {
1.37 - if ((currency1 == null)||(currency2 == null)||(rate == null)) {
1.38 + instanceVersion = 1;
1.39 + if ((currency1 == null) || (currency2 == null) || (rate == null)) {
1.40 throw new IllegalArgumentException("All arguments have to be non-null.");
1.41 }
1.42 this.currency1 = currency1;
1.43 @@ -21,68 +37,165 @@
1.44 this.rate = rate;
1.45 }
1.46
1.47 + Convertor(final CurrencyRate ... currencyRate) {
1.48 + instanceVersion = 2;
1.49 +
1.50 + if (currencyRate == null) {
1.51 + throw new IllegalArgumentException("Parameter cannot be null.");
1.52 + }
1.53 + if (currencyRate.length == 0) {
1.54 + throw new IllegalArgumentException("CurrencyRates cannot be empty.");
1.55 + }
1.56 + Set<Pair<String,String>> currencies = new HashSet<Pair<String,String>>();
1.57 + List<CurrencyRate> curRates = new ArrayList<CurrencyRate>();
1.58 + for (int i = 0; i < currencyRate.length; i++) {
1.59 + CurrencyRate curRat = currencyRate[i];
1.60 + if (curRat == null) {
1.61 + throw new IllegalArgumentException("Parameter cannot be null.");
1.62 + }
1.63 + //check that currencyRate is not defined twice
1.64 + Pair<String, String> curPair= new Pair<String, String>(curRat.getCurrency1(), curRat.getCurrency2());
1.65 + if (currencies.contains(curPair)) {
1.66 + throw new IllegalArgumentException("Pair of currencies in a currency rate cannot be defined twice");
1.67 + }
1.68 + currencies.add(curPair);
1.69 +
1.70 + curRates.add(curRat);
1.71 + }
1.72 + this.currencyRates = Collections.unmodifiableList(curRates);
1.73 + }
1.74 +
1.75 public double convert(String fromCurrency, String toCurrency, int amount) {
1.76 - if ((fromCurrency == null)||(toCurrency == null)) {
1.77 - throw new IllegalArgumentException("All arguments have to be non-null.");
1.78 - }
1.79 -
1.80 - if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
1.81 - return rate.convertAtoB(amount);
1.82 - } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
1.83 - return rate.convertBtoA(amount);
1.84 - } else {
1.85 - throw new IllegalArgumentException("Convertor " + this.toString() +
1.86 - " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
1.87 + if (instanceVersion == 1) {
1.88 + if ((fromCurrency == null) || (toCurrency == null)) {
1.89 + throw new IllegalArgumentException("All arguments have to be non-null.");
1.90 + }
1.91 +
1.92 + if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
1.93 + return rate.convertAtoB(amount);
1.94 + } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
1.95 + return rate.convertBtoA(amount);
1.96 + } else {
1.97 + throw new IllegalArgumentException("Convertor " + this.toString() +
1.98 + " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
1.99 + }
1.100 + } else { //instanceVersion == 2
1.101 + //find suitable convertor
1.102 + for (CurrencyRate curRate : currencyRates) {
1.103 + if ((curRate.getCurrency1().equals(fromCurrency))&&
1.104 + (curRate.getCurrency2().equals(toCurrency)))
1.105 + {
1.106 + return curRate.getRate().convertAtoB(amount);
1.107 + }
1.108 + }
1.109 + //suitable convertor not found, try to find inverse convertor
1.110 + for (CurrencyRate curRate : currencyRates) {
1.111 + if ((curRate.getCurrency2().equals(fromCurrency))&&
1.112 + (curRate.getCurrency1().equals(toCurrency)))
1.113 + {
1.114 + return curRate.getRate().convertBtoA(amount);
1.115 + }
1.116 + }
1.117 + //even inverse convertor not found
1.118 + throw new IllegalArgumentException("Cannot work with selected currencies.");
1.119 }
1.120 }
1.121
1.122 public double convert(String fromCurrency, String toCurrency, double amount) {
1.123 - if ((fromCurrency == null)||(toCurrency == null)) {
1.124 - throw new IllegalArgumentException("All arguments have to be non-null.");
1.125 - }
1.126 -
1.127 - if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
1.128 - return rate.convertAtoB(amount);
1.129 - } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
1.130 - return rate.convertBtoA(amount);
1.131 - } else {
1.132 - throw new IllegalArgumentException("Convertor " + this.toString() +
1.133 - " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
1.134 + if (instanceVersion == 1) {
1.135 + if ((fromCurrency == null) || (toCurrency == null)) {
1.136 + throw new IllegalArgumentException("All arguments have to be non-null.");
1.137 + }
1.138 +
1.139 + if (currency1.equals(fromCurrency) && currency2.equals(toCurrency)) {
1.140 + return rate.convertAtoB(amount);
1.141 + } else if (currency2.equals(fromCurrency) && currency1.equals(toCurrency)) {
1.142 + return rate.convertBtoA(amount);
1.143 + } else {
1.144 + throw new IllegalArgumentException("Convertor " + this.toString() +
1.145 + " cannot work with currencies " + fromCurrency + " and " + toCurrency + ".");
1.146 + }
1.147 + } else { //instanceVersion == 2
1.148 + //find suitable convertor
1.149 + for (CurrencyRate curRate : currencyRates) {
1.150 + if ((curRate.getCurrency1().equals(fromCurrency))&&
1.151 + (curRate.getCurrency2().equals(toCurrency)))
1.152 + {
1.153 + return curRate.getRate().convertAtoB(amount);
1.154 + }
1.155 + }
1.156 + //suitable convertor not found, try to find inverse convertor
1.157 + for (CurrencyRate curRate : currencyRates) {
1.158 + if ((curRate.getCurrency2().equals(fromCurrency))&&
1.159 + (curRate.getCurrency1().equals(toCurrency)))
1.160 + {
1.161 + return curRate.getRate().convertBtoA(amount);
1.162 + }
1.163 + }
1.164 + //even inverse convertor not found
1.165 + throw new IllegalArgumentException("Cannot work with selected currencies.");
1.166 }
1.167 }
1.168 -
1.169 +
1.170 + /**
1.171 + * Returns currency rates. If instantiated with constructor from vesion 1
1.172 + * it creates new collection with one CurrencyRate.
1.173 + * Note, it can cause exception because of empty currencies or same currencies.
1.174 + */
1.175 + public Collection<CurrencyRate> getCurrencyRates() {
1.176 + if (instanceVersion == 1) {
1.177 + List<CurrencyRate> ret = new ArrayList<CurrencyRate>();
1.178 + ret.add(new CurrencyRateImpl(currency1, currency2, rate));
1.179 + return Collections.unmodifiableCollection(ret);
1.180 + } else { //instanceVersion == 2
1.181 + return currencyRates;
1.182 + }
1.183 + }
1.184 +
1.185 @Override
1.186 public String toString() {
1.187 - return currency1+currency2;
1.188 + if (instanceVersion == 1) {
1.189 + return currency1 + currency2;
1.190 + } else { //instanceVersion == 2
1.191 + return super.toString(); //better be compatible in future :-)
1.192 + }
1.193 }
1.194 -
1.195 +
1.196 @Override
1.197 public boolean equals(Object obj) {
1.198 - if (obj == null) {
1.199 - return false;
1.200 + if (instanceVersion == 1) {
1.201 + if (obj == null) {
1.202 + return false;
1.203 + }
1.204 + if (getClass() != obj.getClass()) {
1.205 + return false;
1.206 + }
1.207 + final Convertor other = (Convertor) obj;
1.208 + if (this.currency1 != other.currency1 && (this.currency1 == null || !this.currency1.equals(other.currency1))) {
1.209 + return false;
1.210 + }
1.211 + if (this.currency2 != other.currency2 && (this.currency2 == null || !this.currency2.equals(other.currency2))) {
1.212 + return false;
1.213 + }
1.214 + if (this.rate != other.rate && (this.rate == null || !this.rate.equals(other.rate))) {
1.215 + return false;
1.216 + }
1.217 + return true;
1.218 + } else { //instanceVersion == 2
1.219 + return super.equals(obj); //better be compatible in future :-)
1.220 }
1.221 - if (getClass() != obj.getClass()) {
1.222 - return false;
1.223 - }
1.224 - final Convertor other = (Convertor) obj;
1.225 - if (this.currency1 != other.currency1 && (this.currency1 == null || !this.currency1.equals(other.currency1))) {
1.226 - return false;
1.227 - }
1.228 - if (this.currency2 != other.currency2 && (this.currency2 == null || !this.currency2.equals(other.currency2))) {
1.229 - return false;
1.230 - }
1.231 - if (this.rate != other.rate && (this.rate == null || !this.rate.equals(other.rate))) {
1.232 - return false;
1.233 - }
1.234 - return true;
1.235 }
1.236
1.237 @Override
1.238 public int hashCode() {
1.239 - int hash = 5;
1.240 - hash = 67 * hash + (this.currency1 != null ? this.currency1.hashCode() : 0);
1.241 - hash = 67 * hash + (this.currency2 != null ? this.currency2.hashCode() : 0);
1.242 - hash = 67 * hash + (this.rate != null ? this.rate.hashCode() : 0);
1.243 + if (instanceVersion == 1) {
1.244 + int hash = 5;
1.245 + hash = 67 * hash + (this.currency1 != null ? this.currency1.hashCode() : 0);
1.246 + hash = 67 * hash + (this.currency2 != null ? this.currency2.hashCode() : 0);
1.247 + hash = 67 * hash + (this.rate != null ? this.rate.hashCode() : 0);
1.248 return hash;
1.249 + } else { //instanceVersion == 2
1.250 + return super.hashCode(); //better be compatible in future :-)
1.251 + }
1.252 }
1.253 }
2.1 --- a/task2/solution14/src/org/apidesign/apifest08/currency/ConvertorFactory.java Tue Oct 07 11:19:36 2008 +0200
2.2 +++ b/task2/solution14/src/org/apidesign/apifest08/currency/ConvertorFactory.java Wed Oct 08 12:51:52 2008 +0200
2.3 @@ -1,12 +1,15 @@
2.4
2.5 package org.apidesign.apifest08.currency;
2.6
2.7 +import java.util.ArrayList;
2.8 +import java.util.List;
2.9 +
2.10 public final class ConvertorFactory {
2.11
2.12 //Singleton
2.13 private static ConvertorFactory thisFactory = new ConvertorFactory();
2.14 private ConvertorFactory() {};
2.15 - public static ConvertorFactory newInstance() {
2.16 + public static ConvertorFactory newInstance() { //ehm, mistake - it should be named getInstance
2.17 return thisFactory;
2.18 }
2.19
2.20 @@ -25,4 +28,39 @@
2.21 public Convertor createConvertor(String currency1, String currency2, double rate) {
2.22 return new Convertor(currency1, currency2, new Rate(rate));
2.23 }
2.24 +
2.25 + public Convertor createConvertor(CurrencyRate currencyRate) {
2.26 + return new Convertor(currencyRate);
2.27 + }
2.28 +
2.29 + public Convertor createConvertor(CurrencyRate ... currencyRates) {
2.30 + return new Convertor(currencyRates);
2.31 + }
2.32 +
2.33 + public Convertor mergeConvertors(Convertor ... convertors) {
2.34 + if (convertors == null) {
2.35 + throw new IllegalArgumentException("Parameter cannot be null.");
2.36 + }
2.37 + if (convertors.length == 0) {
2.38 + throw new IllegalArgumentException("Convertors cannot be empty.");
2.39 + }
2.40 + List<CurrencyRate> currRates = new ArrayList<CurrencyRate>();
2.41 + List<Pair<String,String>> currPairs = new ArrayList<Pair<String,String>>();
2.42 + for (Convertor convertor : convertors) {
2.43 + if (convertor == null) {
2.44 + throw new IllegalArgumentException("Parameter cannot be null.");
2.45 + }
2.46 + for (CurrencyRate currRate : convertor.getCurrencyRates()) {
2.47 + Pair<String,String> currPair = new Pair<String,String>(currRate.getCurrency1(), currRate.getCurrency2());
2.48 + if (currPairs.contains(currPair)) {
2.49 + throw new IllegalArgumentException("Cannot merge - convertors contain same currency rates.");
2.50 + }
2.51 + currPairs.add(currPair);
2.52 + currRates.add(currRate);
2.53 + }
2.54 + }
2.55 +
2.56 + return new Convertor(currRates.toArray(new CurrencyRate[0]));
2.57 + }
2.58 +
2.59 }
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/task2/solution14/src/org/apidesign/apifest08/currency/CurrencyRate.java Wed Oct 08 12:51:52 2008 +0200
3.3 @@ -0,0 +1,8 @@
3.4 +package org.apidesign.apifest08.currency;
3.5 +
3.6 +
3.7 +public interface CurrencyRate {
3.8 + public String getCurrency1();
3.9 + public String getCurrency2();
3.10 + public Rate getRate();
3.11 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/task2/solution14/src/org/apidesign/apifest08/currency/CurrencyRateFactory.java Wed Oct 08 12:51:52 2008 +0200
4.3 @@ -0,0 +1,25 @@
4.4 +package org.apidesign.apifest08.currency;
4.5 +
4.6 +
4.7 +public final class CurrencyRateFactory {
4.8 +
4.9 + //Singleton
4.10 + private static CurrencyRateFactory thisFactory = new CurrencyRateFactory();
4.11 + private CurrencyRateFactory() {};
4.12 + public static CurrencyRateFactory getInstance() {
4.13 + return thisFactory;
4.14 + }
4.15 +
4.16 + public CurrencyRate createCurrencyRate(final String currency1, final String currency2, final Rate rate) {
4.17 + return new CurrencyRateImpl(currency1, currency2, rate);
4.18 + }
4.19 +
4.20 + public CurrencyRate createCurrencyRate(final String currency1, final String currency2, int amount1, int amount2) {
4.21 + return new CurrencyRateImpl(currency1, currency2, new Rate(amount1, amount2));
4.22 + }
4.23 +
4.24 + public CurrencyRate createCurrencyRate(final String currency1, final String currency2, double amount1, double amount2) {
4.25 + return new CurrencyRateImpl(currency1, currency2, new Rate(amount1, amount2));
4.26 + }
4.27 +
4.28 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/task2/solution14/src/org/apidesign/apifest08/currency/CurrencyRateImpl.java Wed Oct 08 12:51:52 2008 +0200
5.3 @@ -0,0 +1,37 @@
5.4 +
5.5 +package org.apidesign.apifest08.currency;
5.6 +
5.7 +public final class CurrencyRateImpl implements CurrencyRate {
5.8 + private String currency1;
5.9 + private String currency2;
5.10 + private Rate rate;
5.11 +
5.12 + CurrencyRateImpl(final String currency1, final String currency2, final Rate rate) {
5.13 + if ((currency1 == null)||(currency2 == null) || (rate == null)) {
5.14 + throw new IllegalArgumentException("Argument cannot be null.");
5.15 + }
5.16 + if ("".equals(currency1) || "".equals(currency2)) {
5.17 + throw new IllegalArgumentException("Name of currency cannot be empty string");
5.18 + }
5.19 + if (currency1.equals(currency2)) {
5.20 + throw new IllegalArgumentException("Currencies in rate cannot be the same");
5.21 + }
5.22 +
5.23 + this.currency1 = currency1;
5.24 + this.currency2 = currency2;
5.25 + this.rate = rate;
5.26 + }
5.27 +
5.28 + public String getCurrency1() {
5.29 + return currency1;
5.30 + }
5.31 +
5.32 + public String getCurrency2() {
5.33 + return currency2;
5.34 + }
5.35 +
5.36 + public Rate getRate(){
5.37 + return rate;
5.38 + }
5.39 +
5.40 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/task2/solution14/src/org/apidesign/apifest08/currency/Pair.java Wed Oct 08 12:51:52 2008 +0200
6.3 @@ -0,0 +1,53 @@
6.4 +
6.5 +package org.apidesign.apifest08.currency;
6.6 +
6.7 +
6.8 +public final class Pair<A,B> {
6.9 +
6.10 + private final A first;
6.11 + private final B second;
6.12 +
6.13 + public Pair(A first, B second) {
6.14 + this.first = first;
6.15 + this.second = second;
6.16 + }
6.17 +
6.18 + public A getFirst() { return first; }
6.19 + public B getSecond() { return second; }
6.20 +
6.21 + @Override
6.22 + public String toString() {
6.23 + return "(" + first + ", " + second + ")";
6.24 + }
6.25 +
6.26 + private static boolean equals(Object x, Object y) {
6.27 + return (x == null && y == null) || (x != null && x.equals(y));
6.28 + }
6.29 +
6.30 + @Override
6.31 + public int hashCode() {
6.32 + int hash = 5;
6.33 + hash = 59 * hash + (this.first != null ? this.first.hashCode() : 0);
6.34 + hash = 59 * hash + (this.second != null ? this.second.hashCode() : 0);
6.35 + return hash;
6.36 + }
6.37 +
6.38 + @Override
6.39 + public boolean equals(Object obj) {
6.40 + if (obj == null) {
6.41 + return false;
6.42 + }
6.43 + if (getClass() != obj.getClass()) {
6.44 + return false;
6.45 + }
6.46 + final Pair<A, B> other = (Pair<A, B>) obj;
6.47 + if (this.first != other.first && (this.first == null || !this.first.equals(other.first))) {
6.48 + return false;
6.49 + }
6.50 + if (this.second != other.second && (this.second == null || !this.second.equals(other.second))) {
6.51 + return false;
6.52 + }
6.53 + return true;
6.54 + }
6.55 +
6.56 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/task2/solution14/test/org/apidesign/apifest08/test/Task2Test.java Wed Oct 08 12:51:52 2008 +0200
7.3 @@ -0,0 +1,169 @@
7.4 +package org.apidesign.apifest08.test;
7.5 +
7.6 +import junit.framework.TestCase;
7.7 +import org.apidesign.apifest08.currency.Convertor;
7.8 +import org.apidesign.apifest08.currency.ConvertorFactory;
7.9 +import org.apidesign.apifest08.currency.CurrencyRate;
7.10 +import org.apidesign.apifest08.currency.CurrencyRateFactory;
7.11 +
7.12 +/** There are many currencies around the world and many banks manipulate
7.13 + * with more than one or two at the same time. As banks are usually the
7.14 + * best paying clients, which is true even in case of your Convertor API,
7.15 + * it is reasonable to listen to their requests.
7.16 + * <p>
7.17 + * The quest for today is to enhance your existing convertor API to hold
7.18 + * information about many currencies and allow conversions between any of them.
7.19 + * Also, as conversion rates for diferent currencies usually arise from various
7.20 + * bank departments, there is another important need. There is a need to
7.21 + * compose two convertors into one by merging all the information about
7.22 + * currencies they know about.
7.23 + */
7.24 +public class Task2Test extends TestCase {
7.25 + public Task2Test(String testName) {
7.26 + super(testName);
7.27 + }
7.28 +
7.29 + @Override
7.30 + protected void setUp() throws Exception {
7.31 + }
7.32 +
7.33 + @Override
7.34 + protected void tearDown() throws Exception {
7.35 + }
7.36 +
7.37 + // As in Task1Test, keep in mind, that there are three parts
7.38 + // of the whole system:
7.39 + // 1. there is someone who knows the current exchange rate
7.40 + // 2. there is someone who wants to do the conversion
7.41 + // 3. there is the API between 1. and 2. which allows them to communicate
7.42 + //
7.43 + // Please backward compatibly enhance your existing API to support following
7.44 + // usecases:
7.45 + //
7.46 +
7.47 + /** Create convertor that understands two currencies, CZK and
7.48 + * SKK. Make 100 SKK == 75 CZK. This is method for the group of users that
7.49 + * knows the exchange rate, and needs to use the API to create objects
7.50 + * with the exchange rate. Anyone shall be ready to call this method without
7.51 + * any other method being called previously. The API itself shall know
7.52 + * nothing about any rates, before this method is called.
7.53 + */
7.54 + public static Convertor createTripleConvertor() {
7.55 + // Rates: 1USD = 15CZK
7.56 + // Rates: 1USD = 20SKK
7.57 + // Rates: 75CZK = 100SKK
7.58 + CurrencyRate usdCzk = CurrencyRateFactory.getInstance().createCurrencyRate("USD", "CZK", 1, 15);
7.59 + CurrencyRate usdSkk = CurrencyRateFactory.getInstance().createCurrencyRate("USD", "SKK", 1, 20);
7.60 + CurrencyRate czkSkk = CurrencyRateFactory.getInstance().createCurrencyRate("CZK", "SKK", 75, 100);
7.61 + return ConvertorFactory.newInstance().createConvertor(usdCzk, usdSkk, czkSkk);
7.62 + }
7.63 +
7.64 + /** Define convertor that understands three currencies. Use it.
7.65 + */
7.66 + public void testConvertorForUSDandCZKandSKK() throws Exception {
7.67 + Convertor c = createTripleConvertor();
7.68 +
7.69 + // convert $5 to CZK using c:
7.70 + // assertEquals("Result is 75 CZK");
7.71 + assertEquals("Result is 75 CZK", 75.0, c.convert("USD", "CZK", 5));
7.72 +
7.73 + // convert $5 to SKK using c:
7.74 + // assertEquals("Result is 100 SKK");
7.75 + assertEquals("Result is 100 SKK", 100.0, c.convert("USD", "SKK", 5));
7.76 +
7.77 + // convert 200SKK to CZK using c:
7.78 + // assertEquals("Result is 150 CZK");
7.79 + assertEquals("Result is 150 CZK", 150.0, c.convert("SKK", "CZK", 200));
7.80 +
7.81 + // convert 200SKK to USD using c:
7.82 + // assertEquals("Result is 10 USD");
7.83 + assertEquals("Result is 10 USD", 10.0, c.convert("SKK", "USD", 200));
7.84 + }
7.85 +
7.86 + /** Merge all currency rates of convertor 1 with convertor 2.
7.87 + * Implement this using your API, preferably this method just delegates
7.88 + * into some API method which does the actual work, without requiring
7.89 + * API clients to code anything complex.
7.90 + */
7.91 + public static Convertor merge(Convertor one, Convertor two) {
7.92 + return ConvertorFactory.newInstance().mergeConvertors(one,two);
7.93 + }
7.94 +
7.95 + /** Join the convertors from previous task, Task1Test and show that it
7.96 + * can be used to do reasonable conversions.
7.97 + */
7.98 + public void testConvertorComposition() throws Exception {
7.99 + Convertor c = merge(
7.100 + Task1Test.createCZKtoUSD(),
7.101 + Task1Test.createSKKtoCZK()
7.102 + );
7.103 +
7.104 + // convert $5 to CZK using c:
7.105 + // assertEquals("Result is 85 CZK");
7.106 + assertEquals("Result is 85 CZK", 85.0, c.convert("USD", "CZK", 5));
7.107 +
7.108 + // convert $8 to CZK using c:
7.109 + // assertEquals("Result is 136 CZK");
7.110 + assertEquals("Result is 136 CZK", 136.0, c.convert("USD", "CZK", 8));
7.111 +
7.112 + // convert 1003CZK to USD using c:
7.113 + // assertEquals("Result is 59 USD");
7.114 + assertEquals("Result is 59 USD", 59.0, c.convert("CZK", "USD", 1003));
7.115 +
7.116 + // convert 16CZK using c:
7.117 + // assertEquals("Result is 20 SKK");
7.118 + assertEquals("Result is 20 SKK", 20.0, c.convert("CZK", "SKK", 16));
7.119 +
7.120 + // convert 500SKK to CZK using c:
7.121 + // assertEquals("Result is 400 CZK");
7.122 + assertEquals("Result is 400 CZK", 400.0, c.convert("SKK", "CZK", 500));
7.123 +
7.124 + //test exceptions
7.125 + Convertor one = Task1Test.createCZKtoUSD();
7.126 + Convertor two = Task1Test.createSKKtoCZK();
7.127 + Convertor three = Task1Test.createSKKtoCZK();
7.128 + try {
7.129 + ConvertorFactory.newInstance().mergeConvertors(one,two,three);
7.130 + fail();
7.131 + } catch (IllegalArgumentException e) {
7.132 + //ok
7.133 + }
7.134 +
7.135 + //test exceptions
7.136 + try {
7.137 + ConvertorFactory.newInstance().mergeConvertors(c, two);
7.138 + fail();
7.139 + } catch (IllegalArgumentException e) {
7.140 + //ok
7.141 + }
7.142 +
7.143 + //try convertors from version 1
7.144 + Convertor v1one = ConvertorFactory.newInstance().createConvertor("CZE", "CZE", 1, 2);
7.145 + assertEquals("CZE->CZE 1:2 10 expects 20", 20.0, v1one.convert("CZE", "CZE", 10));
7.146 + try {
7.147 + ConvertorFactory.newInstance().mergeConvertors(v1one, two);
7.148 + fail();
7.149 + } catch (IllegalArgumentException e) {
7.150 + //ok
7.151 + }
7.152 +
7.153 + Convertor v1two = ConvertorFactory.newInstance().createConvertor("EUR", "", 1, 2);
7.154 + assertEquals("EUR->'' 1:2 10 expects 20", 20.0, v1two.convert("EUR", "", 10));
7.155 + try {
7.156 + ConvertorFactory.newInstance().mergeConvertors(v1two, two);
7.157 + fail();
7.158 + } catch (IllegalArgumentException e) {
7.159 + //ok
7.160 + }
7.161 +
7.162 + Convertor v1three = ConvertorFactory.newInstance().createConvertor("EUR", "", 1, 2);
7.163 + assertEquals("''->EUR 1:2 10 expects 5", 5.0, v1three.convert("", "EUR", 10));
7.164 + try {
7.165 + ConvertorFactory.newInstance().mergeConvertors(v1three, two);
7.166 + fail();
7.167 + } catch (IllegalArgumentException e) {
7.168 + //ok
7.169 + }
7.170 +
7.171 + }
7.172 +}