Solution 14, task4
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 17 Oct 2008 17:35:52 +0200
changeset 67bf7622ec1713
parent 66 aa3f99f845ef
child 68 4de3a4b5445a
Solution 14, task4
task4/solution14/src/org/apidesign/apifest08/currency/Convertor.java
task4/solution14/src/org/apidesign/apifest08/currency/ConvertorFactory.java
task4/solution14/src/org/apidesign/apifest08/currency/CurrencyRateFactory.java
task4/solution14/src/org/apidesign/apifest08/currency/CurrencyRateImpl.java
task4/solution14/src/org/apidesign/apifest08/currency/TimeLimitedCurrencyRate.java
task4/solution14/test/org/apidesign/apifest08/test/Task2Test.java
task4/solution14/test/org/apidesign/apifest08/test/Task4Test.java
     1.1 --- a/task4/solution14/src/org/apidesign/apifest08/currency/Convertor.java	Fri Oct 17 17:34:40 2008 +0200
     1.2 +++ b/task4/solution14/src/org/apidesign/apifest08/currency/Convertor.java	Fri Oct 17 17:35:52 2008 +0200
     1.3 @@ -3,6 +3,7 @@
     1.4  import java.util.ArrayList;
     1.5  import java.util.Collection;
     1.6  import java.util.Collections;
     1.7 +import java.util.Date;
     1.8  import java.util.HashSet;
     1.9  import java.util.List;
    1.10  import java.util.Set;
    1.11 @@ -22,7 +23,7 @@
    1.12      private Rate rate = null;
    1.13  
    1.14      //version 2 field
    1.15 -    private List<CurrencyRate> currencyRates = null;
    1.16 +    private List<TimeLimitedCurrencyRate> currencyRates = null;
    1.17  
    1.18      //version - for compatible mode
    1.19      private int instanceVersion = 0; //compatible mode because of problem with empty currency and CZE -> CZE (1:2) rate
    1.20 @@ -47,9 +48,9 @@
    1.21              throw new IllegalArgumentException("CurrencyRates cannot be empty.");
    1.22          }
    1.23          Set<Pair<String,String>> currencies = new HashSet<Pair<String,String>>();
    1.24 -        List<CurrencyRate> curRates = new ArrayList<CurrencyRate>();
    1.25 +        List<TimeLimitedCurrencyRate> curRates = new ArrayList<TimeLimitedCurrencyRate>();
    1.26          for (int i = 0; i < currencyRate.length; i++) {
    1.27 -            CurrencyRate curRat = currencyRate[i];
    1.28 +            final CurrencyRate curRat = currencyRate[i];
    1.29              if (curRat == null) {
    1.30                  throw new IllegalArgumentException("Parameter cannot be null.");
    1.31              }
    1.32 @@ -59,13 +60,66 @@
    1.33                  throw new IllegalArgumentException("Pair of currencies in a currency rate cannot be defined twice");
    1.34              }
    1.35              currencies.add(curPair);
    1.36 -            
    1.37 +
    1.38 +            if (curRat instanceof TimeLimitedCurrencyRate) {
    1.39 +                curRates.add((TimeLimitedCurrencyRate)curRat);
    1.40 +            } else {
    1.41 +                curRates.add(new TimeLimitedCurrencyRate() { //create delegate which implements TimeLimitedCurrencyRate
    1.42 +                    public long getFromTime() {
    1.43 +                        return Long.MIN_VALUE;
    1.44 +                    }
    1.45 +
    1.46 +                    public long getToTime() {
    1.47 +                        return Long.MAX_VALUE;
    1.48 +                    }
    1.49 +
    1.50 +                    public String getCurrency1() {
    1.51 +                        return curRat.getCurrency1();
    1.52 +                    }
    1.53 +
    1.54 +                    public String getCurrency2() {
    1.55 +                        return curRat.getCurrency2();
    1.56 +                    }
    1.57 +
    1.58 +                    public Rate getRate() {
    1.59 +                        return curRat.getRate();
    1.60 +                    }
    1.61 +                });
    1.62 +            }
    1.63 +        }
    1.64 +        this.currencyRates = Collections.unmodifiableList(curRates);
    1.65 +    }
    1.66 +
    1.67 +    Convertor(final int fakeParameter, final TimeLimitedCurrencyRate ... currencyRate) { //use fake parameter just to specify which constructor should be invoked
    1.68 +        instanceVersion = 3;
    1.69 +
    1.70 +        if (currencyRate == null) {
    1.71 +            throw new IllegalArgumentException("Parameter cannot be null.");
    1.72 +        }
    1.73 +        List<TimeLimitedCurrencyRate> curRates = new ArrayList<TimeLimitedCurrencyRate>();
    1.74 +        for (int i = 0; i < currencyRate.length; i++) {
    1.75 +            final TimeLimitedCurrencyRate curRat = currencyRate[i];
    1.76 +            if (curRat == null) {
    1.77 +                throw new IllegalArgumentException("Parameter cannot be null.");
    1.78 +            }
    1.79 +
    1.80              curRates.add(curRat);
    1.81          }
    1.82          this.currencyRates = Collections.unmodifiableList(curRates);
    1.83      }
    1.84  
    1.85      public double convert(String fromCurrency, String toCurrency, int amount) {
    1.86 +        return convert(fromCurrency, toCurrency, amount, System.currentTimeMillis());
    1.87 +    }
    1.88 +
    1.89 +    public double convert(String fromCurrency, String toCurrency, int amount, Date date) {
    1.90 +        if (date == null) {
    1.91 +            throw new IllegalArgumentException("Date cannot be null");
    1.92 +        }
    1.93 +        return convert(fromCurrency, toCurrency, amount, date.getTime());
    1.94 +    }
    1.95 +
    1.96 +    public double convert(String fromCurrency, String toCurrency, int amount, long time) {
    1.97          if (instanceVersion == 1) {
    1.98              if ((fromCurrency == null) || (toCurrency == null)) {
    1.99                  throw new IllegalArgumentException("All arguments have to be non-null.");
   1.100 @@ -81,27 +135,42 @@
   1.101              }
   1.102          } else { //instanceVersion >= 2
   1.103              //find suitable convertor
   1.104 -            for (CurrencyRate curRate : currencyRates) {
   1.105 -                if ((curRate.getCurrency1().equals(fromCurrency))&& 
   1.106 -                        (curRate.getCurrency2().equals(toCurrency))) 
   1.107 +           for (TimeLimitedCurrencyRate curRate : currencyRates) {
   1.108 +                if ((curRate.getCurrency1().equals(fromCurrency))&&
   1.109 +                        (curRate.getCurrency2().equals(toCurrency))&&
   1.110 +                        (curRate.getFromTime() <= time) &&
   1.111 +                        (curRate.getToTime() >= time))
   1.112                  {
   1.113                      return curRate.getRate().convertAtoB(amount);
   1.114                  }
   1.115              }
   1.116              //suitable convertor not found, try to find inverse convertor
   1.117 -            for (CurrencyRate curRate : currencyRates) {
   1.118 +            for (TimeLimitedCurrencyRate curRate : currencyRates) {
   1.119                  if ((curRate.getCurrency2().equals(fromCurrency))&&
   1.120 -                        (curRate.getCurrency1().equals(toCurrency)))
   1.121 +                        (curRate.getCurrency1().equals(toCurrency))&&
   1.122 +                        (curRate.getFromTime() <= time) &&
   1.123 +                        (curRate.getToTime() >= time))
   1.124                  {
   1.125                      return curRate.getRate().convertBtoA(amount);
   1.126                  }
   1.127 -            }            
   1.128 +            }
   1.129              //even inverse convertor not found
   1.130              throw new IllegalArgumentException("Cannot work with selected currencies.");
   1.131          }
   1.132      }
   1.133  
   1.134      public double convert(String fromCurrency, String toCurrency, double amount) {
   1.135 +        return convert(fromCurrency, toCurrency, amount, System.currentTimeMillis());
   1.136 +    }
   1.137 +
   1.138 +    public double convert(String fromCurrency, String toCurrency, double amount, Date date) {
   1.139 +        if (date == null) {
   1.140 +            throw new IllegalArgumentException("Date cannot be null");
   1.141 +        }
   1.142 +        return convert(fromCurrency, toCurrency, amount, date.getTime());
   1.143 +    }
   1.144 +
   1.145 +    public double convert(String fromCurrency, String toCurrency, double amount, long time) {
   1.146          if (instanceVersion == 1) {
   1.147              if ((fromCurrency == null) || (toCurrency == null)) {
   1.148                  throw new IllegalArgumentException("All arguments have to be non-null.");
   1.149 @@ -117,21 +186,25 @@
   1.150              }
   1.151          } else { //instanceVersion >= 2
   1.152              //find suitable convertor
   1.153 -            for (CurrencyRate curRate : currencyRates) {
   1.154 -                if ((curRate.getCurrency1().equals(fromCurrency))&& 
   1.155 -                        (curRate.getCurrency2().equals(toCurrency))) 
   1.156 +            for (TimeLimitedCurrencyRate curRate : currencyRates) {
   1.157 +                if ((curRate.getCurrency1().equals(fromCurrency))&&
   1.158 +                        (curRate.getCurrency2().equals(toCurrency))&&
   1.159 +                        (curRate.getFromTime() <= time) &&
   1.160 +                        (curRate.getToTime() >= time))
   1.161                  {
   1.162                      return curRate.getRate().convertAtoB(amount);
   1.163                  }
   1.164              }
   1.165              //suitable convertor not found, try to find inverse convertor
   1.166 -            for (CurrencyRate curRate : currencyRates) {
   1.167 +            for (TimeLimitedCurrencyRate curRate : currencyRates) {
   1.168                  if ((curRate.getCurrency2().equals(fromCurrency))&&
   1.169 -                        (curRate.getCurrency1().equals(toCurrency)))
   1.170 +                        (curRate.getCurrency1().equals(toCurrency))&&
   1.171 +                        (curRate.getFromTime() <= time) &&
   1.172 +                        (curRate.getToTime() >= time))
   1.173                  {
   1.174                      return curRate.getRate().convertBtoA(amount);
   1.175                  }
   1.176 -            }            
   1.177 +            }
   1.178              //even inverse convertor not found
   1.179              throw new IllegalArgumentException("Cannot work with selected currencies.");
   1.180          }
   1.181 @@ -148,7 +221,19 @@
   1.182              ret.add(new CurrencyRateImpl(currency1, currency2, rate)); //here it checks that currency rate is not nonsense
   1.183              return Collections.unmodifiableCollection(ret);
   1.184          } else { //instanceVersion >= 2
   1.185 -            return currencyRates;
   1.186 +            List<CurrencyRate> ret = new ArrayList<CurrencyRate>(currencyRates);
   1.187 +            return Collections.unmodifiableCollection(ret);
   1.188 +        }
   1.189 +    }
   1.190 +
   1.191 +    public Collection<TimeLimitedCurrencyRate> getTimeLimitedCurrencyRates() {
   1.192 +        if (instanceVersion == 1) {
   1.193 +            List<TimeLimitedCurrencyRate> ret = new ArrayList<TimeLimitedCurrencyRate>();
   1.194 +            ret.add(new CurrencyRateImpl(currency1, currency2, rate)); //here it checks that currency rate is not nonsense
   1.195 +            return Collections.unmodifiableCollection(ret);
   1.196 +        } else { //instanceVersion >= 2
   1.197 +            List<TimeLimitedCurrencyRate> ret = new ArrayList<TimeLimitedCurrencyRate>(currencyRates);
   1.198 +            return Collections.unmodifiableCollection(ret);
   1.199          }
   1.200      }
   1.201  
     2.1 --- a/task4/solution14/src/org/apidesign/apifest08/currency/ConvertorFactory.java	Fri Oct 17 17:34:40 2008 +0200
     2.2 +++ b/task4/solution14/src/org/apidesign/apifest08/currency/ConvertorFactory.java	Fri Oct 17 17:35:52 2008 +0200
     2.3 @@ -2,6 +2,8 @@
     2.4  package org.apidesign.apifest08.currency;
     2.5  
     2.6  import java.util.ArrayList;
     2.7 +import java.util.Collection;
     2.8 +import java.util.Date;
     2.9  import java.util.List;
    2.10  
    2.11  public final class ConvertorFactory {
    2.12 @@ -63,4 +65,54 @@
    2.13          return new Convertor(currRates.toArray(new CurrencyRate[0]));
    2.14      }
    2.15  
    2.16 +    public Convertor mergeConvertorsIgnoreEqualCurrencies(Convertor ... convertors) {
    2.17 +        if (convertors == null) {
    2.18 +            throw new IllegalArgumentException("Parameter cannot be null.");
    2.19 +        }
    2.20 +        if (convertors.length == 0) {
    2.21 +            throw new IllegalArgumentException("Convertors cannot be empty.");
    2.22 +        }
    2.23 +        List<TimeLimitedCurrencyRate> currRates = new ArrayList<TimeLimitedCurrencyRate>();
    2.24 +        for (Convertor convertor : convertors) {
    2.25 +            if (convertor == null) {
    2.26 +                throw new IllegalArgumentException("Parameter cannot be null.");
    2.27 +            }
    2.28 +            currRates.addAll(convertor.getTimeLimitedCurrencyRates());
    2.29 +        }
    2.30 +
    2.31 +        return new Convertor(4, currRates.toArray(new TimeLimitedCurrencyRate[0]));
    2.32 +    }
    2.33 +
    2.34 +    public Convertor limitConvertor(Convertor convertor, Date fromDate, Date toDate) {
    2.35 +        if ((convertor == null)||(fromDate == null)||(toDate == null)) {
    2.36 +            throw new IllegalArgumentException("Parameter cannot be null");
    2.37 +        }
    2.38 +        Collection<TimeLimitedCurrencyRate> timeLimitedCurrencyRates = convertor.getTimeLimitedCurrencyRates();
    2.39 +        List<TimeLimitedCurrencyRate> filteredRates = new ArrayList<TimeLimitedCurrencyRate>();
    2.40 +        for (final TimeLimitedCurrencyRate timeLimitedCurrencyRate : timeLimitedCurrencyRates) {
    2.41 +            final long newFrom = java.lang.Math.max(fromDate.getTime(), timeLimitedCurrencyRate.getFromTime());
    2.42 +            final long newTo = java.lang.Math.min(toDate.getTime(), timeLimitedCurrencyRate.getToTime());
    2.43 +            if (newTo >= newFrom) {
    2.44 +                filteredRates.add(new TimeLimitedCurrencyRate() { //create delegate
    2.45 +                    public long getFromTime() {
    2.46 +                        return newFrom;
    2.47 +                    }
    2.48 +                    public long getToTime() {
    2.49 +                        return newTo;
    2.50 +                    }
    2.51 +                    public String getCurrency1() {
    2.52 +                        return timeLimitedCurrencyRate.getCurrency1();
    2.53 +                    }
    2.54 +                    public String getCurrency2() {
    2.55 +                        return timeLimitedCurrencyRate.getCurrency2();
    2.56 +                    }
    2.57 +                    public Rate getRate() {
    2.58 +                        return timeLimitedCurrencyRate.getRate();
    2.59 +                    }
    2.60 +                });
    2.61 +            }
    2.62 +        }
    2.63 +        return new Convertor(4, filteredRates.toArray(new TimeLimitedCurrencyRate[0]));
    2.64 +    }
    2.65 +
    2.66  }
     3.1 --- a/task4/solution14/src/org/apidesign/apifest08/currency/CurrencyRateFactory.java	Fri Oct 17 17:34:40 2008 +0200
     3.2 +++ b/task4/solution14/src/org/apidesign/apifest08/currency/CurrencyRateFactory.java	Fri Oct 17 17:35:52 2008 +0200
     3.3 @@ -21,5 +21,17 @@
     3.4      public CurrencyRate createCurrencyRate(final String currency1, final String currency2, double amount1, double amount2) {
     3.5          return new CurrencyRateImpl(currency1, currency2, new Rate(amount1, amount2));
     3.6      }
     3.7 +
     3.8 +    public TimeLimitedCurrencyRate createCurrencyRateTimeLimited(final String currency1, final String currency2, final Rate rate, long fromTime, long toTime) {
     3.9 +        return new CurrencyRateImpl(currency1, currency2, rate, fromTime, toTime);
    3.10 +    }
    3.11 +
    3.12 +    public TimeLimitedCurrencyRate createCurrencyRateTimeLimited(final String currency1, final String currency2, int amount1, int amount2, long fromTime, long toTime) {
    3.13 +        return new CurrencyRateImpl(currency1, currency2, new Rate(amount1, amount2), fromTime, toTime);
    3.14 +    }
    3.15 +
    3.16 +    public TimeLimitedCurrencyRate createCurrencyRateTimeLimited(final String currency1, final String currency2, double amount1, double amount2, long fromTime, long toTime) {
    3.17 +        return new CurrencyRateImpl(currency1, currency2, new Rate(amount1, amount2), fromTime, toTime);
    3.18 +    }
    3.19      
    3.20  }
     4.1 --- a/task4/solution14/src/org/apidesign/apifest08/currency/CurrencyRateImpl.java	Fri Oct 17 17:34:40 2008 +0200
     4.2 +++ b/task4/solution14/src/org/apidesign/apifest08/currency/CurrencyRateImpl.java	Fri Oct 17 17:35:52 2008 +0200
     4.3 @@ -1,10 +1,12 @@
     4.4  
     4.5  package org.apidesign.apifest08.currency;
     4.6  
     4.7 -public final class CurrencyRateImpl implements CurrencyRate {
     4.8 +public final class CurrencyRateImpl implements CurrencyRate, TimeLimitedCurrencyRate {
     4.9      private String currency1;
    4.10      private String currency2;
    4.11      private Rate rate;
    4.12 +    private long fromTime;
    4.13 +    private long toTime;
    4.14      
    4.15      CurrencyRateImpl(final String currency1, final String currency2, final Rate rate) {
    4.16          if ((currency1 == null)||(currency2 == null) || (rate == null)) {
    4.17 @@ -20,6 +22,29 @@
    4.18          this.currency1 = currency1;
    4.19          this.currency2 = currency2;
    4.20          this.rate = rate;
    4.21 +        this.fromTime = Long.MIN_VALUE;
    4.22 +        this.toTime = Long.MAX_VALUE;
    4.23 +    }
    4.24 +
    4.25 +    CurrencyRateImpl(final String currency1, final String currency2, final Rate rate, final long fromTime, final long toTime) {
    4.26 +        if ((currency1 == null)||(currency2 == null) || (rate == null)) {
    4.27 +            throw new IllegalArgumentException("Argument cannot be null.");
    4.28 +        }
    4.29 +        if ("".equals(currency1) || "".equals(currency2)) {
    4.30 +            throw new IllegalArgumentException("Name of currency cannot be empty string");
    4.31 +        }
    4.32 +        if (currency1.equals(currency2)) {
    4.33 +            throw new IllegalArgumentException("Currencies in rate cannot be the same");
    4.34 +        }
    4.35 +        if (fromTime > toTime) {
    4.36 +            throw new IllegalArgumentException("Invalid time range");
    4.37 +        }
    4.38 +
    4.39 +        this.currency1 = currency1;
    4.40 +        this.currency2 = currency2;
    4.41 +        this.rate = rate;
    4.42 +        this.fromTime = fromTime;
    4.43 +        this.toTime = toTime;
    4.44      }
    4.45  
    4.46      public String getCurrency1() {
    4.47 @@ -34,4 +59,12 @@
    4.48          return rate;
    4.49      }
    4.50  
    4.51 +    public long getFromTime() {
    4.52 +        return fromTime;
    4.53 +    }
    4.54 +
    4.55 +    public long getToTime() {
    4.56 +        return toTime;
    4.57 +    }
    4.58 +
    4.59  }
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/task4/solution14/src/org/apidesign/apifest08/currency/TimeLimitedCurrencyRate.java	Fri Oct 17 17:35:52 2008 +0200
     5.3 @@ -0,0 +1,9 @@
     5.4 +package org.apidesign.apifest08.currency;
     5.5 +
     5.6 +
     5.7 +public interface TimeLimitedCurrencyRate extends CurrencyRate {
     5.8 +
     5.9 +    public long getFromTime();
    5.10 +    public long getToTime();
    5.11 +
    5.12 +}
     6.1 --- a/task4/solution14/test/org/apidesign/apifest08/test/Task2Test.java	Fri Oct 17 17:34:40 2008 +0200
     6.2 +++ b/task4/solution14/test/org/apidesign/apifest08/test/Task2Test.java	Fri Oct 17 17:35:52 2008 +0200
     6.3 @@ -86,7 +86,7 @@
     6.4       * API clients to code anything complex.
     6.5       */
     6.6      public static Convertor merge(Convertor one, Convertor two) {
     6.7 -        return ConvertorFactory.newInstance().mergeConvertors(one,two);
     6.8 +        return ConvertorFactory.newInstance().mergeConvertorsIgnoreEqualCurrencies(one,two);
     6.9      }
    6.10  
    6.11      /** Join the convertors from previous task, Task1Test and show that it
     7.1 --- a/task4/solution14/test/org/apidesign/apifest08/test/Task4Test.java	Fri Oct 17 17:34:40 2008 +0200
     7.2 +++ b/task4/solution14/test/org/apidesign/apifest08/test/Task4Test.java	Fri Oct 17 17:35:52 2008 +0200
     7.3 @@ -1,8 +1,10 @@
     7.4  package org.apidesign.apifest08.test;
     7.5  
     7.6  import java.util.Date;
     7.7 +import java.util.GregorianCalendar;
     7.8  import junit.framework.TestCase;
     7.9  import org.apidesign.apifest08.currency.Convertor;
    7.10 +import org.apidesign.apifest08.currency.ConvertorFactory;
    7.11  
    7.12  /** The exchange rates are not always the same. They are changing. However
    7.13   * as in order to predict the future, one needs to understand own past. That is
    7.14 @@ -45,19 +47,14 @@
    7.15       * @return new convertor
    7.16       */
    7.17      public static Convertor limitTo(Convertor old, Date from, Date till) {
    7.18 -        return null;
    7.19 +        return ConvertorFactory.newInstance().limitConvertor(old, from, till);
    7.20      }
    7.21  
    7.22  
    7.23      public void testCompositionOfLimitedConvertors() throws Exception {
    7.24 -        if (Boolean.getBoolean("ignore.failing")) {
    7.25 -            // implement me! then delete this if statement
    7.26 -            return;
    7.27 -        }
    7.28 -
    7.29 -        Date d1 = null; // 2008-10-01 0:00 GMT
    7.30 -        Date d2 = null; // 2008-10-02 0:00 GMT
    7.31 -        Date d3 = null; // 2008-10-03 0:00 GMT
    7.32 +        Date d1 = (new GregorianCalendar(2008, 9, 1, 0, 0)).getTime(); // 2008-10-01 0:00 GMT
    7.33 +        Date d2 = (new GregorianCalendar(2008, 9, 2, 0, 0)).getTime(); // 2008-10-02 0:00 GMT
    7.34 +        Date d3 = (new GregorianCalendar(2008, 9, 3, 0, 0)).getTime(); // 2008-10-03 0:00 GMT
    7.35          
    7.36          Convertor c = Task2Test.merge(
    7.37              limitTo(Task1Test.createCZKtoUSD(), d1, d2),
    7.38 @@ -66,36 +63,77 @@
    7.39  
    7.40          // convert $5 to CZK using c:
    7.41          // cannot convert as no rate is applicable to current date
    7.42 +        try {
    7.43 +            c.convert("USD", "CZK", 5);
    7.44 +            fail();
    7.45 +        } catch (IllegalArgumentException e) {
    7.46 +            //ok
    7.47 +        }
    7.48  
    7.49          // convert $8 to CZK using c:
    7.50          // cannot convert as no rate is applicable to current date
    7.51 +        try {
    7.52 +            c.convert("USD", "CZK", 8);
    7.53 +            fail();
    7.54 +        } catch (IllegalArgumentException e) {
    7.55 +            //ok
    7.56 +        }
    7.57  
    7.58          // convert 1003CZK to USD using c:
    7.59          // cannot convert as no rate is applicable to current date
    7.60 +        try {
    7.61 +            c.convert("CZK", "USD", 1003);
    7.62 +            fail();
    7.63 +        } catch (IllegalArgumentException e) {
    7.64 +            //ok
    7.65 +        }
    7.66  
    7.67          // convert 16CZK using c:
    7.68          // cannot convert as no rate is applicable to current date
    7.69 +        try {
    7.70 +            c.convert("CZK", "USD", 16);
    7.71 +            fail();
    7.72 +        } catch (IllegalArgumentException e) {
    7.73 +            //ok
    7.74 +        }
    7.75  
    7.76          // convert 500SKK to CZK using c:
    7.77          // cannot convert as no rate is applicable to current date
    7.78 +        try {
    7.79 +            c.convert("SKK", "CZK", 500);
    7.80 +            fail();
    7.81 +        } catch (IllegalArgumentException e) {
    7.82 +            //ok
    7.83 +        }
    7.84  
    7.85          // convert $5 to CZK using c at 2008-10-01 6:00 GMT:
    7.86          // assertEquals("Result is 85 CZK");
    7.87 +        assertEquals("Result is 85 CZK", 85.0, c.convert("USD", "CZK", 5, (new GregorianCalendar(2008,9,1,6,0)).getTime()));
    7.88  
    7.89          // convert $8 to CZK using c at 2008-10-01 6:00 GMT:
    7.90          // assertEquals("Result is 136 CZK");
    7.91 +        assertEquals("Result is 136 CZK", 136.0, c.convert("USD", "CZK", 8, (new GregorianCalendar(2008,9,1,6,0)).getTime()));
    7.92  
    7.93          // convert 1003CZK to USD using c at 2008-10-01 6:00 GMT:
    7.94          // assertEquals("Result is 59 USD");
    7.95 +        assertEquals("Result is 59 USD", 59.0, c.convert("CZK", "USD", 1003.0, (new GregorianCalendar(2008, 9, 1, 6, 0)).getTime()));
    7.96  
    7.97          // convert 16CZK using c at 2008-10-02 9:00 GMT:
    7.98          // assertEquals("Result is 20 SKK");
    7.99 +        assertEquals("Result is 20 SKK", 20.0, c.convert("CZK", "SKK", 16.0, (new GregorianCalendar(2008, 9, 2, 9, 0)).getTime()));
   7.100  
   7.101          // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
   7.102          // assertEquals("Result is 400 CZK");
   7.103 +        assertEquals("Result is 400 CZK", 400.0, c.convert("SKK", "CZK", 500.0, (new GregorianCalendar(2008, 9, 2, 9, 0)).getTime()));
   7.104  
   7.105          // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
   7.106          // cannot convert as no rate is applicable to current date
   7.107 +        try {
   7.108 +            c.convert("SKK", "CZK", 500.0, (new GregorianCalendar(2008, 9, 1, 6, 0)).getTime());
   7.109 +            fail();
   7.110 +        } catch (IllegalArgumentException e) {
   7.111 +            //ok
   7.112 +        }
   7.113      }
   7.114  
   7.115      /** Create convertor that understands two currencies, CZK and
   7.116 @@ -104,18 +142,13 @@
   7.117       * @return prepared convertor ready for converting SKK to CZK and CZK to SKK
   7.118       */
   7.119      public static Convertor createSKKtoCZK2() {
   7.120 -        return null;
   7.121 +        return ConvertorFactory.newInstance().createConvertor("SKK", "CZK", 100, 90);
   7.122      }
   7.123  
   7.124      public void testDateConvetorWithTwoDifferentRates() throws Exception {
   7.125 -        if (Boolean.getBoolean("ignore.failing")) {
   7.126 -            // implement me! then delete this if statement
   7.127 -            return;
   7.128 -        }
   7.129 -
   7.130 -        Date d1 = null; // 2008-10-01 0:00 GMT
   7.131 -        Date d2 = null; // 2008-10-02 0:00 GMT
   7.132 -        Date d3 = null; // 2008-10-03 0:00 GMT
   7.133 +        Date d1 = (new GregorianCalendar(2008,9,1,0,0)).getTime(); // 2008-10-01 0:00 GMT
   7.134 +        Date d2 = (new GregorianCalendar(2008,9,2,0,0)).getTime(); // 2008-10-02 0:00 GMT
   7.135 +        Date d3 = (new GregorianCalendar(2008,9,6,0,0)).getTime(); // 2008-10-03 0:00 GMT
   7.136  
   7.137          Convertor c = Task2Test.merge(
   7.138              limitTo(createSKKtoCZK2(), d1, d2),
   7.139 @@ -124,9 +157,11 @@
   7.140  
   7.141          // convert 500SKK to CZK using c at 2008-10-02 9:00 GMT:
   7.142          // assertEquals("Result is 400 CZK");
   7.143 +        assertEquals("Result is 400 CZK", 400.0, c.convert("SKK", "CZK", 500.0, (new GregorianCalendar(2008, 9, 2, 9, 0)).getTime()));
   7.144  
   7.145          // convert 500SKK to CZK using c at 2008-10-01 6:00 GMT:
   7.146          // assertEquals("Result is 450 CZK");
   7.147 +        assertEquals("Result is 450 CZK", 450.0, c.convert("SKK", "CZK", 500.0, (new GregorianCalendar(2008, 9, 1, 6, 0)).getTime()));
   7.148      }
   7.149  
   7.150  }