From d40158f6fefd50a2105af3c71e24fea41e6c08aa Mon Sep 17 00:00:00 2001 From: Elisabeth Berg Date: Sun, 24 May 2026 22:32:25 +0200 Subject: [PATCH 1/9] Added more tests to ExchangeTest --- src/test/java/ExchangeTest.java | 234 +++++++++++++++++++++++-- target/test-classes/ExchangeTest.class | Bin 1964 -> 10733 bytes 2 files changed, 223 insertions(+), 11 deletions(-) diff --git a/src/test/java/ExchangeTest.java b/src/test/java/ExchangeTest.java index f80b1d9..9261bd6 100644 --- a/src/test/java/ExchangeTest.java +++ b/src/test/java/ExchangeTest.java @@ -1,8 +1,13 @@ -import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import Model.Exchange; +import Model.Player; +import Model.Share; import Model.Stock; +import Model.Transaction; +import Model.Purchase; +import Model.Sale; import static org.junit.jupiter.api.Assertions.*; @@ -15,9 +20,10 @@ public class ExchangeTest { private Exchange exchange; private Stock apple; private Stock google; + private Player player; - @BeforeAll - public void setUp() { + @BeforeEach + void setUp() { apple = new Stock("AAPL", "Apple", new BigDecimal("100")); google = new Stock("GOOGL", "Google", new BigDecimal("200")); @@ -25,29 +31,235 @@ public void setUp() { stocks.add(apple); stocks.add(google); - exchange = new Exchange("ABC", stocks); + exchange = new Exchange("TestExchange", stocks); + player = new Player("Jane", new BigDecimal("500000")); } + // ---- Positive tests ---- + @Test - public void testFindStocksBySymbol() { - List result = exchange.findStocks("AAPL"); + void testGetName() { + assertEquals("TestExchange", exchange.getName()); + } + + @Test + void testInitialWeekIsOne() { + assertEquals(1, exchange.getWeek()); + } + + @Test + void testAdvanceIncrementsWeek() { + exchange.advance(); + assertEquals(2, exchange.getWeek()); + } + + @Test + void testHasStockReturnsTrue() { + assertTrue(exchange.hasStock("AAPL")); + } + @Test + void testHasStockReturnsFalse() { + assertFalse(exchange.hasStock("MSFT")); + } + + @Test + void testGetStockReturnsCorrectStock() { + assertEquals(apple, exchange.getStock("AAPL")); + } + + @Test + void testGetStockReturnsNullForUnknown() { + assertNull(exchange.getStock("MSFT")); + } + + @Test + void testFindStocksBySymbol() { + List result = exchange.findStocks("AAPL"); assertEquals(1, result.size()); assertEquals("AAPL", result.get(0).getSymbol()); } @Test - public void testFindStocksByCompanyNames() { + void testFindStocksByCompanyName() { List result = exchange.findStocks("e"); - assertEquals(2, result.size()); } @Test - public void testFindStocksNotInList() { + void testFindStocksNoMatch() { List result = exchange.findStocks("Samsung"); - assertEquals(0, result.size()); } - + + @Test + void testFindStocksEmptyTermReturnsAll() { + List result = exchange.findStocks(""); + assertEquals(2, result.size()); + } + + @Test + void testBuyReturnsCommittedPurchase() { + Transaction t = exchange.buy("AAPL", new BigDecimal("5"), player); + assertNotNull(t); + assertTrue(t.isCommitted()); + assertInstanceOf(Purchase.class, t); + } + + @Test + void testBuyDeductsMoneyFromPlayer() { + BigDecimal before = player.getMoney(); + exchange.buy("AAPL", new BigDecimal("5"), player); + assertTrue(player.getMoney().compareTo(before) < 0); + } + + @Test + void testBuyAddsShareToPortfolio() { + exchange.buy("AAPL", new BigDecimal("5"), player); + assertFalse(player.getPortfolio().getShares("AAPL").isEmpty()); + } + + @Test + void testSellReturnsCommittedSale() { + exchange.buy("AAPL", new BigDecimal("5"), player); + Share share = player.getPortfolio().getShares("AAPL").get(0); + + Transaction t = exchange.sell(share, player); + assertNotNull(t); + assertTrue(t.isCommitted()); + assertInstanceOf(Sale.class, t); + } + + @Test + void testSellAddsMoney() { + exchange.buy("AAPL", new BigDecimal("5"), player); + Share share = player.getPortfolio().getShares("AAPL").get(0); + BigDecimal before = player.getMoney(); + + exchange.sell(share, player); + assertTrue(player.getMoney().compareTo(before) > 0); + } + + @Test + void testSellRemovesShareFromPortfolio() { + exchange.buy("AAPL", new BigDecimal("5"), player); + Share share = player.getPortfolio().getShares("AAPL").get(0); + + exchange.sell(share, player); + assertTrue(player.getPortfolio().getShares("AAPL").isEmpty()); + } + + @Test + void testGetGainersReturnsRequestedLimit() { + exchange.advance(); // prices must have changed at least once for a meaningful sort + List gainers = exchange.getGainers(1); + assertEquals(1, gainers.size()); + } + + @Test + void testGetLosersReturnsRequestedLimit() { + exchange.advance(); + List losers = exchange.getLosers(1); + assertEquals(1, losers.size()); + } + + // ---- Negative tests ---- + + @Test + void testConstructorNullNameThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Exchange(null, List.of(apple)) + ); + } + + @Test + void testConstructorBlankNameThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Exchange(" ", List.of(apple)) + ); + } + + @Test + void testConstructorNullStockListThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Exchange("X", null) + ); + } + + @Test + void testConstructorNullStockEntryThrows() { + List withNull = new ArrayList<>(); + withNull.add(apple); + withNull.add(null); + assertThrows(IllegalArgumentException.class, () -> + new Exchange("X", withNull) + ); + } + + @Test + void testBuyNullSymbolThrows() { + assertThrows(IllegalArgumentException.class, () -> + exchange.buy(null, new BigDecimal("5"), player) + ); + } + + @Test + void testBuyUnknownSymbolThrows() { + assertThrows(IllegalArgumentException.class, () -> + exchange.buy("MSFT", new BigDecimal("5"), player) + ); + } + + @Test + void testBuyZeroQuantityThrows() { + assertThrows(IllegalArgumentException.class, () -> + exchange.buy("AAPL", BigDecimal.ZERO, player) + ); + } + + @Test + void testBuyNegativeQuantityThrows() { + assertThrows(IllegalArgumentException.class, () -> + exchange.buy("AAPL", new BigDecimal("-1"), player) + ); + } + + @Test + void testBuyNullPlayerThrows() { + assertThrows(IllegalArgumentException.class, () -> + exchange.buy("AAPL", new BigDecimal("5"), null) + ); + } + + @Test + void testBuyInsufficientFundsThrows() { + Player poorPlayer = new Player("Broke", new BigDecimal("1")); + assertThrows(IllegalStateException.class, () -> + exchange.buy("AAPL", new BigDecimal("5"), poorPlayer) + ); + } + + @Test + void testSellNullPlayerThrows() { + exchange.buy("AAPL", new BigDecimal("5"), player); + Share share = player.getPortfolio().getShares("AAPL").get(0); + assertThrows(IllegalArgumentException.class, () -> + exchange.sell(share, null) + ); + } + + @Test + void testSellShareNotInPortfolioThrows() { + Share unowned = new Share(apple, new BigDecimal("1"), new BigDecimal("100")); + assertThrows(IllegalStateException.class, () -> + exchange.sell(unowned, player) + ); + } + + @Test + void testAddNullObserverThrows() { + assertThrows(IllegalArgumentException.class, () -> + exchange.addObserver(null) + ); + } } diff --git a/target/test-classes/ExchangeTest.class b/target/test-classes/ExchangeTest.class index 69ecbefc1a6f274da23efc9dfb903a0546718f72..238ca9dd2248bbe4e28a26a8a964a5ec95435ded 100644 GIT binary patch literal 10733 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 CFx9dE literal 1964 zcmb7EYg5}s6g}&w5P}dDJCHgL8Xh)Iu|xVGHIUc@s9Ocnm^gLXw3Ur8qO#;la;NUU z>P!=dGSlhj{-{pxN;ZB3X4)^itE+SOo^$u?{{7D%e*)ORNfZGFY5SMjv1-<}1I=-x z2r*2Zs6VS2gJPNe>WNl!83e5hqQA-$>rgW?y|f%dSZy{9jbWnutK?d>A1NNGTUMR_ zh^*_T?rt&!lc_R8Xp43b5yYef5#tP36y4PJT8*k^AE;HHAuCo*HOi{3^Y3mj=ivJV(yNu}S-l56W`J(ntrh-02378o`zK)jpdM@A~rPGewLk`RR;AVnN^ z_xE>+Zkl?&>os4%hs0_%o8`!igfR$F++%ppqt$YCBa^pnwXNumDXtQ$2$Zujf8LUieZd! zJ>k>IL2%cyoZI)j>JMbML53=*SV-m)4^)okyn4b2fieqz*w zYs08L%PpGR2?FX2(URJ5S|+W;lGUZW~ z`awm`r90SojYphd5S-vmQU$~?LkF3qaSgNB!gcahf==~@M?CHm>JneW0t$p-cubjG zlpooq6~oSus9g^Mw7ot8OGN0AJo5&hE1~o$6o$8WD$k^Yrzi*T7vgX5@-4pW(~}XR zE#|1vcc@eISft{-mp-MXE+vtOsza3gh)=0{A*C9L;(d;Jlxmz(_?%Loz@+Db6cI=h qfx836W9P-k-zm-`esS$T6hGp{gO?W1Qt?$Pe*b?LKPG(v=>Gz9nw@n3 From 0187457ae8a3d4c09d7262bb6d596d9e53c98473 Mon Sep 17 00:00:00 2001 From: Elisabeth Berg Date: Sun, 24 May 2026 22:32:47 +0200 Subject: [PATCH 2/9] Added more tests to PortfolioTest --- src/test/java/PortfolioTest.java | 139 ++++++++++++++++++------ target/test-classes/PortfolioTest.class | Bin 2606 -> 5806 bytes 2 files changed, 103 insertions(+), 36 deletions(-) diff --git a/src/test/java/PortfolioTest.java b/src/test/java/PortfolioTest.java index d921601..34e46aa 100644 --- a/src/test/java/PortfolioTest.java +++ b/src/test/java/PortfolioTest.java @@ -1,5 +1,6 @@ import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import Model.Portfolio; @@ -7,82 +8,148 @@ import Model.Stock; import java.math.BigDecimal; +import java.util.List; public class PortfolioTest { - @Test - void testAddSharePortfolio() { - Portfolio portfolio = new Portfolio(); + private Portfolio portfolio; + private Stock stock; + private Share share; - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("10"), new BigDecimal("140")); + @BeforeEach + void setUp() { + portfolio = new Portfolio(); + stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + share = new Share(stock, new BigDecimal("10"), new BigDecimal("140")); + } - boolean result = portfolio.addShare(share); + // ---- Positive tests ---- + @Test + void testAddShare() { + boolean result = portfolio.addShare(share); assertTrue(result); assertTrue(portfolio.contains(share)); } @Test - void testRemoveSharePortfolio() { - Portfolio portfolio = new Portfolio(); - - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("10"), new BigDecimal("140")); + void testAddMultipleShares() { + Stock stock2 = new Stock("GOOGL", "Google", new BigDecimal("200")); + Share share2 = new Share(stock2, new BigDecimal("5"), new BigDecimal("190")); portfolio.addShare(share); + portfolio.addShare(share2); - boolean result = portfolio.removeShare(share); + assertEquals(2, portfolio.getShares().size()); + } + @Test + void testRemoveShare() { + portfolio.addShare(share); + boolean result = portfolio.removeShare(share); assertTrue(result); assertFalse(portfolio.contains(share)); } @Test - void testGetSharesPortfolio() { - Portfolio portfolio = new Portfolio(); - - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("10"), new BigDecimal("140")); + void testRemoveShareNotInPortfolioReturnsFalse() { + boolean result = portfolio.removeShare(share); + assertFalse(result); + } + @Test + void testGetSharesReturnsAll() { portfolio.addShare(share); - - var shares = portfolio.getShares(); - + List shares = portfolio.getShares(); assertEquals(1, shares.size()); assertTrue(shares.contains(share)); } @Test - void testGetSharesBySymbolPortfolio() { - Portfolio portfolio = new Portfolio(); + void testGetSharesIsDefensiveCopy() { + portfolio.addShare(share); + List copy = portfolio.getShares(); + copy.clear(); + assertEquals(1, portfolio.getShares().size()); + } - Stock stock1 = new Stock("AAPL", "Apple", new BigDecimal("150")); + @Test + void testGetSharesBySymbol() { Stock stock2 = new Stock("GOOGL", "Google", new BigDecimal("200")); + Share share2 = new Share(stock2, new BigDecimal("5"), new BigDecimal("190")); - Share share1 = new Share(stock1, new BigDecimal("10"), new BigDecimal("140")); - Share share2 = new Share(stock2, new BigDecimal("10"), new BigDecimal("190")); - - portfolio.addShare(share1); + portfolio.addShare(share); portfolio.addShare(share2); - var result = portfolio.getShares("AAPL"); - + List result = portfolio.getShares("AAPL"); assertEquals(1, result.size()); - assertTrue(result.contains(share1)); + assertTrue(result.contains(share)); + } + + @Test + void testGetSharesBySymbolNoMatch() { + portfolio.addShare(share); + List result = portfolio.getShares("MSFT"); + assertTrue(result.isEmpty()); + } + + @Test + void testContainsReturnsTrueWhenPresent() { + portfolio.addShare(share); + assertTrue(portfolio.contains(share)); } @Test - void testContainsPortfolio() { - Portfolio portfolio = new Portfolio(); + void testContainsReturnsFalseWhenAbsent() { + assertFalse(portfolio.contains(share)); + } - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("10"), new BigDecimal("140")); + @Test + void testGetNetWorthEmptyPortfolio() { + assertEquals(BigDecimal.ZERO, portfolio.getNetWorth()); + } + @Test + void testGetNetWorthWithShares() { portfolio.addShare(share); + // net worth should be positive when portfolio has holdings + assertTrue(portfolio.getNetWorth().compareTo(BigDecimal.ZERO) > 0); + } - assertTrue(portfolio.contains(share)); + // ---- Negative tests ---- + + @Test + void testAddNullShareThrows() { + assertThrows(IllegalArgumentException.class, () -> + portfolio.addShare(null) + ); } - + @Test + void testRemoveNullShareThrows() { + assertThrows(IllegalArgumentException.class, () -> + portfolio.removeShare(null) + ); + } + + @Test + void testContainsNullShareThrows() { + assertThrows(IllegalArgumentException.class, () -> + portfolio.contains(null) + ); + } + + @Test + void testGetSharesByNullSymbolThrows() { + assertThrows(IllegalArgumentException.class, () -> + portfolio.getShares((String) null) + ); + } + + @Test + void testGetSharesByBlankSymbolThrows() { + assertThrows(IllegalArgumentException.class, () -> + portfolio.getShares(" ") + ); + } } diff --git a/target/test-classes/PortfolioTest.class b/target/test-classes/PortfolioTest.class index 9be31bceb298913e26cf5eed9840f892c234ed1a..679e0c4d7ea6495c5d426472e08b43044c6df084 100644 GIT binary patch literal 5806 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 Date: Sun, 24 May 2026 22:33:18 +0200 Subject: [PATCH 3/9] Added more tests to PurchaseTest --- src/test/java/PurchaseTest.java | 93 +++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 16 deletions(-) diff --git a/src/test/java/PurchaseTest.java b/src/test/java/PurchaseTest.java index 2f87b39..d41e71a 100644 --- a/src/test/java/PurchaseTest.java +++ b/src/test/java/PurchaseTest.java @@ -1,4 +1,4 @@ -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; import java.math.BigDecimal; @@ -11,32 +11,93 @@ import Model.Stock; public class PurchaseTest { - Stock stock; - Share share; - Purchase purchase; + + private Stock stock; + private Share share; + private Purchase purchase; + private Player player; @BeforeEach void setUp() { - this.stock = new Stock("symbol", "company", new BigDecimal(100)); - this.share = new Share(this.stock, new BigDecimal(20), new BigDecimal(50)); - this.purchase = new Purchase(this.share, 18); + stock = new Stock("AAPL", "Apple", new BigDecimal("100")); + share = new Share(stock, new BigDecimal("20"), new BigDecimal("50")); + purchase = new Purchase(share, 1); + player = new Player("Jane", new BigDecimal("500000")); } + // ---- Positive tests ---- + @Test - void commit_validPurchase_updatesPlayer() { + void testCommitDeductsMoneyFromPlayer() { + BigDecimal before = player.getMoney(); + purchase.commit(player); + assertTrue(player.getMoney().compareTo(before) < 0); + } - // Arrange - Player player = new Player("Jane", new BigDecimal(500000)); - BigDecimal startingMoney = player.getMoney(); + @Test + void testCommitAddsShareToPortfolio() { + purchase.commit(player); + assertTrue(player.getPortfolio().contains(share)); + } + + @Test + void testCommitRecordedInArchive() { + purchase.commit(player); + assertTrue(player.getTransactionArchive().getAllTransactions().contains(purchase)); + } - // Act - this.purchase.commit(player); + @Test + void testCommitSetsCommittedFlag() { + purchase.commit(player); + assertTrue(purchase.isCommitted()); + } - // Assert - assertEquals(1, startingMoney.subtract(player.getMoney()).signum()); + @Test + void testGetShareReturnsCorrectShare() { + assertEquals(share, purchase.getShare()); + } + @Test + void testGetWeekReturnsCorrectWeek() { + assertEquals(1, purchase.getWeek()); } + // ---- Negative tests ---- - + @Test + void testCommitNullPlayerThrows() { + assertThrows(IllegalArgumentException.class, () -> + purchase.commit(null) + ); + } + + @Test + void testCommitInsufficientFundsThrows() { + Player poorPlayer = new Player("Broke", new BigDecimal("1")); + assertThrows(IllegalStateException.class, () -> + purchase.commit(poorPlayer) + ); + } + + @Test + void testCommitAlreadyCommittedThrows() { + purchase.commit(player); + assertThrows(IllegalStateException.class, () -> + purchase.commit(player) + ); + } + + @Test + void testConstructorWeekZeroThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Purchase(share, 0) + ); + } + + @Test + void testConstructorNegativeWeekThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Purchase(share, -5) + ); + } } From b5da0cf253e0ad73f2c5495563cbec38b1a4af06 Mon Sep 17 00:00:00 2001 From: Elisabeth Berg Date: Sun, 24 May 2026 22:33:36 +0200 Subject: [PATCH 4/9] Added more tests to SaleTest --- src/test/java/SaleTest.java | 116 ++++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 37 deletions(-) diff --git a/src/test/java/SaleTest.java b/src/test/java/SaleTest.java index a17d1e2..622f262 100644 --- a/src/test/java/SaleTest.java +++ b/src/test/java/SaleTest.java @@ -6,57 +6,99 @@ import Model.Share; import Model.Stock; -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 static org.junit.jupiter.api.Assertions.*; import java.math.BigDecimal; public class SaleTest { - Stock stock; - Share share; - Sale sale; + + private Stock stock; + private Share share; + private Sale sale; + private Player player; @BeforeEach - void setUp(){ - this.stock = new Stock("symbol", "company", new BigDecimal(100)); - this.share = new Share(this.stock, new BigDecimal(20), new BigDecimal(80)); - this.sale = new Sale(this.share, 18); - } + void setUp() { + stock = new Stock("AAPL", "Apple", new BigDecimal("100")); + share = new Share(stock, new BigDecimal("20"), new BigDecimal("80")); + sale = new Sale(share, 1); + player = new Player("Jane", new BigDecimal("500")); + player.getPortfolio().addShare(share); + } + + // ---- Positive tests ---- @Test - void commit_validSale_updatesPlayerState() { - - // Arrange - Player player = new Player("Jane", new BigDecimal(500)); - player.getPortfolio().addShare(this.share); + void testCommitAddsMoney() { + BigDecimal before = player.getMoney(); + sale.commit(player); + assertTrue(player.getMoney().compareTo(before) > 0); + } + + @Test + void testCommitRemovesShareFromPortfolio() { + sale.commit(player); + assertFalse(player.getPortfolio().contains(share)); + } - // Act - this.sale.commit(player); + @Test + void testCommitRecordedInArchive() { + sale.commit(player); + assertTrue(player.getTransactionArchive().getAllTransactions().contains(sale)); + } - // Assert - assertTrue(player.getTransactionArchive().getTransactions(this.sale.getWeek()).contains(this.sale)); - assertFalse(player.getPortfolio().contains(this.share)); - assertTrue(this.sale.isCommitted()); + @Test + void testCommitSetsCommittedFlag() { + sale.commit(player); + assertTrue(sale.isCommitted()); } @Test - void commit_alreadyCommitted_noAction() { + void testGetShareReturnsCorrectShare() { + assertEquals(share, sale.getShare()); + } - // Arrange - Player player = new Player("Jane", new BigDecimal(500)); - player.getPortfolio().addShare(this.share); - this.sale.commit(player); - BigDecimal moneyAfterFirstCommit = player.getMoney(); - - // Act - this.sale.commit(player); + @Test + void testGetWeekReturnsCorrectWeek() { + assertEquals(1, sale.getWeek()); + } - // Assert - assertEquals(moneyAfterFirstCommit, player.getMoney()); - assertEquals(1, player.getTransactionArchive().getTransactions(this.sale.getWeek()).size()); - assertTrue(this.sale.isCommitted()); - } + // ---- Negative tests ---- - + @Test + void testCommitNullPlayerThrows() { + assertThrows(IllegalArgumentException.class, () -> + sale.commit(null) + ); + } + + @Test + void testCommitAlreadyCommittedThrows() { + sale.commit(player); + assertThrows(IllegalStateException.class, () -> + sale.commit(player) + ); + } + + @Test + void testCommitShareNotInPortfolioThrows() { + Player otherPlayer = new Player("Bob", new BigDecimal("500")); + assertThrows(IllegalStateException.class, () -> + sale.commit(otherPlayer) + ); + } + + @Test + void testConstructorWeekZeroThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Sale(share, 0) + ); + } + + @Test + void testConstructorNegativeWeekThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Sale(share, -3) + ); + } } From c599f2844cdfadf9dec9eaad06e04a9ec80659aa Mon Sep 17 00:00:00 2001 From: Elisabeth Berg Date: Sun, 24 May 2026 22:33:48 +0200 Subject: [PATCH 5/9] Added more tests to ShareTest --- src/test/java/ShareTest.java | 87 +++++++++++++++++----------- target/test-classes/ShareTest.class | Bin 2146 -> 4255 bytes 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/src/test/java/ShareTest.java b/src/test/java/ShareTest.java index 3d840bb..fbc018d 100644 --- a/src/test/java/ShareTest.java +++ b/src/test/java/ShareTest.java @@ -1,5 +1,6 @@ import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import Model.Share; @@ -7,69 +8,89 @@ import java.math.BigDecimal; - public class ShareTest { - @Test - void testShareConstructor() { + private Stock stock; + + @BeforeEach + void setUp() { + stock = new Stock("AAPL", "Apple", new BigDecimal("150")); + } - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - BigDecimal quantity = new BigDecimal("10"); - BigDecimal purchasePrice = new BigDecimal("140"); + // ---- Positive tests ---- - Share share = new Share(stock, quantity, purchasePrice); + @Test + void testShareConstructorNotNull() { + Share share = new Share(stock, new BigDecimal("10"), new BigDecimal("140")); assertNotNull(share); } @Test void testGetStock() { - - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); Share share = new Share(stock, new BigDecimal("10"), new BigDecimal("140")); - - Stock result = share.getStock(); - - assertEquals(stock, result); + assertEquals(stock, share.getStock()); } @Test void testGetQuantity() { - - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); Share share = new Share(stock, new BigDecimal("10"), new BigDecimal("140")); - - BigDecimal result = share.getQuantity(); - - assertEquals(new BigDecimal("10"), result); + assertEquals(new BigDecimal("10"), share.getQuantity()); } @Test void testGetPurchasePrice() { - - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); Share share = new Share(stock, new BigDecimal("10"), new BigDecimal("140")); - - BigDecimal result = share.getPurchasePrice(); - - assertEquals(new BigDecimal("140"), result); + assertEquals(new BigDecimal("140"), share.getPurchasePrice()); } @Test - void testNullStock() { + void testPurchasePriceZeroAllowed() { + // buying at price 0 is an edge case but not invalid + Share share = new Share(stock, new BigDecimal("5"), BigDecimal.ZERO); + assertEquals(BigDecimal.ZERO, share.getPurchasePrice()); + } - Share share = new Share(null, new BigDecimal("10"), new BigDecimal("100")); + // ---- Negative tests ---- - assertNull(share.getStock()); + @Test + void testNullStockThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Share(null, new BigDecimal("10"), new BigDecimal("100")) + ); } @Test - void testNegativePrice() { + void testNullQuantityThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Share(stock, null, new BigDecimal("100")) + ); + } - Stock stock = new Stock("AAPL", "Apple", new BigDecimal("150")); - Share share = new Share(stock, new BigDecimal("10"), new BigDecimal("-50")); + @Test + void testZeroQuantityThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Share(stock, BigDecimal.ZERO, new BigDecimal("100")) + ); + } - assertEquals(new BigDecimal("-50"), share.getPurchasePrice()); + @Test + void testNegativeQuantityThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Share(stock, new BigDecimal("-5"), new BigDecimal("100")) + ); + } + + @Test + void testNullPurchasePriceThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Share(stock, new BigDecimal("10"), null) + ); } - + @Test + void testNegativePurchasePriceThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Share(stock, new BigDecimal("10"), new BigDecimal("-50")) + ); + } } diff --git a/target/test-classes/ShareTest.class b/target/test-classes/ShareTest.class index 0c78c049703a01bcab74ac0e8ab5fe5fc00f19d0..abf202d7c4c03ab1bbdc16b9533bcd782f12ea8d 100644 GIT binary patch literal 4255 zcmbVO3s)0I7`=l)LRb`|q9}p_Di1NB(yBpgKtyZ=1Vph~x`ZKF*zCs52DR_^`~7bJ zMSI%f(R2C(ditAs`pst9Ou{DAat@pMc4qFq^UeKc_OE{){|Vqceh#4u+XARoP=i{A z#uarIJr_a% zd&Gz)hVwonHqXhwDPbg}I_yJp0Q(gjKnp|NOiH!*EYH&7YO-Px3=MHY08FJH4M z%e+tdnvwH0qEj-XPXX*^%BegD(V+{2Auc3eV>r_l_lz5T8qHxU@pu^9#G_g~YCy$0 zLq_f!BuC#MXZH;TaZ@V- z`g%#6C@XH?$S^cd=g13bKBr|hni4Y%(^g#{x0lJzFkdz;KB^{CQHBFHm8rAr5i-AR z2SA;aHr3|#FdFoaK=vbj9+^}HW-R_$rUlOc%UG(lYx6GKXoA>z= z!!FS+YSO8-4O=vAyxo8=>JR{>9s8XbWMNxdXjt$H4aNBpBU&VklHCy9 zp&64-8-7_6j^6H7)CsXTI*o=+(J5)b6Oot0B5VUQ@6}Q4QV@(VGf# zPV}~j-cevX(R(6#UqRN1J`~YM3M?o3L`0t|Fes|U=OKK7F9Y~W!Poev=mgV@HFK3m z;?7o)5OrACLm zGf!E0u6)Y5$RjEh3|(}hF2@anTh7tR$#UN_94T0?NJ#PW0{D@kwenE+c&hiMb4 z=qjLNPkawhYZtZY>xZ7VD2mW8qu-jIb+BKkQH6PWif*7Dx9O?m2jB(Vp$NE3y;aWS zF$A5y=AI`A%!lj3^-s_+AKtN!o$J{BJN6a;#g`YblhlMI&}J9(Md}lj3j!Z6c?1je zRV3zhJi)>Fp5L(7!EYmcr*YUJ>WKF~!qEcNb~^k)M6GB>JN7$tO?eoXu9Xs?Vvz_p zh!cVrOCIsEOH2!^L@Xrr{(<9<&|k{mO8jl;#vzHn$KzLg`MJlx>heb_^Lyza5vP4b zbdrc8^jUON5)tu4?DQ3}{J%tqtsoI+d_?q+h+YzL{3%2vJrN5|tJDHfqWcx+*U=HD zpEAS)WP+1qfm0H3hr9ZHWNtqTq&(ttWEoKeN;viyBfuk!-7IW!-p^+VWynF#7m4Dc z7u!nnFrzMJLpav+7|;8IUZjc}kw6=KL08IvPWXe45$M$|L08LwPWppR5a{(SLG?1A zQ~sbg2=vyLpy@K8*Zo275a>c>(8elpRnZ2CV{x47Pi%ghfBjA84<5-6`2+K=MA7DM zn@KR$1ePHJx*1)97_|feooFQo3?ox-0-lqA_xb?S1zb`2ED3fFi@7q&CnW+u<#gY> z1S4*0nm3eF0ak>*B0+B)_;OO{!@^5SKI>jmSViEN1iU#ZA@Tj<0-q+$;;%($&VzcF zh@257U4G}_iKGkVKFzMe13aYP3xxX_y?Yt2(0{)5y4QNkYrX5WKJZ!}Q|nv82+{6; Khad10n*RmEn4S0l literal 2146 zcmb`H+fv(B6o&t8Y^*pA2M0SL&;*hOYz$bW&;y1f#t_n0I3%XbaMcm6#)t~rmE_Fy z8G6~vUiA@rQ)2p+LOa{=rIN2-ng`U|3+(uv=EG zdv=Z*}T!uO5Jzu zRY>?hC|LbPbEM(;}KB9@X^6qt$5V#V_;S7kblWt0SNm};li_G?|oc`F%#L>K}y>&bNU{uMd_ z?WeBETKYc=1o zjrqbA0vYjU8jtaW?}J!&h~!X7^Mh3jLkSQE^sj;&b}g^#uop%{f|p@X5~7;MHg;Gr zLcG}*xJ`~Ig}o6y!`L5;T3ULZ#@Eu)7%g2nWGbX%S%Fa1hE$49nHEt?mM<}Wl)0J7UgFkKX7U_U z=eTRA#Vi+lYW9G$+9e(y6&IJzF~1(4j9*}(@BR)=gQl~x8<9Z)6IkPF9XW-x8n_CP zvY3O86~f%ZG#=qI;uZL6m9rtf8|MG#h|}U1k?6k?U7o%VotQoT9zL=67XQSTwc^qR zHu~r}g*HXlX+qtl>ltFtD(r>8%{$mSPbFeZ!9HauvQ(8w*xy3f>U;A1A=oYEoJEm! zh=QIY^gN*p#3*75iv!Tr9`tgUYaKUx&?9)Nat%ED-=TK{XepT}=oLagBGRgY*#(BCuDG1__{g(`ZPQ Date: Sun, 24 May 2026 22:34:02 +0200 Subject: [PATCH 6/9] Added more tests to StockTest --- src/test/java/StockTest.java | 159 +++++++++++++++++++++++++--- target/test-classes/StockTest.class | Bin 1373 -> 6225 bytes 2 files changed, 142 insertions(+), 17 deletions(-) diff --git a/src/test/java/StockTest.java b/src/test/java/StockTest.java index fcc0d09..6a6a477 100644 --- a/src/test/java/StockTest.java +++ b/src/test/java/StockTest.java @@ -1,3 +1,4 @@ +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import Model.Stock; @@ -5,35 +6,159 @@ import static org.junit.jupiter.api.Assertions.*; import java.math.BigDecimal; - +import java.util.List; public class StockTest { - @Test - public void testGetSalesPrice() { - Stock stock = new Stock("AAPL", "APPLE", new BigDecimal("1000")); + private Stock stock; + + @BeforeEach + void setUp() { + stock = new Stock("AAPL", "Apple", new BigDecimal("1000")); + } + + // ---- Positive tests ---- + + @Test + void testGetSymbol() { + assertEquals("AAPL", stock.getSymbol()); + } + + @Test + void testGetCompany() { + assertEquals("Apple", stock.getCompany()); + } + + @Test + void testGetSalesPrice() { assertEquals(new BigDecimal("1000"), stock.getSalesPrice()); } - - @Test - public void testAddNewSalesPrice() { - Stock stock = new Stock("AAPL", "APPLE", new BigDecimal("1000")); + + @Test + void testGetSalesPriceZero() { + Stock zeroStock = new Stock("ZERO", "ZeroCorp", new BigDecimal("0")); + assertEquals(new BigDecimal("0"), zeroStock.getSalesPrice()); + } + + @Test + void testAddNewSalesPrice() { stock.addNewSalesPrice(new BigDecimal("1200")); assertEquals(new BigDecimal("1200"), stock.getSalesPrice()); } - @Test - public void testGetSalesPriceNone() { - Stock stock = new Stock("AAPL", "APPLE", new BigDecimal("0")); + @Test + void testAddNewSalesPriceZero() { + stock.addNewSalesPrice(new BigDecimal("0")); assertEquals(new BigDecimal("0"), stock.getSalesPrice()); } - @Test - public void testAddNewSalesPriceNone() { - Stock stock = new Stock("AAPL", "APPLE", new BigDecimal("1000")); - stock.addNewSalesPrice(new BigDecimal("0")); - assertEquals(new BigDecimal("0"), stock.getSalesPrice()); + @Test + void testGetHistoricalPricesInitial() { + List history = stock.getHistoricalPrices(); + assertEquals(1, history.size()); + assertEquals(new BigDecimal("1000"), history.get(0)); + } + + @Test + void testGetHistoricalPricesAfterUpdates() { + stock.addNewSalesPrice(new BigDecimal("1100")); + stock.addNewSalesPrice(new BigDecimal("1200")); + assertEquals(3, stock.getHistoricalPrices().size()); + } + + @Test + void testGetHighestPrice() { + stock.addNewSalesPrice(new BigDecimal("1500")); + stock.addNewSalesPrice(new BigDecimal("800")); + assertEquals(new BigDecimal("1500"), stock.getHighestPrice()); + } + + @Test + void testGetLowestPrice() { + stock.addNewSalesPrice(new BigDecimal("1500")); + stock.addNewSalesPrice(new BigDecimal("800")); + assertEquals(new BigDecimal("800"), stock.getLowestPrice()); + } + + @Test + void testGetLatestPriceChangePositive() { + stock.addNewSalesPrice(new BigDecimal("1100")); + assertEquals(new BigDecimal("100"), stock.getLatestPriceChange()); + } + + @Test + void testGetLatestPriceChangeNegative() { + stock.addNewSalesPrice(new BigDecimal("900")); + assertEquals(new BigDecimal("-100"), stock.getLatestPriceChange()); + } + + @Test + void testGetLatestPriceChangeOnlyOnePrice() { + assertEquals(BigDecimal.ZERO, stock.getLatestPriceChange()); + } + + @Test + void testHistoricalPricesIsDefensiveCopy() { + List history = stock.getHistoricalPrices(); + history.add(new BigDecimal("9999")); + assertEquals(1, stock.getHistoricalPrices().size()); + } + + // ---- Negative tests ---- + + @Test + void testNullSymbolThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Stock(null, "Apple", new BigDecimal("100")) + ); + } + + @Test + void testBlankSymbolThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Stock(" ", "Apple", new BigDecimal("100")) + ); } - + @Test + void testNullCompanyThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Stock("AAPL", null, new BigDecimal("100")) + ); + } + + @Test + void testBlankCompanyThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Stock("AAPL", " ", new BigDecimal("100")) + ); + } + + @Test + void testNullInitialPriceThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Stock("AAPL", "Apple", null) + ); + } + + @Test + void testNegativeInitialPriceThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Stock("AAPL", "Apple", new BigDecimal("-1")) + ); + } + + @Test + void testAddNullPriceThrows() { + assertThrows(IllegalArgumentException.class, () -> + stock.addNewSalesPrice(null) + ); + } + + @Test + void testAddNegativePriceThrows() { + assertThrows(IllegalArgumentException.class, () -> + stock.addNewSalesPrice(new BigDecimal("-10")) + ); + } } diff --git a/target/test-classes/StockTest.class b/target/test-classes/StockTest.class index 1a942861ec9e00b95e7616525ed76e5f340df15e..0008700068cbbe4a7129761956c9351e88fe7dbe 100644 GIT binary patch literal 6225 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 s%Gbz8zd;VnZjWOb{}jV8CH z+WUub_gp#*6M7(6WyrWB{7$$HZV0Dt%QoGf|JXBK*%eLcNV;A#P0Qu3v`o6as9SbN zyXcW28ZV_QY>i(^P5G}Tkfr?Z$)2HkB1z=PZ>?6>lPEBZ*6MZrD1kYKocGKwch9v$ z*?A+{vdfJm?o#+}rBX>@7K`e6OAPsTh=Uleo2QuMVHHc?Dqi(w@iNX>DC?LkYUgl&d2_fC#J_qahIx5A$Lm9B<7 z`zNa2qmF72@}`H#Qt5K4bhWdyWASxRy(Bb+a8Du3U^k6D>{C1zzre$))jDp8BZ7|okE$ed>HWb-$eJ)mub3y8Wjr8dhKG^bj<3BRsa^KOcgV>VD#3cl zNEUIjpCcoAtf4@~n+=)S56mnFW*$YFi3agF3_@*&^!p$dNPUq&EQPc;1MLBbr;*zK g144=a1rcea4`S8ButvY;9@ax Date: Sun, 24 May 2026 22:34:36 +0200 Subject: [PATCH 7/9] Created PlayerTest class --- src/test/java/PlayerTest.java | 128 ++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/test/java/PlayerTest.java diff --git a/src/test/java/PlayerTest.java b/src/test/java/PlayerTest.java new file mode 100644 index 0000000..ac1f95a --- /dev/null +++ b/src/test/java/PlayerTest.java @@ -0,0 +1,128 @@ +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import Model.Player; + +import java.math.BigDecimal; + +public class PlayerTest { + + private Player player; + + @BeforeEach + void setUp() { + player = new Player("Jane", new BigDecimal("1000")); + } + + // ---- Positive tests ---- + + @Test + void testGetName() { + assertEquals("Jane", player.getName()); + } + + @Test + void testGetMoneyMatchesStartingCapital() { + assertEquals(new BigDecimal("1000"), player.getMoney()); + } + + @Test + void testAddMoney() { + player.addMoney(new BigDecimal("500")); + assertEquals(new BigDecimal("1500"), player.getMoney()); + } + + @Test + void testAddMoneyZero() { + player.addMoney(BigDecimal.ZERO); + assertEquals(new BigDecimal("1000"), player.getMoney()); + } + + @Test + void testWithdrawMoney() { + player.withdrawMoney(new BigDecimal("400")); + assertEquals(new BigDecimal("600"), player.getMoney()); + } + + @Test + void testWithdrawMoneyZero() { + player.withdrawMoney(BigDecimal.ZERO); + assertEquals(new BigDecimal("1000"), player.getMoney()); + } + + @Test + void testPortfolioInitiallyEmpty() { + assertTrue(player.getPortfolio().getShares().isEmpty()); + } + + @Test + void testTransactionArchiveInitiallyEmpty() { + assertTrue(player.getTransactionArchive().isEmpty()); + } + + @Test + void testStartingMoneyZeroAllowed() { + Player broke = new Player("Broke", BigDecimal.ZERO); + assertEquals(BigDecimal.ZERO, broke.getMoney()); + } + + // ---- Negative tests ---- + + @Test + void testNullNameThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Player(null, new BigDecimal("1000")) + ); + } + + @Test + void testBlankNameThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Player(" ", new BigDecimal("1000")) + ); + } + + @Test + void testNullStartingMoneyThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Player("Jane", null) + ); + } + + @Test + void testNegativeStartingMoneyThrows() { + assertThrows(IllegalArgumentException.class, () -> + new Player("Jane", new BigDecimal("-1")) + ); + } + + @Test + void testAddNullAmountThrows() { + assertThrows(IllegalArgumentException.class, () -> + player.addMoney(null) + ); + } + + @Test + void testAddNegativeAmountThrows() { + assertThrows(IllegalArgumentException.class, () -> + player.addMoney(new BigDecimal("-100")) + ); + } + + @Test + void testWithdrawNullAmountThrows() { + assertThrows(IllegalArgumentException.class, () -> + player.withdrawMoney(null) + ); + } + + @Test + void testWithdrawNegativeAmountThrows() { + assertThrows(IllegalArgumentException.class, () -> + player.withdrawMoney(new BigDecimal("-100")) + ); + } +} From 770fbe87fe8cacde1686e9d74e8bb60dd57eefe4 Mon Sep 17 00:00:00 2001 From: Elisabeth Berg Date: Sun, 24 May 2026 22:34:49 +0200 Subject: [PATCH 8/9] Created TransactionArchiveTest class --- src/test/java/TransactionArchiveTest.java | 148 ++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 src/test/java/TransactionArchiveTest.java diff --git a/src/test/java/TransactionArchiveTest.java b/src/test/java/TransactionArchiveTest.java new file mode 100644 index 0000000..14ff009 --- /dev/null +++ b/src/test/java/TransactionArchiveTest.java @@ -0,0 +1,148 @@ +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import Model.Player; +import Model.Purchase; +import Model.Sale; +import Model.Share; +import Model.Stock; +import Model.TransactionArchive; + +import java.math.BigDecimal; +import java.util.List; + +public class TransactionArchiveTest { + + private TransactionArchive archive; + private Stock stock; + private Share share; + private Purchase purchase; + private Sale sale; + + @BeforeEach + void setUp() { + archive = new TransactionArchive(); + stock = new Stock("AAPL", "Apple", new BigDecimal("100")); + share = new Share(stock, new BigDecimal("10"), new BigDecimal("90")); + purchase = new Purchase(share, 1); + sale = new Sale(share, 2); + } + + // ---- Positive tests ---- + + @Test + void testIsEmptyOnCreation() { + assertTrue(archive.isEmpty()); + } + + @Test + void testIsEmptyAfterAdd() { + archive.add(purchase); + assertFalse(archive.isEmpty()); + } + + @Test + void testAddReturnsTrue() { + assertTrue(archive.add(purchase)); + } + + @Test + void testGetAllTransactions() { + archive.add(purchase); + archive.add(sale); + assertEquals(2, archive.getAllTransactions().size()); + } + + @Test + void testGetAllTransactionsIsDefensiveCopy() { + archive.add(purchase); + List copy = archive.getAllTransactions(); + copy.clear(); + assertEquals(1, archive.getAllTransactions().size()); + } + + @Test + void testGetTransactionsByWeek() { + archive.add(purchase); // week 1 + archive.add(sale); // week 2 + + List week1 = archive.getTransactions(1); + assertEquals(1, week1.size()); + assertTrue(week1.contains(purchase)); + } + + @Test + void testGetTransactionsByWeekNoMatch() { + archive.add(purchase); // week 1 + assertTrue(archive.getTransactions(99).isEmpty()); + } + + @Test + void testGetPurchaseByWeek() { + archive.add(purchase); // week 1 + archive.add(sale); // week 2 + + List purchases = archive.getPurchase(1); + assertEquals(1, purchases.size()); + assertTrue(purchases.contains(purchase)); + } + + @Test + void testGetPurchaseByWeekExcludesSales() { + // Add a sale at week 1 — should not appear in getPurchase(1) + Sale saleWeek1 = new Sale(share, 1); + archive.add(saleWeek1); + + assertTrue(archive.getPurchase(1).isEmpty()); + } + + @Test + void testGetSaleByWeek() { + archive.add(purchase); // week 1 + archive.add(sale); // week 2 + + List sales = archive.getSale(2); + assertEquals(1, sales.size()); + assertTrue(sales.contains(sale)); + } + + @Test + void testGetSaleByWeekExcludesPurchases() { + // Add a purchase at week 2 — should not appear in getSale(2) + Purchase purchaseWeek2 = new Purchase(share, 2); + archive.add(purchaseWeek2); + + assertTrue(archive.getSale(2).isEmpty()); + } + + @Test + void testCountDistinctWeeksEmpty() { + assertEquals(0, archive.countDistinctWeeks()); + } + + @Test + void testCountDistinctWeeksMultipleTransactionsSameWeek() { + Purchase purchase2 = new Purchase(share, 1); + archive.add(purchase); + archive.add(purchase2); + assertEquals(1, archive.countDistinctWeeks()); + } + + @Test + void testCountDistinctWeeksAcrossWeeks() { + archive.add(purchase); // week 1 + archive.add(sale); // week 2 + assertEquals(2, archive.countDistinctWeeks()); + } + + // ---- Negative tests ---- + + @Test + void testAddNullThrows() { + assertThrows(IllegalArgumentException.class, () -> + archive.add(null) + ); + } +} From 6d850315a153e29b2a1725328feef96c0da42f10 Mon Sep 17 00:00:00 2001 From: Elisabeth Berg Date: Sun, 24 May 2026 22:47:18 +0200 Subject: [PATCH 9/9] Change into lambda/streams --- .../java/Controller/StockFileHandler.java | 42 ++++++------------- src/main/java/Model/Portfolio.java | 19 +++------ .../compile/default-compile/inputFiles.lst | 2 + 3 files changed, 21 insertions(+), 42 deletions(-) diff --git a/src/main/java/Controller/StockFileHandler.java b/src/main/java/Controller/StockFileHandler.java index 8874232..b64f9c0 100644 --- a/src/main/java/Controller/StockFileHandler.java +++ b/src/main/java/Controller/StockFileHandler.java @@ -11,43 +11,27 @@ public class StockFileHandler { // lesing public List loadStocksFromFile(String filename) throws IOException { - List stocks = new ArrayList<>(); - List lines = Files.readAllLines(Paths.get(filename)); - - for (String line : lines) { - line = line.trim(); - if (line.isEmpty() || line.startsWith("#")) { - continue; - } - - String[] parts = line.split(","); - if (parts.length == 3) { - String symbol = parts[0]; - String name = parts[1]; - BigDecimal price = new BigDecimal(parts[2]); - - stocks.add(new Stock(symbol, name, price)); - } - } - return stocks; // returnerer listen + return Files.readAllLines(Paths.get(filename)).stream() + .map(String::trim) + .filter(line -> !line.isEmpty() && !line.startsWith("#")) + .map(line -> line.split(",")) + .filter(parts -> parts.length == 3) + .map(parts -> new Stock(parts[0], parts[1], new BigDecimal(parts[2]))) + .toList(); } // lagring public void saveStocksToFile(String filename, List stocks) throws IOException { List lines = new ArrayList<>(); - - // header lines.add("# Ticker,Name,Price"); - - for (Stock stock : stocks) { - // formaterer hver aksje som "SYMBOL,NAME,PRICE" - String line = String.format("%s,%s,%s", + + lines.addAll(stocks.stream() + .map(stock -> String.format("%s,%s,%s", stock.getSymbol(), stock.getCompany(), - stock.getSalesPrice().toString()); - lines.add(line); - } - + stock.getSalesPrice().toString())) + .toList()); + Files.write(Paths.get(filename), lines); } } \ No newline at end of file diff --git a/src/main/java/Model/Portfolio.java b/src/main/java/Model/Portfolio.java index 949bea3..ba050e7 100644 --- a/src/main/java/Model/Portfolio.java +++ b/src/main/java/Model/Portfolio.java @@ -33,13 +33,9 @@ public List getShares(String symbol) { if (symbol == null || symbol.isBlank()) { throw new IllegalArgumentException("Symbol cannot be null or blank"); } - List result = new ArrayList<>(); - for (Share share : shares) { - if (share.getStock().getSymbol().equals(symbol)) { - result.add(share); - } - } - return result; + return shares.stream() + .filter(share -> share.getStock().getSymbol().equals(symbol)) + .toList(); } public boolean contains(Share share) { @@ -50,12 +46,9 @@ public boolean contains(Share share) { } public BigDecimal getNetWorth() { - BigDecimal total = BigDecimal.ZERO; - for (Share share : shares) { - SaleCalculator calc = new SaleCalculator(share); - total = total.add(calc.calculateTotal()); - } - return total; + return shares.stream() + .map(share -> new SaleCalculator(share).calculateTotal()) + .reduce(BigDecimal.ZERO, BigDecimal::add); } } diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst index f40803d..88de729 100644 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -2,6 +2,7 @@ C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Control C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Exchange.java C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\ExchangeObserver.java C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Player.java +C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\PlayerStatus.java C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Portfolio.java C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Purchase.java C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\PurchaseCalculator.java @@ -12,6 +13,7 @@ C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\S C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\Transaction.java C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\TransactionArchive.java C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\TransactionCalculator.java +C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\Model\TransactionFactory.java C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\View\GameSetupScene.java C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\View\Launcher.java C:\Users\elisa\Downloads\progdel1\Programmering2_mappe_v26\src\main\java\View\MainGameScene.java