Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/main/java/millions/Exchange.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,33 @@ public Exchange(String name, List<Stock> stockList) {
this.stocks = new HashMap<>();
this.weekNumber = 1;

if (name == null || name.isBlank()) {
throw new IllegalArgumentException("Exchange name cannot be null or blank");
}

// Populate the stocks map to get ticker -> stock
for (Stock stock : stockList) {
this.stocks.put(stock.getSymbol(), stock);
}
}

public void buy(Player player, Stock stock, BigDecimal quantity) {
public void buy(String symbol, Player player, BigDecimal quantity) {

Stock stock = this.stocks.get(symbol);
if (stock == null) {
throw new IllegalArgumentException("Stock not found");
}

Share shareToBuy = new Share(stock, quantity, stock.getSalesPrice());
Purchase purchase = new Purchase(shareToBuy, this.weekNumber);
purchase.commit(player);
}

public void sell(Player player, Share share) {
public void buy(String symbol, Player player, int quantity) {
this.buy(symbol, player, BigDecimal.valueOf(quantity));
}

public void sell(Share share, Player player) {
Sale sale = new Sale(share, weekNumber);
sale.commit(player);
}
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/millions/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,27 @@ public Player(String name, BigDecimal startingMoney) {
this.money = startingMoney;
this.portfolio = new Portfolio();
this.transactionArchive = new TransactionArchive();

if (name == null || name.isBlank()) {
throw new IllegalArgumentException("Player name cannot be null or blank");
}

if (startingMoney == null || startingMoney.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Starting money cannot be null or negative");
}
}

public void addMoney(BigDecimal amount) {
if (amount == null || amount.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Amount cannot be null or negative");
}
this.money = this.money.add(amount);
}

public void withdrawMoney(BigDecimal amount) {
if (amount == null || amount.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Amount cannot be null or negative");
}
this.money = this.money.subtract(amount);
}

Expand Down
14 changes: 14 additions & 0 deletions src/main/java/millions/Share.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ public Share(Stock stock, BigDecimal quantity, BigDecimal purchasePrice) {
this.stock = stock;
this.quantity = quantity;
this.purchasePrice = purchasePrice;

if (stock == null) {
throw new IllegalArgumentException("Stock cannot be null");
}
if (quantity == null) {
throw new IllegalArgumentException("Quantity cannot be null");
}
if (purchasePrice == null) {
throw new IllegalArgumentException("Purchase price cannot be null");
}
}

public Share(Stock stock, int quantity, BigDecimal purchasePrice) {
this(stock, BigDecimal.valueOf(quantity), purchasePrice);
}

public Stock getStock() {
Expand Down
15 changes: 14 additions & 1 deletion src/main/java/millions/Stock.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package millions;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class Stock {
Expand All @@ -11,7 +12,19 @@ public class Stock {
public Stock(String symbol, String company, List<BigDecimal> prices) {
this.symbol = symbol;
this.company = company;
this.prices = prices;
this.prices = new ArrayList<>(prices);

if (symbol == null || symbol.isBlank()) {
throw new IllegalArgumentException("Symbol cannot be null or blank");
}

if (company == null || company.isBlank()) {
throw new IllegalArgumentException("Company cannot be null or blank");
}
}

public Stock(String symbol, String company, BigDecimal initialPrice) {
this(symbol, company, new ArrayList<>(List.of(initialPrice)));
}

public String getSymbol() {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/millions/calculators/SaleCalculator.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class SaleCalculator implements TransactionCalculator {
public SaleCalculator(Share share) {
super();
this.purchasePrice = share.getPurchasePrice();
this.salesPrice = share.getStock().getSalesPrice();
this.quantity = share.getQuantity();
}

@Override
Expand Down
80 changes: 79 additions & 1 deletion src/test/java/millions/ExchangeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,82 @@

import static org.junit.jupiter.api.Assertions.*;

class ExchangeTest {}
import java.math.BigDecimal;
import java.util.List;
import org.junit.jupiter.api.Test;

class ExchangeTest {
@Test
public void testGetters() {
Stock s1 = new Stock("PEAR", "Pear Inc.", BigDecimal.valueOf(300));
Stock s2 = new Stock("DOGL", "DOOGLE Inc.", BigDecimal.valueOf(200.00));
Stock s3 = new Stock("MSFT", "EpsteinSoft Inc.", BigDecimal.valueOf(0.02));

Exchange exchange = new Exchange("exchange", List.of(s1, s2));

assertFalse(exchange.hasStock("MSFT"));
assertTrue(exchange.getStock("DOGL").equals(s2));
assertNull(exchange.getStock("XYZ"));
assertTrue(exchange.findStocks("Amozon").isEmpty());

assertTrue(exchange.hasStock("DOGL"));
assertFalse(exchange.findStocks("Pear").isEmpty());
assertFalse(exchange.findStocks("PE").isEmpty());

assertTrue(exchange.findStocks("Inc").size() == 2);
}

@Test
public void happyPath() {
Stock s1 = new Stock("PEAR", "Pear Inc.", BigDecimal.valueOf(300));
Stock s2 = new Stock("DOGL", "DOOGLE Inc.", BigDecimal.valueOf(200.00));
Stock s3 = new Stock("MSFT", "EpsteinSoft Inc.", BigDecimal.valueOf(0.02));

Exchange exchange = new Exchange("exchange", List.of(s1, s2, s3));
Player player = new Player("name", BigDecimal.valueOf(1000));

BigDecimal previousMoney = player.getMoney();
exchange.buy("PEAR", player, 2);
assertTrue(previousMoney.compareTo(player.getMoney()) > 0);

BigDecimal previousPrice = s1.getSalesPrice();
exchange.advance();
assertFalse(previousPrice.equals(s1.getSalesPrice()));

Share share = player.getPortfolio().getShares().getFirst();

previousMoney = player.getMoney();
exchange.sell(share, player);
assertTrue(previousMoney.compareTo(player.getMoney()) < 0);
assertTrue(player.getPortfolio().getShares().isEmpty());
}

@Test
public void testNullsAndInvalid() {
Stock s1 = new Stock("MSFT", "EpsteinSoft Inc.", BigDecimal.valueOf(0.02));

Exchange exchange = new Exchange("exchange", List.of(s1));
Player player = new Player("name", BigDecimal.valueOf(1000));

Share unownedShare = new Share(s1, BigDecimal.valueOf(1), s1.getSalesPrice());
assertThrows(IllegalStateException.class, () -> exchange.sell(unownedShare, player));

Player noMoney = new Player("nomoney", BigDecimal.valueOf(0));
assertThrows(IllegalStateException.class, () -> exchange.buy("MSFT", noMoney, 1));

assertThrows(
IllegalArgumentException.class,
() -> new Exchange("", List.of(new Stock("PEAR", "Pear Inc.", BigDecimal.valueOf(300)))));

assertThrows(
IllegalArgumentException.class,
() -> new Exchange(null, List.of(new Stock("PEAR", "Pear Inc.", BigDecimal.valueOf(300)))));

assertThrows(IllegalArgumentException.class, () -> exchange.buy("DOGL", player, 2));

assertThrows(IllegalArgumentException.class, () -> exchange.buy("DOGL", player, -2));

assertThrows(
IllegalArgumentException.class, () -> exchange.buy("DOGL", player, BigDecimal.valueOf(-2)));
}
}
35 changes: 34 additions & 1 deletion src/test/java/millions/PlayerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,37 @@

import static org.junit.jupiter.api.Assertions.*;

class PlayerTest {}
import java.math.BigDecimal;
import org.junit.jupiter.api.Test;

class PlayerTest {

@Test
public void happyPath() {
Player player = new Player("name", BigDecimal.valueOf(1000));
assertEquals(BigDecimal.valueOf(1000), player.getMoney());

player.addMoney(BigDecimal.valueOf(500));
assertEquals(BigDecimal.valueOf(1500), player.getMoney());

player.withdrawMoney(BigDecimal.valueOf(200));
assertEquals(BigDecimal.valueOf(1300), player.getMoney());
}

@Test
public void testGetters() {
Player player = new Player("name", BigDecimal.valueOf(1000));
assertEquals("name", player.getName());
assertEquals(BigDecimal.valueOf(1000), player.getMoney());
assertTrue(player.getPortfolio().getShares().isEmpty());
assertTrue(player.getTransactionArchive().isEmpty());
}

@Test
public void testNullsAndInvalid() {
assertThrows(IllegalArgumentException.class, () -> new Player(null, BigDecimal.valueOf(1000)));
assertThrows(IllegalArgumentException.class, () -> new Player("", BigDecimal.valueOf(1000)));
assertThrows(IllegalArgumentException.class, () -> new Player("name", null));
assertThrows(IllegalArgumentException.class, () -> new Player("name", BigDecimal.valueOf(-1)));
}
}
61 changes: 60 additions & 1 deletion src/test/java/millions/PortfolioTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,63 @@

import static org.junit.jupiter.api.Assertions.*;

class PortfolioTest {}
import java.math.BigDecimal;
import org.junit.jupiter.api.Test;

class PortfolioTest {

@Test
public void happyPath() {
Portfolio portfolio = new Portfolio();
Stock stock = new Stock("PEAR", "Pear Inc.", BigDecimal.valueOf(300));
Share share = new Share(stock, 10, BigDecimal.valueOf(300));

assertTrue(portfolio.addShare(share));
assertTrue(portfolio.contains(share));
assertEquals(1, portfolio.getShares().size());
assertEquals(share, portfolio.getShares().get(0));

assertTrue(portfolio.removeShare(share));
assertFalse(portfolio.contains(share));
assertTrue(portfolio.getShares().isEmpty());
}

@Test
public void testGettersAndSetters() {
Portfolio portfolio = new Portfolio();
Stock stock1 = new Stock("PEAR", "Pear Inc.", BigDecimal.valueOf(300));
Stock stock2 = new Stock("DOGL", "DOOGLE Inc.", BigDecimal.valueOf(200.00));
Share share1 = new Share(stock1, 10, BigDecimal.valueOf(300));
Share share2 = new Share(stock2, 5, BigDecimal.valueOf(200));

portfolio.addShare(share1);
portfolio.addShare(share2);

assertEquals(2, portfolio.getShares().size());
assertTrue(portfolio.getShares().contains(share1));
assertTrue(portfolio.getShares().contains(share2));

assertEquals(1, portfolio.getShares("PEAR").size());
assertTrue(portfolio.getShares("PEAR").contains(share1));
assertFalse(portfolio.getShares("PEAR").contains(share2));

assertEquals(1, portfolio.getShares("DOGL").size());
assertFalse(portfolio.getShares("DOGL").contains(share1));
assertTrue(portfolio.getShares("DOGL").contains(share2));

assertTrue(portfolio.getShares("XYZ").isEmpty());

portfolio.removeShare(share1);
assertEquals(1, portfolio.getShares().size());
}

@Test
public void testNullsAndInvalid() {
Stock stock1 = new Stock("PEAR", "Pear Inc.", BigDecimal.valueOf(300));
Share share1 = new Share(stock1, 10, BigDecimal.valueOf(300));
Portfolio portfolio = new Portfolio();
assertFalse(portfolio.removeShare(null));
assertFalse(portfolio.contains(null));
assertFalse(portfolio.removeShare(share1));
}
}
37 changes: 36 additions & 1 deletion src/test/java/millions/PurchaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,39 @@

import static org.junit.jupiter.api.Assertions.*;

class PurchaseTest {}
import java.math.BigDecimal;
import org.junit.jupiter.api.Test;

class PurchaseTest {
@Test
public void testHappyPath() {
Stock stock = new Stock("TestStock", "TST", BigDecimal.valueOf(10));
Share share = new Share(stock, 2, BigDecimal.valueOf(10));
Player player = new Player("TestPlayer", BigDecimal.valueOf(100));
Purchase purchase = new Purchase(share, 1);
purchase.commit(player);
assertTrue(purchase.isCommitted());

// 1 less because of tax
assertEquals(79, player.getMoney().intValue());
assertTrue(player.getPortfolio().getShares().contains(share));
}

@Test
public void testNullsAndInvalid() {

Stock stock = new Stock("TestStock", "TST", BigDecimal.valueOf(10));
Share share = new Share(stock, 2, BigDecimal.valueOf(10));
Player player = new Player("TestPlayer", BigDecimal.valueOf(100));
Purchase purchase = new Purchase(share, 1);

// Double commit
purchase.commit(player);
assertThrows(IllegalStateException.class, () -> purchase.commit(player));

// Insufficient funds
Player poorPlayer = new Player("PoorPlayer", BigDecimal.valueOf(10));
Purchase expensivePurchase = new Purchase(new Share(stock, 20, BigDecimal.valueOf(10)), 1);
assertThrows(IllegalStateException.class, () -> expensivePurchase.commit(poorPlayer));
}
}
29 changes: 28 additions & 1 deletion src/test/java/millions/SaleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,31 @@

import static org.junit.jupiter.api.Assertions.*;

class SaleTest {}
import java.math.BigDecimal;
import org.junit.jupiter.api.Test;

class SaleTest {

@Test
public void testHappyPath() {
Stock stock = new Stock("TestStock", "TST", BigDecimal.valueOf(10));
Share share = new Share(stock, 2, BigDecimal.valueOf(10));
Player player = new Player("TestPlayer", BigDecimal.valueOf(100));
player.getPortfolio().addShare(share);
Sale sale = new Sale(share, 1);
sale.commit(player);
assertTrue(sale.isCommitted());

assertEquals(120, player.getMoney().intValue());
assertFalse(player.getPortfolio().getShares().contains(share));
}

@Test
public void testNullsAndInvalid() {
Stock stock = new Stock("TestStock", "TST", BigDecimal.valueOf(10));
Share share = new Share(stock, 2, BigDecimal.valueOf(10));
Player player = new Player("TestPlayer", BigDecimal.valueOf(100));
Sale sale = new Sale(share, 1);
assertThrows(IllegalStateException.class, () -> sale.commit(player));
}
}
Loading