diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java index bc1ec00..c467434 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/Exchange.java @@ -4,9 +4,6 @@ import edu.ntnu.idi.idatt2003.g40.mappe.model.Share; import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock; import edu.ntnu.idi.idatt2003.g40.mappe.model.Transaction; -import edu.ntnu.idi.idatt2003.g40.mappe.service.PurchaseCalculator; -import edu.ntnu.idi.idatt2003.g40.mappe.service.SaleCalculator; -import edu.ntnu.idi.idatt2003.g40.mappe.service.TransactionCalculator; import edu.ntnu.idi.idatt2003.g40.mappe.service.TransactionFactory; import edu.ntnu.idi.idatt2003.g40.mappe.service.TransactionType; import edu.ntnu.idi.idatt2003.g40.mappe.utils.Validator; @@ -16,7 +13,7 @@ import java.util.List; import java.util.Map; import java.util.Random; -import javafx.beans.property.IntegerProperty; +import javafx.beans.property.ReadOnlyIntegerProperty; import javafx.beans.property.ReadOnlyIntegerWrapper; /** @@ -30,7 +27,7 @@ *

Advances week.

* * @see Player - * @see TransactionCalculator + * @see edu.ntnu.idi.idatt2003.g40.mappe.service.TransactionCalculator * * @version 1.0.0 * */ @@ -98,12 +95,12 @@ public int getWeek() { } /** - * Getter method for the {@link IntegerProperty} object of week. + * Getter method for the {@link ReadOnlyIntegerProperty} object of week. * * @return week. * */ - public IntegerProperty weekProperty() { - return week; + public ReadOnlyIntegerProperty weekProperty() { + return week.getReadOnlyProperty(); } /** @@ -177,9 +174,8 @@ public Transaction buy(final String symbol, } Stock stock = getStock(symbol); Share share = new Share(stock, quantity, stock.getSalesPrice()); - TransactionCalculator calculator = new PurchaseCalculator(share); Transaction purchase = TransactionFactory.createTransaction( - TransactionType.PURCHASE, share, getWeek(), calculator + TransactionType.PURCHASE, share, getWeek() ); player.handleTransaction(purchase); return purchase; @@ -200,9 +196,8 @@ public Transaction sell(final Share share, final Player player) if (share == null || player == null) { throw new IllegalArgumentException("Invalid sell!"); } - TransactionCalculator calculator = new SaleCalculator(share); Transaction sale = TransactionFactory.createTransaction( - TransactionType.SALE, share, getWeek(), calculator + TransactionType.SALE, share, getWeek() ); player.handleTransaction(sale); return sale; @@ -212,9 +207,7 @@ TransactionType.SALE, share, getWeek(), calculator * Method called when a player sells share, * defined by an amount instead of specific {@link Share} object. * - *

Might split shares into multiples to ensure proper selling. - * Uses the {@link edu.ntnu.idi.idatt2003.g40.mappe.model.Portfolio} - * to split.

+ *

{@link edu.ntnu.idi.idatt2003.g40.mappe.model.Portfolio}

* * @param amount the amount of "shares" to sell. * @param stockSymbol the stock to sell shares in. @@ -227,58 +220,38 @@ TransactionType.SALE, share, getWeek(), calculator * or if player does not own any shares * of the given stock. * */ - public List sell(BigDecimal amount, + public Transaction sell(BigDecimal amount, final String stockSymbol, final Player player) throws IllegalArgumentException { if (amount == null - || player == null - || !Validator.VALID_STOCK_SYMBOL.isValid(stockSymbol)) { - throw new IllegalArgumentException("Invalid sell!"); + || player == null + || !Validator.VALID_STOCK_SYMBOL.isValid(stockSymbol)) { + throw new IllegalArgumentException("Invalid sell parameters!"); } - // Get all shares the player owns of the stock given in the parameter. - List sharesOfStock = player.getPortfolio().getShares().stream() - .filter(s -> s.getStock().getSymbol().equals(stockSymbol)) - .toList(); + List matchingShares = player.getPortfolio().getShares(stockSymbol); - // Throws error if player does not own any shares of the given stock. - if (sharesOfStock.isEmpty()) { - throw new IllegalArgumentException("Player does not own" - + " any shares of this stock!"); + if (matchingShares.isEmpty()) { + throw new IllegalArgumentException("Player does not own any shares of this stock!"); } - // Gets the total quantity amount of shares owned of given stock. - BigDecimal totalOwned = player.getPortfolio() - .getTotalSharesBySymbol(stockSymbol); + Share ownedPosition = matchingShares.getFirst(); + BigDecimal totalOwned = ownedPosition.getQuantity(); - // If amount wanted to sell is greater than total owned, - // sells entire collection. if (amount.compareTo(totalOwned) > 0) { amount = totalOwned; } - ArrayList transactions = new ArrayList<>(); - BigDecimal remainingToSell = amount; - // For every share owned, sells if the quantity is less than - // or equal to the remaining amount of shares to sell. - // Splits share if the remaining amount to sell is less than share quantity. - for (Share share : sharesOfStock) { + Stock stock = ownedPosition.getStock(); + Share shareToSell = new Share(stock, amount, stock.getSalesPrice()); - BigDecimal shareQty = share.getQuantity(); + Transaction sale = TransactionFactory.createTransaction( + TransactionType.SALE, shareToSell, getWeek() + ); + player.handleTransaction(sale); - if (shareQty.compareTo(remainingToSell) <= 0) { - remainingToSell = remainingToSell.subtract(shareQty); - transactions.add(sell(share, player)); - } else { - Share newShare = player.getPortfolio().splitShare( - share, remainingToSell - ); - transactions.add(sell(newShare, player)); - break; - } - } - return transactions; + return sale; } /** diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Portfolio.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Portfolio.java index 0c7ea5e..333d2e2 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Portfolio.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/model/Portfolio.java @@ -1,13 +1,10 @@ package edu.ntnu.idi.idatt2003.g40.mappe.model; -import edu.ntnu.idi.idatt2003.g40.mappe.service.PurchaseCalculator; -import edu.ntnu.idi.idatt2003.g40.mappe.service.SaleCalculator; import edu.ntnu.idi.idatt2003.g40.mappe.utils.Validator; - import java.math.BigDecimal; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import java.util.Objects; +import java.util.Map; /** * Represents a player's portfolio of shares. @@ -18,9 +15,9 @@ public final class Portfolio { /** - * List of shares. + * Map used to handle internal shares. * */ - private final List shares = new ArrayList<>(); + private final Map shares = new HashMap<>(); /** * Creates an empty portfolio. @@ -30,24 +27,41 @@ public Portfolio() { } /** - * Adds a share to the portfolio. + * Adds a share to the portfolio. If share already exists, merges shares. * * @param share the share to add * - * @return {@code true} if the share was added, {@code false} otherwise - * * @throws IllegalArgumentException if share is null. */ - public boolean addShare(final Share share) throws IllegalArgumentException { + public void addShare(final Share share) throws IllegalArgumentException { if (share == null) { throw new IllegalArgumentException("Invalid share!"); } - return shares.add(share); + String symbol = share.getStock().getSymbol().toUpperCase(); + + if (shares.containsKey(symbol)) { + Share existingShare = shares.get(symbol); + BigDecimal totalQuantity = + existingShare.getQuantity().add(share.getQuantity()); + + shares.put(symbol, + new Share( + share.getStock(), + totalQuantity, existingShare.getPurchasePrice() + ) + ); + } else { + shares.put(symbol, share); + } } /** * Removes a share from the portfolio. * + *

Uses the quantity value to deduct share amount from the map. + * If quantity to remove is equal to amount held, removes share entirely. + * If not, splits the share.

+ * * @param share the share to remove * * @return {@code true} if the share was removed, @@ -56,11 +70,37 @@ public boolean addShare(final Share share) throws IllegalArgumentException { * @throws IllegalArgumentException if share is null. * */ - public boolean removeShare(final Share share) throws IllegalArgumentException { + public boolean removeShare(final Share share) + throws IllegalArgumentException { if (share == null) { throw new IllegalArgumentException("Invalid share!"); } - return shares.remove(share); + String symbol = share.getStock().getSymbol().toUpperCase(); + if (!shares.containsKey(symbol)) { + return false; + } + + Share ownedShare = shares.get(symbol); + int comparison = ownedShare.getQuantity().compareTo(share.getQuantity()); + + if (comparison < 0) { + throw new IllegalArgumentException( + "Cannot remove more shares than are currently owned!"); + } else if (comparison == 0) { + + shares.remove(symbol); + } else { + BigDecimal remainingQuantity = + ownedShare.getQuantity().subtract(share.getQuantity()); + shares.put(symbol, + new Share( + share.getStock(), + remainingQuantity, + ownedShare.getPurchasePrice() + ) + ); + } + return true; } /** @@ -69,7 +109,7 @@ public boolean removeShare(final Share share) throws IllegalArgumentException { * @return a list of shares */ public List getShares() { - return List.copyOf(shares); + return List.copyOf(shares.values()); } /** @@ -81,14 +121,14 @@ public List getShares() { * * @throws IllegalArgumentException if symbol is invalid. */ - public List getShares(final String symbol) throws IllegalArgumentException { + public List getShares(final String symbol) + throws IllegalArgumentException { if (!Validator.VALID_STOCK_SYMBOL.isValid(symbol)) { throw new IllegalArgumentException( Validator.VALID_STOCK_SYMBOL.getErrorMessage()); } - return shares.stream() - .filter(s -> symbol.equalsIgnoreCase(s.getStock().getSymbol())) - .toList(); + Share share = shares.get(symbol.toUpperCase()); + return share != null ? List.of(share) : List.of(); } /** @@ -101,11 +141,15 @@ public List getShares(final String symbol) throws IllegalArgumentExceptio * * @throws IllegalArgumentException if share is null. */ - public boolean contains(final Share share) throws IllegalArgumentException { + public boolean contains(final Share share) + throws IllegalArgumentException { if (share == null) { throw new IllegalArgumentException("Invalid share!"); } - return shares.contains(share); + String symbol = share.getStock().getSymbol().toUpperCase(); + Share owned = shares.get(symbol); + return owned != null + && owned.getQuantity().compareTo(share.getQuantity()) >= 0; } /** @@ -115,11 +159,11 @@ public boolean contains(final Share share) throws IllegalArgumentException { * @return the net worth. * */ public BigDecimal getNetWorth() { - BigDecimal netWorth = new BigDecimal("0"); - - for (Share s : shares) { - SaleCalculator calculator = new SaleCalculator(s); - netWorth = netWorth.add(calculator.calculateTotal()); + BigDecimal netWorth = BigDecimal.ZERO; + for (Share s : shares.values()) { + netWorth = netWorth.add( + s.getQuantity().multiply(s.getStock().getSalesPrice()) + ); } return netWorth; } @@ -127,37 +171,16 @@ public BigDecimal getNetWorth() { /** * Helper method to get total amount of shares owned in a specific stock. * - * @param symbol the symbol of the stock to check for shares. - * */ - public BigDecimal getTotalSharesBySymbol(final String symbol) { - return shares.stream() - .filter(s -> s.getStock().getSymbol().equals(symbol)) - .map(Share::getQuantity) - .reduce(BigDecimal.ZERO, BigDecimal::add); - } - - /** - * "Splits" a share in two pieces based on an amount. - * - * @param share the share to split. - * @param splitAmount the amount to split by. + * @param symbol the symbol of the stock to check for shares. * - * @return the split share from the original to the split amount. - * - * @throws IllegalArgumentException if share or split amount is invalid. + * @return BigDecimal representing total quantity of all + * shares of this symbol. * */ - public Share splitShare(final Share share, final BigDecimal splitAmount) - throws IllegalArgumentException { - if (!contains(share) || splitAmount.compareTo(share.getQuantity()) > 0) { - throw new IllegalArgumentException("Cannot split share!"); + public BigDecimal getTotalSharesBySymbol(final String symbol) { + if (symbol == null) { + return BigDecimal.ZERO; } - BigDecimal remainingAmount = share.getQuantity().subtract(splitAmount); - - Share newShare1 = new Share(share.getStock(), splitAmount, share.getPurchasePrice()); - Share newShare2 = new Share(share.getStock(), remainingAmount, share.getPurchasePrice()); - removeShare(share); - addShare(newShare1); - addShare(newShare2); - return newShare1; + Share share = shares.get(symbol.toUpperCase()); + return share != null ? share.getQuantity() : BigDecimal.ZERO; } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardController.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardController.java index 9d31d0d..fa1333c 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/dashboard/DashBoardController.java @@ -149,15 +149,13 @@ protected void initInteractions() { getViewElement().setOnAction(DashBoardActions.SELL_SHARES, () -> { if (Validator.NOT_EMPTY.isValid(getViewElement().getQuantityInputField().getText()) && Float.parseFloat(getViewElement().getQuantityInputField().getText()) > 0) { - List transactions = exchange.sell( + Transaction sale = exchange.sell( new BigDecimal(getViewElement().getQuantityInputField().getText()), getViewElement().getCurrentStock().getSymbol(), player); - for (Transaction t : transactions) { - if(t.isCommited()) { - getViewElement().addOwnedShares(-t.getShare().getQuantity().floatValue()); - } + if(sale.isCommited()) { + getViewElement().addOwnedShares(-sale.getShare().getQuantity().floatValue()); } } }); diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/ExchangeTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/ExchangeTest.java index 147810b..66ce0c5 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/ExchangeTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/ExchangeTest.java @@ -187,44 +187,18 @@ void sellShareObjectThrowsExceptionOnIllegalArguments() { } @Test - void sellingPartialSharesUpdatesPlayerMoneyAndPortfolioCorrectly() { + void sellingSharesBasedOnAmountFunctionsAsIntended() { testExchange.buy(appleStock.getSymbol(), new BigDecimal("3"), testPlayer); - List sales = - testExchange.sell(new BigDecimal("1.5"), appleStock.getSymbol(), testPlayer); - - assertEquals(1, sales.size()); + Transaction sale = testExchange.sell(new BigDecimal("1.5"), appleStock.getSymbol(), testPlayer); + assertInstanceOf(Sale.class, sale); BigDecimal expectedPlayerMoney = new BigDecimal("847.000"); assertEquals(expectedPlayerMoney, testPlayer.getMoney()); + BigDecimal actualQuantity = testPlayer.getPortfolio().getShares(appleStock.getSymbol()).getFirst().getQuantity(); BigDecimal expectedRemainingShares = new BigDecimal("1.5"); - assertEquals(expectedRemainingShares, - testPlayer - .getPortfolio() - .getShares(appleStock.getSymbol()) - .getFirst() - .getQuantity() - ); - } - - @Test - void sellingPartialAmountOfSharesRequiringSplitSplitsSharesCorrectly() { - testExchange.buy(appleStock.getSymbol(), - new BigDecimal("3.12"), testPlayer); - testExchange.buy(appleStock.getSymbol(), - new BigDecimal("4.56"), testPlayer); - - List sales = - testExchange.sell(new BigDecimal("6.00"), - appleStock.getSymbol(), testPlayer); - - assertEquals(2, sales.size()); - assertEquals(new BigDecimal("3.12"), sales.get(0).getShare().getQuantity()); - assertEquals(new BigDecimal("2.88"), sales.get(1).getShare().getQuantity()); - - BigDecimal expectedPlayerMoney = new BigDecimal("822.16000"); - assertEquals(expectedPlayerMoney, testPlayer.getMoney()); + assertEquals(0, expectedRemainingShares.compareTo(actualQuantity)); } @Test @@ -234,16 +208,13 @@ void attemptingToSellMoreSharesThanOwnedSellsAllSharesOwned() { testExchange.buy(appleStock.getSymbol(), new BigDecimal("4.56"), testPlayer); - List sales = - testExchange.sell(new BigDecimal("100.00"), - appleStock.getSymbol(), testPlayer); - assertEquals(2, sales.size()); - - assertEquals(new BigDecimal("3.12"), sales.get(0).getShare().getQuantity()); - assertEquals(new BigDecimal("4.56"), sales.get(1).getShare().getQuantity()); + testExchange.sell(new BigDecimal("100.00"), + appleStock.getSymbol(), testPlayer); BigDecimal expectedPlayerMoney = new BigDecimal("988.48000"); - assertEquals(expectedPlayerMoney, testPlayer.getMoney()); + assertEquals(0, expectedPlayerMoney.compareTo(testPlayer.getMoney())); + + assertTrue(testPlayer.getPortfolio().getShares(appleStock.getSymbol()).isEmpty()); } @Test diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/TransactionArchiveTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/TransactionArchiveTest.java index 78ffaf7..fce1960 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/TransactionArchiveTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/engine/TransactionArchiveTest.java @@ -11,8 +11,6 @@ import edu.ntnu.idi.idatt2003.g40.mappe.model.Share; import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock; import edu.ntnu.idi.idatt2003.g40.mappe.model.Transaction; -import edu.ntnu.idi.idatt2003.g40.mappe.service.PurchaseCalculator; -import edu.ntnu.idi.idatt2003.g40.mappe.service.SaleCalculator; import edu.ntnu.idi.idatt2003.g40.mappe.service.TransactionFactory; import edu.ntnu.idi.idatt2003.g40.mappe.service.TransactionType; import java.math.BigDecimal; @@ -32,24 +30,12 @@ final class TransactionArchiveTest { * */ private Share sampleShare; - /** - * Sample sale calculator to calculate sales. - * */ - private SaleCalculator saleCalculator; - - /** - * Sample purchase calculater used to calculate purchases. - * */ - private PurchaseCalculator purchaseCalculator; - @BeforeEach void setUp() { transactionArchive = new TransactionArchive(); Stock sampleStock = new Stock("AAPL", "Apple", new BigDecimal("100.00")); sampleShare = new Share(sampleStock, new BigDecimal("1.00"), sampleStock.getSalesPrice()); - saleCalculator = new SaleCalculator(sampleShare); - purchaseCalculator = new PurchaseCalculator(sampleShare); } @Test @@ -163,15 +149,15 @@ void countDistinctWeeksCountsUniqueWeeksOnly() { assertEquals(3, transactionArchive.countDistinctWeeks()); } - private Transaction createPurchase(int week) { + private Transaction createPurchase(final int week) { return TransactionFactory.createTransaction( - TransactionType.PURCHASE, sampleShare, week, purchaseCalculator + TransactionType.PURCHASE, sampleShare, week ); } - private Transaction createSale(int week) { + private Transaction createSale(final int week) { return TransactionFactory.createTransaction( - TransactionType.SALE, sampleShare, week, saleCalculator + TransactionType.SALE, sampleShare, week ); } } diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/model/PortfolioTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/model/PortfolioTest.java index 470f26a..781e06f 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/model/PortfolioTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/model/PortfolioTest.java @@ -1,104 +1,152 @@ package edu.ntnu.idi.idatt2003.g40.mappe.model; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.util.List; -import edu.ntnu.idi.idatt2003.g40.mappe.service.SaleCalculator; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; final class PortfolioTest { + /** + * Test portfolio used. + * */ + private Portfolio testPortfolio; + + /** + * Test stock used. + * */ + private Stock testStock; + + /** + * Test share used. + * */ + private Share testShare; + + @BeforeEach + void setUp() { + testPortfolio = new Portfolio(); + testStock = new Stock("AAPL", "Apple", new BigDecimal("150")); + testShare = new Share(testStock, new BigDecimal("2"), new BigDecimal("100")); + } + @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")); + assertDoesNotThrow( + () -> testPortfolio.addShare(testShare)); - boolean result = portfolio.addShare(share); + assertTrue(testPortfolio.contains(testShare)); + } - assertTrue(result); - assertTrue(portfolio.contains(share)); + @Test + void addingNullShareThrowsException() { + assertThrows(IllegalArgumentException.class, + () -> testPortfolio.addShare(null)); + + assertFalse(testPortfolio.contains(testShare)); } @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")); + assertFalse(testPortfolio.contains(testShare)); + + testPortfolio.addShare(testShare); - portfolio.addShare(share); - boolean result = portfolio.removeShare(share); + assertTrue(testPortfolio.contains(testShare)); + + boolean result = testPortfolio.removeShare(testShare); assertTrue(result); - assertFalse(portfolio.contains(share)); + assertFalse(testPortfolio.contains(testShare)); } @Test - void getSharesReturnsAllShares() { - Portfolio portfolio = new Portfolio(); + void removingNullShareThrowsException() { + assertThrows(IllegalArgumentException.class, + () -> testPortfolio.removeShare(null)); + } - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("3"), new BigDecimal("150")); + @Test + void removingMoreSharesThanOwnedThrowsException() { + testPortfolio.addShare(testShare); + Share testShare2 = new Share(testStock, new BigDecimal("4"), testStock.getSalesPrice()); + assertThrows(IllegalArgumentException.class, + () -> testPortfolio.removeShare(testShare2) + ); + } - portfolio.addShare(share); + @Test + void getSharesReturnsAllShares() { + testPortfolio.addShare(testShare); - List shares = portfolio.getShares(); + List shares = testPortfolio.getShares(); assertEquals(1, shares.size()); - assertTrue(shares.contains(share)); + assertTrue(shares.contains(testShare)); } @Test void getSharesWithSymbolReturnsMatchingShares() { - Portfolio portfolio = new Portfolio(); + Stock testStock2 = new Stock("TSLA", "Tesla", new BigDecimal("200")); - Stock apple = new Stock("AAPL", "Apple", new BigDecimal("150")); - Stock tesla = new Stock("TSLA", "Tesla", new BigDecimal("200")); - - Share appleShare = new Share(apple, - new BigDecimal("1"), - new BigDecimal("150")); - Share teslaShare = new Share(tesla, + Share testShare2 = new Share(testStock2, new BigDecimal("1"), new BigDecimal("200")); - portfolio.addShare(appleShare); - portfolio.addShare(teslaShare); + testPortfolio.addShare(testShare); + testPortfolio.addShare(testShare2); - List result = portfolio.getShares("AAPL"); + List result = testPortfolio.getShares("AAPL"); assertEquals(1, result.size()); - assertTrue(result.contains(appleShare)); + assertTrue(result.contains(testShare)); } @Test - void containsReturnsFalseWhenShareNotPresent() { - Portfolio portfolio = new Portfolio(); - - Stock stock = new Stock("NVDA", "Nvidia", new BigDecimal("800")); - Share share = new Share(stock, new BigDecimal("1"), new BigDecimal("800")); - - assertFalse(portfolio.contains(share)); + void getSharesWithSymbolThrowsExceptionOnIllegalArgument() { + assertThrows(IllegalArgumentException.class, + () -> testPortfolio.getShares(null) + ); } @Test - void getNetWorthReturnsNetWorth() { - Portfolio portfolio = new Portfolio(); - - Stock stock = new Stock("NVDA", "Nvidia", new BigDecimal("800")); - Share share = new Share(stock, new BigDecimal("1"), new BigDecimal("800")); - portfolio.addShare(share); - - SaleCalculator saleCalculator = new SaleCalculator(share); - - BigDecimal calculatedNetWorth = saleCalculator.calculateTotal(); + void containsReturnsFalseWhenShareNotPresent() { + assertFalse(testPortfolio.contains(testShare)); + } - BigDecimal actualNetWorth = portfolio.getNetWorth(); + @Test + void containsThrowsExceptionOnIllegalArgument() { + assertThrows(IllegalArgumentException.class, + () -> testPortfolio.contains(null) + ); + } - assertEquals(calculatedNetWorth, actualNetWorth); + @Test + void getTotalSharesBySymbolReturnsCorrectValues() { + assertEquals(0, + BigDecimal.ZERO.compareTo( + testPortfolio.getTotalSharesBySymbol("AAPL") + ) + ); + + assertEquals(0, + BigDecimal.ZERO.compareTo( + testPortfolio.getTotalSharesBySymbol(null) + ) + ); + + testPortfolio.addShare(testShare); + + assertEquals(0, + new BigDecimal("2.0").compareTo( + testPortfolio.getTotalSharesBySymbol("AAPL") + ) + ); } } diff --git a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/service/TransactionFactoryTest.java b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/service/TransactionFactoryTest.java index 6b25c35..1f49c32 100644 --- a/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/service/TransactionFactoryTest.java +++ b/src/test/java/edu/ntnu/idi/idatt2003/g40/mappe/service/TransactionFactoryTest.java @@ -1,7 +1,9 @@ package edu.ntnu.idi.idatt2003.g40.mappe.service; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import edu.ntnu.idi.idatt2003.g40.mappe.model.Purchase; import edu.ntnu.idi.idatt2003.g40.mappe.model.Sale; @@ -15,56 +17,45 @@ class TransactionFactoryTest { private Stock testStock; private Share testShare; - private Sale testSale; - private Purchase testPurchase; - private SaleCalculator testSaleCalculator; - private PurchaseCalculator testPurchaseCalculator; @BeforeEach void setUp() { testStock = new Stock("AAPL", "APPLE INC.", new BigDecimal("100.00")); testShare = new Share(testStock, new BigDecimal("10.0"), testStock.getSalesPrice()); - testSaleCalculator = new SaleCalculator(testShare); - testSale = new Sale(testShare, 1, testSaleCalculator); - testPurchaseCalculator = new PurchaseCalculator(testShare); - testPurchase = new Purchase(testShare, 1, testPurchaseCalculator); } @Test void factoryReturnsCorrectSale() { - Transaction sale2 = TransactionFactory.createTransaction(TransactionType.SALE, testShare, 1, testSaleCalculator); - assertTrue(equalTransactions(testSale, sale2)); + int targetWeek = 1; + Transaction transaction = TransactionFactory.createTransaction(TransactionType.SALE, testShare, targetWeek); + assertNotNull(transaction); + assertInstanceOf(Sale.class, transaction); + assertEquals(targetWeek, transaction.getWeek()); + assertEquals(testShare, transaction.getShare()); + assertNotNull(transaction.getCalculator()); } @Test void factoryReturnsCorrectPurchase() { - Transaction purchase2 = TransactionFactory.createTransaction(TransactionType.PURCHASE, testShare, 1, testPurchaseCalculator); - assertTrue(equalTransactions(testPurchase, purchase2)); + int targetWeek = 1; + Transaction transaction = TransactionFactory.createTransaction(TransactionType.PURCHASE, testShare, targetWeek); + assertNotNull(transaction); + assertInstanceOf(Purchase.class, transaction); + assertEquals(targetWeek, transaction.getWeek()); + assertEquals(testShare, transaction.getShare()); + assertNotNull(transaction.getCalculator()); } @Test void factoryThrowsErrors() { - assertThrows(IllegalArgumentException.class, () -> { - TransactionFactory.createTransaction(TransactionType.PURCHASE, null, 1, testPurchaseCalculator); - }); - - assertThrows(IllegalArgumentException.class, () -> { - TransactionFactory.createTransaction(TransactionType.PURCHASE, testShare, -1, testPurchaseCalculator); - }); - - assertThrows(IllegalArgumentException.class, () -> { - TransactionFactory.createTransaction(TransactionType.PURCHASE, testShare, 1, null); - }); - - assertThrows(IllegalArgumentException.class, () -> { - TransactionFactory.createTransaction(null, testShare, 1, testPurchaseCalculator); - }); - } - - private boolean equalTransactions(final Transaction transaction1, final Transaction transaction2) { - return (transaction1.getWeek() == transaction2.getWeek() - && transaction1.getShare() == transaction2.getShare() - && transaction1.getCalculator() == transaction2.getCalculator() - && transaction1.isCommited() == transaction2.isCommited()); + assertThrows(IllegalArgumentException.class, + () -> TransactionFactory.createTransaction(TransactionType.PURCHASE, null, 1) + ); + assertThrows(IllegalArgumentException.class, + () -> TransactionFactory.createTransaction(TransactionType.PURCHASE, testShare, -1) + ); + assertThrows(IllegalArgumentException.class, + () -> TransactionFactory.createTransaction(null, testShare, 1) + ); } } \ No newline at end of file