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;
|
||||
|
||||
import mage.cards.Card;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.CardUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
|
@ -59,6 +61,41 @@ public class DayNightTest extends CardTestPlayerBase {
|
|||
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
|
||||
public void testNightbound() {
|
||||
currentGame.setDaytime(false);
|
||||
|
|
|
|||
|
|
@ -62,10 +62,14 @@ public abstract class ModalDoubleFacedCard extends CardImpl implements CardWithH
|
|||
|
||||
public ModalDoubleFacedCard(ModalDoubleFacedCard card) {
|
||||
super(card);
|
||||
this.leftHalfCard = card.getLeftHalfCard().copy();
|
||||
((ModalDoubleFacedCardHalf) leftHalfCard).setParentCard(this);
|
||||
this.rightHalfCard = card.rightHalfCard.copy();
|
||||
((ModalDoubleFacedCardHalf) rightHalfCard).setParentCard(this);
|
||||
if (card.leftHalfCard != null) {
|
||||
this.leftHalfCard = card.leftHalfCard;
|
||||
((ModalDoubleFacedCardHalf) this.leftHalfCard).setParentCard(this);
|
||||
}
|
||||
if (card.rightHalfCard != null) {
|
||||
this.rightHalfCard = card.rightHalfCard;
|
||||
((ModalDoubleFacedCardHalf) this.rightHalfCard).setParentCard(this);
|
||||
}
|
||||
}
|
||||
|
||||
public ModalDoubleFacedCardHalf getLeftHalfCard() {
|
||||
|
|
|
|||
|
|
@ -38,10 +38,14 @@ public abstract class SplitCard extends CardImpl implements CardWithHalves {
|
|||
|
||||
protected SplitCard(SplitCard card) {
|
||||
super(card);
|
||||
this.leftHalfCard = card.getLeftHalfCard().copy();
|
||||
((SplitCardHalf) leftHalfCard).setParentCard(this);
|
||||
this.rightHalfCard = card.rightHalfCard.copy();
|
||||
((SplitCardHalf) rightHalfCard).setParentCard(this);
|
||||
if (card.leftHalfCard != null) {
|
||||
this.leftHalfCard = card.leftHalfCard;
|
||||
((SplitCardHalf) this.leftHalfCard).setParentCard(this);
|
||||
}
|
||||
if (card.rightHalfCard != null) {
|
||||
this.rightHalfCard = card.rightHalfCard;
|
||||
((SplitCardHalf) this.rightHalfCard).setParentCard(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void setParts(SplitCardHalf leftHalfCard, SplitCardHalf rightHalfCard) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import mage.game.permanent.PermanentToken;
|
|||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.util.FuzzyTestsUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
|
@ -416,6 +417,9 @@ public final class ZonesHandler {
|
|||
&& card.removeFromZone(game, fromZone, source)) {
|
||||
success = true;
|
||||
event.setTarget(permanent);
|
||||
|
||||
// tests only: inject fuzzy data with random phased out permanents
|
||||
FuzzyTestsUtil.addRandomPhasedOutPermanent(permanent, source, game);
|
||||
} else {
|
||||
// revert controller to owner if permanent does not enter
|
||||
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