mirror of
https://github.com/correl/mage.git
synced 2024-12-26 03:00:11 +00:00
Test framework improves:
* added command to check graveyard count command; * added wrong cast/activate command auto-checks in strict mode;
This commit is contained in:
parent
3333cf3287
commit
e7684e4bba
5 changed files with 137 additions and 33 deletions
|
@ -18,14 +18,23 @@ public class IrencragFeatTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Irencrag Feat", 1);
|
||||
addCard(Zone.HAND, playerA, "Dwarven Trader", 2);
|
||||
|
||||
// 1
|
||||
checkPlayableAbility("can cast before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Dwarven Trader", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Irencrag Feat");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// 2
|
||||
checkPlayableAbility("can cast after feat 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Dwarven Trader", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dwarven Trader");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dwarven Trader");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// 3
|
||||
checkPlayableAbility("can't cast after feat 2", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Dwarven Trader", false);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
//assertAllCommandsUsed(); // second trader must be restricted to cast
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertHandCount(playerA, "Dwarven Trader", 1);
|
||||
assertPermanentCount(playerA, "Dwarven Trader", 1);
|
||||
|
@ -38,16 +47,32 @@ public class IrencragFeatTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Irencrag Feat", 1);
|
||||
addCard(Zone.HAND, playerA, "Dwarven Trader", 4);
|
||||
|
||||
// 1
|
||||
checkPlayableAbility("can cast before feat 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Dwarven Trader", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dwarven Trader");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// 2
|
||||
checkPlayableAbility("can cast before feat 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Dwarven Trader", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dwarven Trader");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// 3
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Irencrag Feat");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// 4
|
||||
checkPlayableAbility("can cast after feat 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Dwarven Trader", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dwarven Trader");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dwarven Trader");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// 5
|
||||
checkPlayableAbility("can't cast after feat 2", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Dwarven Trader", false);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
//assertAllCommandsUsed(); // second trader must be restricted to cast
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertHandCount(playerA, "Dwarven Trader", 1);
|
||||
assertPermanentCount(playerA, "Dwarven Trader", 3);
|
||||
|
@ -59,6 +84,7 @@ public class IrencragFeatTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Irencrag Feat", 1);
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt", 4);
|
||||
|
||||
// no restrictions for stack
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Irencrag Feat");
|
||||
|
@ -80,17 +106,25 @@ public class IrencragFeatTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Irencrag Feat", 1);
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt", 4);
|
||||
|
||||
// on stack before
|
||||
checkPlayableAbility("can cast before feat 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
checkPlayableAbility("can cast before feat 2", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
|
||||
// feat
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Irencrag Feat");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// after resolve
|
||||
checkPlayableAbility("can cast after feat 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
checkPlayableAbility("can't cast after feat 2", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", false);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
//assertAllCommandsUsed(0); // second bolt must be restricted to cast
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertHandCount(playerA, "Lightning Bolt", 4 - 3);
|
||||
assertLife(playerB, 20 - 3 * 3);
|
||||
|
|
|
@ -39,14 +39,20 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testCantCastTreatsToShareTwice() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
|
||||
checkPlayableAbility("can play on first", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPlayableAbility("can't play on second", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", false);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertActionsCount(playerA, 1);
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertHandCount(playerA, 0);
|
||||
assertPermanentCount(playerA, "Food", 1);
|
||||
assertExileCount(playerA, "Curious Pair", 1);
|
||||
|
@ -430,18 +436,21 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testCantCastCuriousPairWithMelek() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Melek, Izzet Paragon");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Melek, Izzet Paragon");
|
||||
//
|
||||
addCard(Zone.LIBRARY, playerA, "Curious Pair");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
||||
checkPlayableAbility("can't play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Curious Pair", false);
|
||||
checkPlayableAbility("can play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", true);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertActionsCount(playerA, 1);
|
||||
assertPermanentCount(playerA, "Curious Pair", 0);
|
||||
assertLibraryCount(playerA, 1);
|
||||
}
|
||||
|
@ -477,19 +486,21 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testCantCastTreatsToShareWithGarruksHorde() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Garruk's Horde");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Garruk's Horde");
|
||||
//
|
||||
addCard(Zone.LIBRARY, playerA, "Curious Pair");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
|
||||
// showAvaileableAbilities("abils", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||
checkPlayableAbility("can play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Curious Pair", true);
|
||||
checkPlayableAbility("can't play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Treats to Share", false);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertActionsCount(playerA, 1);
|
||||
assertPermanentCount(playerA, "Food", 0);
|
||||
assertLibraryCount(playerA, 1);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ import mage.game.match.Match;
|
|||
import mage.game.match.MatchPlayer;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.PermanentToken;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.game.stack.StackObject;
|
||||
import mage.game.tournament.Tournament;
|
||||
import mage.player.ai.ComputerPlayer;
|
||||
|
@ -430,6 +431,8 @@ public class TestPlayer implements Player {
|
|||
// two search mode: for cards/permanents (strict) and for abilities (like)
|
||||
if (object instanceof Ability) {
|
||||
return object.getName().startsWith(nameOrAlias);
|
||||
} else if (object instanceof Spell) {
|
||||
return ((Spell) object).getSpellAbility().getName().startsWith(nameOrAlias);
|
||||
} else {
|
||||
return object.getName().equals(nameOrAlias);
|
||||
}
|
||||
|
@ -668,11 +671,13 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
} else if (action.getAction().startsWith("waitStackResolved")) {
|
||||
if (game.getStack().isEmpty()) {
|
||||
// can use next command
|
||||
// all done, can use next command
|
||||
actions.remove(action);
|
||||
continue;
|
||||
} else {
|
||||
// need pass to empty stack
|
||||
break;
|
||||
// need to wait (don't remove command)
|
||||
tryToPlayPriority(game);
|
||||
return true;
|
||||
}
|
||||
} else if (action.getAction().startsWith("playerAction:")) {
|
||||
String command = action.getAction();
|
||||
|
@ -692,6 +697,7 @@ public class TestPlayer implements Player {
|
|||
game.concede(getId());
|
||||
((GameImpl) game).checkConcede();
|
||||
actions.remove(action);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (action.getAction().startsWith(AI_PREFIX)) {
|
||||
|
@ -786,6 +792,13 @@ public class TestPlayer implements Player {
|
|||
wasProccessed = true;
|
||||
}
|
||||
|
||||
// check graveyard count: card name, count
|
||||
if (params[0].equals(CHECK_COMMAND_GRAVEYARD_COUNT) && params.length == 3) {
|
||||
assertGraveyardCount(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
|
||||
actions.remove(action);
|
||||
wasProccessed = true;
|
||||
}
|
||||
|
||||
// check hand count: count
|
||||
if (params[0].equals(CHECK_COMMAND_HAND_COUNT) && params.length == 2) {
|
||||
assertHandCount(action, game, computerPlayer, Integer.parseInt(params[1]));
|
||||
|
@ -842,7 +855,9 @@ public class TestPlayer implements Player {
|
|||
wasProccessed = true;
|
||||
}
|
||||
}
|
||||
if (!wasProccessed) {
|
||||
if (wasProccessed) {
|
||||
return true;
|
||||
} else {
|
||||
Assert.fail("Unknow check command or params: " + command);
|
||||
}
|
||||
} else if (action.getAction().startsWith(SHOW_PREFIX)) {
|
||||
|
@ -938,17 +953,23 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
}
|
||||
|
||||
if (!wasProccessed) {
|
||||
if (wasProccessed) {
|
||||
return true;
|
||||
} else {
|
||||
Assert.fail("Unknow show command or params: " + command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (AIPlayer) {
|
||||
computerPlayer.priority(game);
|
||||
} else {
|
||||
computerPlayer.pass(game);
|
||||
|
||||
// you don't need to use stack command all the time, so some cast commands can be skiped to next check
|
||||
if (game.getStack().isEmpty()) {
|
||||
this.chooseStrictModeFailed("cast/activate", game,
|
||||
"Can't find available command - " + action.getAction() + " (use checkPlayableAbility for non castable checks)", true);
|
||||
}
|
||||
} // turn/step
|
||||
}
|
||||
|
||||
tryToPlayPriority(game);
|
||||
|
||||
// check to prevent endless loops
|
||||
if (numberOfActions == actions.size()) {
|
||||
foundNoAction++;
|
||||
|
@ -962,6 +983,14 @@ public class TestPlayer implements Player {
|
|||
return false;
|
||||
}
|
||||
|
||||
private void tryToPlayPriority(Game game) {
|
||||
if (AIPlayer) {
|
||||
computerPlayer.priority(game);
|
||||
} else {
|
||||
computerPlayer.pass(game);
|
||||
}
|
||||
}
|
||||
|
||||
private Permanent findPermanentWithAssert(PlayerAction action, Game game, Player player, String cardName) {
|
||||
for (Permanent perm : game.getBattlefield().getAllPermanents()) {
|
||||
// need by controller
|
||||
|
@ -1208,6 +1237,17 @@ public class TestPlayer implements Player {
|
|||
Assert.assertEquals(action.getActionName() + " - card " + permanentName + " must exists in exile zone with " + count + " instances", count, foundedCount);
|
||||
}
|
||||
|
||||
private void assertGraveyardCount(PlayerAction action, Game game, Player player, String permanentName, int count) {
|
||||
int foundedCount = 0;
|
||||
for (Card card : player.getGraveyard().getCards(game)) {
|
||||
if (isObjectHaveTargetNameOrAlias(card, permanentName) && card.isOwnedBy(player.getId())) {
|
||||
foundedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertEquals(action.getActionName() + " - card " + permanentName + " must exists in graveyard zone with " + count + " instances", count, foundedCount);
|
||||
}
|
||||
|
||||
private void assertHandCount(PlayerAction action, Game game, Player player, int count) {
|
||||
Assert.assertEquals(action.getActionName() + " - hand must contain " + count, count, player.getHand().size());
|
||||
}
|
||||
|
@ -1668,7 +1708,16 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
private void chooseStrictModeFailed(String choiceType, Game game, String reason) {
|
||||
chooseStrictModeFailed(choiceType, game, reason, false);
|
||||
}
|
||||
|
||||
private void chooseStrictModeFailed(String choiceType, Game game, String reason, boolean printAbilities) {
|
||||
if (strictChooseMode && !AICanChooseInStrictMode) {
|
||||
if (printAbilities) {
|
||||
printStart("Available abilities for " + computerPlayer.getName());
|
||||
printAbilities(game, computerPlayer.getPlayable(game, true));
|
||||
printEnd();
|
||||
}
|
||||
Assert.fail("Missing " + choiceType + " def for"
|
||||
+ " turn " + game.getTurnNum()
|
||||
+ ", step " + (game.getStep() != null ? game.getStep().getType().name() : "not started")
|
||||
|
|
|
@ -93,6 +93,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
public static final String CHECK_COMMAND_PERMANENT_COUNT = "PERMANENT_COUNT";
|
||||
public static final String CHECK_COMMAND_PERMANENT_COUNTERS = "PERMANENT_COUNTERS";
|
||||
public static final String CHECK_COMMAND_EXILE_COUNT = "EXILE_COUNT";
|
||||
public static final String CHECK_COMMAND_GRAVEYARD_COUNT = "GRAVEYARD_COUNT";
|
||||
public static final String CHECK_COMMAND_HAND_COUNT = "HAND_COUNT";
|
||||
public static final String CHECK_COMMAND_HAND_CARD_COUNT = "HAND_CARD_COUNT";
|
||||
public static final String CHECK_COMMAND_COMMAND_CARD_COUNT = "COMMAND_CARD_COUNT";
|
||||
|
@ -380,6 +381,11 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
check(checkName, turnNum, step, player, CHECK_COMMAND_EXILE_COUNT, permanentName, count.toString());
|
||||
}
|
||||
|
||||
public void checkGraveyardCount(String checkName, int turnNum, PhaseStep step, TestPlayer player, String permanentName, Integer count) {
|
||||
//Assert.assertNotEquals("", permanentName);
|
||||
check(checkName, turnNum, step, player, CHECK_COMMAND_GRAVEYARD_COUNT, permanentName, count.toString());
|
||||
}
|
||||
|
||||
public void checkHandCount(String checkName, int turnNum, PhaseStep step, TestPlayer player, Integer count) {
|
||||
check(checkName, turnNum, step, player, CHECK_COMMAND_HAND_COUNT, count.toString());
|
||||
}
|
||||
|
|
|
@ -145,9 +145,13 @@ public class SpellAbility extends ActivatedAbilityImpl {
|
|||
this.costs.clearPaid();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name;
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue