From ce22bf444e0a74aa3e269fab7bcefae70e48b01b Mon Sep 17 00:00:00 2001 From: asvitkine Date: Sat, 2 Mar 2024 22:59:06 -0500 Subject: [PATCH] Add BidPlaceDelegateTest (#12384) Adapted from PlaceDelegateTest, with failing tests updated with expectations that makes sense for BidPlaceDelegate. No behavior changes, but I plan to add more test cases to this class when I change behavior for: https://github.com/triplea-game/triplea/issues/12376 --- .../delegate/AbstractDelegateTestCase.java | 8 + .../delegate/BidPlaceDelegateTest.java | 261 ++++++++++++++++++ .../triplea/delegate/PlaceDelegateTest.java | 8 - 3 files changed, 269 insertions(+), 8 deletions(-) create mode 100644 game-app/game-core/src/test/java/games/strategy/triplea/delegate/BidPlaceDelegateTest.java diff --git a/game-app/game-core/src/test/java/games/strategy/triplea/delegate/AbstractDelegateTestCase.java b/game-app/game-core/src/test/java/games/strategy/triplea/delegate/AbstractDelegateTestCase.java index cc1fc77d222..f04ac435a6f 100644 --- a/game-app/game-core/src/test/java/games/strategy/triplea/delegate/AbstractDelegateTestCase.java +++ b/game-app/game-core/src/test/java/games/strategy/triplea/delegate/AbstractDelegateTestCase.java @@ -7,11 +7,13 @@ import games.strategy.engine.data.GamePlayer; import games.strategy.engine.data.Resource; import games.strategy.engine.data.Territory; +import games.strategy.engine.data.Unit; import games.strategy.engine.data.UnitType; import games.strategy.triplea.Constants; import games.strategy.triplea.attachments.TechAttachment; import games.strategy.triplea.settings.AbstractClientSettingTestCase; import games.strategy.triplea.xml.TestMapGameData; +import java.util.List; import org.junit.jupiter.api.BeforeEach; /** @@ -97,6 +99,12 @@ public void setUp() { addTechAttachment(germans); } + protected List create(GamePlayer player, UnitType unitType, int quantity) { + var units = unitType.create(quantity, player); + player.getUnitCollection().addAll(units); + return units; + } + private void addTechAttachment(final GamePlayer player) { player.addAttachment( Constants.TECH_ATTACHMENT_NAME, diff --git a/game-app/game-core/src/test/java/games/strategy/triplea/delegate/BidPlaceDelegateTest.java b/game-app/game-core/src/test/java/games/strategy/triplea/delegate/BidPlaceDelegateTest.java new file mode 100644 index 00000000000..24e4ec0cd25 --- /dev/null +++ b/game-app/game-core/src/test/java/games/strategy/triplea/delegate/BidPlaceDelegateTest.java @@ -0,0 +1,261 @@ +package games.strategy.triplea.delegate; + +import static games.strategy.triplea.Constants.DAMAGE_FROM_BOMBING_DONE_TO_UNITS_INSTEAD_OF_TERRITORIES; +import static games.strategy.triplea.Constants.UNIT_PLACEMENT_RESTRICTIONS; +import static games.strategy.triplea.delegate.GameDataTestUtil.unitType; +import static games.strategy.triplea.delegate.Matches.unitIsOfType; +import static games.strategy.triplea.delegate.MockDelegateBridge.newDelegateBridge; +import static games.strategy.triplea.delegate.remote.IAbstractPlaceDelegate.BidMode.NOT_BID; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.hasSize; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import games.strategy.engine.data.Unit; +import games.strategy.engine.delegate.IDelegateBridge; +import games.strategy.triplea.delegate.data.PlaceableUnits; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.triplea.java.collections.CollectionUtils; + +class BidPlaceDelegateTest extends AbstractDelegateTestCase { + private BidPlaceDelegate delegate; + + @BeforeEach + void setupPlaceDelegate() { + final IDelegateBridge bridge = newDelegateBridge(british); + delegate = new BidPlaceDelegate(); + delegate.initialize("bid"); + delegate.setDelegateBridgeAndPlayer(bridge); + delegate.start(); + } + + @Test + void testValid() { + final String response = delegate.placeUnits(create(british, infantry, 2), uk, NOT_BID); + assertValid(response); + } + + @Test + void testNotCorrectUnitsValid() { + final var unitsNotHeldByPlayer = infantry.create(3, british); + final String response = delegate.placeUnits(unitsNotHeldByPlayer, uk, NOT_BID); + assertError(response); + } + + @Test + void testOnlySeaInSeaZone() { + final String response = + delegate.canUnitsBePlaced(northSea, create(british, infantry, 2), british); + assertError(response); + } + + @Test + void testSeaCanGoInSeaZone() { + final String response = + delegate.canUnitsBePlaced(northSea, create(british, transport, 2), british); + assertValid(response); + } + + @Test + void testLandCanGoInLandZone() { + final String response = delegate.placeUnits(create(british, infantry, 2), uk, NOT_BID); + assertValid(response); + } + + @Test + void testSeaCantGoInSeaInLandZone() { + final String response = delegate.canUnitsBePlaced(uk, create(british, transport, 2), british); + assertError(response); + } + + @Test + void testNoGoIfOpposingTroopsSea() { + final String response = + delegate.canUnitsBePlaced(northSea, create(japanese, transport, 2), japanese); + assertError(response); + } + + @Test + void testNoGoIfOpposingTroopsLand() { + final String response = delegate.canUnitsBePlaced(japan, create(british, infantry, 2), british); + assertError(response); + } + + @Test + void testOnlyOneFactoryPlaced() { + final String response = delegate.canUnitsBePlaced(uk, create(british, factory, 1), british); + assertError(response); + } + + @Test + void testCantPlaceAaWhenOneAlreadyThere() { + final String response = delegate.canUnitsBePlaced(uk, create(british, aaGun, 1), british); + assertError(response); + } + + @Test + void testCantPlaceTwoAa() { + final String response = + delegate.canUnitsBePlaced(westCanada, create(british, aaGun, 2), british); + assertError(response); + } + + @Test + void testProduceFactory() { + final String response = delegate.canUnitsBePlaced(egypt, create(british, factory, 1), british); + assertValid(response); + } + + @Test + void testMustOwnToPlace() { + final String response = + delegate.canUnitsBePlaced(germany, create(british, infantry, 2), british); + assertError(response); + } + + @Test + void testCanProduce() { + final PlaceableUnits response = + delegate.getPlaceableUnits(create(british, infantry, 2), westCanada); + assertFalse(response.isError()); + } + + @Test + void testCanProduceInSea() { + final PlaceableUnits response = + delegate.getPlaceableUnits(create(british, transport, 2), northSea); + assertFalse(response.isError()); + } + + @Test + void testCanProduceAboveTerritoryLimit() { + final PlaceableUnits response = + delegate.getPlaceableUnits(create(british, infantry, 25), westCanada); + assertFalse(response.isError()); + assertEquals(25, response.getMaxUnits()); + } + + @Test + void testRequiresUnitsDoesNotLimitBidPlacement() { + gameData.getProperties().set(UNIT_PLACEMENT_RESTRICTIONS, true); + // Needed for canProduceXUnits to work. (!) + gameData.getProperties().set(DAMAGE_FROM_BOMBING_DONE_TO_UNITS_INSTEAD_OF_TERRITORIES, true); + final var infantry2 = unitType("infantry2", gameData); + + final var threeInfantry2 = create(british, infantry2, 3); + final var fourInfantry2 = create(british, infantry2, 4); + + uk.getUnitCollection().clear(); + assertValid(delegate.canUnitsBePlaced(uk, threeInfantry2, british)); + assertValid(delegate.canUnitsBePlaced(uk, fourInfantry2, british)); + final PlaceableUnits response = delegate.getPlaceableUnits(fourInfantry2, uk); + assertThat(response.getUnits(), hasSize(4)); + } + + @Test + void testAlreadyProducedUnitsIgnoredForBid() { + delegate.setProduced(Map.of(westCanada, create(british, infantry, 2))); + final PlaceableUnits response = + delegate.getPlaceableUnits(create(british, infantry, 25), westCanada); + assertFalse(response.isError()); + assertEquals(25, response.getMaxUnits()); + } + + @Test + void testMultipleFactories() { + String response = delegate.canUnitsBePlaced(egypt, create(british, factory, 1), british); + // we can place 1 factory + assertValid(response); + // we can't place 2 + response = delegate.canUnitsBePlaced(egypt, create(british, factory, 2), british); + assertError(response); + } + + @Test + void testUnitAttachmentStackingLimit() { + // we can place 4 + Collection fourTanks = create(british, armour, 4); + assertValid(delegate.canUnitsBePlaced(uk, fourTanks, british)); + + // we can't place 5 per the unit attachment's placementLimit + Collection fiveTanks = create(british, armour, 5); + assertError(delegate.canUnitsBePlaced(uk, fiveTanks, british)); + + // we can't place 3, if 2 are already scheduled to be placed + delegate.setProduced(Map.of(uk, create(british, armour, 2))); + Collection threeTanks = create(british, armour, 3); + assertError(delegate.canUnitsBePlaced(uk, threeTanks, british)); + // but we can place 2 + Collection twoTanks = create(british, armour, 2); + assertValid(delegate.canUnitsBePlaced(uk, twoTanks, british)); + + // we also can't place 3, if there's one in the territory and another scheduled to be placed. + delegate.setProduced(Map.of(uk, create(british, armour, 1))); + uk.getUnitCollection().addAll(create(british, armour, 1)); + assertError(delegate.canUnitsBePlaced(uk, threeTanks, british)); + // but we can place 2 + assertValid(delegate.canUnitsBePlaced(uk, twoTanks, british)); + } + + @Test + void testPlayerAttachmentStackingLimit() { + // we can place 3 battleships + Collection units = create(british, battleship, 3); + assertValid(delegate.canUnitsBePlaced(northSea, units, british)); + // but not 4 + units = create(british, battleship, 4); + assertError(delegate.canUnitsBePlaced(northSea, units, british)); + + // we can also place 2 battleships and a carrier + units = create(british, battleship, 2); + units.addAll(create(british, carrier, 1)); + assertValid(delegate.canUnitsBePlaced(northSea, units, british)); + // but not 2 battleships and 2 carriers + units.addAll(create(british, carrier, 1)); + assertError(delegate.canUnitsBePlaced(northSea, units, british)); + // However, getPlaceableUnits() should return 2 of each, since that's what's for filtering the + // options given to the user. + assertThat( + delegate.getPlaceableUnits(units, northSea).getUnits(), + containsInAnyOrder(units.toArray())); + units.addAll(create(british, carrier, 5)); + units.addAll(create(british, battleship, 7)); + var result = delegate.getPlaceableUnits(units, northSea).getUnits(); + assertThat(result, hasSize(6)); + assertThat(CollectionUtils.getMatches(result, Matches.unitIsOfType(battleship)), hasSize(3)); + assertThat(CollectionUtils.getMatches(result, Matches.unitIsOfType(carrier)), hasSize(3)); + } + + @Test + void testStackingLimitFilteringHappensAfterPlacementRestrictions() { + // Note: battleship is marked as not placeable in "West Canada Sea Zone" on the test map. + + // Add a carrier to the sea zone. + westCanadaSeaZone.getUnitCollection().addAll(create(british, carrier, 1)); + + // If we filter list of 2 battleships and 2 carriers, the 2 carriers should be selected. + List units = create(british, battleship, 2); + units.addAll(create(british, carrier, 2)); + // First, we can't place all of them (expected). + assertError(delegate.canUnitsBePlaced(westCanadaSeaZone, units, british)); + + PlaceableUnits response = delegate.getPlaceableUnits(units, westCanadaSeaZone); + assertThat(response.getUnits(), hasSize(2)); + assertThat(response.getUnits(), is(CollectionUtils.getMatches(units, unitIsOfType(carrier)))); + + // Check that it's the case even if we shuffle the list a few times. + for (int i = 0; i < 5; i++) { + Collections.shuffle(units); + response = delegate.getPlaceableUnits(units, westCanadaSeaZone); + assertThat(response.getUnits(), hasSize(2)); + assertThat(response.getUnits(), is(CollectionUtils.getMatches(units, unitIsOfType(carrier)))); + } + } +} diff --git a/game-app/game-core/src/test/java/games/strategy/triplea/delegate/PlaceDelegateTest.java b/game-app/game-core/src/test/java/games/strategy/triplea/delegate/PlaceDelegateTest.java index 724754e63df..30cd686bf3d 100644 --- a/game-app/game-core/src/test/java/games/strategy/triplea/delegate/PlaceDelegateTest.java +++ b/game-app/game-core/src/test/java/games/strategy/triplea/delegate/PlaceDelegateTest.java @@ -13,9 +13,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import games.strategy.engine.data.GamePlayer; import games.strategy.engine.data.Unit; -import games.strategy.engine.data.UnitType; import games.strategy.engine.delegate.IDelegateBridge; import games.strategy.triplea.delegate.data.PlaceableUnits; import java.util.Collection; @@ -38,12 +36,6 @@ void setupPlaceDelegate() { delegate.start(); } - private List create(GamePlayer player, UnitType unitType, int quantity) { - var units = unitType.create(quantity, player); - player.getUnitCollection().addAll(units); - return units; - } - @Test void testValid() { final String response = delegate.placeUnits(create(british, infantry, 2), uk, NOT_BID);