From 2a08b6c0635dcb106b793f140307d71e41126217 Mon Sep 17 00:00:00 2001 From: Christian 'ketura' McCarty Date: Tue, 26 Jan 2021 00:47:46 -0600 Subject: [PATCH] Set up individual card unit testing Added GenericCardTest, a helper class that extends AbstractAtTest with a focus on easily and clearly setting up unit tests for testing the implementation of card game text. Set up the PC errata for Elrond, Lord of Rivendell as a proof of concept. --- .../gempukku/lotro/cards/GenericCardTest.java | 223 ++++++++++++++++++ .../pc/errata/Elrond_LoRErrataTest.java | 142 +++++++++++ 2 files changed, 365 insertions(+) create mode 100644 gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTest.java create mode 100644 gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/Elrond_LoRErrataTest.java diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTest.java new file mode 100644 index 000000000..b22c29215 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTest.java @@ -0,0 +1,223 @@ +package com.gempukku.lotro.cards; + +import com.gempukku.lotro.at.AbstractAtTest; +import com.gempukku.lotro.common.Phase; +import com.gempukku.lotro.common.Zone; +import com.gempukku.lotro.game.CardNotFoundException; +import com.gempukku.lotro.game.PhysicalCardImpl; +import com.gempukku.lotro.logic.decisions.AwaitingDecision; +import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; + +import java.util.*; + +import static org.junit.Assert.assertEquals; + +public class GenericCardTest extends AbstractAtTest { + + private int LastCardID; + + public Map freepsCards = new HashMap<>(); + public Map shadowCards = new HashMap<>(); + + public GenericCardTest(Map freepsIDs, Map shadowIDs, Collection freepsdeck, Collection shadowdeck) throws CardNotFoundException, DecisionResultInvalidException { + super(); + LastCardID = 100; + + + if(freepsIDs != null) + { + for(String name : freepsIDs.keySet()) + { + String id = freepsIDs.get(name); + freepsCards.put(name, CreateCard(P1, id)); + } + } + + if(shadowIDs != null) + { + for(String name : shadowIDs.keySet()) + { + String id = shadowIDs.get(name); + shadowCards.put(name, CreateCard(P2, id)); + } + } + + Map> deckCards = new HashMap>(); + + if(freepsdeck == null) + { + deckCards.put(P1, new ArrayList()); + } + else + { + deckCards.put(P1, freepsdeck); + } + + if(shadowdeck == null) + { + deckCards.put(P2, new ArrayList()); + } + else + { + deckCards.put(P2, shadowdeck); + } + + Setup(deckCards); + } + + public PhysicalCardImpl CreateCard(String playerID, String cardID) throws CardNotFoundException { + return new PhysicalCardImpl(LastCardID++, cardID, playerID, _library.getLotroCardBlueprint(cardID)); + } + + public void Setup(Map> deckCards) throws DecisionResultInvalidException + { + initializeSimplestGame(deckCards); + } + + public void StartGame() throws DecisionResultInvalidException { + skipMulligans(); + } + + public List FreepsGetAvailableActions() { return GetAvailableActions(P1); } + public List ShadowGetAvailableActions() { return GetAvailableActions(P2); } + public List GetAvailableActions(String playerID) + { + AwaitingDecision decision = _userFeedback.getAwaitingDecision(playerID); + return Arrays.asList((String[])decision.getDecisionParameters().get("actionText")); + } + + public AwaitingDecision FreepsGetAwaitingDecision() { return GetAwaitingDecision(P1); } + public AwaitingDecision ShadowGetAwaitingDecision() { return GetAwaitingDecision(P2); } + public AwaitingDecision GetAwaitingDecision(String playerID) { return _userFeedback.getAwaitingDecision(playerID); } + + public void FreepsUseAction(String name) throws DecisionResultInvalidException { + playerDecided(P1, getCardActionId(P1, name)); + } + + public int FreepsGetWoundsOn(String cardName) + { + return GetWoundsOn(freepsCards.get(cardName)); + } + + public int ShadowGetWoundsOn(String cardName) + { + return GetWoundsOn(shadowCards.get(cardName)); + } + + public int GetWoundsOn(PhysicalCardImpl card) + { + return _game.getGameState().getWounds(card); + } + + public int GetFreepsHandCount() { return GetPlayerHandCount(P1); } + + public int GetPlayerHandCount(String player) + { + return _game.getGameState().getHand(player).size(); + } + + public int GetFreepsDeckCount() { return GetPlayerDeckCount(P1); } + + public int GetPlayerDeckCount(String player) + { + return _game.getGameState().getDeck(player).size(); + } + + public Phase GetCurrentPhase() + { + return _game.getGameState().getCurrentPhase(); + } + + public Boolean FreepsActionAvailable(String action) + { + return ActionAvailable(P1, action); + } + + public Boolean ActionAvailable(String player, String action) + { + List actions = GetAvailableActions(player); + return actions.stream().anyMatch(x -> x.startsWith(action)); + } + + + public void SetTwilight(int amount) + { + _game.getGameState().setTwilight(amount); + } + + public void FreepsMoveCardToHand(String cardName) { MoveCardToZone(P1, freepsCards.get(cardName), Zone.HAND); } + public void FreepsMoveCardToHand(PhysicalCardImpl card) { MoveCardToZone(P1, card, Zone.HAND); } + + public void FreepsMoveCardToDeck(String cardName) { MoveCardToZone(P1, freepsCards.get(cardName), Zone.DECK); } + public void FreepsMoveCardToDeck(PhysicalCardImpl card) { MoveCardToZone(P1, card, Zone.DECK); } + + public void FreepsMoveCharToTable(String cardName) { MoveCardToZone(P1, freepsCards.get(cardName), Zone.FREE_CHARACTERS); } + public void FreepsMoveCharToTable(PhysicalCardImpl card) + { + MoveCardToZone(P1, card, Zone.FREE_CHARACTERS); + } + + public void FreepsMove(String cardID, Zone zone) + { + MoveCardToZone(P1, freepsCards.get(cardID), zone); + } + public void ShadowMove(String cardID, Zone zone) + { + MoveCardToZone(P2, shadowCards.get(cardID), zone); + } + + public void MoveCardToZone(String player, PhysicalCardImpl card, Zone zone) + { + _game.getGameState().addCardToZone(_game, card, zone); + } + + public List FreepsGetADParamAsList(String paramName) { return Arrays.asList((String[])GetAwaitingDecisionParam(P1, paramName)); } + public List ShadowGetADParamAsList(String paramName) { return Arrays.asList((String[])GetAwaitingDecisionParam(P2, paramName)); } + public Object FreepsGetADParam(String paramName) { return GetAwaitingDecisionParam(P1, paramName); } + public Object ShadowGetADParam(String paramName) { return GetAwaitingDecisionParam(P2, paramName); } + public Object GetAwaitingDecisionParam(String playerID, String paramName) + { + AwaitingDecision decision = _userFeedback.getAwaitingDecision(P1); + return decision.getDecisionParameters().get(paramName); + } + + public Map GetAwaitingDecisionParams(String playerID) + { + AwaitingDecision decision = _userFeedback.getAwaitingDecision(P1); + return decision.getDecisionParameters(); + } + + public void FreepsPlayCharFromHand(String cardName) throws DecisionResultInvalidException + { + PhysicalCardImpl card = freepsCards.get(cardName); + List availableIds = FreepsGetADParamAsList("cardId"); + + Integer index = availableIds.indexOf(String.valueOf(card.getCardId())); + playerDecided(P1, index.toString()); + } + + public void FreepsAddWoundsToChar(String cardName, int count) + { + AddWoundsToChar(freepsCards.get(cardName), count); + } + + public void AddWoundsToChar(PhysicalCardImpl card, int count) + { + for(int i = 0; i < count; i++) + { + AddWoundToChar(card); + } + } + + public void AddWoundToChar(PhysicalCardImpl card) + { + _game.getGameState().addWound(card); + } + + public void SkipToNextFreepsTurn() + { + + } + + +} diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/Elrond_LoRErrataTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/Elrond_LoRErrataTest.java new file mode 100644 index 000000000..aa2760d27 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/Elrond_LoRErrataTest.java @@ -0,0 +1,142 @@ +package com.gempukku.lotro.cards.unofficial.pc.errata; + +import com.gempukku.lotro.cards.GenericCardTest; +import com.gempukku.lotro.common.Phase; +import com.gempukku.lotro.game.CardNotFoundException; +import com.gempukku.lotro.game.PhysicalCardImpl; +import com.gempukku.lotro.logic.decisions.AwaitingDecision; +import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; +import org.junit.Assert; +import org.junit.Test; + +import java.util.*; + +import static junit.framework.Assert.assertEquals; + +public class Elrond_LoRErrataTest +{ + + protected GenericCardTest GetSimpleDeckScenario() throws CardNotFoundException, DecisionResultInvalidException { + return new GenericCardTest( + new HashMap() + {{ + put("elrond", "21_1040"); + put("randomcard", "1_3"); + }}, + null, + null, + null + ); + } + + protected GenericCardTest GetSimpleSpotScenario() throws CardNotFoundException, DecisionResultInvalidException { + return new GenericCardTest( + new HashMap() + {{ + put("elrond", "21_1040"); + put("gandalf", "1_72"); + put("arwen", "1_30"); + }}, + null, + null, + null + ); + } + + protected GenericCardTest GetHome3AllyScenario() throws CardNotFoundException, DecisionResultInvalidException { + return new GenericCardTest( + new HashMap() + {{ + put("elrond", "21_1040"); + put("ally1", "1_60"); + put("ally2", "1_27"); + }}, + null, + null, + null + ); + } + + @Test + public void FellowshipActionExertsTwiceToDrawACard() throws DecisionResultInvalidException, CardNotFoundException + { + //Pre-game setup + GenericCardTest scenario = GetSimpleDeckScenario(); + PhysicalCardImpl elrond = scenario.freepsCards.get("elrond"); + scenario.FreepsMoveCharToTable(elrond); + + scenario.StartGame(); + + scenario.FreepsMoveCardToDeck("randomcard"); + + Assert.assertEquals(Phase.FELLOWSHIP, scenario.GetCurrentPhase()); + Assert.assertTrue(scenario.FreepsActionAvailable("Use Elrond")); + + Assert.assertEquals(0, scenario.GetWoundsOn(elrond)); + Assert.assertEquals(0, scenario.GetFreepsHandCount()); + Assert.assertEquals(1, scenario.GetFreepsDeckCount()); + + scenario.FreepsUseAction("Use Elrond"); + + Assert.assertEquals(2, scenario.GetWoundsOn(elrond)); + Assert.assertEquals(0, scenario.GetFreepsDeckCount()); + Assert.assertEquals(1, scenario.GetFreepsHandCount()); + + } + + @Test + public void CardCanPlayIfGandalfInPlay() throws DecisionResultInvalidException, CardNotFoundException + { + //Pre-game setup + GenericCardTest scenario = GetSimpleSpotScenario(); + scenario.FreepsMoveCardToHand("elrond"); + scenario.FreepsMoveCardToHand("gandalf"); + + scenario.StartGame(); + + Assert.assertEquals(Phase.FELLOWSHIP, scenario.GetCurrentPhase()); + Assert.assertFalse(scenario.FreepsActionAvailable("Play Elrond")); + + scenario.FreepsPlayCharFromHand("gandalf"); + Assert.assertTrue(scenario.FreepsActionAvailable("Play Elrond")); + } + + @Test + public void CardCanPlayIfElfInPlay() throws DecisionResultInvalidException, CardNotFoundException + { + //Pre-game setup + GenericCardTest scenario = GetSimpleSpotScenario(); + scenario.FreepsMoveCardToHand("elrond"); + scenario.FreepsMoveCardToHand("arwen"); + + scenario.StartGame(); + + Assert.assertEquals(Phase.FELLOWSHIP, scenario.GetCurrentPhase()); + Assert.assertFalse(scenario.FreepsActionAvailable("Play Elrond")); + + scenario.FreepsPlayCharFromHand("arwen"); + Assert.assertTrue(scenario.FreepsActionAvailable("Play Elrond")); + } + + @Test + public void AllyHealsCappedAt2() throws DecisionResultInvalidException, CardNotFoundException + { + //Pre-game setup + GenericCardTest scenario = GetHome3AllyScenario(); + scenario.FreepsMoveCharToTable("elrond"); + scenario.FreepsMoveCharToTable("ally1"); + scenario.FreepsMoveCharToTable("ally2"); + + scenario.FreepsAddWoundsToChar("elrond", 1); + scenario.FreepsAddWoundsToChar("ally1", 1); + scenario.FreepsAddWoundsToChar("ally2", 1); + + scenario.StartGame(); + + Assert.assertEquals(Phase.BETWEEN_TURNS, scenario.GetCurrentPhase()); + + Assert.assertEquals(3, scenario.FreepsGetADParamAsList("cardId").size()); + Assert.assertEquals("0", scenario.FreepsGetADParam("min")); + Assert.assertEquals("2", scenario.FreepsGetADParam("max")); + } +}