mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
tests: added fuzzy testing (disabled by default, added random phased out permanents, part of #13748);
This commit is contained in:
parent
58b5bb76f9
commit
849aea5946
5 changed files with 147 additions and 8 deletions
|
|
@ -1,8 +1,10 @@
|
||||||
package org.mage.test.cards.abilities.keywords;
|
package org.mage.test.cards.abilities.keywords;
|
||||||
|
|
||||||
|
import mage.cards.Card;
|
||||||
import mage.constants.PhaseStep;
|
import mage.constants.PhaseStep;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.util.CardUtil;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
@ -59,6 +61,41 @@ public class DayNightTest extends CardTestPlayerBase {
|
||||||
assertRuffianSmasher(true);
|
assertRuffianSmasher(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCopy() {
|
||||||
|
// possible bug: stack overflow on copy
|
||||||
|
addCard(Zone.HAND, playerA, ruffian);
|
||||||
|
|
||||||
|
runCode("copy", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||||
|
Card card = currentGame.getCards().stream().filter(c -> c.getName().equals(ruffian)).findFirst().orElse(null);
|
||||||
|
Assert.assertNotNull(card);
|
||||||
|
Assert.assertNotNull(card.getSecondCardFace());
|
||||||
|
|
||||||
|
// original
|
||||||
|
Assert.assertNotNull(card.getSecondCardFace());
|
||||||
|
// copy
|
||||||
|
Card copy = card.copy();
|
||||||
|
Assert.assertNotNull(copy.getSecondCardFace());
|
||||||
|
// deep copy
|
||||||
|
copy = CardUtil.deepCopyObject(card);
|
||||||
|
Assert.assertNotNull(copy.getSecondCardFace());
|
||||||
|
|
||||||
|
// copied
|
||||||
|
Card copied = game.copyCard(card, null, playerA.getId());
|
||||||
|
Assert.assertNotNull(copied.getSecondCardFace());
|
||||||
|
// copy
|
||||||
|
copy = copied.copy();
|
||||||
|
Assert.assertNotNull(copy.getSecondCardFace());
|
||||||
|
// deep copy
|
||||||
|
copy = CardUtil.deepCopyObject(copied);
|
||||||
|
Assert.assertNotNull(copy.getSecondCardFace());
|
||||||
|
});
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNightbound() {
|
public void testNightbound() {
|
||||||
currentGame.setDaytime(false);
|
currentGame.setDaytime(false);
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,14 @@ public abstract class ModalDoubleFacedCard extends CardImpl implements CardWithH
|
||||||
|
|
||||||
public ModalDoubleFacedCard(ModalDoubleFacedCard card) {
|
public ModalDoubleFacedCard(ModalDoubleFacedCard card) {
|
||||||
super(card);
|
super(card);
|
||||||
this.leftHalfCard = card.getLeftHalfCard().copy();
|
if (card.leftHalfCard != null) {
|
||||||
((ModalDoubleFacedCardHalf) leftHalfCard).setParentCard(this);
|
this.leftHalfCard = card.leftHalfCard;
|
||||||
this.rightHalfCard = card.rightHalfCard.copy();
|
((ModalDoubleFacedCardHalf) this.leftHalfCard).setParentCard(this);
|
||||||
((ModalDoubleFacedCardHalf) rightHalfCard).setParentCard(this);
|
}
|
||||||
|
if (card.rightHalfCard != null) {
|
||||||
|
this.rightHalfCard = card.rightHalfCard;
|
||||||
|
((ModalDoubleFacedCardHalf) this.rightHalfCard).setParentCard(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModalDoubleFacedCardHalf getLeftHalfCard() {
|
public ModalDoubleFacedCardHalf getLeftHalfCard() {
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,14 @@ public abstract class SplitCard extends CardImpl implements CardWithHalves {
|
||||||
|
|
||||||
protected SplitCard(SplitCard card) {
|
protected SplitCard(SplitCard card) {
|
||||||
super(card);
|
super(card);
|
||||||
this.leftHalfCard = card.getLeftHalfCard().copy();
|
if (card.leftHalfCard != null) {
|
||||||
((SplitCardHalf) leftHalfCard).setParentCard(this);
|
this.leftHalfCard = card.leftHalfCard;
|
||||||
this.rightHalfCard = card.rightHalfCard.copy();
|
((SplitCardHalf) this.leftHalfCard).setParentCard(this);
|
||||||
((SplitCardHalf) rightHalfCard).setParentCard(this);
|
}
|
||||||
|
if (card.rightHalfCard != null) {
|
||||||
|
this.rightHalfCard = card.rightHalfCard;
|
||||||
|
((SplitCardHalf) this.rightHalfCard).setParentCard(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParts(SplitCardHalf leftHalfCard, SplitCardHalf rightHalfCard) {
|
public void setParts(SplitCardHalf leftHalfCard, SplitCardHalf rightHalfCard) {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import mage.game.permanent.PermanentToken;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.TargetCard;
|
import mage.target.TargetCard;
|
||||||
|
import mage.util.FuzzyTestsUtil;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
@ -416,6 +417,9 @@ public final class ZonesHandler {
|
||||||
&& card.removeFromZone(game, fromZone, source)) {
|
&& card.removeFromZone(game, fromZone, source)) {
|
||||||
success = true;
|
success = true;
|
||||||
event.setTarget(permanent);
|
event.setTarget(permanent);
|
||||||
|
|
||||||
|
// tests only: inject fuzzy data with random phased out permanents
|
||||||
|
FuzzyTestsUtil.addRandomPhasedOutPermanent(permanent, source, game);
|
||||||
} else {
|
} else {
|
||||||
// revert controller to owner if permanent does not enter
|
// revert controller to owner if permanent does not enter
|
||||||
game.getContinuousEffects().setController(permanent.getId(), permanent.getOwnerId());
|
game.getContinuousEffects().setController(permanent.getId(), permanent.getOwnerId());
|
||||||
|
|
|
||||||
90
Mage/src/main/java/mage/util/FuzzyTestsUtil.java
Normal file
90
Mage/src/main/java/mage/util/FuzzyTestsUtil.java
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
package mage.util;
|
||||||
|
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.effects.EntersBattlefieldEffect;
|
||||||
|
import mage.abilities.keyword.PhasingAbility;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class for fuzzy testing
|
||||||
|
* <p>
|
||||||
|
* Support:
|
||||||
|
* - [x] enable by command line;
|
||||||
|
* - [x] phased out permanents must be hidden
|
||||||
|
* - [ ] TODO: out of range players and permanents must be hidden
|
||||||
|
* - [ ] TODO: leave/disconnected players must be hidden
|
||||||
|
* <p>
|
||||||
|
* How-to use:
|
||||||
|
* - enable here or by command line
|
||||||
|
* - run unit tests and research the fails
|
||||||
|
*
|
||||||
|
* @author JayDi85
|
||||||
|
*/
|
||||||
|
public class FuzzyTestsUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Phased out permanents must be hidden
|
||||||
|
* Make sure other cards and effects do not see phased out permanents and ignore it
|
||||||
|
* <p>
|
||||||
|
* Use case:
|
||||||
|
* - each permanent on battlefield will have copied phased out version with all abilities and effects
|
||||||
|
* <p>
|
||||||
|
* How-to use:
|
||||||
|
* - set true or run with -Dxmage.tests.addRandomPhasedOutPermanents=true
|
||||||
|
*/
|
||||||
|
public static boolean ADD_RANDOM_PHASED_OUT_PERMANENTS = false;
|
||||||
|
|
||||||
|
static {
|
||||||
|
String val = System.getProperty("xmage.tests.addRandomPhasedOutPermanents");
|
||||||
|
if (val != null) {
|
||||||
|
ADD_RANDOM_PHASED_OUT_PERMANENTS = Boolean.parseBoolean(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create duplicated phased out permanent
|
||||||
|
*/
|
||||||
|
public static void addRandomPhasedOutPermanent(Permanent originalPermanent, Ability source, Game game) {
|
||||||
|
if (!ADD_RANDOM_PHASED_OUT_PERMANENTS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Player samplePlayer = game.getPlayers().values().stream().findFirst().orElse(null);
|
||||||
|
if (samplePlayer == null || !samplePlayer.isTestsMode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy permanent and put it to battlefield as phased out (diff sides also supported here)
|
||||||
|
// TODO: add phased out tests support (must not fail on it)
|
||||||
|
Card originalCardSide = game.getCard(originalPermanent.getId());
|
||||||
|
Card originalCardMain = originalCardSide.getMainCard();
|
||||||
|
if (!originalCardMain.hasAbility(PhasingAbility.getInstance(), game)) {
|
||||||
|
boolean canCreate = true;
|
||||||
|
Card doppelgangerCardMain = game.copyCard(originalCardMain, source, originalPermanent.getControllerId());
|
||||||
|
Map<UUID, MageObject> mapOldToNew = CardUtil.getOriginalToCopiedPartsMap(originalCardMain, doppelgangerCardMain);
|
||||||
|
Card doppelgangerCardSide = (Card) mapOldToNew.getOrDefault(originalCardSide.getId(), null);
|
||||||
|
doppelgangerCardSide.addAbility(PhasingAbility.getInstance());
|
||||||
|
|
||||||
|
// compatibility workaround: remove all etb abilities to skip any etb choices (e.g. copy effect)
|
||||||
|
doppelgangerCardSide.getAbilities().removeIf(a -> a.getEffects().stream().anyMatch(e -> e instanceof EntersBattlefieldEffect));
|
||||||
|
// compatibility workaround: ignore aura to skip any etb choices (e.g. select new target)
|
||||||
|
if (doppelgangerCardSide.hasSubtype(SubType.AURA, game)) {
|
||||||
|
canCreate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canCreate) {
|
||||||
|
doppelgangerCardSide.putOntoBattlefield(game, Zone.BATTLEFIELD, source, originalPermanent.getControllerId());
|
||||||
|
Permanent doppelgangerPerm = CardUtil.getPermanentFromCardPutToBattlefield(doppelgangerCardSide, game);
|
||||||
|
doppelgangerPerm.phaseOut(game, true); // use indirect, so no phase in on untap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue