Test framework improves for stack and skips:

* Added realtime command to show stack objects: showStack;
* Added realtime command to check stack size or stack objects amount: checkStackSize, checkStackObject;
* Allows to skip stack resolves by steps: waitStackResolved with special oneTime param;
This commit is contained in:
Oleg Agafonov 2020-06-30 20:41:48 +04:00
parent c4082548c8
commit 429df8cf77
3 changed files with 262 additions and 88 deletions

View file

@ -660,13 +660,17 @@ public class TestPlayer implements Player {
}
}
} else if (action.getAction().startsWith("waitStackResolved")) {
boolean oneTime = action.getAction().equals("waitStackResolved:1");
if (game.getStack().isEmpty()) {
// all done, can use next command
actions.remove(action);
continue;
} else {
// need to wait (don't remove command)
// need to wait (don't remove command, except one time)
tryToPlayPriority(game);
if (oneTime) {
actions.remove(action);
}
return true;
}
} else if (action.getAction().startsWith("playerAction:")) {
@ -844,6 +848,20 @@ public class TestPlayer implements Player {
actions.remove(action);
wasProccessed = true;
}
// check stack size: need size
if (params[0].equals(CHECK_COMMAND_STACK_SIZE) && params.length == 2) {
assertStackSize(action, game, Integer.parseInt(params[1]));
actions.remove(action);
wasProccessed = true;
}
// check stack object: stack ability name, amount
if (params[0].equals(CHECK_COMMAND_STACK_OBJECT) && params.length == 3) {
assertStackObject(action, game, params[1], Integer.parseInt(params[2]));
actions.remove(action);
wasProccessed = true;
}
}
if (wasProccessed) {
return true;
@ -941,6 +959,15 @@ public class TestPlayer implements Player {
actions.remove(action);
wasProccessed = true;
}
// show stack
if (params[0].equals(SHOW_COMMAND_STACK) && params.length == 1) {
printStart(action.getActionName());
printStack(game);
printEnd();
actions.remove(action);
wasProccessed = true;
}
}
if (wasProccessed) {
@ -1121,6 +1148,13 @@ public class TestPlayer implements Player {
}
}
private void printStack(Game game) {
System.out.println("Stack objects: " + game.getStack().size());
game.getStack().forEach(stack -> {
System.out.println(stack.getStackAbility().toString());
});
}
private void assertPT(PlayerAction action, Game game, Player player, String permanentName, int Power, int Toughness) {
Permanent perm = findPermanentWithAssert(action, game, player, permanentName);
@ -1361,6 +1395,21 @@ public class TestPlayer implements Player {
}
}
private void assertStackSize(PlayerAction action, Game game, int needStackSize) {
Assert.assertEquals(action.getActionName() + " - stack size must be " + needStackSize + " but is " + game.getStack().size(), needStackSize, game.getStack().size());
}
private void assertStackObject(PlayerAction action, Game game, String stackAbilityName, int needAmount) {
long foundedAmount = game.getStack()
.stream()
.filter(stack -> stack.getStackAbility().toString().startsWith(stackAbilityName))
.count();
if (needAmount != foundedAmount) {
printStack(game);
Assert.fail(action.getActionName() + " - stack must have " + needAmount + " objects with ability [" + stackAbilityName + "] but have " + foundedAmount);
}
}
private void assertManaPoolInner(PlayerAction action, Player player, ManaType manaType, Integer amount) {
Integer normal = player.getManaPool().getMana().get(manaType);
Integer conditional = player.getManaPool().getConditionalMana().stream().mapToInt(a -> a.get(manaType)).sum(); // calcs FULL conditional mana, not real conditions

View file

@ -1,13 +1,5 @@
package org.mage.test.serverside.base.impl;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import mage.MageObject;
import mage.Mana;
import mage.ObjectColor;
@ -43,6 +35,15 @@ import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestAPI;
import org.mage.test.serverside.base.MageTestPlayerBase;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* API for test initialization and asserting the test results.
*
@ -103,6 +104,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
public static final String CHECK_COMMAND_MANA_POOL = "MANA_POOL";
public static final String CHECK_COMMAND_ALIAS_ZONE = "ALIAS_ZONE";
public static final String CHECK_COMMAND_PLAYER_IN_GAME = "PLAYER_IN_GAME";
public static final String CHECK_COMMAND_STACK_SIZE = "STACK_COUNT";
public static final String CHECK_COMMAND_STACK_OBJECT = "STACK_OBJECT";
// TODO: add target player param to commands
public static final String SHOW_COMMAND_LIBRARY = "LIBRARY";
@ -114,6 +117,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
public static final String SHOW_COMMAND_AVAILABLE_ABILITIES = "AVAILABLE_ABILITIES";
public static final String SHOW_COMMAND_AVAILABLE_MANA = "AVAILABLE_MANA";
public static final String SHOW_COMMAND_ALIASES = "ALIASES";
public static final String SHOW_COMMAND_STACK = "STACK";
// TODO: add target player param to commands
public static final String ALIAS_COMMAND_ADD = "ADD";
@ -274,7 +278,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
}
}
Assert.assertFalse("Wrong stop command on " + this.stopOnTurn + " / " + this.stopAtStep + " (" + this.stopAtStep.getIndex() + ")"
+ " (found actions after stop on " + maxTurn + " / " + maxPhase + ")",
+ " (found actions after stop on " + maxTurn + " / " + maxPhase + ")",
(maxTurn > this.stopOnTurn) || (maxTurn == this.stopOnTurn && maxPhase > this.stopAtStep.getIndex()));
for (Player player : currentGame.getPlayers().values()) {
@ -425,6 +429,14 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
check(checkName, turnNum, step, player, CHECK_COMMAND_ALIAS_ZONE, alias, zone.toString(), mustHave.toString());
}
public void checkStackSize(String checkName, int turnNum, PhaseStep step, TestPlayer player, Integer needStackSize) {
check(checkName, turnNum, step, player, CHECK_COMMAND_STACK_SIZE, needStackSize.toString());
}
public void checkStackObject(String checkName, int turnNum, PhaseStep step, TestPlayer player, String spellAbilityOnStack, Integer needAmount) {
check(checkName, turnNum, step, player, CHECK_COMMAND_STACK_OBJECT, spellAbilityOnStack, needAmount.toString());
}
// show commands
private void show(String showName, int turnNum, PhaseStep step, TestPlayer player, String command, String... params) {
String res = "show:" + command;
@ -470,6 +482,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
show(showName, turnNum, step, player, SHOW_COMMAND_ALIASES);
}
public void showStack(String showName, int turnNum, PhaseStep step, TestPlayer player) {
show(showName, turnNum, step, player, SHOW_COMMAND_STACK);
}
/**
* Removes all cards from player's library from the game. Usually this
* should be used once before initialization to form the library in certain
@ -507,8 +523,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* 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 player {@link Player} to add cards for. Use either playerA or
* playerB.
* @param cardName Card name in string format.
*/
@Override
@ -520,10 +536,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* 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 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 count Amount of cards to be added.
*/
@Override
public void addCard(Zone gameZone, TestPlayer player, String cardName, int count) {
@ -534,13 +550,13 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* 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 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
* @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) {
@ -621,7 +637,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Set player's initial life count.
*
* @param player {@link Player} to set life count for.
* @param life Life count to set.
* @param life Life count to set.
*/
@Override
public void setLife(TestPlayer player, int life) {
@ -698,7 +714,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* 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.
* @param life Expected player's life to compare with.
*/
@Override
public void assertLife(Player player, int life) throws AssertionError {
@ -715,14 +731,14 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* 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 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"
* @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)
@ -812,8 +828,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param cardName
* @param ability
* @param mustHave true if creature should contain ability, false if it
* should NOT contain it instead
* @param count number of permanents with that ability
* should NOT contain it instead
* @param count number of permanents with that ability
* @throws AssertionError
*/
public void assertAbility(Player player, String cardName, Ability ability, boolean mustHave, int count) throws AssertionError {
@ -846,7 +862,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert permanent count under player's control.
*
* @param player {@link Player} which permanents should be counted.
* @param count Expected count.
* @param count Expected count.
*/
@Override
public void assertPermanentCount(Player player, int count) throws AssertionError {
@ -862,9 +878,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert permanent count under player's control.
*
* @param player {@link Player} which permanents should be counted.
* @param player {@link Player} which permanents should be counted.
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
@Override
public void assertPermanentCount(Player player, String cardName, int count) throws AssertionError {
@ -914,8 +930,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert counter count on a permanent
*
* @param cardName Name of the cards that should be counted.
* @param type Type of the counter that should be counted.
* @param count Expected count.
* @param type Type of the counter that should be counted.
* @param count Expected count.
*/
public void assertCounterCount(String cardName, CounterType type, int count) throws AssertionError {
this.assertCounterCount(null, cardName, type, count);
@ -938,8 +954,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert counter count on a card in exile
*
* @param cardName Name of the cards that should be counted.
* @param type Type of the counter that should be counted.
* @param count Expected count.
* @param type Type of the counter that should be counted.
* @param count Expected count.
*/
public void assertCounterOnExiledCardCount(String cardName, CounterType type, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -962,8 +978,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert counter count on a player
*
* @param player The player whos counters should be counted.
* @param type Type of the counter that should be counted.
* @param count Expected count.
* @param type Type of the counter that should be counted.
* @param count Expected count.
*/
public void assertCounterCount(Player player, CounterType type, int count) throws AssertionError {
Assert.assertEquals("(Battlefield) Counter counts are not equal (" + player.getName() + ':' + type + ')', count, player.getCounters().getCount(type));
@ -973,7 +989,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is a specified type or not
*
* @param cardName Name of the permanent that should be checked.
* @param type A type to test for
* @param type A type to test for
* @param mustHave true if creature should have type, false if it should not
*/
public void assertType(String cardName, CardType type, boolean mustHave) throws AssertionError {
@ -998,8 +1014,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is a specified type
*
* @param cardName Name of the permanent that should be checked.
* @param type A type to test for
* @param subType a subtype to test for
* @param type A type to test for
* @param subType a subtype to test for
*/
public void assertType(String cardName, CardType type, SubType subType) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1014,7 +1030,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is not a specified type
*
* @param cardName Name of the permanent that should be checked.
* @param type A type to test for
* @param type A type to test for
*/
public void assertNotType(String cardName, CardType type) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1026,7 +1042,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is not a specified subtype
*
* @param cardName Name of the permanent that should be checked.
* @param subType a subtype to test for
* @param subType a subtype to test for
*/
public void assertNotSubtype(String cardName, SubType subType) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1039,10 +1055,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert permanent color
*
* @param player player to check
* @param cardName card name on battlefield from player
* @param player player to check
* @param cardName card name on battlefield from player
* @param searchColors colors list with searchable values
* @param mustHave must or not must have that colors
* @param mustHave must or not must have that colors
*/
public void assertColor(Player player, String cardName, ObjectColor searchColors, boolean mustHave) {
//Assert.assertNotEquals("", cardName);
@ -1077,7 +1093,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is tapped or not
*
* @param cardName Name of the permanent that should be checked.
* @param tapped Whether the permanent is tapped or not
* @param tapped Whether the permanent is tapped or not
*/
public void assertTapped(String cardName, boolean tapped) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1104,8 +1120,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether X permanents of the same name are tapped or not.
*
* @param cardName Name of the permanent that should be checked.
* @param tapped Whether the permanent is tapped or not
* @param count The amount of this permanents that should be tapped
* @param tapped Whether the permanent is tapped or not
* @param count The amount of this permanents that should be tapped
*/
public void assertTappedCount(String cardName, boolean tapped, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1127,7 +1143,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert whether a permanent is attacking or not
*
* @param cardName Name of the permanent that should be checked.
* @param cardName Name of the permanent that should be checked.
* @param attacking Whether the permanent is attacking or not
*/
public void assertAttacking(String cardName, boolean attacking) throws AssertionError {
@ -1149,7 +1165,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert card count in player's hand.
*
* @param player {@link Player} who's hand should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertHandCount(Player player, int count) throws AssertionError {
int actual = currentGame.getPlayer(player.getId()).getHand().size();
@ -1159,9 +1175,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert card count in player's hand.
*
* @param player {@link Player} who's hand should be counted.
* @param player {@link Player} who's hand should be counted.
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertHandCount(Player player, String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1209,7 +1225,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert card count in player's graveyard.
*
* @param player {@link Player} who's graveyard should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertGraveyardCount(Player player, int count) throws AssertionError {
int actual = currentGame.getPlayer(player.getId()).getGraveyard().size();
@ -1220,7 +1236,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert card count in exile.
*
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertExileCount(String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1258,9 +1274,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert card count in player's exile.
*
* @param owner {@link Player} who's exile should be counted.
* @param owner {@link Player} who's exile should be counted.
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertExileCount(Player owner, String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1279,9 +1295,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert card count in player's graveyard.
*
* @param player {@link Player} who's graveyard should be counted.
* @param player {@link Player} who's graveyard should be counted.
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertGraveyardCount(Player player, String cardName, int count) throws AssertionError {
assertAliaseSupportInActivateCommand(cardName, true);
@ -1300,7 +1316,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert library card count.
*
* @param player {@link Player} who's library should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertLibraryCount(Player player, int count) throws AssertionError {
List<Card> libraryList = player.getLibrary().getCards(currentGame);
@ -1311,9 +1327,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* Assert specific card count in player's library.
*
* @param player {@link Player} who's library should be counted.
* @param player {@link Player} who's library should be counted.
* @param cardName Name of the cards that should be counted.
* @param count Expected count.
* @param count Expected count.
*/
public void assertLibraryCount(Player player, String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName);
@ -1467,7 +1483,12 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
}
public void waitStackResolved(int turnNum, PhaseStep step, TestPlayer player) {
player.addAction(turnNum, step, "waitStackResolved");
}
public void waitStackResolved(int turnNum, PhaseStep step, TestPlayer player, boolean oneTime) {
String command = "waitStackResolved" + (oneTime ? ":1" : "");
player.addAction(turnNum, step, command);
}
/**
@ -1500,8 +1521,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param player
* @param cardName
* @param targetName for modes you can add "mode=3" before target name,
* multiple targets can be seperated by ^, not target marks as
* TestPlayer.NO_TARGET
* multiple targets can be seperated by ^, not target marks as
* TestPlayer.NO_TARGET
*/
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName) {
//Assert.assertNotEquals("", cardName);
@ -1524,8 +1545,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param step
* @param player
* @param cardName
* @param targetName for modal spells add the mode to the name e.g.
* "mode=2SilvercoatLion^mode3=PillarfieldOx"
* @param targetName for modal spells add the mode to the name e.g.
* "mode=2SilvercoatLion^mode3=PillarfieldOx"
* @param spellOnStack
*/
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName, String spellOnStack) {
@ -1612,7 +1633,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param step
* @param player
* @param ability
* @param targetName use NO_TARGET if there is no target to set
* @param targetName use NO_TARGET if there is no target to set
* @param spellOnStack
*/
public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName, String spellOnStack) {
@ -1625,8 +1646,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param step
* @param player
* @param ability
* @param targetName if not target has to be defined use the constant
* NO_TARGET
* @param targetName if not target has to be defined use the constant
* NO_TARGET
* @param spellOnStack
* @param clause
*/
@ -1721,10 +1742,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
*
* @param player
* @param choice starting with "1" for mode 1, "2" for mode 2 and so on (to
* set multiple modes call the command multiple times). If a spell mode can
* be used only once like Demonic Pact, the value has to be set to the
* number of the remaining modes (e.g. if only 2 are left the number need to
* be 1 or 2).
* set multiple modes call the command multiple times). If a spell mode can
* be used only once like Demonic Pact, the value has to be set to the
* number of the remaining modes (e.g. if only 2 are left the number need to
* be 1 or 2).
*/
public void setModeChoice(TestPlayer player, String choice) {
player.addModeChoice(choice);
@ -1735,12 +1756,12 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
*
* @param player
* @param target you can add multiple targets by separating them by the "^"
* character e.g. "creatureName1^creatureName2" you can qualify the target
* additional by setcode e.g. "creatureName-M15" you can add [no copy] to
* the end of the target name to prohibit targets that are copied you can
* add [only copy] to the end of the target name to allow only targets that
* are copies. For modal spells use a prefix with the mode number:
* mode=1Lightning Bolt^mode=2Silvercoat Lion
* character e.g. "creatureName1^creatureName2" you can qualify the target
* additional by setcode e.g. "creatureName-M15" you can add [no copy] to
* the end of the target name to prohibit targets that are copied you can
* add [only copy] to the end of the target name to allow only targets that
* are copies. For modal spells use a prefix with the mode number:
* mode=1Lightning Bolt^mode=2Silvercoat Lion
*/
// TODO: mode options doesn't work here (see BrutalExpulsionTest)
public void addTarget(TestPlayer player, String target) {
@ -1772,7 +1793,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/**
* @param player
* @param target use TestPlayer.TARGET_SKIP to 0 targets selects or to stop
* "up two xxx" selection
* "up two xxx" selection
* @param amount
*/
public void addTargetAmount(TestPlayer player, String target, int amount) {
@ -1821,17 +1842,21 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
}
public void waitStackResolved(int turnNum, PhaseStep step) {
waitStackResolved(turnNum, step, false);
}
public void waitStackResolved(int turnNum, PhaseStep step, boolean oneTime) {
if (playerA != null) {
waitStackResolved(turnNum, step, playerA);
waitStackResolved(turnNum, step, playerA, oneTime);
}
if (playerB != null) {
waitStackResolved(turnNum, step, playerB);
waitStackResolved(turnNum, step, playerB, oneTime);
}
if (playerC != null) {
waitStackResolved(turnNum, step, playerC);
waitStackResolved(turnNum, step, playerC, oneTime);
}
if (playerD != null) {
waitStackResolved(turnNum, step, playerD);
waitStackResolved(turnNum, step, playerD, oneTime);
}
}

View file

@ -0,0 +1,100 @@
package org.mage.test.testapi;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author JayDi85
*/
public class WaitStackResolvedTest extends CardTestPlayerBase {
@Test
public void test_Spells() {
addCard(Zone.HAND, playerA, "Firebolt", 1); // sorcery
addCard(Zone.HAND, playerA, "Lightning Bolt", 2); // instant
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
checkStackSize("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 0);
// prepare - cast 3 spells
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Firebolt", playerB);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
checkStackSize("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 3);
checkStackObject("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Firebolt", 1);
checkStackObject("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", 2);
// skip 1 (bolt)
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true);
checkStackSize("after 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 2);
checkStackObject("after 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Firebolt", 1);
checkStackObject("after 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", 1);
// skip 2 (bolt)
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true);
checkStackSize("after 2", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 1);
checkStackObject("after 2", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Firebolt", 1);
checkStackObject("after 2", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", 0);
// skip 3 (firebolt)
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true);
checkStackSize("after 3", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 0);
checkStackObject("after 3", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Firebolt", 0);
checkStackObject("after 3", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", 0);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
}
@Test
public void test_Abilities() {
// {1}{R}, Sacrifice Pyromania: Pyromania deals 1 damage to any target.
addCard(Zone.BATTLEFIELD, playerA, "Pyromania", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
//
// {2}: Goblin Cannon deals 1 damage to any target. Sacrifice Goblin Cannon.
addCard(Zone.BATTLEFIELD, playerA, "Goblin Cannon", 2);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2 * 2);
String goblinAbility = "{2}:";
String pyroAbility = "{1}{R}, Sacrifice";
checkStackSize("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 0);
// prepare - activate 3 abilities
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, goblinAbility, playerB);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, pyroAbility, playerB);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, goblinAbility, playerB);
checkStackSize("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 3);
checkStackObject("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, pyroAbility, 1);
checkStackObject("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, goblinAbility, 2);
showStack("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
// skip 1 (goblin)
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true);
checkStackSize("after 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 2);
checkStackObject("after 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, pyroAbility, 1);
checkStackObject("after 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, goblinAbility, 1);
// skip 2 (pyro)
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true);
checkStackSize("after 2", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 1);
checkStackObject("after 2", 1, PhaseStep.PRECOMBAT_MAIN, playerA, pyroAbility, 0);
checkStackObject("after 2", 1, PhaseStep.PRECOMBAT_MAIN, playerA, goblinAbility, 1);
// skip 3 (goblin)
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true);
checkStackSize("after 3", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 0);
checkStackObject("after 3", 1, PhaseStep.PRECOMBAT_MAIN, playerA, pyroAbility, 0);
checkStackObject("after 3", 1, PhaseStep.PRECOMBAT_MAIN, playerA, goblinAbility, 0);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
}
}