diff --git a/src/main/java/guru/springframework/Bank.java b/src/main/java/guru/springframework/Bank.java new file mode 100644 index 00000000..6f2c3c0a --- /dev/null +++ b/src/main/java/guru/springframework/Bank.java @@ -0,0 +1,21 @@ +package guru.springframework; + +import java.util.HashMap; + +public class Bank { + private HashMap rateMap = new HashMap<>(); + public Money reduce(Expression source, String toCurrency) { + return source.reduce(this, toCurrency); + } + + public int rate(String from, String to){ + if (from.equals(to)) { + return 1; + } + return rateMap.get(new Pair(from, to)); + + } + public void addRate(String from, String to, int rate) { + rateMap.put(new Pair(from, to), rate); + } +} diff --git a/src/main/java/guru/springframework/Expression.java b/src/main/java/guru/springframework/Expression.java new file mode 100644 index 00000000..27072c0e --- /dev/null +++ b/src/main/java/guru/springframework/Expression.java @@ -0,0 +1,5 @@ +package guru.springframework; + +public interface Expression { + Money reduce(Bank bank, String to); +} diff --git a/src/main/java/guru/springframework/Money.java b/src/main/java/guru/springframework/Money.java new file mode 100644 index 00000000..30df6a94 --- /dev/null +++ b/src/main/java/guru/springframework/Money.java @@ -0,0 +1,49 @@ +package guru.springframework; + +public class Money implements guru.springframework.Expression { + protected int amount; + protected String currency; + public Money(int amount, String currency) { + this.amount = amount; + this.currency = currency; + } + + protected String currency() { + return currency; + } + + + public static Money franc(int amount){return new Money(amount, "CHF");} + + public static Money dollar(int amount){ + return new Money(amount, "USD"); + } + public boolean equals(Object object){ + Money money = (Money) object; + return amount == money.amount + && this.currency == money.currency; + } + + @Override + public Money reduce(Bank bank, String to){ + //return this; + //int rate = (currency.equals("CHF") && to.equals("USD")) ? 2 : 1; + return new Money(amount / bank.rate(this.currency, to), to); + } + + @Override + public String toString() { + return "Money{" + + "amount=" + amount + + ", currency='" + currency + '\'' + + '}'; + } + + public Money times(int multiplier) { + return new Money(amount * multiplier, this.currency); + } + + public Expression plus(Money addend) { + return new Sum(this, addend); + } +} diff --git a/src/main/java/guru/springframework/Pair.java b/src/main/java/guru/springframework/Pair.java new file mode 100644 index 00000000..c9f73e7e --- /dev/null +++ b/src/main/java/guru/springframework/Pair.java @@ -0,0 +1,27 @@ +package guru.springframework; + +import java.util.Objects; + +public class Pair { + + private final String from; + private final String to; + + public Pair(String from, String to) { + this.from = from; + this.to = to; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Pair)) return false; + Pair pair = (Pair) o; + return Objects.equals(from, pair.from) && Objects.equals(to, pair.to); + } + + @Override + public int hashCode() { + return Objects.hash(from, to); + } +} diff --git a/src/main/java/guru/springframework/Sum.java b/src/main/java/guru/springframework/Sum.java new file mode 100644 index 00000000..7bba7ebc --- /dev/null +++ b/src/main/java/guru/springframework/Sum.java @@ -0,0 +1,17 @@ +package guru.springframework; + +public class Sum implements Expression{ + Money augmend; + Money addmend; + + public Sum(Money augmend, Money addmend) { + this.augmend = augmend; + this.addmend = addmend; + } + + @Override + public Money reduce(Bank bank, String to){ + int amount = augmend.amount + addmend.amount; + return new Money(amount, to); + } +} diff --git a/src/test/java/guru/springframework/MoneyTest.java b/src/test/java/guru/springframework/MoneyTest.java new file mode 100644 index 00000000..55b31843 --- /dev/null +++ b/src/test/java/guru/springframework/MoneyTest.java @@ -0,0 +1,81 @@ +package guru.springframework; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +public class MoneyTest { +//TODO on Dell 16, Project Structure was running Java 17. Had to be rolled back to Java 11 to avoid warnings +//Dell 16, Project Structure was running Java 17. Had to be rolled back to Java 11 to avoid warnings + @Test + void testMultiplication(){ + Money five = Money.dollar(5); + assertEquals(Money.dollar(10), five.times(2)); + assertEquals(Money.dollar(15), five.times(3)); + Money fiveF = Money.franc(5); + assertEquals(Money.franc(10), fiveF.times(2)); + + } + + @Test + void testEquality(){ + assertEquals(Money.dollar(5), Money.dollar(5)); + assertNotEquals(Money.dollar(5), Money.dollar(8)); + assertEquals(Money.franc(5), Money.franc(5)); + assertNotEquals(Money.dollar(5), Money.franc(5)); + } + + @Test + void testCurrency(){ + assertEquals("USD", Money.dollar(1).currency()); + assertEquals("CHF", Money.franc(1).currency()); + } + + @Test + void testSimpleAddition(){ + Money five = Money.dollar(5); + Expression sum = (Expression) five.plus(five); + Bank bank = new Bank(); + Money reduced = bank.reduce(sum, "USD"); + assertEquals(Money.dollar(10), reduced); + } + + @Test + void testPlusReturnsSum() { + Money five = Money.dollar(5); + Expression result = five.plus(five); + Sum sum = (Sum) result; + assertEquals(five, sum.augmend); + assertEquals(five, sum.addmend); + } + + @Test + void testReduceSum() { + Expression sum = new Sum(Money.dollar(3), Money.dollar(4)); + Bank bank = new Bank(); + Money result = bank.reduce(sum, "USD"); + assertEquals(Money.dollar(7), result); + } + + @Test + void testReduceMoney() { + Bank bank = new Bank(); + Money result = bank.reduce(Money.dollar(1), "USD"); + assertEquals(Money.dollar(1), result); + } + + @Test + void testReduceMoneyDifferentCurrency() { + Bank bank = new Bank(); + bank.addRate("CHF", "USD", 2); + Money result = bank.reduce(Money.franc(2), "USD"); + assertEquals(Money.dollar(1), result); + } + + @Test + void testIdentityRate() { + assertEquals(1, new Bank().rate("USD", "USD")); + assertEquals(1, new Bank().rate("CHF", "CHF")); + } +}