Skip to content
21 changes: 21 additions & 0 deletions src/main/java/guru/springframework/Bank.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package guru.springframework;

import java.util.HashMap;

public class Bank {
private HashMap<Pair, Integer> 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);
}
}
5 changes: 5 additions & 0 deletions src/main/java/guru/springframework/Expression.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package guru.springframework;

public interface Expression {
Money reduce(Bank bank, String to);
}
49 changes: 49 additions & 0 deletions src/main/java/guru/springframework/Money.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
27 changes: 27 additions & 0 deletions src/main/java/guru/springframework/Pair.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
17 changes: 17 additions & 0 deletions src/main/java/guru/springframework/Sum.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
81 changes: 81 additions & 0 deletions src/test/java/guru/springframework/MoneyTest.java
Original file line number Diff line number Diff line change
@@ -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"));
}
}