mirror of
https://github.com/correl/mage.git
synced 2024-11-25 03:00:11 +00:00
Test framework: improved aliases support:
* added check commands support; * added on of the choose method support; * added todo and checks for wrong test commands setup;
This commit is contained in:
parent
016f5fa9f5
commit
ec6b0b94c6
4 changed files with 187 additions and 88 deletions
|
@ -212,11 +212,14 @@ public class CloneTest extends CardTestPlayerBase {
|
|||
setChoice(playerA, "Elf");
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Clone");
|
||||
setChoice(playerB, "Yes");
|
||||
setChoice(playerB, "Adaptive Automaton");
|
||||
setChoice(playerB, "Goblin");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerA, "Adaptive Automaton", 1);
|
||||
Permanent original = getPermanent("Adaptive Automaton", playerA);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package org.mage.test.cards.copy;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
@ -8,7 +7,6 @@ import org.junit.Test;
|
|||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class IdentityThiefTest extends CardTestPlayerBase {
|
||||
|
@ -33,10 +31,13 @@ public class IdentityThiefTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Molten Sentry");
|
||||
|
||||
attack(2, playerB, "Identity Thief");
|
||||
setChoice(playerB, "Yes");
|
||||
addTarget(playerB, "Molten Sentry");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertExileCount(playerA, 1);
|
||||
assertExileCount("Molten Sentry", 1);
|
||||
|
@ -76,7 +77,7 @@ public class IdentityThiefTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Sylvan Advocate", 1); // {1}{G} 2/3 vigilance
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.HAND, playerA, "Battlegrowth"); // {G} instant - Put a +1/+1 counter on target creature.
|
||||
|
||||
|
||||
// Whenever Identity Thief attacks, you may exile another target nontoken creature.
|
||||
// If you do, Identity Thief becomes a copy of that creature until end of turn.
|
||||
// Return the exiled card to the battlefield under its owner's control at the beginning of the next end step.
|
||||
|
@ -84,7 +85,7 @@ public class IdentityThiefTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Battlegrowth");
|
||||
addTarget(playerA, "Sylvan Advocate");
|
||||
|
||||
|
||||
attack(2, playerB, "Identity Thief");
|
||||
addTarget(playerB, "Sylvan Advocate");
|
||||
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
package org.mage.test.player;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import mage.MageItem;
|
||||
import mage.MageObject;
|
||||
import mage.MageObjectReference;
|
||||
|
@ -61,6 +56,13 @@ import mage.util.CardUtil;
|
|||
import org.apache.log4j.Logger;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl.*;
|
||||
|
||||
/**
|
||||
|
@ -140,7 +142,7 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
public UUID getAliasByName(String searchName) {
|
||||
if (searchName.startsWith("@")) {
|
||||
if (searchName.startsWith(ALIASE_PREFIX)) {
|
||||
return this.aliases.getOrDefault(searchName.substring(1), null);
|
||||
} else {
|
||||
return this.aliases.getOrDefault(searchName, null);
|
||||
|
@ -177,7 +179,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
/**
|
||||
* @param maxCallsWithoutAction max number of priority passes a player may
|
||||
* have for this test (default = 100)
|
||||
* have for this test (default = 100)
|
||||
*/
|
||||
public void setMaxCallsWithoutAction(int maxCallsWithoutAction) {
|
||||
this.maxCallsWithoutAction = maxCallsWithoutAction;
|
||||
|
@ -358,7 +360,7 @@ public class TestPlayer implements Player {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (nameOrAliase.startsWith("@") && object.getId().equals(getAliasByName(nameOrAliase))) {
|
||||
if (nameOrAliase.startsWith(ALIASE_PREFIX) && object.getId().equals(getAliasByName(nameOrAliase))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -498,9 +500,9 @@ public class TestPlayer implements Player {
|
|||
for (PlayerAction action : tempActions) {
|
||||
if (action.getTurnNum() == game.getTurnNum() && action.getStep() == game.getStep().getType()) {
|
||||
|
||||
if (action.getAction().startsWith("activate:")) {
|
||||
if (action.getAction().startsWith(ACTIVATE_ABILITY)) {
|
||||
String command = action.getAction();
|
||||
command = command.substring(command.indexOf("activate:") + 9);
|
||||
command = command.substring(command.indexOf(ACTIVATE_ABILITY) + ACTIVATE_ABILITY.length());
|
||||
groupsForTargetHandling = null;
|
||||
String[] groups = command.split("\\$");
|
||||
if (groups.length > 2 && !checkExecuteCondition(groups, game)) {
|
||||
|
@ -615,11 +617,11 @@ public class TestPlayer implements Player {
|
|||
actions.remove(action);
|
||||
}
|
||||
}
|
||||
} else if (action.getAction().startsWith("check:")) {
|
||||
} else if (action.getAction().startsWith(CHECK_PREFIX)) {
|
||||
String command = action.getAction();
|
||||
command = command.substring(command.indexOf("check:") + "check:".length());
|
||||
command = command.substring(command.indexOf(CHECK_PREFIX) + CHECK_PREFIX.length());
|
||||
|
||||
String[] params = command.split("@");
|
||||
String[] params = command.split(CHECK_PARAM_DELIMETER);
|
||||
boolean wasProccessed = false;
|
||||
if (params.length > 0) {
|
||||
|
||||
|
@ -749,7 +751,7 @@ public class TestPlayer implements Player {
|
|||
String command = action.getAction();
|
||||
command = command.substring(command.indexOf("show:") + "show:".length());
|
||||
|
||||
String[] params = command.split("@");
|
||||
String[] params = command.split(CHECK_PARAM_DELIMETER);
|
||||
boolean wasProccessed = false;
|
||||
if (params.length > 0) {
|
||||
|
||||
|
@ -863,13 +865,21 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
private Permanent findPermanentWithAssert(PlayerAction action, Game game, Player player, String cardName) {
|
||||
Permanent founded = null;
|
||||
for (Permanent perm : game.getBattlefield().getAllPermanents()) {
|
||||
if (perm.getName().equals(cardName) && perm.getControllerId().equals(player.getId())) {
|
||||
return perm;
|
||||
// need by controller
|
||||
if (!perm.getControllerId().equals(player.getId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// need by alias or by name
|
||||
if (!isObjectHaveTargetNameOrAliase(perm, cardName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// all fine
|
||||
return perm;
|
||||
}
|
||||
Assert.assertNotNull(action.getActionName() + " - can''t find permanent to check: " + cardName, founded);
|
||||
Assert.fail(action.getActionName() + " - can''t find permanent to check: " + cardName);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -903,12 +913,12 @@ public class TestPlayer implements Player {
|
|||
|
||||
List<String> data = cards.stream()
|
||||
.map(c -> (((c instanceof PermanentToken) ? "[T] " : "[C] ")
|
||||
+ c.getIdName()
|
||||
+ (c.isCopy() ? " [copy of " + c.getCopyFrom().getId().toString().substring(0, 3) + "]" : "")
|
||||
+ " - " + c.getPower().getValue() + "/" + c.getToughness().getValue()
|
||||
+ (c.isPlaneswalker() ? " - L" + c.getCounters(game).getCount(CounterType.LOYALTY) : "")
|
||||
+ ", " + (c.isTapped() ? "Tapped" : "Untapped")
|
||||
+ (c.getAttachedTo() == null ? "" : ", attached to " + game.getPermanent(c.getAttachedTo()).getIdName())))
|
||||
+ c.getIdName()
|
||||
+ (c.isCopy() ? " [copy of " + c.getCopyFrom().getId().toString().substring(0, 3) + "]" : "")
|
||||
+ " - " + c.getPower().getValue() + "/" + c.getToughness().getValue()
|
||||
+ (c.isPlaneswalker() ? " - L" + c.getCounters(game).getCount(CounterType.LOYALTY) : "")
|
||||
+ ", " + (c.isTapped() ? "Tapped" : "Untapped")
|
||||
+ (c.getAttachedTo() == null ? "" : ", attached to " + game.getPermanent(c.getAttachedTo()).getIdName())))
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
@ -932,11 +942,11 @@ public class TestPlayer implements Player {
|
|||
|
||||
List<String> data = abilities.stream()
|
||||
.map(a -> (a.getZone() + " -> "
|
||||
+ a.getSourceObject(game).getIdName() + " -> "
|
||||
+ (a.toString().length() > 0
|
||||
? a.toString().substring(0, Math.min(20, a.toString().length()) - 1)
|
||||
: a.getClass().getSimpleName())
|
||||
+ "..."))
|
||||
+ a.getSourceObject(game).getIdName() + " -> "
|
||||
+ (a.toString().length() > 0
|
||||
? a.toString().substring(0, Math.min(20, a.toString().length()) - 1)
|
||||
: a.getClass().getSimpleName())
|
||||
+ "..."))
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
@ -1290,7 +1300,7 @@ public class TestPlayer implements Player {
|
|||
UUID defenderId = null;
|
||||
boolean mustAttackByAction = false;
|
||||
boolean madeAttackByAction = false;
|
||||
for (Iterator<org.mage.test.player.PlayerAction> it = actions.iterator(); it.hasNext();) {
|
||||
for (Iterator<org.mage.test.player.PlayerAction> it = actions.iterator(); it.hasNext(); ) {
|
||||
PlayerAction action = it.next();
|
||||
if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("attack:")) {
|
||||
mustAttackByAction = true;
|
||||
|
@ -1470,6 +1480,24 @@ public class TestPlayer implements Player {
|
|||
return "Target: " + (o != null ? o.getClass().getSimpleName() + ": " + o.getMessage() : "null");
|
||||
}
|
||||
|
||||
private void assertAliaseSupportInChoices(boolean methodSupportAliases) {
|
||||
// TODO: add alias support for all false methods (replace name compare by isObjectHaveTargetNameOrAliase)
|
||||
if (!methodSupportAliases && !choices.isEmpty()) {
|
||||
if (choices.get(0).contains(ALIASE_PREFIX)) {
|
||||
Assert.fail("That choice method do not support aliases, but found " + choices.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void assertAliaseSupportInTargets(boolean methodSupportAliases) {
|
||||
// TODO: add alias support for all false methods (replace name compare by isObjectHaveTargetNameOrAliase)
|
||||
if (!methodSupportAliases && !targets.isEmpty()) {
|
||||
if (targets.get(0).contains(ALIASE_PREFIX)) {
|
||||
Assert.fail("That target method do not support aliases, but found " + targets.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void chooseStrictModeFailed(String choiceType, Game game, String reason) {
|
||||
if (strictChooseMode) {
|
||||
Assert.fail("Missing " + choiceType + " def for"
|
||||
|
@ -1508,6 +1536,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public boolean choose(Outcome outcome, Choice choice, Game game) {
|
||||
assertAliaseSupportInChoices(false);
|
||||
if (!choices.isEmpty()) {
|
||||
if (choice.setChoiceByAnswers(choices, true)) {
|
||||
return true;
|
||||
|
@ -1525,6 +1554,7 @@ public class TestPlayer implements Player {
|
|||
if (rEffects.size() <= 1) {
|
||||
return 0;
|
||||
}
|
||||
assertAliaseSupportInChoices(false);
|
||||
if (!choices.isEmpty()) {
|
||||
String choice = choices.get(0);
|
||||
|
||||
|
@ -1547,13 +1577,14 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game, Map<String, Serializable> options) {
|
||||
// support aliases in choices
|
||||
UUID abilityControllerId = computerPlayer.getId();
|
||||
if (target.getTargetController() != null && target.getAbilityController() != null) {
|
||||
abilityControllerId = target.getAbilityController();
|
||||
}
|
||||
|
||||
assertAliaseSupportInChoices(true);
|
||||
if (!choices.isEmpty()) {
|
||||
|
||||
List<String> usedChoices = new ArrayList<>();
|
||||
List<UUID> usedTargets = new ArrayList<>();
|
||||
|
||||
|
@ -1571,8 +1602,8 @@ public class TestPlayer implements Player {
|
|||
} else {
|
||||
filterPermanent = ((TargetPermanent) target.getOriginalTarget()).getFilter();
|
||||
}
|
||||
for (String choose2 : choices) {
|
||||
String[] targetList = choose2.split("\\^");
|
||||
for (String choiceRecord : choices) {
|
||||
String[] targetList = choiceRecord.split("\\^");
|
||||
boolean targetFound = false;
|
||||
for (String targetName : targetList) {
|
||||
boolean originOnly = false;
|
||||
|
@ -1591,7 +1622,7 @@ public class TestPlayer implements Player {
|
|||
if (target.getTargets().contains(permanent.getId())) {
|
||||
continue;
|
||||
}
|
||||
if (permanent.getName().equals(targetName)) {
|
||||
if (isObjectHaveTargetNameOrAliase(permanent, targetName)) {
|
||||
if (target.isNotTarget() || target.canTarget(abilityControllerId, permanent.getId(), source, game)) {
|
||||
if ((permanent.isCopy() && !originOnly) || (!permanent.isCopy() && !copyOnly)) {
|
||||
target.add(permanent.getId(), game);
|
||||
|
@ -1599,7 +1630,7 @@ public class TestPlayer implements Player {
|
|||
break;
|
||||
}
|
||||
}
|
||||
} else if ((permanent.getName() + '-' + permanent.getExpansionSetCode()).equals(targetName)) {
|
||||
} else if ((permanent.getName() + '-' + permanent.getExpansionSetCode()).equals(targetName)) { // TODO: remove search by exp code?
|
||||
if (target.isNotTarget() || target.canTarget(abilityControllerId, permanent.getId(), source, game)) {
|
||||
if ((permanent.isCopy() && !originOnly) || (!permanent.isCopy() && !copyOnly)) {
|
||||
target.add(permanent.getId(), game);
|
||||
|
@ -1611,7 +1642,7 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
}
|
||||
if (targetFound) {
|
||||
choices.remove(choose2);
|
||||
choices.remove(choiceRecord);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1656,7 +1687,7 @@ public class TestPlayer implements Player {
|
|||
CheckTargetsList:
|
||||
for (UUID targetId : possibleCards) {
|
||||
MageObject targetObject = game.getObject(targetId);
|
||||
if (targetObject != null && targetObject.getName().equals(possibleChoice)) {
|
||||
if (isObjectHaveTargetNameOrAliase(targetObject, possibleChoice)) {
|
||||
if (target.canTarget(targetObject.getId(), game)) {
|
||||
// only unique targets
|
||||
if (usedTargets.contains(targetObject.getId())) {
|
||||
|
@ -1702,26 +1733,26 @@ public class TestPlayer implements Player {
|
|||
Set<UUID> possibleTargets;
|
||||
TargetSource t = ((TargetSource) target.getOriginalTarget());
|
||||
possibleTargets = t.possibleTargets(sourceId, abilityControllerId, game);
|
||||
for (String choose2 : choices) {
|
||||
String[] targetList = choose2.split("\\^");
|
||||
for (String choiceRecord : choices) {
|
||||
String[] targetList = choiceRecord.split("\\^");
|
||||
boolean targetFound = false;
|
||||
for (String targetName : targetList) {
|
||||
for (UUID targetId : possibleTargets) {
|
||||
MageObject targetObject = game.getObject(targetId);
|
||||
if (targetObject != null) {
|
||||
if (targetObject.getName().equals(targetName)) {
|
||||
if (isObjectHaveTargetNameOrAliase(targetObject, targetName)) {
|
||||
List<UUID> alreadyTargetted = target.getTargets();
|
||||
if (t.canTarget(targetObject.getId(), game)) {
|
||||
if (alreadyTargetted != null && !alreadyTargetted.contains(targetObject.getId())) {
|
||||
target.add(targetObject.getId(), game);
|
||||
choices.remove(choose2);
|
||||
choices.remove(choiceRecord);
|
||||
targetFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (targetFound) {
|
||||
choices.remove(choose2);
|
||||
choices.remove(choiceRecord);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1774,12 +1805,13 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
UUID sourceId = source != null ? source.getSourceId() : null;
|
||||
|
||||
assertAliaseSupportInTargets(false);
|
||||
if (!targets.isEmpty()) {
|
||||
|
||||
// skip targets
|
||||
if (targets.get(0).equals(TARGET_SKIP)) {
|
||||
Assert.assertTrue("found skip target, but it require more targets, needs "
|
||||
+ (target.getMinNumberOfTargets() - target.getTargets().size()) + " more",
|
||||
+ (target.getMinNumberOfTargets() - target.getTargets().size()) + " more",
|
||||
target.getTargets().size() >= target.getMinNumberOfTargets());
|
||||
targets.remove(0);
|
||||
return true;
|
||||
|
@ -2016,6 +2048,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
// wrong target settings by addTarget
|
||||
// how to fix: implement target class processing above
|
||||
assertAliaseSupportInTargets(false);
|
||||
if (!targets.isEmpty()) {
|
||||
String message;
|
||||
|
||||
|
@ -2040,6 +2073,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
|
||||
assertAliaseSupportInTargets(false);
|
||||
if (!targets.isEmpty()) {
|
||||
for (String targetDefinition : targets) {
|
||||
String[] targetList = targetDefinition.split("\\^");
|
||||
|
@ -2069,6 +2103,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public TriggeredAbility chooseTriggeredAbility(List<TriggeredAbility> abilities, Game game) {
|
||||
assertAliaseSupportInChoices(false);
|
||||
if (!choices.isEmpty()) {
|
||||
for (TriggeredAbility ability : abilities) {
|
||||
if (ability.toString().startsWith(choices.get(0))) {
|
||||
|
@ -2082,7 +2117,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
this.chooseStrictModeFailed("choice", game,
|
||||
"Triggered list (total " + abilities.size() + "):\n"
|
||||
+ abilities.stream().map(a -> getInfo(a, game)).collect(Collectors.joining("\n")));
|
||||
+ abilities.stream().map(a -> getInfo(a, game)).collect(Collectors.joining("\n")));
|
||||
return computerPlayer.chooseTriggeredAbility(abilities, game);
|
||||
}
|
||||
|
||||
|
@ -2096,6 +2131,7 @@ public class TestPlayer implements Player {
|
|||
if (message.equals("Scry 1?")) {
|
||||
return false;
|
||||
}
|
||||
assertAliaseSupportInChoices(false);
|
||||
if (!choices.isEmpty()) {
|
||||
if (choices.get(0).equals("No")) {
|
||||
choices.remove(0);
|
||||
|
@ -2117,6 +2153,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public int announceXMana(int min, int max, int multiplier, String message, Game game, Ability ability) {
|
||||
assertAliaseSupportInChoices(false);
|
||||
if (!choices.isEmpty()) {
|
||||
for (String choice : choices) {
|
||||
if (choice.startsWith("X=")) {
|
||||
|
@ -2134,6 +2171,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variablCost) {
|
||||
assertAliaseSupportInChoices(false);
|
||||
if (!choices.isEmpty()) {
|
||||
if (choices.get(0).startsWith("X=")) {
|
||||
int xValue = Integer.parseInt(choices.get(0).substring(2));
|
||||
|
@ -2149,6 +2187,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public int getAmount(int min, int max, String message, Game game) {
|
||||
assertAliaseSupportInChoices(false);
|
||||
if (!choices.isEmpty()) {
|
||||
if (choices.get(0).startsWith("X=")) {
|
||||
int xValue = Integer.parseInt(choices.get(0).substring(2));
|
||||
|
@ -3258,7 +3297,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public boolean choose(Outcome outcome, Target target,
|
||||
UUID sourceId, Game game
|
||||
UUID sourceId, Game game
|
||||
) {
|
||||
// needed to call here the TestPlayer because it's overwitten
|
||||
return choose(outcome, target, sourceId, game, null);
|
||||
|
@ -3266,8 +3305,9 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public boolean choose(Outcome outcome, Cards cards,
|
||||
TargetCard target, Game game
|
||||
TargetCard target, Game game
|
||||
) {
|
||||
assertAliaseSupportInChoices(false);
|
||||
if (!choices.isEmpty()) {
|
||||
for (String choose2 : choices) {
|
||||
// TODO: More targetting to fix
|
||||
|
@ -3302,19 +3342,20 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target,
|
||||
Ability source, Game game
|
||||
Ability source, Game game
|
||||
) {
|
||||
// chooseTargetAmount calls for EACH target cycle (e.g. one target per click, see TargetAmount)
|
||||
// if use want to stop choosing then chooseTargetAmount must return false (example: up to xxx)
|
||||
|
||||
Assert.assertNotEquals("chooseTargetAmount needs non zero amount remaining", 0, target.getAmountRemaining());
|
||||
|
||||
assertAliaseSupportInTargets(false);
|
||||
if (!targets.isEmpty()) {
|
||||
|
||||
// skip targets
|
||||
if (targets.get(0).equals(TARGET_SKIP)) {
|
||||
Assert.assertTrue("found skip target, but it require more targets, needs "
|
||||
+ (target.getMinNumberOfTargets() - target.getTargets().size()) + " more",
|
||||
+ (target.getMinNumberOfTargets() - target.getTargets().size()) + " more",
|
||||
target.getTargets().size() >= target.getMinNumberOfTargets());
|
||||
targets.remove(0);
|
||||
return false; // false in chooseTargetAmount = stop to choose
|
||||
|
@ -3367,15 +3408,15 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public boolean choosePile(Outcome outcome, String message,
|
||||
List<? extends Card> pile1, List<? extends Card> pile2,
|
||||
Game game
|
||||
List<? extends Card> pile1, List<? extends Card> pile2,
|
||||
Game game
|
||||
) {
|
||||
return computerPlayer.choosePile(outcome, message, pile1, pile2, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playMana(Ability ability, ManaCost unpaid,
|
||||
String promptText, Game game
|
||||
String promptText, Game game
|
||||
) {
|
||||
groupsForTargetHandling = null;
|
||||
return computerPlayer.playMana(ability, unpaid, promptText, game);
|
||||
|
@ -3389,15 +3430,15 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup,
|
||||
List<UUID> blockerOrder, Game game
|
||||
List<UUID> blockerOrder, Game game
|
||||
) {
|
||||
return computerPlayer.chooseBlockerOrder(blockers, combatGroup, blockerOrder, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assignDamage(int damage, List<UUID> targets,
|
||||
String singleTargetName, UUID sourceId,
|
||||
Game game
|
||||
String singleTargetName, UUID sourceId,
|
||||
Game game
|
||||
) {
|
||||
computerPlayer.assignDamage(damage, targets, singleTargetName, sourceId, game);
|
||||
}
|
||||
|
@ -3416,14 +3457,14 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public void pickCard(List<Card> cards, Deck deck,
|
||||
Draft draft
|
||||
Draft draft
|
||||
) {
|
||||
computerPlayer.pickCard(cards, deck, draft);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean scry(int value, Ability source,
|
||||
Game game
|
||||
Game game
|
||||
) {
|
||||
// Don't scry at the start of the game.
|
||||
if (game.getTurnNum() == 1 && game.getStep() == null) {
|
||||
|
@ -3434,44 +3475,44 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public boolean surveil(int value, Ability source,
|
||||
Game game
|
||||
Game game
|
||||
) {
|
||||
return computerPlayer.surveil(value, source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveCards(Card card, Zone toZone,
|
||||
Ability source, Game game
|
||||
Ability source, Game game
|
||||
) {
|
||||
return computerPlayer.moveCards(card, toZone, source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveCards(Card card, Zone toZone,
|
||||
Ability source, Game game,
|
||||
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
|
||||
Ability source, Game game,
|
||||
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
|
||||
) {
|
||||
return computerPlayer.moveCards(card, toZone, source, game, tapped, faceDown, byOwner, appliedEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveCards(Cards cards, Zone toZone,
|
||||
Ability source, Game game
|
||||
Ability source, Game game
|
||||
) {
|
||||
return computerPlayer.moveCards(cards, toZone, source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveCards(Set<Card> cards, Zone toZone,
|
||||
Ability source, Game game
|
||||
Ability source, Game game
|
||||
) {
|
||||
return computerPlayer.moveCards(cards, toZone, source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveCards(Set<Card> cards, Zone toZone,
|
||||
Ability source, Game game,
|
||||
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
|
||||
Ability source, Game game,
|
||||
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
|
||||
) {
|
||||
return computerPlayer.moveCards(cards, toZone, source, game, tapped, faceDown, byOwner, appliedEffects);
|
||||
}
|
||||
|
@ -3560,6 +3601,7 @@ public class TestPlayer implements Player {
|
|||
@Override
|
||||
public SpellAbility chooseAbilityForCast(Card card, Game game, boolean noMana) {
|
||||
String allInfo = "";
|
||||
assertAliaseSupportInChoices(false);
|
||||
if (!choices.isEmpty()) {
|
||||
Map<UUID, ActivatedAbility> useable = PlayerImpl.getSpellAbilities(this.getId(), card, game.getState().getZone(card.getId()), game);
|
||||
for (ActivatedAbility ability : useable.values()) {
|
||||
|
|
|
@ -34,6 +34,7 @@ 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;
|
||||
|
@ -43,10 +44,33 @@ import java.util.stream.Collectors;
|
|||
/**
|
||||
* API for test initialization and asserting the test results.
|
||||
*
|
||||
* @author ayratn
|
||||
* @author ayratn, JayDi85
|
||||
*/
|
||||
public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implements CardTestAPI {
|
||||
|
||||
public static final String ALIASE_PREFIX = "@"; // don't change -- it uses in user's tests
|
||||
public static final String CHECK_PARAM_DELIMETER = "#";
|
||||
public static final String CHECK_PREFIX = "check:"; // prefix for all check commands
|
||||
|
||||
static {
|
||||
// aliases can be used in check commands, so all prefixes and delimeters must be unique
|
||||
// already uses by targets: ^ $ [ ]
|
||||
Assert.assertFalse("prefix must be unique", CHECK_PARAM_DELIMETER.contains(ALIASE_PREFIX));
|
||||
Assert.assertFalse("prefix must be unique", CHECK_PREFIX.contains(ALIASE_PREFIX));
|
||||
Assert.assertFalse("prefix must be unique", ALIASE_PREFIX.contains(CHECK_PREFIX));
|
||||
}
|
||||
|
||||
// prefix for activate commands
|
||||
public static final String ACTIVATE_ABILITY = "activate:";
|
||||
public static final String ACTIVATE_PLAY = "activate:Play ";
|
||||
public static final String ACTIVATE_CAST = "activate:Cast ";
|
||||
|
||||
static {
|
||||
// cards can be played/casted by activate ability command too
|
||||
Assert.assertTrue("musts contains activate ability part", ACTIVATE_PLAY.startsWith(ACTIVATE_ABILITY));
|
||||
Assert.assertTrue("musts contains activate ability part", ACTIVATE_CAST.startsWith(ACTIVATE_ABILITY));
|
||||
}
|
||||
|
||||
// TODO: add target player param to commands
|
||||
public static final String CHECK_COMMAND_PT = "PT";
|
||||
public static final String CHECK_COMMAND_DAMAGE = "DAMAGE";
|
||||
|
@ -287,9 +311,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
// check commands
|
||||
|
||||
private void check(String checkName, int turnNum, PhaseStep step, TestPlayer player, String command, String... params) {
|
||||
String res = "check:" + command;
|
||||
String res = CHECK_PREFIX + command;
|
||||
for (String param : params) {
|
||||
res += "@" + param;
|
||||
res += CHECK_PARAM_DELIMETER + param;
|
||||
}
|
||||
player.addAction(checkName, turnNum, step, res);
|
||||
}
|
||||
|
@ -386,7 +410,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
private void show(String showName, int turnNum, PhaseStep step, TestPlayer player, String command, String... params) {
|
||||
String res = "show:" + command;
|
||||
for (String param : params) {
|
||||
res += "@" + param;
|
||||
res += CHECK_PARAM_DELIMETER + param;
|
||||
}
|
||||
player.addAction(showName, turnNum, step, res);
|
||||
}
|
||||
|
@ -494,9 +518,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
// aliases for mage objects
|
||||
String aliasName = "";
|
||||
boolean useAliasMultiNames = (count != 1);
|
||||
if (cardName.contains("@")) {
|
||||
aliasName = cardName.substring(cardName.indexOf("@") + 1);
|
||||
cardName = cardName.substring(0, cardName.indexOf("@"));
|
||||
if (cardName.contains(ALIASE_PREFIX)) {
|
||||
aliasName = cardName.substring(cardName.indexOf(ALIASE_PREFIX) + ALIASE_PREFIX.length());
|
||||
cardName = cardName.substring(0, cardName.indexOf(ALIASE_PREFIX));
|
||||
}
|
||||
|
||||
// one card = one aliase, massive adds can use auto-name
|
||||
|
@ -1339,23 +1363,27 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
|
||||
public void playLand(int turnNum, PhaseStep step, TestPlayer player, String cardName) {
|
||||
//Assert.assertNotEquals("", cardName);
|
||||
player.addAction(turnNum, step, "activate:Play " + cardName);
|
||||
assertAliaseSupportInActivateCommand(cardName, false);
|
||||
player.addAction(turnNum, step, ACTIVATE_PLAY + cardName);
|
||||
}
|
||||
|
||||
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName) {
|
||||
//Assert.assertNotEquals("", cardName);
|
||||
player.addAction(turnNum, step, "activate:Cast " + cardName);
|
||||
assertAliaseSupportInActivateCommand(cardName, false);
|
||||
player.addAction(turnNum, step, ACTIVATE_CAST + cardName);
|
||||
}
|
||||
|
||||
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, Player target) {
|
||||
//Assert.assertNotEquals("", cardName);
|
||||
// warning, target in spell cast command setups without choose target call
|
||||
player.addAction(turnNum, step, "activate:Cast " + cardName + "$targetPlayer=" + target.getName());
|
||||
assertAliaseSupportInActivateCommand(cardName, false);
|
||||
player.addAction(turnNum, step, ACTIVATE_CAST + cardName + "$targetPlayer=" + target.getName());
|
||||
}
|
||||
|
||||
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, Player target, int manaInPool) {
|
||||
//Assert.assertNotEquals("", cardName);
|
||||
player.addAction(turnNum, step, "activate:Cast " + cardName + "$targetPlayer=" + target.getName() + "$manaInPool=" + manaInPool);
|
||||
assertAliaseSupportInActivateCommand(cardName, false);
|
||||
player.addAction(turnNum, step, ACTIVATE_CAST + cardName + "$targetPlayer=" + target.getName() + "$manaInPool=" + manaInPool);
|
||||
}
|
||||
|
||||
public void waitStackResolved(int turnNum, PhaseStep step, TestPlayer player) {
|
||||
|
@ -1396,7 +1424,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
*/
|
||||
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName) {
|
||||
//Assert.assertNotEquals("", cardName);
|
||||
player.addAction(turnNum, step, "activate:Cast " + cardName + "$target=" + targetName);
|
||||
assertAliaseSupportInActivateCommand(cardName, false);
|
||||
player.addAction(turnNum, step, ACTIVATE_CAST + cardName + "$target=" + targetName);
|
||||
}
|
||||
|
||||
public enum StackClause {
|
||||
|
@ -1435,12 +1464,15 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
*/
|
||||
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName, String spellOnStack, StackClause clause) {
|
||||
//Assert.assertNotEquals("", cardName);
|
||||
assertAliaseSupportInActivateCommand(cardName, false);
|
||||
assertAliaseSupportInActivateCommand(targetName, false);
|
||||
assertAliaseSupportInActivateCommand(spellOnStack, false);
|
||||
if (StackClause.WHILE_ON_STACK == clause) {
|
||||
player.addAction(turnNum, step, "activate:Cast " + cardName
|
||||
player.addAction(turnNum, step, ACTIVATE_CAST + cardName
|
||||
+ '$' + (targetName != null && targetName.startsWith("target") ? targetName : "target=" + targetName)
|
||||
+ "$spellOnStack=" + spellOnStack);
|
||||
} else {
|
||||
player.addAction(turnNum, step, "activate:Cast " + cardName
|
||||
player.addAction(turnNum, step, ACTIVATE_CAST + cardName
|
||||
+ '$' + (targetName != null && targetName.startsWith("target") ? targetName : "target=" + targetName)
|
||||
+ "$!spellOnStack=" + spellOnStack);
|
||||
}
|
||||
|
@ -1448,7 +1480,11 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
|
||||
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName, String spellOnStack, String spellOnTopOfStack) {
|
||||
//Assert.assertNotEquals("", cardName);
|
||||
String action = "activate:Cast " + cardName + "$target=" + targetName;
|
||||
assertAliaseSupportInActivateCommand(cardName, false);
|
||||
assertAliaseSupportInActivateCommand(targetName, false);
|
||||
assertAliaseSupportInActivateCommand(spellOnStack, false);
|
||||
assertAliaseSupportInActivateCommand(spellOnTopOfStack, false);
|
||||
String action = ACTIVATE_CAST + cardName + "$target=" + targetName;
|
||||
if (spellOnStack != null && !spellOnStack.isEmpty()) {
|
||||
action += "$spellOnStack=" + spellOnStack;
|
||||
}
|
||||
|
@ -1464,17 +1500,23 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
|
||||
public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability) {
|
||||
// TODO: it's uses computerPlayer to execute, only ability target will work, but choices and targets commands aren't
|
||||
player.addAction(turnNum, step, "activate:" + ability);
|
||||
assertAliaseSupportInActivateCommand(ability, false);
|
||||
player.addAction(turnNum, step, ACTIVATE_ABILITY + ability);
|
||||
}
|
||||
|
||||
public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, Player target) {
|
||||
// TODO: it's uses computerPlayer to execute, only ability target will work, but choices and targets commands aren't
|
||||
player.addAction(turnNum, step, "activate:" + ability + "$targetPlayer=" + target.getName());
|
||||
assertAliaseSupportInActivateCommand(ability, false);
|
||||
player.addAction(turnNum, step, ACTIVATE_ABILITY + ability + "$targetPlayer=" + target.getName());
|
||||
}
|
||||
|
||||
public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String... targetNames) {
|
||||
// TODO: it's uses computerPlayer to execute, only ability target will work, but choices and targets commands aren't
|
||||
player.addAction(turnNum, step, "activate:" + ability + "$target=" + String.join("^", targetNames));
|
||||
assertAliaseSupportInActivateCommand(ability, false);
|
||||
Arrays.stream(targetNames).forEach(n -> {
|
||||
assertAliaseSupportInActivateCommand(n, false);
|
||||
});
|
||||
player.addAction(turnNum, step, ACTIVATE_ABILITY + ability + "$target=" + String.join("^", targetNames));
|
||||
}
|
||||
|
||||
public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName, String spellOnStack) {
|
||||
|
@ -1493,7 +1535,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
* @param clause
|
||||
*/
|
||||
public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName, String spellOnStack, StackClause clause) {
|
||||
StringBuilder sb = new StringBuilder("activate:").append(ability);
|
||||
assertAliaseSupportInActivateCommand(ability, false);
|
||||
assertAliaseSupportInActivateCommand(targetName, false);
|
||||
StringBuilder sb = new StringBuilder(ACTIVATE_ABILITY).append(ability);
|
||||
if (targetName != null && !targetName.isEmpty()) {
|
||||
sb.append("$target=").append(targetName);
|
||||
}
|
||||
|
@ -1553,7 +1597,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
* For use choices set "Yes" or "No" the the choice string. For X values set
|
||||
* "X=[xValue]" example: for X=3 set choice string to "X=3".
|
||||
* <br>For ColorChoice use "Red", "Green", "Blue", "Black" or "White"
|
||||
*
|
||||
*
|
||||
* @param player
|
||||
* @param choice
|
||||
*/
|
||||
|
@ -1676,4 +1720,13 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
if (playerC != null) waitStackResolved(turnNum, step, playerC);
|
||||
if (playerD != null) waitStackResolved(turnNum, step, playerD);
|
||||
}
|
||||
|
||||
private void assertAliaseSupportInActivateCommand(String targetName, boolean methodSupportAliases) {
|
||||
// TODO: add alias support for all false methods (replace name compare by isObjectHaveTargetNameOrAliase in activate code)
|
||||
if (!methodSupportAliases) {
|
||||
if (targetName != null && targetName.contains(ALIASE_PREFIX)) {
|
||||
Assert.fail("That activate command do not support aliases, but found " + targetName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue