diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Exchange.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Exchange.java index 6276925..5115125 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Exchange.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Exchange.java @@ -1,81 +1,218 @@ package edu.ntnu.idi.idatt2003.g40.mappe; import java.math.BigDecimal; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; /** * Represents a stock exchange where stocks can be traded. - */ -public class Exchange { - - private final String name; - private int week; - private final Map stockMap; - private final Random random; - - public Exchange(String name, List stocks) { - this.name = name; - this.week = 1; - this.stockMap = new HashMap<>(); - this.random = new Random(); - - for (Stock stock : stocks) { - stockMap.put(stock.getSymbol(), stock); - } + * + *

Holds a map of stocks where stock symbol is key and stock is value.

+ * + *

Delegates buying and selling to player elements using calculators

+ * + *

Advances week.

+ * + * @see Player + * @see TransactionCalculator + * */ +public final class Exchange { + + /** + * Exchange name. + * */ + private final String name; + + /** + * Current week (set to 1 in constructor). + * */ + private int week; + + /** + * Map of {@link Stock} objects. Key is stock symbol. Value is stock. + * */ + private final Map stockMap; + + /** + * Random value determining week changes. + * */ + private final Random random; + + /** + * Constructor. + * + * @param name name of exchange. + * @param stocks list of {@link Stock} objects. + * */ + public Exchange(final String name, final List stocks) { + this.name = name; + this.week = 1; + this.stockMap = new HashMap<>(); + this.random = new Random(); + + for (Stock stock : stocks) { + stockMap.put(stock.getSymbol(), stock); } - - public String getName() { - return name; - } - - public int getWeek() { - return week; - } - - public boolean hasStock(String symbol) { - return stockMap.containsKey(symbol); - } - - public Stock getStock(String symbol) { - return stockMap.get(symbol); - } - - public List findStocks(String searchTerm) { - List result = new ArrayList<>(); - for (Stock stock : stockMap.values()) { - if (stock.getSymbol().toLowerCase().contains(searchTerm.toLowerCase()) - || stock.getCompany().toLowerCase().contains(searchTerm.toLowerCase())) { - result.add(stock); - } - } - return result; + } + + /** + * Getter method for name. + * + * @return name of exchange. + * */ + public String getName() { + return name; + } + + /** + * Getter method for current week. + * + * @return week. + * */ + public int getWeek() { + return week; + } + + /** + * Method for checking whether exchange has a stock. + * + * @param symbol the stock symbol. + * + * @return true or false. + * */ + public boolean hasStock(final String symbol) { + return stockMap.containsKey(symbol); + } + + /** + * Getter method for stock element. + * + * @param symbol the symbol of the stock to get. + * + * @return {@link Stock} element gotten. + * */ + public Stock getStock(final String symbol) { + return stockMap.get(symbol); + } + + /** + * Returns a list of stocks matching a given search term. + * + * @param searchTerm the term to search for. + * + * @return a list of {@link Stock} objects. + * */ + public List findStocks(final String searchTerm) { + List result = new ArrayList<>(); + for (Stock stock : stockMap.values()) { + if (stock.getSymbol().toLowerCase() + .contains(searchTerm.toLowerCase()) + || stock.getCompany().toLowerCase() + .contains(searchTerm.toLowerCase())) { + result.add(stock); + } } - - public Transaction buy(String symbol, BigDecimal quantity, Player player) { - Stock stock = stockMap.get(symbol); - Share share = new Share(stock, quantity, stock.getSalesPrice()); - TransactionCalculator calculator = new PurchaseCalculator(share); - player.withdrawMoney(calculator.calculateTotal()); - return new Purchase(share, week, calculator); - } - - public Transaction sell(Share share, Player player) { - TransactionCalculator calculator = new SaleCalculator(share); - player.addMoney(calculator.calculateTotal()); - return new Sale(share, week, calculator); - } - - public void advance() { - week++; - - for (Stock stock : stockMap.values()) { - BigDecimal currentPrice = stock.getSalesPrice(); - - double change = (random.nextDouble() * 0.10) - 0.05; - BigDecimal factor = BigDecimal.valueOf(1 + change); - - BigDecimal newPrice = currentPrice.multiply(factor); - stock.addNewSalesPrice(newPrice); - } + return result; + } + + /** + * Method called when a player buys a stock. + * + * @param symbol the stock this player buys. + * @param quantity the amount of stock to buy. + * @param player the player buying stock. + * + * @return Transaction representing the transaction. + * */ + public Transaction buy(final String symbol, + final BigDecimal quantity, + final Player player) { + Stock stock = stockMap.get(symbol); + Share share = new Share(stock, quantity, stock.getSalesPrice()); + TransactionCalculator calculator = new PurchaseCalculator(share); + player.withdrawMoney(calculator.calculateTotal()); + return new Purchase(share, week, calculator); + } + + /** + * Method called when a player sells share. + * + * @param share the share to sell. + * @param player the player buying stock. + * + * @return Transaction representing the transaction. + * */ + public Transaction sell(final Share share, final Player player) { + TransactionCalculator calculator = new SaleCalculator(share); + player.addMoney(calculator.calculateTotal()); + return new Sale(share, week, calculator); + } + + /** + * Method for advancing time, increasing the amount of weeks. + * */ + public void advance() { + week++; + + for (Stock stock : stockMap.values()) { + BigDecimal currentPrice = stock.getSalesPrice(); + + double change = (random.nextDouble() * 0.10) - 0.05; + BigDecimal factor = BigDecimal.valueOf(1 + change); + + BigDecimal newPrice = currentPrice.multiply(factor); + stock.addNewSalesPrice(newPrice); } -} \ No newline at end of file + } + + /** + * Method for getting the stocks with the most + * amount of increase since last week. + * + * @param limit the maximum amount of stocks returned + * + * @return list of {@link Stock} objects. + * */ + public List getGainers(final int limit) { + return stockMap.entrySet().stream() + // We only want the stocks with a positive price change. + .filter(e -> + e.getValue().getLatestPriceChange() + .compareTo(BigDecimal.ZERO) > 0) + // We sort the stocks based on the price change. + .sorted((e1, e2) -> + e2.getValue().getLatestPriceChange() + .compareTo(e1.getValue().getLatestPriceChange())) + // Sets a limit to the stream. + .limit(limit) + .map(Map.Entry::getValue) + // Converts to a list + .toList(); + } + + /** + * Method for getting the stocks with the highest + * loss of price since last week. + * + * @param limit the maximum amount of stocks returned + * + * @return list of {@link Stock} objects. + * */ + public List getLosers(final int limit) { + return stockMap.entrySet().stream() + // Only get entries with negative price change. + .filter(e -> + e.getValue().getLatestPriceChange() + .compareTo(BigDecimal.ZERO) < 0) + // Sort (lowest first) + .sorted((e1, e2) -> + e1.getValue().getLatestPriceChange() + .compareTo(e2.getValue().getLatestPriceChange())) + .limit(limit) + .map(Map.Entry::getValue) + .toList(); + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Player.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Player.java index 0d5939d..9186f09 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Player.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Player.java @@ -2,79 +2,122 @@ import java.math.BigDecimal; -public class Player { +/** + * Represents a player in the system. + * + *

Each player:

+ *
    + *
  • Has a portfolio
  • + *
  • Can buy and sell shares on an {@link Exchange}
  • + *
  • Has a set amount of money to use on said exchange.
  • + *
  • Has a {@link TransactionArchive}
  • + *
+ * */ +public final class Player { - private final String name; - private final BigDecimal startingMoney; - private BigDecimal money; - private final Portfolio portfolio; - private final TransactionArchive transactionArchive; + /** + * Name of player. + * */ + private final String name; - /** - * Creates a new player with a given name and starting capital. - * - * @param name the name of the player - * @param startingMoney the starting amount of money - */ - public Player(String name, BigDecimal startingMoney) { - this.name = name; - this.startingMoney = startingMoney; - this.money = this.startingMoney; - this.portfolio = new Portfolio(); - this.transactionArchive = new TransactionArchive(); - } + /** + * Starting money of player. + * */ + private final BigDecimal startingMoney; - /** - * Returns the name of the player. - * - * @return the player's name - */ - public String getName() { - return name; - } + /** + * Current money of player. + * */ + private BigDecimal money; - /** - * Returns the players current balance. - * - * @return the current amount of money - */ - public BigDecimal getMoney() { - return money; - } + /** + * The players' portfolio, holding their shares. + * */ + private final Portfolio portfolio; - /** - * Adds money to the players balance. - * - * @param amount the amount to add - */ - public void addMoney(BigDecimal amount) { - money = money.add(amount); - } + /** + * The players' transaction archive, + * holding a history of transactions on the exchange. + * */ + private final TransactionArchive transactionArchive; - /** - * Withdraws money from the players balance. - * - * @param amount the amount to withdraw - */ - public void withdrawMoney(BigDecimal amount) { - money = money.subtract(amount); - } + /** + * Creates a new player with a given name and starting capital. + * + * @param name the name of the player + * @param startingMoney the starting amount of money + */ + public Player(final String name, final BigDecimal startingMoney) { + this.name = name; + this.startingMoney = startingMoney; + this.money = this.startingMoney; + this.portfolio = new Portfolio(); + this.transactionArchive = new TransactionArchive(); + } - /** - * Returns the players portfolio. - * - * @return the portfolio - */ - public Portfolio getPortfolio() { - return portfolio; - } + /** + * Returns the name of the player. + * + * @return the player's name + */ + public String getName() { + return name; + } - /** - * Returns the players transaction archive. - * - * @return the transaction archive - */ - public TransactionArchive getTransactionArchive() { - return transactionArchive; - } -} \ No newline at end of file + /** + * Returns the players current balance. + * + * @return the current amount of money + */ + public BigDecimal getMoney() { + return money; + } + + /** + * Adds money to the players balance. + * + * @param amount the amount to add + */ + public void addMoney(final BigDecimal amount) { + money = money.add(amount); + } + + /** + * Withdraws money from the players balance. + * + * @param amount the amount to withdraw + */ + public void withdrawMoney(final BigDecimal amount) { + money = money.subtract(amount); + } + + /** + * Returns the players portfolio. + * + * @return the portfolio + */ + public Portfolio getPortfolio() { + return portfolio; + } + + /** + * Returns the players transaction archive. + * + * @return the transaction archive + */ + public TransactionArchive getTransactionArchive() { + return transactionArchive; + } + + /** + * Returns the total net worth of the player, + * including the shares in the players' portfolio. + * + * @return the net worth of the player. + * */ + public BigDecimal getNetWorth() { + BigDecimal netWorth = new BigDecimal("0"); + netWorth = netWorth.add(portfolio.getNetWorth()).add(money); + return netWorth; + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Portfolio.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Portfolio.java index f27e44c..25b0953 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Portfolio.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Portfolio.java @@ -1,79 +1,102 @@ package edu.ntnu.idi.idatt2003.g40.mappe; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** * Represents a player's portfolio of shares. - *

- * The portfolio stores shares and provides operations for adding, removing, - * retrieving and checking ownership of shares. - *

+ * + *

The portfolio stores shares and provides operations for adding, removing, + * retrieving and checking ownership of shares.

*/ -public class Portfolio { +public final class Portfolio { - private final List shares = new ArrayList<>(); + /** + * List of shares. + * */ + private final List shares = new ArrayList<>(); - /** - * Creates an empty portfolio. - */ - public Portfolio() { - // Intentionally empty - } + /** + * Creates an empty portfolio. + */ + public Portfolio() { + // Intentionally empty + } - /** - * Adds a share to the portfolio. - * - * @param share the share to add - * @return {@code true} if the share was added, {@code false} otherwise - */ - public boolean addShare(Share share) { - Objects.requireNonNull(share, "share cannot be null"); - return shares.add(share); - } + /** + * Adds a share to the portfolio. + * + * @param share the share to add + * @return {@code true} if the share was added, {@code false} otherwise + */ + public boolean addShare(final Share share) { + Objects.requireNonNull(share, "share cannot be null"); + return shares.add(share); + } - /** - * Removes a share from the portfolio. - * - * @param share the share to remove - * @return {@code true} if the share was removed, {@code false} if it was not present - */ - public boolean removeShare(Share share) { - Objects.requireNonNull(share, "share cannot be null"); - return shares.remove(share); - } + /** + * Removes a share from the portfolio. + * + * @param share the share to remove + * @return {@code true} if the share was removed, + * {@code false} if it was not present. + */ + public boolean removeShare(final Share share) { + Objects.requireNonNull(share, "share cannot be null"); + return shares.remove(share); + } - /** - * Returns an immutable snapshot of all shares in the portfolio. - * - * @return a list of shares - */ - public List getShares() { - return List.copyOf(shares); - } + /** + * Returns an immutable snapshot of all shares in the portfolio. + * + * @return a list of shares + */ + public List getShares() { + return List.copyOf(shares); + } - /** - * Returns an immutable snapshot of all shares whose stock symbol matches the given symbol. - * - * @param symbol the stock symbol to match - * @return a list of shares matching the symbol - */ - public List getShares(String symbol) { - Objects.requireNonNull(symbol, "symbol cannot be null"); - return shares.stream() - .filter(s -> symbol.equalsIgnoreCase(s.getStock().getSymbol())) - .toList(); - } + /** + * Returns an immutable snapshot of all shares whose + * stock symbol matches the given symbol. + * + * @param symbol the stock symbol to match + * @return a list of shares matching the symbol + */ + public List getShares(final String symbol) { + Objects.requireNonNull(symbol, "symbol cannot be null"); + return shares.stream() + .filter(s -> symbol.equalsIgnoreCase(s.getStock().getSymbol())) + .toList(); + } + + /** + * Checks whether the given share exists in the portfolio. + * + * @param share the share to check + * @return {@code true} if the portfolio + * contains the share, otherwise {@code false} + */ + public boolean contains(final Share share) { + Objects.requireNonNull(share, "share cannot be null"); + return shares.contains(share); + } + + /** + * Returns the total net worth of the portfolios shares, + * using a sale calculator. + * + * @return the net worth. + * */ + public BigDecimal getNetWorth() { + BigDecimal netWorth = new BigDecimal("0"); + + for (Share s : shares) { + SaleCalculator calculator = new SaleCalculator(s); - /** - * Checks whether the given share exists in the portfolio. - * - * @param share the share to check - * @return {@code true} if the portfolio contains the share, otherwise {@code false} - */ - public boolean contains(Share share) { - Objects.requireNonNull(share, "share cannot be null"); - return shares.contains(share); + netWorth = netWorth.add(calculator.calculateTotal()); } + return netWorth; + } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Purchase.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Purchase.java index 717c73c..f042cb0 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Purchase.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Purchase.java @@ -6,16 +6,19 @@ *

Extends {@link Transaction}

* * */ -public class Purchase extends Transaction { +public final class Purchase extends Transaction { /** * Constructor. * * @param share the {@link Share} object to purchase. * @param week the week to purchase during. - * @param calculator the {@link TransactionCalculator} object to calculate this purchase. + * @param calculator the {@link TransactionCalculator} + * object to calculate this purchase. * */ - public Purchase(final Share share, final int week, final TransactionCalculator calculator) { + public Purchase(final Share share, + final int week, + final TransactionCalculator calculator) { super(share, week, calculator); } @@ -26,6 +29,6 @@ public Purchase(final Share share, final int week, final TransactionCalculator c * */ @Override public void commit(final Player player) { - commited = true; + setCommitted(true); } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseCalculator.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseCalculator.java index 6cffe1c..8e3cf16 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseCalculator.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseCalculator.java @@ -2,66 +2,75 @@ import java.math.BigDecimal; - /** * Calculator for purchase transactions. - *

- * Uses the share's purchase price and quantity to calculate: - * gross value, commission, tax and total cost. - *

+ * + *

Uses the share's purchase price and quantity to calculate: + * gross value, commission, tax and total cost.

*/ -public class PurchaseCalculator implements TransactionCalculator { +public final class PurchaseCalculator implements TransactionCalculator { + + /** + * The constant commission rate for purchases. + * */ + private static final BigDecimal COMMISSION_RATE + = new BigDecimal("0.005"); // 0.5% - private static final BigDecimal COMMISSION_RATE = new BigDecimal("0.005"); // 0.5% + /** + * The price of the purchase. + * */ + private final BigDecimal purchasePrice; - private final BigDecimal purchasePrice; - private final BigDecimal quantity; + /** + * The quantity bought. + * */ + private final BigDecimal quantity; - /** - * Creates a new {@code PurchaseCalculator} based on a share. - * - * @param share the share to base calculations on - */ - public PurchaseCalculator(Share share) { - this.purchasePrice = share.getPurchasePrice(); - this.quantity = share.getQuantity(); - } + /** + * Creates a new {@code PurchaseCalculator} based on a share. + * + * @param share the share to base calculations on + */ + public PurchaseCalculator(final Share share) { + this.purchasePrice = share.getPurchasePrice(); + this.quantity = share.getQuantity(); + } - /** - * {@inheritDoc} - * Gross value = purchasePrice * quantity. - */ - @Override - public BigDecimal calculateGross() { - return purchasePrice.multiply(quantity); - } + /** + * {@inheritDoc} + * Gross value = purchasePrice * quantity. + */ + @Override + public BigDecimal calculateGross() { + return purchasePrice.multiply(quantity); + } - /** - * {@inheritDoc} - * Commission = 0.5% of gross value. - */ - @Override - public BigDecimal calculateCommission() { - return calculateGross().multiply(COMMISSION_RATE); - } + /** + * {@inheritDoc} + * Commission = 0.5% of gross value. + */ + @Override + public BigDecimal calculateCommission() { + return calculateGross().multiply(COMMISSION_RATE); + } - /** - * {@inheritDoc} - * No tax on purchases. - */ - @Override - public BigDecimal calculateTax() { - return BigDecimal.ZERO; - } + /** + * {@inheritDoc} + * No tax on purchases. + */ + @Override + public BigDecimal calculateTax() { + return BigDecimal.ZERO; + } - /** - * {@inheritDoc} - * Total cost = gross + commission + tax. - */ - @Override - public BigDecimal calculateTotal() { - return calculateGross() - .add(calculateCommission()) - .add(calculateTax()); - } + /** + * {@inheritDoc} + * Total cost = gross + commission + tax. + */ + @Override + public BigDecimal calculateTotal() { + return calculateGross() + .add(calculateCommission()) + .add(calculateTax()); + } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Sale.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Sale.java index 8fcf55b..50cbb24 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Sale.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Sale.java @@ -6,16 +6,19 @@ *

Extends {@link Transaction}

* * */ -public class Sale extends Transaction { +public final class Sale extends Transaction { /** * Constructor. * * @param share the {@link Share} object to purchase. * @param week the week to purchase during. - * @param calculator the {@link TransactionCalculator} object to calculate this purchase. + * @param calculator the {@link TransactionCalculator} + * object to calculate this purchase. * */ - public Sale(final Share share, final int week, final TransactionCalculator calculator) { + public Sale(final Share share, + final int week, + final TransactionCalculator calculator) { super(share, week, calculator); } @@ -26,6 +29,6 @@ public Sale(final Share share, final int week, final TransactionCalculator calcu * */ @Override public void commit(final Player player) { - commited = true; + setCommitted(true); } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleCalculator.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleCalculator.java index ecc4242..8fb6227 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleCalculator.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleCalculator.java @@ -4,75 +4,94 @@ /** * Calculator for sale transactions. - *

- * Calculates gross value, commission, tax and total sale value - * based on the share's purchase price, current sales price and quantity. - *

+ * + *

Calculates gross value, commission, tax and total sale value + * based on the share's purchase price, current sales price and quantity.

*/ -public class SaleCalculator implements TransactionCalculator { +public final class SaleCalculator implements TransactionCalculator { - private static final BigDecimal COMMISSION_RATE = new BigDecimal("0.01"); // 1% - private static final BigDecimal TAX_RATE = new BigDecimal("0.30"); // 30% + /** + * The constant commission rate for sales. + * */ + private static final BigDecimal COMMISSION_RATE = + new BigDecimal("0.01"); // 1% - private final BigDecimal purchasePrice; - private final BigDecimal salesPrice; - private final BigDecimal quantity; + /** + * The constant tax rates for sales. + * */ + private static final BigDecimal TAX_RATE = + new BigDecimal("0.30"); // 30% - /** - * Creates a new {@code SaleCalculator} based on a share. - * - * @param share the share to base calculations on - */ - public SaleCalculator(Share share) { - this.purchasePrice = share.getPurchasePrice(); - this.salesPrice = share.getStock().getSalesPrice(); - this.quantity = share.getQuantity(); - } + /** + * The purchase price of the share. + * */ + private final BigDecimal purchasePrice; - /** - * {@inheritDoc} - * Gross value = salesPrice * quantity. - */ - @Override - public BigDecimal calculateGross() { - return salesPrice.multiply(quantity); - } + /** + * The sale price of the share. + * */ + private final BigDecimal salesPrice; - /** - * {@inheritDoc} - * Commission = 1% of gross value. - */ - @Override - public BigDecimal calculateCommission() { - return calculateGross().multiply(COMMISSION_RATE); - } + /** + * The quantity the share represents. + * */ + private final BigDecimal quantity; - /** - * {@inheritDoc} - * Tax = 30% of profit. - * Profit = gross - commission - (purchasePrice * quantity). - * If profit is negative or zero, tax is zero. - */ - @Override - public BigDecimal calculateTax() { - BigDecimal purchaseCost = purchasePrice.multiply(quantity); - BigDecimal profit = calculateGross() - .subtract(calculateCommission()) - .subtract(purchaseCost); + /** + * Creates a new {@code SaleCalculator} based on a share. + * + * @param share the share to base calculations on + */ + public SaleCalculator(final Share share) { + this.purchasePrice = share.getPurchasePrice(); + this.salesPrice = share.getStock().getSalesPrice(); + this.quantity = share.getQuantity(); + } - return profit.signum() > 0 - ? profit.multiply(TAX_RATE) - : BigDecimal.ZERO; - } + /** + * {@inheritDoc} + * Gross value = salesPrice * quantity. + */ + @Override + public BigDecimal calculateGross() { + return salesPrice.multiply(quantity); + } - /** - * {@inheritDoc} - * Total value = gross - commission - tax. - */ - @Override - public BigDecimal calculateTotal() { - return calculateGross() - .subtract(calculateCommission()) - .subtract(calculateTax()); - } -} \ No newline at end of file + /** + * {@inheritDoc} + * Commission = 1% of gross value. + */ + @Override + public BigDecimal calculateCommission() { + return calculateGross().multiply(COMMISSION_RATE); + } + + /** + * {@inheritDoc} + * Tax = 30% of profit. + * Profit = gross - commission - (purchasePrice * quantity). + * If profit is negative or zero, tax is zero. + */ + @Override + public BigDecimal calculateTax() { + BigDecimal purchaseCost = purchasePrice.multiply(quantity); + BigDecimal profit = calculateGross() + .subtract(calculateCommission()) + .subtract(purchaseCost); + + return profit.signum() > 0 + ? profit.multiply(TAX_RATE) + : BigDecimal.ZERO; + } + + /** + * {@inheritDoc} + * Total value = gross - commission - tax. + */ + @Override + public BigDecimal calculateTotal() { + return calculateGross() + .subtract(calculateCommission()) + .subtract(calculateTax()); + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Share.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Share.java index d27478a..0373bd4 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Share.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Share.java @@ -4,53 +4,66 @@ /** * Represents a share owned by a player. - *

- * A share contains information about which stock was purchased, - * the quantity purchased, and the purchase price. - *

+ * + *

A share contains information about which stock was purchased, + * the quantity purchased, and the purchase price.

*/ -public class Share { - private final Stock stock; - private final BigDecimal quantity; - private final BigDecimal purchasePrice; - - /** - * Creates a new {@code Share}. - * - * @param stock the stock that was purchased - * @param quantity the quantity purchased - * @param purchasePrice the price per unit at purchase time - */ - public Share(Stock stock, BigDecimal quantity, BigDecimal purchasePrice) { - this.stock = stock; - this.quantity = quantity; - this.purchasePrice = purchasePrice; - } - - /** - * Returns the stock associated with this share. - * - * @return the stock - */ - public Stock getStock() { - return stock; - } - - /** - * Returns the quantity of the stock owned. - * - * @return the quantity - */ - public BigDecimal getQuantity() { - return quantity; - } - - /** - * Returns the purchase price per unit. - * - * @return the purchase price - */ - public BigDecimal getPurchasePrice() { - return purchasePrice; - } +public final class Share { + + /** + * The stock this share is associated with. + * */ + private final Stock stock; + + /** + * The quantity of this share. + * */ + private final BigDecimal quantity; + + /** + * The purchase price of this share. + * */ + private final BigDecimal purchasePrice; + + /** + * Creates a new {@code Share}. + * + * @param stock the stock that was purchased + * @param quantity the quantity purchased + * @param purchasePrice the price per unit at purchase time + */ + public Share(final Stock stock, + final BigDecimal quantity, + final BigDecimal purchasePrice) { + this.stock = stock; + this.quantity = quantity; + this.purchasePrice = purchasePrice; + } + + /** + * Returns the stock associated with this share. + * + * @return the stock + */ + public Stock getStock() { + return stock; + } + + /** + * Returns the quantity of the stock owned. + * + * @return the quantity + */ + public BigDecimal getQuantity() { + return quantity; + } + + /** + * Returns the purchase price per unit. + * + * @return the purchase price + */ + public BigDecimal getPurchasePrice() { + return purchasePrice; + } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Stock.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Stock.java index c870265..6f433a1 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Stock.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Stock.java @@ -2,63 +2,132 @@ import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; /** * Represents a stock listed on an exchange. */ -public class Stock { - - private final String symbol; - private final String company; - private final List prices = new ArrayList<>(); - - /** - * Creates a new {@code Stock} with an initial sales price. - * - * @param symbol the unique stock symbol - * @param company the name of the company - * @param salesPrice the initial sales price of the stock - */ - public Stock(String symbol, String company, BigDecimal salesPrice){ - this.symbol = symbol; - this.company = company; - prices.add(salesPrice); - } +public final class Stock { - /** - * Returns the stock symbol. - * - * @return the stock symbol - */ - public String getSymbol(){ - return symbol; - } + /** + * Symbol of this stock. Needs to be 4 characters. + * */ + private final String symbol; - /** - * Returns the stock company. - * - * @return the stocks company - */ - public String getCompany(){ - return company; - } + /** + * Name of the company. + * */ + private final String company; + + /** + * List of prices this stock has had. + * */ + private final List prices = new ArrayList<>(); - /** - * Returns the current sales price of the stock. - * - * @return the curret sales price - */ - public BigDecimal getSalesPrice() { - return prices.getLast(); + /** + * Creates a new {@code Stock} with an initial sales price. + * + * @param symbol the unique stock symbol + * @param company the name of the company + * @param salesPrice the initial sales price of the stock + */ + public Stock(final String symbol, + final String company, + final BigDecimal salesPrice) { + + if (symbol.length() != 4) { + throw new IllegalArgumentException( + "Stock's symbol must be 4 characters!"); } + this.symbol = symbol; + this.company = company; + prices.add(salesPrice); + } + + /** + * Returns the stock symbol. + * + * @return the stock symbol + */ + public String getSymbol() { + return symbol; + } + + /** + * Returns the stock company. + * + * @return the stocks company + */ + public String getCompany() { + return company; + } + + /** + * Returns the current sales price of the stock. + * + * @return the current sales price + */ + public BigDecimal getSalesPrice() { + return prices.getLast(); + } - /** - * Adds a new sales price to the price history. - * - * @param price the new sales price - */ - public void addNewSalesPrice(BigDecimal price) { - prices.add(price); + /** + * Adds a new sales price to the price history. + * + * @param price the new sales price + */ + public void addNewSalesPrice(final BigDecimal price) { + prices.add(price); + } + + /** + * Returns list of all prices for this stock. + * + * @return {@link List} object containing all prices. + * */ + public List getHistoricalPrices() { + return prices; + } + + /** + * Returns highest price this stock has been, or zero is list is empty. + * + * @return {@link BigDecimal} highest price. + * */ + public BigDecimal getHighestPrice() { + return prices.stream() + .max(Comparator.naturalOrder()) + .orElse(BigDecimal.ZERO); + } + + /** + * Returns lowest price this stock has been, or zero if list is empty. + * + * @return {@link BigDecimal} lowest price. + * */ + public BigDecimal getLowestPrice() { + return prices.stream() + .min(Comparator.naturalOrder()) + .orElse(BigDecimal.ZERO); + } + + /** + * Returns the latest price change of this stock. + * + *

Returns 0 if latest price is only price.

+ * + * @return {@link BigDecimal} price change price. + * */ + public BigDecimal getLatestPriceChange() { + if (prices.size() < 2) { + return BigDecimal.ZERO; } + + BigDecimal currentPrice = prices.getLast(); + BigDecimal previousPrice = prices.get(prices.size() - 2); + + return currentPrice.subtract(previousPrice); + } + } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Transaction.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Transaction.java index 78156de..8da798a 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Transaction.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Transaction.java @@ -6,19 +6,32 @@ *

Used for transactions

*/ public abstract class Transaction { + /** + * Flag used to determine whether this transaction has been committed or not. + * */ + private boolean committed = false; + + /** + * The share this transaction is about. + * */ private final Share share; + /** + * The week this transaction takes place. + * */ private final int week; + /** + * The calculator this transaction uses. + * */ private final TransactionCalculator calculator; - protected boolean commited = false; - /** * Creates a new {@code Transaction} with a share, week and calculator. * * @param share the share to perform the transaction on * @param week the current week to perform the transaction under + * @param calculator the {@link TransactionCalculator} to use. */ protected Transaction(final Share share, final int week, @@ -58,9 +71,22 @@ public TransactionCalculator getCalculator() { * * @return commited*/ public boolean isCommited() { - return commited; + return committed; } - /** Commits the transaction. */ + /** + * Commits the transaction. + * + * @param player The player that performed the transaction. + * */ public abstract void commit(Player player); + + /** + * Sets the committed flag. + * + * @param value the value to set the committed flag to. + * */ + protected void setCommitted(final boolean value) { + committed = value; + } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionArchive.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionArchive.java index c09cec6..83bb7cc 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionArchive.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionArchive.java @@ -6,96 +6,104 @@ /** * Stores completed transactions. */ -public class TransactionArchive { +public final class TransactionArchive { - private final List transactions = new ArrayList<>(); + /** + * List of transactions. + * */ + private final List transactions = new ArrayList<>(); - /** - * Creates an empty transaction archive. - */ - public TransactionArchive() { - } + /** + * Creates an empty transaction archive. + */ + public TransactionArchive() { + } - /** - * Adds a transaction to the archive. - * - * @param transaction the transaction to add - * @return true if the transaction was added - */ - public boolean add(Transaction transaction) { - return transactions.add(transaction); - } + /** + * Adds a transaction to the archive. + * + * @param transaction the transaction to add + * + * @return true if the transaction was added + */ + public boolean add(final Transaction transaction) { + return transactions.add(transaction); + } - /** - * Checks whether the archive is empty. - * - * @return true if no transactions exist - */ - public boolean isEmpty() { - return transactions.isEmpty(); - } + /** + * Checks whether the archive is empty. + * + * @return true if no transactions exist + */ + public boolean isEmpty() { + return transactions.isEmpty(); + } - /** - * Returns all transactions from a given week. - * - * @param week the week number - * @return list of transactions from the given week - */ - public List getTransactions(int week) { - List result = new ArrayList<>(); - for (Transaction transaction : transactions) { - if (transaction.getWeek() == week) { - result.add(transaction); - } - } - return result; + /** + * Returns all transactions from a given week. + * + * @param week the week number + * + * @return list of transactions from the given week + */ + public List getTransactions(final int week) { + List result = new ArrayList<>(); + for (Transaction transaction : transactions) { + if (transaction.getWeek() == week) { + result.add(transaction); + } } + return result; + } - /** - * Returns all purchase transactions from a given week. - * - * @param week the week number - * @return list of purchases from the given week - */ - public List getPurchases(int week) { - List result = new ArrayList<>(); - for (Transaction transaction : transactions) { - if (transaction instanceof Purchase purchase && transaction.getWeek() == week) { - result.add(purchase); - } - } - return result; + /** + * Returns all purchase transactions from a given week. + * + * @param week the week number + * + * @return list of purchases from the given week + */ + public List getPurchases(final int week) { + List result = new ArrayList<>(); + for (Transaction transaction : transactions) { + if (transaction instanceof Purchase purchase + && transaction.getWeek() == week) { + result.add(purchase); + } } + return result; + } - /** - * Returns all sale transactions from a given week. - * - * @param week the week number - * @return list of sales from the given week - */ - public List getSales(int week) { - List result = new ArrayList<>(); - for (Transaction transaction : transactions) { - if (transaction instanceof Sale sale && transaction.getWeek() == week) { - result.add(sale); - } - } - return result; + /** + * Returns all sale transactions from a given week. + * + * @param week the week number + * + * @return list of sales from the given week + */ + public List getSales(final int week) { + List result = new ArrayList<>(); + for (Transaction transaction : transactions) { + if (transaction instanceof Sale sale && transaction.getWeek() == week) { + result.add(sale); + } } + return result; + } - /** - * Counts the number of distinct weeks with transactions. - * - * @return number of distinct weeks - */ - public int countDistinctWeeks() { - List weeks = new ArrayList<>(); - for (Transaction transaction : transactions) { - int week = transaction.getWeek(); - if (!weeks.contains(week)) { - weeks.add(week); - } - } - return weeks.size(); + /** + * Counts the number of distinct weeks with transactions. + * + * @return number of distinct weeks + */ + public int countDistinctWeeks() { + List weeks = new ArrayList<>(); + for (Transaction transaction : transactions) { + int week = transaction.getWeek(); + if (!weeks.contains(week)) { + weeks.add(week); + } } -} \ No newline at end of file + return weeks.size(); + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionCalculator.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionCalculator.java index 37619ac..aa13dea 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionCalculator.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionCalculator.java @@ -8,15 +8,31 @@ *

Has methods for calculating gross, commission fee, tax and total

*/ public interface TransactionCalculator { - /** Method for calculating gross transaction amount. */ + /** + * Method for calculating gross transaction amount. + * + * @return the gross money before applying tax or commission. + * */ BigDecimal calculateGross(); - /** Method for calculating commission fee for transaction amount. */ + /** + * Method for calculating commission fee for transaction amount. + * + * @return the amount of money "lost" from commission fee. + * */ BigDecimal calculateCommission(); - /** Method for calculating tax fee for transaction amount. */ + /** + * Method for calculating tax fee for transaction amount. + * + * @return the amount of money "lost" to tax. + * */ BigDecimal calculateTax(); - /** Method for calculating total amount for transaction. */ + /** + * Method for calculating total amount for transaction. + * + * @return the total money, after tax and commission fees. + * */ BigDecimal calculateTotal(); } diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/ExchangeTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/ExchangeTest.java index 9e11d44..5cdd13d 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/ExchangeTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/ExchangeTest.java @@ -1,92 +1,148 @@ package edu.ntnu.idi.idatt2003.g40.mappe; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +final class ExchangeTest { + + private Stock appleStock; + + @BeforeEach + void setUp() { + appleStock = new Stock("AAPL", "Apple", new BigDecimal("100")); + } + + @Test + void constructorSetsNameWeekAndStocksCorrectly() { + Stock tesla = new Stock("TSLA", "Tesla", new BigDecimal("200")); + + Exchange exchange = new Exchange("NASDAQ", List.of(appleStock, tesla)); + + assertEquals("NASDAQ", exchange.getName()); + assertEquals(1, exchange.getWeek()); + assertTrue(exchange.hasStock("AAPL")); + assertTrue(exchange.hasStock("TSLA")); + } + + @Test + void getStockReturnsCorrectStock() { + Exchange exchange = new Exchange("NASDAQ", List.of(appleStock)); + + Stock result = exchange.getStock("AAPL"); + + assertSame(appleStock, result); + } + + @Test + void findStocksReturnsMatchingStocksBySymbolOrCompany() { + Stock tesla = new Stock("TSLA", "Tesla", new BigDecimal("200")); + Exchange exchange = new Exchange("NASDAQ", List.of(appleStock, tesla)); + + List resultBySymbol = exchange.findStocks("AAP"); + List resultByCompany = exchange.findStocks("tes"); + + assertEquals(1, resultBySymbol.size()); + assertTrue(resultBySymbol.contains(appleStock)); + + assertEquals(1, resultByCompany.size()); + assertTrue(resultByCompany.contains(tesla)); + } + + @Test + void buyReturnsPurchaseAndWithdrawsMoneyFromPlayer() { + Exchange exchange = new Exchange("NASDAQ", List.of(appleStock)); + Player player = new Player("Alice", new BigDecimal("1000")); + + Transaction transaction = exchange.buy("AAPL", new BigDecimal("2"), player); + + assertInstanceOf(Purchase.class, transaction); + assertEquals(1, transaction.getWeek()); + assertEquals(new BigDecimal("2"), transaction.getShare().getQuantity()); + assertEquals(new BigDecimal("100"), transaction.getShare() + .getPurchasePrice()); + assertEquals(new BigDecimal("799.000"), player.getMoney()); + } -class ExchangeTest { + @Test + void sellReturnsSaleAndAddsMoneyToPlayer() { + Stock apple = new Stock("AAPL", "Apple", new BigDecimal("150")); + Exchange exchange = new Exchange("NASDAQ", List.of(apple)); + Player player = new Player("Alice", new BigDecimal("1000")); + Share share = new Share(apple, new BigDecimal("2"), new BigDecimal("100")); - @Test - void constructorSetsNameWeekAndStocksCorrectly() { - Stock apple = new Stock("AAPL", "Apple", new BigDecimal("150")); - Stock tesla = new Stock("TSLA", "Tesla", new BigDecimal("200")); + Transaction transaction = exchange.sell(share, player); - Exchange exchange = new Exchange("NASDAQ", List.of(apple, tesla)); + assertInstanceOf(Sale.class, transaction); + assertEquals(1, transaction.getWeek()); + assertSame(share, transaction.getShare()); + assertEquals(new BigDecimal("1267.9000"), player.getMoney()); + } - assertEquals("NASDAQ", exchange.getName()); - assertEquals(1, exchange.getWeek()); - assertTrue(exchange.hasStock("AAPL")); - assertTrue(exchange.hasStock("TSLA")); - } + @Test + void advanceIncreasesWeekAndUpdatesStockPrice() { + Exchange exchange = new Exchange("NASDAQ", List.of(appleStock)); - @Test - void getStockReturnsCorrectStock() { - Stock apple = new Stock("AAPL", "Apple", new BigDecimal("150")); - Exchange exchange = new Exchange("NASDAQ", List.of(apple)); + BigDecimal oldPrice = appleStock.getSalesPrice(); + exchange.advance(); - Stock result = exchange.getStock("AAPL"); + assertEquals(2, exchange.getWeek()); + assertNotEquals(oldPrice, appleStock.getSalesPrice()); + } - assertSame(apple, result); - } + @Test + void getGainersActuallyReturnsProperGainers() { + Stock teslaStock = new Stock("TSLA", "Tesla", new BigDecimal("200.00")); + Stock pearStock = new Stock("PEAR", "Pear inc.", new BigDecimal("97.00")); - @Test - void findStocksReturnsMatchingStocksBySymbolOrCompany() { - Stock apple = new Stock("AAPL", "Apple", new BigDecimal("150")); - Stock tesla = new Stock("TSLA", "Tesla", new BigDecimal("200")); - Exchange exchange = new Exchange("NASDAQ", List.of(apple, tesla)); + appleStock.addNewSalesPrice(new BigDecimal("150.00")); + teslaStock.addNewSalesPrice(new BigDecimal("230.00")); + pearStock.addNewSalesPrice(new BigDecimal("112.00")); - List resultBySymbol = exchange.findStocks("AAP"); - List resultByCompany = exchange.findStocks("tes"); + Exchange exchange = new Exchange("Exchange", List.of(appleStock, teslaStock, pearStock)); - assertEquals(1, resultBySymbol.size()); - assertTrue(resultBySymbol.contains(apple)); + List actualGainers = exchange.getGainers(2); - assertEquals(1, resultByCompany.size()); - assertTrue(resultByCompany.contains(tesla)); - } + boolean actualGainersContainLimitedGainers = actualGainers.contains(teslaStock) + && actualGainers.contains(appleStock); + assertTrue(actualGainersContainLimitedGainers); - @Test - void buyReturnsPurchaseAndWithdrawsMoneyFromPlayer() { - Stock apple = new Stock("AAPL", "Apple", new BigDecimal("100")); - Exchange exchange = new Exchange("NASDAQ", List.of(apple)); - Player player = new Player("Alice", new BigDecimal("1000")); + boolean actualGainersInCorrectOrder = actualGainers.getFirst() == appleStock; + assertTrue(actualGainersInCorrectOrder); - Transaction transaction = exchange.buy("AAPL", new BigDecimal("2"), player); + boolean actualGainersNotContainsGainerOutsideOfLimit = !actualGainers.contains(pearStock); + assertTrue(actualGainersNotContainsGainerOutsideOfLimit); + } - assertInstanceOf(Purchase.class, transaction); - assertEquals(1, transaction.getWeek()); - assertEquals(new BigDecimal("2"), transaction.getShare().getQuantity()); - assertEquals(new BigDecimal("100"), transaction.getShare().getPurchasePrice()); - assertEquals(new BigDecimal("799.000"), player.getMoney()); - } + @Test + void getLosersActuallyReturnsProperLosers() { + Stock teslaStock = new Stock("TSLA", "Tesla", new BigDecimal("200.00")); + Stock pearStock = new Stock("PEAR", "Pear inc.", new BigDecimal("97.00")); - @Test - void sellReturnsSaleAndAddsMoneyToPlayer() { - Stock apple = new Stock("AAPL", "Apple", new BigDecimal("150")); - Exchange exchange = new Exchange("NASDAQ", List.of(apple)); - Player player = new Player("Alice", new BigDecimal("1000")); - Share share = new Share(apple, new BigDecimal("2"), new BigDecimal("100")); + appleStock.addNewSalesPrice(new BigDecimal("50.00")); + teslaStock.addNewSalesPrice(new BigDecimal("170.00")); + pearStock.addNewSalesPrice(new BigDecimal("82.00")); - Transaction transaction = exchange.sell(share, player); + Exchange exchange = new Exchange("Exchange", List.of(appleStock, teslaStock, pearStock)); - assertInstanceOf(Sale.class, transaction); - assertEquals(1, transaction.getWeek()); - assertSame(share, transaction.getShare()); - assertEquals(new BigDecimal("1267.9000"), player.getMoney()); - } + List actualLosers = exchange.getLosers(2); - @Test - void advanceIncreasesWeekAndUpdatesStockPrice() { - Stock apple = new Stock("AAPL", "Apple", new BigDecimal("100")); - Exchange exchange = new Exchange("NASDAQ", List.of(apple)); + boolean actualLosersContainsValidLosers = actualLosers.contains(teslaStock) + && actualLosers.contains(appleStock); + assertTrue(actualLosersContainsValidLosers); - BigDecimal oldPrice = apple.getSalesPrice(); - exchange.advance(); + boolean actualLosersInCorrectOrder = actualLosers.getFirst() == appleStock; + assertTrue(actualLosersInCorrectOrder); - assertEquals(2, exchange.getWeek()); - assertNotEquals(oldPrice, apple.getSalesPrice()); - } -} \ No newline at end of file + boolean actualLosersNotContainingLoserOutsideOfLimit = !actualLosers.contains(pearStock); + assertTrue(actualLosersNotContainingLoserOutsideOfLimit); + } +} diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PlayerTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PlayerTest.java index f62c0d5..b73f257 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PlayerTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PlayerTest.java @@ -1,48 +1,63 @@ package edu.ntnu.idi.idatt2003.g40.mappe; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.math.BigDecimal; +import org.junit.jupiter.api.Test; + +final class PlayerTest { + + @Test + void constructorSetsNameMoneyPortfolioAndArchive() { + Player player = new Player("Alice", new BigDecimal("1000")); + + assertEquals("Alice", player.getName()); + assertEquals(new BigDecimal("1000"), player.getMoney()); + assertNotNull(player.getPortfolio()); + assertNotNull(player.getTransactionArchive()); + } -import static org.junit.jupiter.api.Assertions.*; + @Test + void addMoneyIncreasesBalance() { + Player player = new Player("Bob", new BigDecimal("500")); -class PlayerTest { + player.addMoney(new BigDecimal("200")); - @Test - void constructorSetsNameMoneyPortfolioAndArchive() { - Player player = new Player("Alice", new BigDecimal("1000")); + assertEquals(new BigDecimal("700"), player.getMoney()); + } - assertEquals("Alice", player.getName()); - assertEquals(new BigDecimal("1000"), player.getMoney()); - assertNotNull(player.getPortfolio()); - assertNotNull(player.getTransactionArchive()); - } + @Test + void withdrawMoneyDecreasesBalance() { + Player player = new Player("Charlie", new BigDecimal("500")); - @Test - void addMoneyIncreasesBalance() { - Player player = new Player("Bob", new BigDecimal("500")); + player.withdrawMoney(new BigDecimal("150")); - player.addMoney(new BigDecimal("200")); + assertEquals(new BigDecimal("350"), player.getMoney()); + } - assertEquals(new BigDecimal("700"), player.getMoney()); - } + @Test + void addAndWithdrawMoneyUpdateBalanceCorrectly() { + Player player = new Player("Dana", new BigDecimal("1000")); - @Test - void withdrawMoneyDecreasesBalance() { - Player player = new Player("Charlie", new BigDecimal("500")); + player.addMoney(new BigDecimal("250")); + player.withdrawMoney(new BigDecimal("300")); - player.withdrawMoney(new BigDecimal("150")); + assertEquals(new BigDecimal("950"), player.getMoney()); + } - assertEquals(new BigDecimal("350"), player.getMoney()); - } + @Test + void getNetWorthCalculatesCorrectly() { + Stock stock = new Stock("AAPL", "Apple inc.,", new BigDecimal("100.00")); + Player player = new Player("Bob", new BigDecimal("900")); + Share share = new Share(stock, new BigDecimal("1"), new BigDecimal("100.00")); - @Test - void addAndWithdrawMoneyUpdateBalanceCorrectly() { - Player player = new Player("Dana", new BigDecimal("1000")); + player.getPortfolio().addShare(share); + SaleCalculator saleCalculator = new SaleCalculator(share); - player.addMoney(new BigDecimal("250")); - player.withdrawMoney(new BigDecimal("300")); + BigDecimal calculatedNetWorth = player.getMoney().add(saleCalculator.calculateTotal()); + BigDecimal actualNetWorth = player.getNetWorth(); - assertEquals(new BigDecimal("950"), player.getMoney()); - } -} \ No newline at end of file + assertEquals(calculatedNetWorth, actualNetWorth); + } +} diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PortfolioTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PortfolioTest.java index c8a5e3a..93fa5f4 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PortfolioTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PortfolioTest.java @@ -1,80 +1,102 @@ package edu.ntnu.idi.idatt2003.g40.mappe; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.util.List; +import org.junit.jupiter.api.Test; + +final class PortfolioTest { + + @Test + void addShareAddsShareToPortfolio() { + Portfolio portfolio = new Portfolio(); + Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); + + boolean result = portfolio.addShare(share); + + assertTrue(result); + assertTrue(portfolio.contains(share)); + } + + @Test + void removeShareRemovesShareFromPortfolio() { + Portfolio portfolio = new Portfolio(); + Stock stock = new Stock("TSLA", "Tesla", new BigDecimal("200")); + Share share = new Share(stock, new BigDecimal("1"), new BigDecimal("200")); -import static org.junit.jupiter.api.Assertions.*; + portfolio.addShare(share); + boolean result = portfolio.removeShare(share); -class PortfolioTest { + assertTrue(result); + assertFalse(portfolio.contains(share)); + } - @Test - void addShareAddsShareToPortfolio() { - Portfolio portfolio = new Portfolio(); - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); + @Test + void getSharesReturnsAllShares() { + Portfolio portfolio = new Portfolio(); - boolean result = portfolio.addShare(share); + Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + Share share = new Share(stock, new BigDecimal("3"), new BigDecimal("150")); - assertTrue(result); - assertTrue(portfolio.contains(share)); - } + portfolio.addShare(share); - @Test - void removeShareRemovesShareFromPortfolio() { - Portfolio portfolio = new Portfolio(); - Stock stock = new Stock("TSLA", "Tesla", new BigDecimal("200")); - Share share = new Share(stock, new BigDecimal("1"), new BigDecimal("200")); + List shares = portfolio.getShares(); - portfolio.addShare(share); - boolean result = portfolio.removeShare(share); + assertEquals(1, shares.size()); + assertTrue(shares.contains(share)); + } - assertTrue(result); - assertFalse(portfolio.contains(share)); - } + @Test + void getSharesWithSymbolReturnsMatchingShares() { + Portfolio portfolio = new Portfolio(); - @Test - void getSharesReturnsAllShares() { - Portfolio portfolio = new Portfolio(); + Stock apple = new Stock("AAPL", "Apple", new BigDecimal("150")); + Stock tesla = new Stock("TSLA", "Tesla", new BigDecimal("200")); - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("3"), new BigDecimal("150")); + Share appleShare = new Share(apple, + new BigDecimal("1"), + new BigDecimal("150")); + Share teslaShare = new Share(tesla, + new BigDecimal("1"), + new BigDecimal("200")); - portfolio.addShare(share); + portfolio.addShare(appleShare); + portfolio.addShare(teslaShare); - List shares = portfolio.getShares(); + List result = portfolio.getShares("AAPL"); - assertEquals(1, shares.size()); - assertTrue(shares.contains(share)); - } + assertEquals(1, result.size()); + assertTrue(result.contains(appleShare)); + } - @Test - void getSharesWithSymbolReturnsMatchingShares() { - Portfolio portfolio = new Portfolio(); + @Test + void containsReturnsFalseWhenShareNotPresent() { + Portfolio portfolio = new Portfolio(); - Stock apple = new Stock("AAPL", "Apple", new BigDecimal("150")); - Stock tesla = new Stock("TSLA", "Tesla", new BigDecimal("200")); + Stock stock = new Stock("NVDA", "Nvidia", new BigDecimal("800")); + Share share = new Share(stock, new BigDecimal("1"), new BigDecimal("800")); - Share appleShare = new Share(apple, new BigDecimal("1"), new BigDecimal("150")); - Share teslaShare = new Share(tesla, new BigDecimal("1"), new BigDecimal("200")); + assertFalse(portfolio.contains(share)); + } - portfolio.addShare(appleShare); - portfolio.addShare(teslaShare); + @Test + void getNetWorthReturnsNetWorth() { + Portfolio portfolio = new Portfolio(); - List result = portfolio.getShares("AAPL"); + Stock stock = new Stock("NVDA", "Nvidia", new BigDecimal("800")); + Share share = new Share(stock, new BigDecimal("1"), new BigDecimal("800")); + portfolio.addShare(share); - assertEquals(1, result.size()); - assertTrue(result.contains(appleShare)); - } + SaleCalculator saleCalculator = new SaleCalculator(share); - @Test - void containsReturnsFalseWhenShareNotPresent() { - Portfolio portfolio = new Portfolio(); + BigDecimal calculatedNetWorth = saleCalculator.calculateTotal(); - Stock stock = new Stock("NVDA", "Nvidia", new BigDecimal("800")); - Share share = new Share(stock, new BigDecimal("1"), new BigDecimal("800")); + BigDecimal actualNetWorth = portfolio.getNetWorth(); - assertFalse(portfolio.contains(share)); - } -} \ No newline at end of file + assertEquals(calculatedNetWorth, actualNetWorth); + } +} diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseCalculatorTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseCalculatorTest.java index 4c73305..543688a 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseCalculatorTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseCalculatorTest.java @@ -1,45 +1,45 @@ package edu.ntnu.idi.idatt2003.g40.mappe; -import org.junit.jupiter.api.Test; -import java.math.BigDecimal; - import static org.junit.jupiter.api.Assertions.assertEquals; -class PurchaseCalculatorTest { +import java.math.BigDecimal; +import org.junit.jupiter.api.Test; + +final class PurchaseCalculatorTest { - @Test - void calculateGrossReturnsPurchasePriceTimesQuantity() { - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); - PurchaseCalculator calculator = new PurchaseCalculator(share); + @Test + void calculateGrossReturnsPurchasePriceTimesQuantity() { + Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); + PurchaseCalculator calculator = new PurchaseCalculator(share); - assertEquals(new BigDecimal("200"), calculator.calculateGross()); - } + assertEquals(new BigDecimal("200"), calculator.calculateGross()); + } - @Test - void calculateCommissionReturnsHalfPercentOfGross() { - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); - PurchaseCalculator calculator = new PurchaseCalculator(share); + @Test + void calculateCommissionReturnsHalfPercentOfGross() { + Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); + PurchaseCalculator calculator = new PurchaseCalculator(share); - assertEquals(new BigDecimal("1.000"), calculator.calculateCommission()); - } + assertEquals(new BigDecimal("1.000"), calculator.calculateCommission()); + } - @Test - void calculateTaxReturnsZero() { - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); - PurchaseCalculator calculator = new PurchaseCalculator(share); + @Test + void calculateTaxReturnsZero() { + Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); + PurchaseCalculator calculator = new PurchaseCalculator(share); - assertEquals(BigDecimal.ZERO, calculator.calculateTax()); - } + assertEquals(BigDecimal.ZERO, calculator.calculateTax()); + } - @Test - void calculateTotalReturnsGrossPlusCommission() { - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); - PurchaseCalculator calculator = new PurchaseCalculator(share); + @Test + void calculateTotalReturnsGrossPlusCommission() { + Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); + PurchaseCalculator calculator = new PurchaseCalculator(share); - assertEquals(new BigDecimal("201.000"), calculator.calculateTotal()); - } + assertEquals(new BigDecimal("201.000"), calculator.calculateTotal()); + } } diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseTest.java index 33174da..e66c84b 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/PurchaseTest.java @@ -9,15 +9,34 @@ /** * Test class for {@link Purchase}. * */ -class PurchaseTest { - - Stock testStock = new Stock("AAPL", "Apple Inc.", new BigDecimal("100.00")); - Share testShare = new Share(testStock, new BigDecimal("10"), new BigDecimal("10")); - PurchaseCalculator testPurchaseCalculator = new PurchaseCalculator(testShare); - Player testPlayer = new Player("TestName", new BigDecimal("1000.00")); +final class PurchaseTest { + + /** + * Valid test stock. + * */ + private final Stock testStock = + new Stock("AAPL", "Apple Inc.", new BigDecimal("100.00")); + + /** + * Valid test share. + * */ + private final Share testShare = + new Share(testStock, new BigDecimal("10"), new BigDecimal("10")); + + /** + * Valid test purchase calculator. + * */ + private final PurchaseCalculator testPurchaseCalculator = + new PurchaseCalculator(testShare); + + /** + * Valid test player. + * */ + private final Player testPlayer = + new Player("TestName", new BigDecimal("1000.00")); @Test - void constructor_sets_values() { + void constructorSetsValues() { Purchase purchase = new Purchase(testShare, 1, testPurchaseCalculator); assertEquals(testShare, purchase.getShare()); @@ -26,7 +45,7 @@ void constructor_sets_values() { } @Test - void commit_method_sets_commit_to_true() { + void commitMethodSetsCommitToTrue() { Purchase purchase = new Purchase(testShare, 1, testPurchaseCalculator); purchase.commit(testPlayer); diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleCalculatorTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleCalculatorTest.java index 3b7a0c6..e8a4640 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleCalculatorTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleCalculatorTest.java @@ -1,55 +1,54 @@ package edu.ntnu.idi.idatt2003.g40.mappe; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.math.BigDecimal; +import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; - -class SaleCalculatorTest { +final class SaleCalculatorTest { - @Test - void calculateGrossReturnsSalesPriceTimesQuantity() { - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); - SaleCalculator calculator = new SaleCalculator(share); + @Test + void calculateGrossReturnsSalesPriceTimesQuantity() { + Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); + SaleCalculator calculator = new SaleCalculator(share); - assertEquals(new BigDecimal("300"), calculator.calculateGross()); - } + assertEquals(new BigDecimal("300"), calculator.calculateGross()); + } - @Test - void calculateCommissionReturnsOnePercentOfGross() { - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); - SaleCalculator calculator = new SaleCalculator(share); + @Test + void calculateCommissionReturnsOnePercentOfGross() { + Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); + SaleCalculator calculator = new SaleCalculator(share); - assertEquals(new BigDecimal("3.00"), calculator.calculateCommission()); - } + assertEquals(new BigDecimal("3.00"), calculator.calculateCommission()); + } - @Test - void calculateTaxReturnsThirtyPercentOfProfitWhenProfitIsPositive() { - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); - SaleCalculator calculator = new SaleCalculator(share); + @Test + void calculateTaxReturnsThirtyPercentOfProfitWhenProfitIsPositive() { + Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); + SaleCalculator calculator = new SaleCalculator(share); - assertEquals(new BigDecimal("29.1000"), calculator.calculateTax()); - } + assertEquals(new BigDecimal("29.1000"), calculator.calculateTax()); + } - @Test - void calculateTaxReturnsZeroWhenProfitIsZeroOrNegative() { - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("90")); - Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); - SaleCalculator calculator = new SaleCalculator(share); + @Test + void calculateTaxReturnsZeroWhenProfitIsZeroOrNegative() { + Stock stock = new Stock("AAPL", "Apple", new BigDecimal("90")); + Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); + SaleCalculator calculator = new SaleCalculator(share); - assertEquals(BigDecimal.ZERO, calculator.calculateTax()); - } + assertEquals(BigDecimal.ZERO, calculator.calculateTax()); + } - @Test - void calculateTotalReturnsGrossMinusCommissionMinusTax() { - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); - SaleCalculator calculator = new SaleCalculator(share); + @Test + void calculateTotalReturnsGrossMinusCommissionMinusTax() { + Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + Share share = new Share(stock, new BigDecimal("2"), new BigDecimal("100")); + SaleCalculator calculator = new SaleCalculator(share); - assertEquals(new BigDecimal("267.9000"), calculator.calculateTotal()); - } + assertEquals(new BigDecimal("267.9000"), calculator.calculateTotal()); + } } \ No newline at end of file diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleTest.java index 12f14f7..996437a 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/SaleTest.java @@ -9,15 +9,34 @@ /** * Test class for {@link Sale}. * */ -class SaleTest { - - Stock testStock = new Stock("AAPL", "Apple Inc.", new BigDecimal("100.00")); - Share testShare = new Share(testStock, new BigDecimal("10"), new BigDecimal("10")); - SaleCalculator testSaleCalculator = new SaleCalculator(testShare); - Player testPlayer = new Player("TestName", new BigDecimal("1000.00")); +final class SaleTest { + + /** + * Valid test stock. + * */ + private final Stock testStock = + new Stock("AAPL", "Apple Inc.", new BigDecimal("100.00")); + + /** + * Valid test share. + * */ + private final Share testShare = + new Share(testStock, new BigDecimal("10"), new BigDecimal("10")); + + /** + * Valid test purchase calculator. + * */ + private final PurchaseCalculator testSaleCalculator = + new PurchaseCalculator(testShare); + + /** + * Valid test player. + * */ + private final Player testPlayer = + new Player("TestName", new BigDecimal("1000.00")); @Test - void constructor_sets_values() { + void constructorSetsValues() { Sale sale = new Sale(testShare, 1, testSaleCalculator); assertEquals(testShare, sale.getShare()); @@ -26,7 +45,7 @@ void constructor_sets_values() { } @Test - void commit_method_sets_commit_to_true() { + void commitMethodSetsCommitToTrue() { Sale sale = new Sale(testShare, 1, testSaleCalculator); sale.commit(testPlayer); diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/ShareTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/ShareTest.java index 0a5deb1..de9d2c1 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/ShareTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/ShareTest.java @@ -1,48 +1,51 @@ package edu.ntnu.idi.idatt2003.g40.mappe; -import org.junit.jupiter.api.Test; - -import java.math.BigDecimal; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; -class ShareTest { - - @Test - void constructorStoresAllValuesCorrectly() { - Stock stock = new Stock("AAPL", "Apple Inc.", new BigDecimal("150.00")); - BigDecimal quantity = new BigDecimal("10"); - BigDecimal purchasePrice = new BigDecimal("145.50"); - - Share share = new Share(stock, quantity, purchasePrice); - - assertSame(stock, share.getStock()); - assertEquals(quantity, share.getQuantity()); - assertEquals(purchasePrice, share.getPurchasePrice()); - } - - @Test - void shareSupportsDecimalValues() { - Stock stock = new Stock("TSLA", "Tesla Inc.", new BigDecimal("200.00")); - - Share share = new Share( - stock, - new BigDecimal("2.5"), - new BigDecimal("198.75") - ); - - assertEquals(new BigDecimal("2.5"), share.getQuantity()); - assertEquals(new BigDecimal("198.75"), share.getPurchasePrice()); - } - - @Test - void getStockReturnsCorrectStockObject() { - Stock stock = new Stock("NVDA", "NVIDIA Corporation", new BigDecimal("875.40")); - Share share = new Share(stock, new BigDecimal("4"), new BigDecimal("850.00")); - - assertSame(stock, share.getStock()); - assertEquals("NVDA", share.getStock().getSymbol()); - assertEquals("NVIDIA Corporation", share.getStock().getCompany()); - } -} \ No newline at end of file +import java.math.BigDecimal; +import org.junit.jupiter.api.Test; + +final class ShareTest { + + @Test + void constructorStoresAllValuesCorrectly() { + Stock stock = new Stock("AAPL", "Apple Inc.", new BigDecimal("150.00")); + BigDecimal quantity = new BigDecimal("10"); + BigDecimal purchasePrice = new BigDecimal("145.50"); + + Share share = new Share(stock, quantity, purchasePrice); + + assertSame(stock, share.getStock()); + assertEquals(quantity, share.getQuantity()); + assertEquals(purchasePrice, share.getPurchasePrice()); + } + + @Test + void shareSupportsDecimalValues() { + Stock stock = new Stock("TSLA", "Tesla Inc.", new BigDecimal("200.00")); + + Share share = new Share( + stock, + new BigDecimal("2.5"), + new BigDecimal("198.75") + ); + + assertEquals(new BigDecimal("2.5"), share.getQuantity()); + assertEquals(new BigDecimal("198.75"), share.getPurchasePrice()); + } + + @Test + void getStockReturnsCorrectStockObject() { + Stock stock = new Stock("NVDA", + "NVIDIA Corporation", + new BigDecimal("875.40")); + Share share = new Share(stock, + new BigDecimal("4"), + new BigDecimal("850.00")); + + assertSame(stock, share.getStock()); + assertEquals("NVDA", share.getStock().getSymbol()); + assertEquals("NVIDIA Corporation", share.getStock().getCompany()); + } +} diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/StockTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/StockTest.java index 097cd27..1aaa672 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/StockTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/StockTest.java @@ -1,58 +1,116 @@ package edu.ntnu.idi.idatt2003.g40.mappe; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; -import java.util.NoSuchElementException; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +final class StockTest { + + private Stock testStock; + + @BeforeEach + void setUp() { + testStock = new Stock("AAPL", "Apple Inc.", new BigDecimal("100.00")); + } + + @Test + void constructorSetsSymbolAndCompany() { + assertEquals("AAPL", testStock.getSymbol()); + assertEquals("Apple Inc.", testStock.getCompany()); + } + + /** + * Tests if getting price throws error on new stock. + * + * @deprecated as of part 2. + * */ + /* + @Test + void getSalesPrice_throwsWhenNoPricesExist_currentImplementation() { + Stock stock = new Stock("AAPL", "Apple Inc.", new BigDecimal("100.00")); + + // Because constructor does not add the initial salesPrice to prices, + // prices is empty and getLast() throws NoSuchElementException. + assertThrows(NoSuchElementException.class, stock::getSalesPrice); + }*/ + + @Test + void addNewSalesPriceThenGetSalesPriceReturnsLastAddedPrice() { + testStock.addNewSalesPrice(new BigDecimal("123.45")); + + assertEquals(new BigDecimal("123.45"), testStock.getSalesPrice()); + } + + @Test + void addNewSalesPriceTwiceGetSalesPriceReturnsMostRecent() { + testStock.addNewSalesPrice(new BigDecimal("10.00")); + testStock.addNewSalesPrice(new BigDecimal("20.00")); + + assertEquals(new BigDecimal("20.00"), testStock.getSalesPrice()); + } + + @Test + void addNewSalesPriceAllowsNullCurrentImplementation() { -import static org.junit.jupiter.api.Assertions.*; + testStock.addNewSalesPrice(null); -class StockTest { + // List allows nulls; getLast returns null -> should not throw. + assertDoesNotThrow(testStock::getSalesPrice); + assertNull(testStock.getSalesPrice()); + } - @Test - void constructor_setsSymbolAndCompany() { - Stock stock = new Stock("AAPL", "Apple Inc.", new BigDecimal("100.00")); + @Test + void getHistoricalPricesGetsAllPrices() { + testStock.addNewSalesPrice(new BigDecimal("200.00")); - assertEquals("AAPL", stock.getSymbol()); - assertEquals("Apple Inc.", stock.getCompany()); - } + List historicalPrices = testStock.getHistoricalPrices(); - @Test - void getSalesPrice_throwsWhenNoPricesExist_currentImplementation() { - Stock stock = new Stock("AAPL", "Apple Inc.", new BigDecimal("100.00")); + boolean historicalPricesContainBothValues = historicalPrices.contains(new BigDecimal("100.00")) + && historicalPrices.contains(new BigDecimal("200.00")); - // Because constructor does not add the initial salesPrice to prices, - // prices is empty and getLast() throws NoSuchElementException. - assertThrows(NoSuchElementException.class, stock::getSalesPrice); - } - @Test - void addNewSalesPrice_thenGetSalesPrice_returnsLastAddedPrice() { - Stock stock = new Stock("AAPL", "Apple Inc.", new BigDecimal("100.00")); + assertTrue(historicalPricesContainBothValues); + } - stock.addNewSalesPrice(new BigDecimal("123.45")); + @Test + void getHighestAndLowestPriceReturnsProperValues() { + // Values ranging from lowest to highest. + BigDecimal lowestPrice = new BigDecimal("98.00"); + BigDecimal fillerPrice1 = new BigDecimal("99.00"); + BigDecimal fillerPrice2 = new BigDecimal("101.00"); + BigDecimal highestPrice = new BigDecimal("102.00"); - assertEquals(new BigDecimal("123.45"), stock.getSalesPrice()); - } + // Random order + testStock.addNewSalesPrice(fillerPrice2); + testStock.addNewSalesPrice(highestPrice); + testStock.addNewSalesPrice(lowestPrice); + testStock.addNewSalesPrice(fillerPrice1); - @Test - void addNewSalesPrice_twice_getSalesPrice_returnsMostRecent() { - Stock stock = new Stock("AAPL", "Apple Inc.", new BigDecimal("100.00")); + assertEquals(lowestPrice, testStock.getLowestPrice()); + assertEquals(highestPrice, testStock.getHighestPrice()); + } - stock.addNewSalesPrice(new BigDecimal("10.00")); - stock.addNewSalesPrice(new BigDecimal("20.00")); + @Test + void getLatestPriceChangeGetsLatestPriceChangeWhenMultiplePrices() { + BigDecimal price1 = new BigDecimal("98.00"); + BigDecimal price2 = new BigDecimal("102.00"); - assertEquals(new BigDecimal("20.00"), stock.getSalesPrice()); - } + BigDecimal expectedPriceChange = price2.subtract(price1); - @Test - void addNewSalesPrice_allowsNull_currentImplementation() { - Stock stock = new Stock("AAPL", "Apple Inc.", new BigDecimal("100.00")); + testStock.addNewSalesPrice(price1); + testStock.addNewSalesPrice(price2); - stock.addNewSalesPrice(null); + assertEquals(expectedPriceChange, testStock.getLatestPriceChange()); + } - // List allows nulls; getLast returns null -> should not throw. - assertDoesNotThrow(stock::getSalesPrice); - assertNull(stock.getSalesPrice()); - } + @Test + void getLatestPriceChangeReturnsZeroWhenNotMultiplePrices() { + assertEquals(BigDecimal.ZERO, testStock.getLatestPriceChange()); + } } diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionArchiveTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionArchiveTest.java index 17726ad..f447b8b 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionArchiveTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/TransactionArchiveTest.java @@ -1,130 +1,138 @@ package edu.ntnu.idi.idatt2003.g40.mappe; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.util.List; +import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - -class TransactionArchiveTest { - - private final TransactionCalculator calculator = new TransactionCalculator() { - @Override - public BigDecimal calculateGross() { - return BigDecimal.ZERO; - } - - @Override - public BigDecimal calculateCommission() { - return BigDecimal.ZERO; - } - - @Override - public BigDecimal calculateTax() { - return BigDecimal.ZERO; - } - - @Override - public BigDecimal calculateTotal() { - return BigDecimal.ZERO; - } - }; - - @Test - void newArchiveIsEmpty() { - TransactionArchive archive = new TransactionArchive(); - - assertTrue(archive.isEmpty()); - } - - @Test - void addMakesArchiveNonEmpty() { - TransactionArchive archive = new TransactionArchive(); - Transaction transaction = createPurchase("AAPL", "Apple", 1); - - boolean result = archive.add(transaction); - - assertTrue(result); - assertFalse(archive.isEmpty()); - } - - @Test - void getTransactionsReturnsOnlyTransactionsFromGivenWeek() { - TransactionArchive archive = new TransactionArchive(); - - Transaction transaction1 = createPurchase("AAPL", "Apple", 1); - Transaction transaction2 = createSale("TSLA", "Tesla", 2); - Transaction transaction3 = createPurchase("NVDA", "Nvidia", 1); - - archive.add(transaction1); - archive.add(transaction2); - archive.add(transaction3); - - List result = archive.getTransactions(1); - - assertEquals(2, result.size()); - assertTrue(result.contains(transaction1)); - assertTrue(result.contains(transaction3)); - } - - @Test - void getPurchasesReturnsOnlyPurchasesFromGivenWeek() { - TransactionArchive archive = new TransactionArchive(); - - Purchase purchase1 = createPurchase("AAPL", "Apple", 1); - Purchase purchase2 = createPurchase("NVDA", "Nvidia", 2); - Sale sale = createSale("TSLA", "Tesla", 1); - - archive.add(purchase1); - archive.add(purchase2); - archive.add(sale); - - List result = archive.getPurchases(1); - - assertEquals(1, result.size()); - assertTrue(result.contains(purchase1)); - } - - @Test - void getSalesReturnsOnlySalesFromGivenWeek() { - TransactionArchive archive = new TransactionArchive(); - - Sale sale1 = createSale("TSLA", "Tesla", 1); - Sale sale2 = createSale("NVDA", "Nvidia", 2); - Purchase purchase = createPurchase("AAPL", "Apple", 1); - - archive.add(sale1); - archive.add(sale2); - archive.add(purchase); +final class TransactionArchiveTest { - List result = archive.getSales(1); + /** + * Transaction calculator to be used for testing. + * */ + private final TransactionCalculator calculator = new TransactionCalculator() { + @Override + public BigDecimal calculateGross() { + return BigDecimal.ZERO; + } - assertEquals(1, result.size()); - assertTrue(result.contains(sale1)); - } + @Override + public BigDecimal calculateCommission() { + return BigDecimal.ZERO; + } - @Test - void countDistinctWeeksCountsUniqueWeeksOnly() { - TransactionArchive archive = new TransactionArchive(); - - archive.add(createPurchase("AAPL", "Apple", 1)); - archive.add(createSale("TSLA", "Tesla", 1)); - archive.add(createPurchase("NVDA", "Nvidia", 2)); - archive.add(createSale("META", "Meta", 3)); - - assertEquals(3, archive.countDistinctWeeks()); - } - - private Purchase createPurchase(String symbol, String company, int week) { - Stock stock = new Stock(symbol, company, new BigDecimal("100")); - Share share = new Share(stock, BigDecimal.ONE, new BigDecimal("100")); - return new Purchase(share, week, calculator); - } + @Override + public BigDecimal calculateTax() { + return BigDecimal.ZERO; + } - private Sale createSale(String symbol, String company, int week) { - Stock stock = new Stock(symbol, company, new BigDecimal("100")); - Share share = new Share(stock, BigDecimal.ONE, new BigDecimal("100")); - return new Sale(share, week, calculator); - } -} \ No newline at end of file + @Override + public BigDecimal calculateTotal() { + return BigDecimal.ZERO; + } + }; + + @Test + void newArchiveIsEmpty() { + TransactionArchive archive = new TransactionArchive(); + + assertTrue(archive.isEmpty()); + } + + @Test + void addMakesArchiveNonEmpty() { + TransactionArchive archive = new TransactionArchive(); + Transaction transaction = createPurchase("AAPL", "Apple", 1); + + boolean result = archive.add(transaction); + + assertTrue(result); + assertFalse(archive.isEmpty()); + } + + @Test + void getTransactionsReturnsOnlyTransactionsFromGivenWeek() { + TransactionArchive archive = new TransactionArchive(); + + Transaction transaction1 = createPurchase("AAPL", "Apple", 1); + Transaction transaction2 = createSale("TSLA", "Tesla", 2); + Transaction transaction3 = createPurchase("NVDA", "Nvidia", 1); + + archive.add(transaction1); + archive.add(transaction2); + archive.add(transaction3); + + List result = archive.getTransactions(1); + + assertEquals(2, result.size()); + assertTrue(result.contains(transaction1)); + assertTrue(result.contains(transaction3)); + } + + @Test + void getPurchasesReturnsOnlyPurchasesFromGivenWeek() { + TransactionArchive archive = new TransactionArchive(); + + Purchase purchase1 = createPurchase("AAPL", "Apple", 1); + Purchase purchase2 = createPurchase("NVDA", "Nvidia", 2); + Sale sale = createSale("TSLA", "Tesla", 1); + + archive.add(purchase1); + archive.add(purchase2); + archive.add(sale); + + List result = archive.getPurchases(1); + + assertEquals(1, result.size()); + assertTrue(result.contains(purchase1)); + } + + @Test + void getSalesReturnsOnlySalesFromGivenWeek() { + TransactionArchive archive = new TransactionArchive(); + + Sale sale1 = createSale("TSLA", "Tesla", 1); + Sale sale2 = createSale("NVDA", "Nvidia", 2); + Purchase purchase = createPurchase("AAPL", "Apple", 1); + + archive.add(sale1); + archive.add(sale2); + archive.add(purchase); + + List result = archive.getSales(1); + + assertEquals(1, result.size()); + assertTrue(result.contains(sale1)); + } + + @Test + void countDistinctWeeksCountsUniqueWeeksOnly() { + TransactionArchive archive = new TransactionArchive(); + + archive.add(createPurchase("AAPL", "Apple", 1)); + archive.add(createSale("TSLA", "Tesla", 1)); + archive.add(createPurchase("NVDA", "Nvidia", 2)); + archive.add(createSale("META", "Meta", 3)); + + assertEquals(3, archive.countDistinctWeeks()); + } + + private Purchase createPurchase(final String symbol, + final String company, + final int week) { + Stock stock = new Stock(symbol, company, new BigDecimal("100")); + Share share = new Share(stock, BigDecimal.ONE, new BigDecimal("100")); + return new Purchase(share, week, calculator); + } + + private Sale createSale(final String symbol, + final String company, + final int week) { + Stock stock = new Stock(symbol, company, new BigDecimal("100")); + Share share = new Share(stock, BigDecimal.ONE, new BigDecimal("100")); + return new Sale(share, week, calculator); + } +}