mirror of
https://github.com/magefree/mage.git
synced 2026-01-10 04:42:07 -08:00
Refactor: Add proper support for modifying and querying base P/T (#9409)
This commit is contained in:
parent
d83eb41073
commit
07a142c9e8
415 changed files with 1844 additions and 2095 deletions
|
|
@ -0,0 +1,180 @@
|
|||
package org.mage.test.cards.continuous;
|
||||
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.h.HalimarTidecaller;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* Check that effects which increase the base PT interact correctly with effects which boost PT.
|
||||
* And check that the test functions created to read both base and boosted values work correctly.
|
||||
*
|
||||
* @author Alex-Vasile
|
||||
*/
|
||||
public class SetPowerToughnessTest extends CardTestPlayerBase {
|
||||
// {U}
|
||||
// Enchanted creature gets +1/+1 and has flying.
|
||||
private static final String arcaneFlight = "Arcane Flight";
|
||||
// {X}{G/U}{G/U}
|
||||
// Creatures you control have base power and toughness X/X until end of turn.
|
||||
private static final String biomassMutation = "Biomass Mutation";
|
||||
private static final String lion = "Silvercoat Lion";
|
||||
|
||||
/**
|
||||
* Test that for a boosted creature, both base and the boosted power and toughness are correctly measured
|
||||
*/
|
||||
@Test
|
||||
public void testBoostedVsBasePT() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, lion);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
addCard(Zone.HAND, playerA, arcaneFlight);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcaneFlight);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertBasePowerToughness(playerA, lion, 2, 2);
|
||||
assertPowerToughness(playerA, lion, 3, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that base power effects work properly with +1/+1 and -1/-1 counters
|
||||
*/
|
||||
@Test
|
||||
public void testBaseChangeAndCounter() {
|
||||
// {B}{B}
|
||||
// When Ancestral Vengeance enters the battlefield, put a +1/+1 counter on target creature you control.
|
||||
// Enchanted creature gets -1/-1.
|
||||
String ancestralVengeance = "Ancestral Vengeance";
|
||||
// 4/4
|
||||
String airElemental = "Air Elemental";
|
||||
|
||||
addCard(Zone.HAND, playerA, ancestralVengeance);
|
||||
addCard(Zone.HAND, playerA, biomassMutation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, lion); // 2/2
|
||||
addCard(Zone.BATTLEFIELD, playerA, airElemental);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 7);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ancestralVengeance);
|
||||
addTarget(playerA, airElemental); // decrease from 4/4 to a 3/3
|
||||
addTarget(playerA, lion); // Boost from 2/2 to a 3/3
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertBasePowerToughness(playerA, lion, 2, 2);
|
||||
assertPowerToughness(playerA, lion, 3, 3); // 2/2 + +1/+1
|
||||
assertBasePowerToughness(playerA, airElemental, 4, 4);
|
||||
assertPowerToughness(playerA, airElemental, 3, 3); // 3/3 + -1/-1
|
||||
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, biomassMutation);
|
||||
setChoice(playerA, "X=5"); // Everyone should have base P/T of 5/5
|
||||
|
||||
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertBasePowerToughness(playerA, lion, 5, 5);
|
||||
assertPowerToughness(playerA, lion, 6, 6);
|
||||
assertBasePowerToughness(playerA, airElemental, 5, 5);
|
||||
assertPowerToughness(playerA, airElemental, 4, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that base PT change effects lasts between turns if they're supposed to.
|
||||
*/
|
||||
@Test
|
||||
public void testBaseChangeLasts() {
|
||||
// {1}{U}
|
||||
// Enchanted artifact is a creature with base power and toughness 5/5 in addition to its other types.
|
||||
String ensoulArtifact = "Ensoul Artifact";
|
||||
String solRing = "Sol Ring";
|
||||
// Destroy target artifact, enchantment, or creature with flying.
|
||||
String brokenWing = "Broken Wings";
|
||||
|
||||
addCard(Zone.HAND, playerA, ensoulArtifact);
|
||||
addCard(Zone.HAND, playerA, arcaneFlight);
|
||||
addCard(Zone.HAND, playerA, brokenWing);
|
||||
addCard(Zone.BATTLEFIELD, playerA, solRing);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ensoulArtifact);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcaneFlight);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertPowerToughness(playerA, solRing, 6, 6);
|
||||
assertBasePowerToughness(playerA, solRing, 5, 5);
|
||||
assertAbility(playerA, solRing, FlyingAbility.getInstance(), true);
|
||||
|
||||
setStopAt(3, PhaseStep.PRECOMBAT_MAIN); // wait two turns and make sure it keeps working
|
||||
execute();
|
||||
assertPowerToughness(playerA, solRing, 6, 6);
|
||||
assertBasePowerToughness(playerA, solRing, 5, 5);
|
||||
assertAbility(playerA, solRing, FlyingAbility.getInstance(), true);
|
||||
|
||||
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, brokenWing, ensoulArtifact);
|
||||
setStopAt(5, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
// Remove Ensoul Artifact, and have Arcane Flight fall off, and check that the Sol Ring goes back to 0/0
|
||||
assertPowerToughness(playerA, solRing, 0, 0);
|
||||
assertBasePowerToughness(playerA, solRing, 0, 0);
|
||||
assertAbility(playerA, solRing, FlyingAbility.getInstance(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that base PT change effects are properly reset between turns.
|
||||
*/
|
||||
@Test
|
||||
public void testBaseChangePTResets() {
|
||||
addCard(Zone.HAND, playerA, biomassMutation);
|
||||
addCard(Zone.HAND, playerA, arcaneFlight);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, lion);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcaneFlight);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, biomassMutation);
|
||||
setChoice(playerA, "X=1");
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertBasePowerToughness(playerA, lion, 1, 1);
|
||||
assertPowerToughness(playerA, lion, 2, 2);
|
||||
|
||||
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertBasePowerToughness(playerA, lion, 2, 2);
|
||||
assertPowerToughness(playerA, lion, 3, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that BecomesCreatureAttachedEffect works properly
|
||||
*/
|
||||
@Test
|
||||
public void becomesTokenWorks() {
|
||||
// {2}{W}
|
||||
// Enchant creature
|
||||
// Enchanted creature loses all abilities and is a blue Fish with base power and toughness 0/1.
|
||||
String ichthyomorphosis = "Ichthyomorphosis";
|
||||
|
||||
addCard(Zone.HAND, playerA, ichthyomorphosis);
|
||||
addCard(Zone.BATTLEFIELD, playerA, lion);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ichthyomorphosis, lion);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertBasePowerToughness(playerA, lion, 0, 1);
|
||||
assertPowerToughness(playerA, lion, 0, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -28,14 +28,15 @@ public class IdentityThiefTest extends CardTestPlayerBase {
|
|||
// Return the exiled card to the battlefield under its owner's control at the beginning of the next end step.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Identity Thief"); // {2}{U}{U}
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Molten Sentry");
|
||||
setFlipCoinResult(playerA, true);
|
||||
|
||||
attack(2, playerB, "Identity Thief");
|
||||
setChoice(playerB, true);
|
||||
addTarget(playerB, "Molten Sentry");
|
||||
setChoice(playerB, true);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
|
|
@ -57,21 +58,29 @@ public class IdentityThiefTest extends CardTestPlayerBase {
|
|||
// Return the exiled card to the battlefield under its owner's control at the beginning of the next end step.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Identity Thief"); // {2}{U}{U}
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Primal Clay");
|
||||
setChoice(playerA, "a 3/3 artifact creature");
|
||||
|
||||
attack(2, playerB, "Identity Thief");
|
||||
setChoice(playerB, "Yes");
|
||||
addTarget(playerB, "Primal Clay");
|
||||
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertExileCount(playerA, 1);
|
||||
assertExileCount("Primal Clay", 1);
|
||||
assertExileCount(playerA, "Primal Clay", 1);
|
||||
|
||||
assertPermanentCount(playerB, "Identity Thief", 0);
|
||||
assertPermanentCount(playerB, "Primal Clay", 1);
|
||||
assertPowerToughness(playerB, "Primal Clay", 3, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reported bug: https://github.com/magefree/mage/issues/2131
|
||||
* If I copy a creature with a +1/+1 counter on it, it copies the counter as well as the other stats. This should not be the case.
|
||||
*/
|
||||
@Test
|
||||
public void testShouldNotCopyP1P1Counters() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Sylvan Advocate", 1); // {1}{G} 2/3 vigilance
|
||||
|
|
@ -99,6 +108,6 @@ public class IdentityThiefTest extends CardTestPlayerBase {
|
|||
assertPermanentCount(playerB, "Identity Thief", 0);
|
||||
assertPermanentCount(playerB, "Sylvan Advocate", 1);
|
||||
assertCounterCount(playerB, "Sylvan Advocate", CounterType.P1P1, 0);
|
||||
assertPowerToughness(playerB, "Sylvan Advocate", 2, 3); // finds it with 3 power 4 toughness
|
||||
assertPowerToughness(playerB, "Sylvan Advocate", 2, 3);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@ public class SoulSeparatorTest extends CardTestPlayerBase {
|
|||
assertPowerToughness(playerA, "Sylvan Advocate", 1, 1);
|
||||
}
|
||||
|
||||
// Reported bug: Exiled Tree of Perdition with Soul Separator
|
||||
// The token copy when activated reduced the opponent's life total to 13 (tree toughness) instead of 1 (1/1 token)
|
||||
// Reported bug: https://github.com/magefree/mage/issues/2174
|
||||
// Exiled Tree of Perdition with Soul Separator
|
||||
// The token copy when activated reduced the opponent's life total to 13 (tree toughness) instead of 1 (1/1 token)
|
||||
@Test
|
||||
public void testExileTreeOfPerdition() {
|
||||
// Soul Separator {3} Artifact
|
||||
|
|
|
|||
|
|
@ -18,9 +18,10 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
|
|||
public class TreeOfPerditionTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Reported bug: Tree of Perdition retains toughness change after being bounced and replayed
|
||||
* Exchanged toughness with opponent's life to become an 0/20, got bounced,
|
||||
* and when replayed it was still 0/20. It should be a new object and enter as an 0/13.
|
||||
* Reported bug: https://github.com/magefree/mage/issues/2101
|
||||
* Tree of Perdition retains toughness change after being bounced and replayed
|
||||
* Exchanged toughness with opponent's life to become an 0/20, got bounced,
|
||||
* and when replayed it was still 0/20. It should be a new object and enter as an 0/13.
|
||||
*/
|
||||
@Test
|
||||
public void testTreeOfPerditionBouncedAndReplayed() {
|
||||
|
|
@ -45,8 +46,9 @@ public class TreeOfPerditionTest extends CardTestPlayerBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Reported bug: Tree of Perdition is gaining both power and toughness equal to opponent's life total
|
||||
* instead of just toughness equal to it.
|
||||
* Reported bug:
|
||||
* Tree of Perdition is gaining both power and toughness equal to opponent's life total
|
||||
* instead of just toughness equal to it.
|
||||
*/
|
||||
@Test
|
||||
public void testTreeOfPerditionOnlyGainsToughnessEqualToLife() {
|
||||
|
|
|
|||
|
|
@ -117,24 +117,28 @@ public interface CardTestAPI {
|
|||
void assertLife(Player player, int life) throws AssertionError;
|
||||
|
||||
/**
|
||||
*
|
||||
* Assert creature's power and toughness by card name.
|
||||
* <p/>
|
||||
* Throws {@link AssertionError} in the following cases: 1. no such player
|
||||
* 2. no such creature under player's control 3. depending on comparison
|
||||
* scope: 3a. any: no creature under player's control with the specified p\t
|
||||
* params 3b. all: there is at least one creature with the cardName with the
|
||||
* different p\t params
|
||||
* Throws {@link AssertionError} in the following cases:
|
||||
* 1. no such player
|
||||
* 2. no such creature under player's control
|
||||
* 3. depending on comparison scope:
|
||||
* 3a. any: no creature under player's control with the specified p\t params
|
||||
* 3b. all: there is at least one creature with the cardName with the different p\t params
|
||||
*
|
||||
* @param player {@link Player} to get creatures for comparison.
|
||||
* @param cardName Card name to compare with.
|
||||
* @param power Expected power to compare with.
|
||||
* @param player {@link Player} to get creatures for comparison.
|
||||
* @param cardName Card name to compare with.
|
||||
* @param power Expected power to compare with.
|
||||
* @param toughness Expected toughness to compare with.
|
||||
* @param scope {@link Filter.ComparisonScope} Use ANY, if you want "at
|
||||
* least one creature with given name should have specified p\t" Use ALL, if
|
||||
* you want "all creature with gived name should have specified p\t"
|
||||
* @param scope {@link mage.filter.Filter.ComparisonScope} Use ANY, if
|
||||
* you want "at least one creature with given name should
|
||||
* have specified p\t" Use ALL, if you want "all creature
|
||||
* with given name should have specified p\t"
|
||||
* @param base If true, the comparison looks that base power and toughness of the creature.
|
||||
* If false, the comparison looks at the final values.
|
||||
*/
|
||||
void assertPowerToughness(Player player, String cardName, int power, int toughness, Filter.ComparisonScope scope)
|
||||
throws AssertionError;
|
||||
public void assertPowerToughness(Player player, String cardName, int powerNeeded, int toughnessNeeded, Filter.ComparisonScope scope, boolean checkBaseValues) throws AssertionError;
|
||||
|
||||
/**
|
||||
* Assert creature's abilities.
|
||||
|
|
|
|||
|
|
@ -1,372 +0,0 @@
|
|||
package org.mage.test.serverside.base.impl;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.repository.CardInfo;
|
||||
import mage.cards.repository.CardRepository;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.Filter;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.PermanentCard;
|
||||
import mage.players.Player;
|
||||
import org.junit.Assert;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestAPI;
|
||||
import org.mage.test.serverside.base.MageTestBase;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* API for test initialization and asserting the test results.
|
||||
*
|
||||
* @author ayratn
|
||||
*/
|
||||
public abstract class CardTestAPIImpl extends MageTestBase implements CardTestAPI {
|
||||
/**
|
||||
* Removes all cards from player's library from the game.
|
||||
* Usually this should be used once before initialization to form the library in certain order.
|
||||
*
|
||||
* @param player {@link Player} to remove all library cards from.
|
||||
*/
|
||||
public void removeAllCardsFromLibrary(Player player) {
|
||||
if (player.equals(playerA)) {
|
||||
commandsA.put(Zone.LIBRARY, "clear");
|
||||
} else if (player.equals(playerB)) {
|
||||
commandsB.put(Zone.LIBRARY, "clear");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a card to specified zone of specified player.
|
||||
*
|
||||
* @param gameZone {@link mage.constants.Zone} to add cards to.
|
||||
* @param player {@link Player} to add cards for. Use either playerA or playerB.
|
||||
* @param cardName Card name in string format.
|
||||
*/
|
||||
@Override
|
||||
public void addCard(Zone gameZone, TestPlayer player, String cardName) {
|
||||
addCard(gameZone, player, cardName, 1, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any amount of cards to specified zone of specified player.
|
||||
*
|
||||
* @param gameZone {@link mage.constants.Zone} to add cards to.
|
||||
* @param player {@link Player} to add cards for. Use either playerA or playerB.
|
||||
* @param cardName Card name in string format.
|
||||
* @param count Amount of cards to be added.
|
||||
*/
|
||||
@Override
|
||||
public void addCard(Zone gameZone, TestPlayer player, String cardName, int count) {
|
||||
addCard(gameZone, player, cardName, count, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any amount of cards to specified zone of specified player.
|
||||
*
|
||||
* @param gameZone {@link mage.constants.Zone} to add cards to.
|
||||
* @param player {@link Player} to add cards for. Use either playerA or playerB.
|
||||
* @param cardName Card name in string format.
|
||||
* @param count Amount of cards to be added.
|
||||
* @param tapped In case gameZone is Battlefield, determines whether permanent should be tapped.
|
||||
* In case gameZone is other than Battlefield, {@link IllegalArgumentException} is thrown
|
||||
*/
|
||||
@Override
|
||||
public void addCard(Zone gameZone, TestPlayer player, String cardName, int count, boolean tapped) {
|
||||
|
||||
|
||||
if (gameZone == Zone.BATTLEFIELD) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
CardInfo cardInfo = CardRepository.instance.findCard(cardName);
|
||||
Card card = cardInfo != null ? cardInfo.getCard() : null;
|
||||
if (card == null) {
|
||||
throw new IllegalArgumentException("[TEST] Couldn't find a card: " + cardName);
|
||||
}
|
||||
PermanentCard p = new PermanentCard(card, null, currentGame);
|
||||
p.setTapped(tapped);
|
||||
if (player.equals(playerA)) {
|
||||
battlefieldCardsA.add(p);
|
||||
} else if (player.equals(playerB)) {
|
||||
battlefieldCardsB.add(p);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (tapped) {
|
||||
throw new IllegalArgumentException("Parameter tapped=true can be used only for Zone.BATTLEFIELD.");
|
||||
}
|
||||
List<Card> cards = getCardList(gameZone, player);
|
||||
for (int i = 0; i < count; i++) {
|
||||
CardInfo cardInfo = CardRepository.instance.findCard(cardName);
|
||||
Card card = cardInfo != null ? cardInfo.getCard() : null;
|
||||
cards.add(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns card list containter for specified game zone and player.
|
||||
*
|
||||
* @param gameZone
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
private List<Card> getCardList(Zone gameZone, Player player) {
|
||||
if (player.equals(playerA)) {
|
||||
if (gameZone == Zone.HAND) {
|
||||
return handCardsA;
|
||||
} else if (gameZone == Zone.GRAVEYARD) {
|
||||
return graveyardCardsA;
|
||||
} else if (gameZone == Zone.LIBRARY) {
|
||||
return libraryCardsA;
|
||||
}
|
||||
} else if (player.equals(playerB)) {
|
||||
if (gameZone == Zone.HAND) {
|
||||
return handCardsB;
|
||||
} else if (gameZone == Zone.GRAVEYARD) {
|
||||
return graveyardCardsB;
|
||||
} else if (gameZone == Zone.LIBRARY) {
|
||||
return libraryCardsB;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set player's initial life count.
|
||||
*
|
||||
* @param player {@link Player} to set life count for.
|
||||
* @param life Life count to set.
|
||||
*/
|
||||
@Override
|
||||
public void setLife(TestPlayer player, int life) {
|
||||
if (player.equals(playerA)) {
|
||||
commandsA.put(Zone.OUTSIDE, "life:" + life);
|
||||
} else if (player.equals(playerB)) {
|
||||
commandsB.put(Zone.OUTSIDE, "life:" + life);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define turn number to stop the game on.
|
||||
*/
|
||||
@Override
|
||||
public void setStopOnTurn(int turn) {
|
||||
stopOnTurn = turn == -1 ? null : turn;
|
||||
stopAtStep = PhaseStep.UNTAP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define turn number and step to stop the game on.
|
||||
*/
|
||||
@Override
|
||||
public void setStopAt(int turn, PhaseStep step) {
|
||||
stopOnTurn = turn == -1 ? null : turn;
|
||||
stopAtStep = step;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert turn number after test execution.
|
||||
*
|
||||
* @param turn Expected turn number to compare with. 1-based.
|
||||
*/
|
||||
@Override
|
||||
public void assertTurn(int turn) throws AssertionError {
|
||||
Assert.assertEquals("Turn numbers are not equal", turn, currentGame.getTurnNum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert game result after test execution.
|
||||
*
|
||||
* @param result Expected {@link GameResult} to compare with.
|
||||
*/
|
||||
@Override
|
||||
public void assertResult(Player player, GameResult result) throws AssertionError {
|
||||
if (player.equals(playerA)) {
|
||||
GameResult actual = CardTestAPI.GameResult.DRAW;
|
||||
switch (currentGame.getWinner()) {
|
||||
case "Player PlayerA is the winner":
|
||||
actual = CardTestAPI.GameResult.WON;
|
||||
break;
|
||||
case "Player PlayerB is the winner":
|
||||
actual = CardTestAPI.GameResult.LOST;
|
||||
break;
|
||||
}
|
||||
Assert.assertEquals("Game results are not equal", result, actual);
|
||||
} else if (player.equals(playerB)) {
|
||||
GameResult actual = CardTestAPI.GameResult.DRAW;
|
||||
switch (currentGame.getWinner()) {
|
||||
case "Player PlayerB is the winner":
|
||||
actual = CardTestAPI.GameResult.WON;
|
||||
break;
|
||||
case "Player PlayerA is the winner":
|
||||
actual = CardTestAPI.GameResult.LOST;
|
||||
break;
|
||||
}
|
||||
Assert.assertEquals("Game results are not equal", result, actual);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert player's life count after test execution.
|
||||
*
|
||||
* @param player {@link Player} to get life for comparison.
|
||||
* @param life Expected player's life to compare with.
|
||||
*/
|
||||
@Override
|
||||
public void assertLife(Player player, int life) throws AssertionError {
|
||||
int actual = currentGame.getPlayer(player.getId()).getLife();
|
||||
Assert.assertEquals("Life amounts are not equal", life, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert creature's power and toughness by card name.
|
||||
* <p/>
|
||||
* Throws {@link AssertionError} in the following cases:
|
||||
* 1. no such player
|
||||
* 2. no such creature under player's control
|
||||
* 3. depending on comparison scope:
|
||||
* 3a. any: no creature under player's control with the specified p\t params
|
||||
* 3b. all: there is at least one creature with the cardName with the different p\t params
|
||||
*
|
||||
* @param player {@link Player} to get creatures for comparison.
|
||||
* @param cardName Card name to compare with.
|
||||
* @param power Expected power to compare with.
|
||||
* @param toughness Expected toughness to compare with.
|
||||
* @param scope {@link mage.filter.Filter.ComparisonScope} Use ANY, if you want "at least one creature with given name should have specified p\t"
|
||||
* Use ALL, if you want "all creature with gived name should have specified p\t"
|
||||
*/
|
||||
@Override
|
||||
public void assertPowerToughness(Player player, String cardName, int power, int toughness, Filter.ComparisonScope scope)
|
||||
throws AssertionError {
|
||||
int count = 0;
|
||||
int fit = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents(player.getId())) {
|
||||
if (permanent.getName().equals(cardName)) {
|
||||
count++;
|
||||
if (scope == Filter.ComparisonScope.All) {
|
||||
Assert.assertEquals("Power is not the same (" + power + " vs. " + permanent.getPower().getValue() + ')',
|
||||
power, permanent.getPower().getValue());
|
||||
Assert.assertEquals("Toughness is not the same (" + toughness + " vs. " + permanent.getToughness().getValue() + ')',
|
||||
toughness, permanent.getToughness().getValue());
|
||||
} else if (scope == Filter.ComparisonScope.Any) {
|
||||
if (power == permanent.getPower().getValue() && toughness == permanent.getToughness().getValue()) {
|
||||
fit++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertTrue("There is no such permanent under player's control, player=" + player.getName() +
|
||||
", cardName=" + cardName, count > 0);
|
||||
|
||||
if (scope == Filter.ComparisonScope.Any) {
|
||||
Assert.assertTrue("There is no such creature under player's control with specified power&toughness, player=" + player.getName() +
|
||||
", cardName=" + cardName, fit > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void assertAbilities(Player player, String cardName, List<Ability> abilities)
|
||||
throws AssertionError {
|
||||
int count = 0;
|
||||
Permanent found = null;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents(player.getId())) {
|
||||
if (permanent.getName().equals(cardName)) {
|
||||
found = permanent;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertNotNull("There is no such permanent under player's control, player=" + player.getName() +
|
||||
", cardName=" + cardName, found);
|
||||
|
||||
Assert.assertTrue("There is more than one such permanent under player's control, player=" + player.getName() +
|
||||
", cardName=" + cardName, count == 1);
|
||||
|
||||
for (Ability ability : abilities) {
|
||||
Assert.assertTrue("No such ability=" + ability.toString() + ", player=" + player.getName() +
|
||||
", cardName=" + cardName, found.getAbilities().contains(ability));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert permanent count under player's control.
|
||||
*
|
||||
* @param player {@link Player} which permanents should be counted.
|
||||
* @param count Expected count.
|
||||
*/
|
||||
@Override
|
||||
public void assertPermanentCount(Player player, int count) throws AssertionError {
|
||||
int actualCount = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) {
|
||||
if (permanent.getControllerId().equals(player.getId())) {
|
||||
actualCount++;
|
||||
}
|
||||
}
|
||||
Assert.assertEquals("(Battlefield) Card counts are not equal ", count, actualCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert permanent count under player's control.
|
||||
*
|
||||
* @param player {@link Player} which permanents should be counted.
|
||||
* @param cardName Name of the cards that should be counted.
|
||||
* @param count Expected count.
|
||||
*/
|
||||
@Override
|
||||
public void assertPermanentCount(Player player, String cardName, int count) throws AssertionError {
|
||||
int actualCount = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) {
|
||||
if (permanent.getControllerId().equals(player.getId())) {
|
||||
if (permanent.getName().equals(cardName)) {
|
||||
actualCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.assertEquals("(Battlefield) Card counts are not equal (" + cardName + ')', count, actualCount);
|
||||
}
|
||||
|
||||
public Permanent getPermanent(String cardName, UUID controller) {
|
||||
Permanent permanent0 = null;
|
||||
int count = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) {
|
||||
if (permanent.getControllerId().equals(controller)) {
|
||||
if (permanent.getName().equals(cardName)) {
|
||||
permanent0 = permanent;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.assertNotNull("Couldn't find a card with specified name: " + cardName, permanent0);
|
||||
Assert.assertEquals("More than one permanent was found: " + cardName + '(' + count + ')', 1, count);
|
||||
return permanent0;
|
||||
}
|
||||
|
||||
public void playLand(Player player, String cardName) {
|
||||
player.addAction("play:" + cardName);
|
||||
}
|
||||
|
||||
public void castSpell(Player player, String cardName) {
|
||||
player.addAction("cast:" + cardName);
|
||||
}
|
||||
|
||||
public void addFixedTarget(Player player, String cardName, Player target) {
|
||||
player.addAction("cast:" + cardName + ";name=" + target.getName());
|
||||
}
|
||||
|
||||
public void addFixedTarget(Player player, String cardName, String targetName) {
|
||||
player.addAction("cast:" + cardName + ";name=" + targetName);
|
||||
}
|
||||
|
||||
public void useAbility(Player player, String cardName) {
|
||||
}
|
||||
|
||||
public void attack(Player player, String cardName) {
|
||||
player.addAction("attack:" + cardName);
|
||||
}
|
||||
}
|
||||
|
|
@ -776,27 +776,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
Assert.assertEquals("Life amounts are not equal for player " + player.getName(), life, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert creature's power and toughness by card name.
|
||||
* <p/>
|
||||
* Throws {@link AssertionError} in the following cases: 1. no such player
|
||||
* 2. no such creature under player's control 3. depending on comparison
|
||||
* scope: 3a. any: no creature under player's control with the specified p\t
|
||||
* params 3b. all: there is at least one creature with the cardName with the
|
||||
* different p\t params
|
||||
*
|
||||
* @param player {@link Player} to get creatures for comparison.
|
||||
* @param cardName Card name to compare with.
|
||||
* @param power Expected power to compare with.
|
||||
* @param toughness Expected toughness to compare with.
|
||||
* @param scope {@link mage.filter.Filter.ComparisonScope} Use ANY, if
|
||||
* you want "at least one creature with given name should
|
||||
* have specified p\t" Use ALL, if you want "all creature
|
||||
* with given name should have specified p\t"
|
||||
*/
|
||||
@Override
|
||||
public void assertPowerToughness(Player player, String cardName, int power, int toughness, Filter.ComparisonScope scope)
|
||||
throws AssertionError {
|
||||
public void assertPowerToughness(Player player, String cardName, int powerNeeded, int toughnessNeeded, Filter.ComparisonScope scope, boolean checkBaseValues) throws AssertionError {
|
||||
//Assert.assertNotEquals("", cardName);
|
||||
int count = 0;
|
||||
int fit = 0;
|
||||
|
|
@ -804,22 +785,26 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
int foundToughness = 0;
|
||||
int found = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) {
|
||||
if (isObjectHaveTargetNameOrAlias(player, permanent, cardName) && permanent.getControllerId().equals(player.getId())) {
|
||||
count++;
|
||||
if (scope == Filter.ComparisonScope.All) {
|
||||
Assert.assertEquals("Power is not the same (" + power + " vs. " + permanent.getPower().getValue() + ')',
|
||||
power, permanent.getPower().getValue());
|
||||
Assert.assertEquals("Toughness is not the same (" + toughness + " vs. " + permanent.getToughness().getValue() + ')',
|
||||
toughness, permanent.getToughness().getValue());
|
||||
} else if (scope == Filter.ComparisonScope.Any) {
|
||||
if (power == permanent.getPower().getValue() && toughness == permanent.getToughness().getValue()) {
|
||||
fit++;
|
||||
break;
|
||||
}
|
||||
found++;
|
||||
foundPower = permanent.getPower().getValue();
|
||||
foundToughness = permanent.getToughness().getValue();
|
||||
if (!isObjectHaveTargetNameOrAlias(player, permanent, cardName) || !permanent.getControllerId().equals(player.getId())) {
|
||||
continue;
|
||||
}
|
||||
int powerFound = checkBaseValues ? permanent.getPower().getModifiedBaseValue() : permanent.getPower().getValue();
|
||||
int toughnessFound = checkBaseValues ? permanent.getToughness().getModifiedBaseValue() : permanent.getToughness().getValue();
|
||||
|
||||
count++;
|
||||
if (scope == Filter.ComparisonScope.All) {
|
||||
Assert.assertEquals((checkBaseValues ? "Base power" : "Power") + " is not the same (" + powerNeeded + " vs. " + powerFound + ')',
|
||||
powerNeeded, powerFound);
|
||||
Assert.assertEquals((checkBaseValues ? "Base toughness" : "Toughness") + " is not the same (" + toughnessNeeded + " vs. " + toughnessFound + ')',
|
||||
toughnessNeeded, toughnessFound);
|
||||
} else if (scope == Filter.ComparisonScope.Any) {
|
||||
if (powerNeeded == powerFound && toughnessNeeded == toughnessFound) {
|
||||
fit++;
|
||||
break;
|
||||
}
|
||||
found++;
|
||||
foundPower = powerFound;
|
||||
foundToughness = toughnessFound;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -827,24 +812,25 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
+ ", cardName=" + cardName, count > 0);
|
||||
|
||||
if (scope == Filter.ComparisonScope.Any) {
|
||||
assertTrue("There is no such creature under player's control with specified p/t of " + power + '/' + toughness + ", player=" + player.getName()
|
||||
assertTrue("There is no such creature under player's control with specified" + (checkBaseValues ? " base " : ' ') + "p/t of " + powerNeeded + '/' + toughnessNeeded + ", player=" + player.getName()
|
||||
+ ", cardName=" + cardName + " (found similar: " + found + ", one of them: power=" + foundPower + " toughness=" + foundToughness + ')', fit > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See
|
||||
* {@link #assertPowerToughness(mage.players.Player, String, int, int, mage.filter.Filter.ComparisonScope)}
|
||||
*
|
||||
* @param player
|
||||
* @param cardName
|
||||
* @param power
|
||||
* @param toughness
|
||||
*/
|
||||
public void assertPowerToughness(Player player, String cardName, int power, int toughness) {
|
||||
assertPowerToughness(player, cardName, power, toughness, Filter.ComparisonScope.Any);
|
||||
public void assertPowerToughness(Player player, String cardName, int power, int toughness, Filter.ComparisonScope scope) {
|
||||
assertPowerToughness(player, cardName, power, toughness, scope, false);
|
||||
}
|
||||
|
||||
public void assertPowerToughness(Player player, String cardName, int powerNeeded, int toughnessNeeded) {
|
||||
assertPowerToughness(player, cardName, powerNeeded, toughnessNeeded, Filter.ComparisonScope.Any, false);
|
||||
}
|
||||
|
||||
public void assertBasePowerToughness(Player player, String cardName, int powerNeeded, int toughnessNeeded) {
|
||||
assertPowerToughness(player, cardName, powerNeeded, toughnessNeeded, Filter.ComparisonScope.Any, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue