From d40158f6fefd50a2105af3c71e24fea41e6c08aa Mon Sep 17 00:00:00 2001 From: Elisabeth Berg Date: Sun, 24 May 2026 22:32:25 +0200 Subject: [PATCH] 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