Fixing several tests. Working towards enabling assertAllCommandsUsed() inside execute().

This commit is contained in:
Alex Vasile 2022-05-24 21:20:09 -06:00
parent 185d645ba7
commit db68e4798a
35 changed files with 525 additions and 418 deletions

View file

@ -2,6 +2,7 @@ package org.mage.test.cards.abilities.curses;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@ -68,7 +69,8 @@ public class CursesTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Exhaustion", playerB);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
checkPlayableAbility("Can't cast a 2nd spell", 1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Cast Lightning", false);
setStopAt(1, PhaseStep.END_TURN);
execute();
@ -116,10 +118,9 @@ public class CursesTest extends CardTestPlayerBase {
castSpell(4, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(4, PhaseStep.PRECOMBAT_MAIN, playerB, "Copy Enchantment");
setChoice(playerB, true);
setChoice(playerB, "Curse of Exhaustion");
setChoice(playerB, "targetPlayer=PlayerA");
castSpell(4, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
// Choices for Copy Enchantment get auto-chosen
checkPlayableAbility("Can't cast a 2nd spell", 4, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cast Lightning", false);
setStopAt(4, PhaseStep.END_TURN);
execute();
@ -151,7 +152,8 @@ public class CursesTest extends CardTestPlayerBase {
setChoice(playerB, "PlayerA");
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
checkPlayableAbility("Can't cast a 2nd spell", 2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cast Lightning", false);
setStopAt(2, PhaseStep.END_TURN);
execute();
@ -292,7 +294,6 @@ public class CursesTest extends CardTestPlayerBase {
@Test
public void cruelRealityHasBothCreatureAndPwChoosePw() {
String ugin = "Ugin, the Spirit Dragon";
String memnite = "Memnite"; // {0} 1/1
@ -315,7 +316,6 @@ public class CursesTest extends CardTestPlayerBase {
@Test
public void cruelRealityHasBothCreatureAndPwChooseCreature() {
String ugin = "Ugin, the Spirit Dragon";
String memnite = "Memnite"; // {0} 1/1
@ -338,7 +338,6 @@ public class CursesTest extends CardTestPlayerBase {
@Test
public void cruelRealityOnlyHasCreatureNoChoiceMade() {
String memnite = "Memnite"; // {0} 1/1
addCard(Zone.HAND, playerA, cReality);
@ -357,7 +356,6 @@ public class CursesTest extends CardTestPlayerBase {
@Test
public void cruelRealityOnlyHasPwNoChoiceMade() {
String ugin = "Ugin, the Spirit Dragon";
addCard(Zone.HAND, playerA, cReality);
@ -376,35 +374,40 @@ public class CursesTest extends CardTestPlayerBase {
@Test
public void cruelRealityOnlyHasCreatureTryToChooseNotToSac() {
String memnite = "Memnite"; // {0} 1/1
addCard(Zone.HAND, playerA, cReality);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 7);
addCard(Zone.BATTLEFIELD, playerB, memnite);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cReality, playerB);
setChoice(playerB, false);
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
execute();
assertGraveyardCount(playerB, memnite, 1);
assertPermanentCount(playerA, cReality, 1);
assertLife(playerB, 20);
try {
execute();
assertAllCommandsUsed();
} catch (Throwable e) {
if (!e.getMessage().contains("Missing CHOICE def for turn 2, step UPKEEP, PlayerB")) {
Assert.fail("Should have had error about needing a target, but got:\n" + e.getMessage());
}
}
}
@Test
public void cruelRealityNoCreatureOrPwForcesLifeLoss() {
String gPrison = "Ghostly Prison"; // {2}{W} enchantment - doesnt matter text for this
addCard(Zone.HAND, playerA, cReality);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 7);
addCard(Zone.BATTLEFIELD, playerB, gPrison);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cReality, playerB);
setChoice(playerB, gPrison); // try to set choice to enchantment
// No choice needed since no valid target available for Cruel Reality's triggered ability
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
execute();
@ -414,10 +417,10 @@ public class CursesTest extends CardTestPlayerBase {
assertLife(playerB, 15);
}
/*
/**
* Reported bug issue #3326
* When {Witchbane Orb} triggers when entering the field and there IS a curse attached to you, an error message (I sadly skipped) appears and your turn is reset.
This happened to me in a 4-player Commander game with {Curse of the Shallow Graves} on the field.
* This happened to me in a 4-player Commander game with {Curse of the Shallow Graves} on the field.
*/
@Test
public void witchbaneOrbDestroysCursesOnETB() {

View file

@ -44,7 +44,6 @@ public class MasterBiomancerTest extends CardTestPlayerBase {
@Test
public void testCreatureGetsDoubleCountersFromCorpsejackMenace() {
// a creature enters the battlefield and gets a counter for each point of power of Master Biomancer
// doubled by Corpsejack Menace (when he ist cast, his own ability will not apply)
// http://blogs.magicjudges.org/rulestips/2013/03/corpsejack-menace-and-master-biomancer/
@ -80,31 +79,25 @@ public class MasterBiomancerTest extends CardTestPlayerBase {
}
/**
* Progenitor Mimic Creature - Shapeshifter 0/0 You may have Progenitor
* Mimic enter the battlefield as a copy of any creature on the battlefield
* except it gains "At the beginning of your upkeep, if this creature isn't
* a token, put a token onto the battlefield that's a copy of this
* creature."
* Progenitor Mimic
* Creature - Shapeshifter 0/0
* You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield
* except it gains "At the beginning of your upkeep, if this creature isn't a token,
* put a token onto the battlefield that's a copy of this creature."
*
* If Progenitor Mimic comes into play, it gets two +1/+1 counters from the
* Master Biomancer already in play. It copies the Master Biomancer and is
* therfore a 4/6 creature. The Token generated next round from Progenitor
* Mimic has to get 2 + 4 counters and is therefore a 8/10 creature.
* If Progenitor Mimic comes into play, it gets two +1/+1 counters from the Master Biomancer already in play.
* It copies the Master Biomancer and is therfore a 4/6 creature.
* The Token generated next round from Progenitor Mimic has to get 2 + 4 counters and is therefore a 8/10 creature.
*/
@Test
public void testWithProgenitorMimic() {
// a creature enters the battlefield and gets a counter for each point of power of Master Biomancer
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
// A creature enters the battlefield and gets a counter for each point of power of Master Biomancer
addCard(Zone.BATTLEFIELD, playerA, "Master Biomancer", 1);
// You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield
// except it gains "At the beginning of your upkeep, if this creature isn't a token,
// put a token onto the battlefield that's a copy of this creature."
addCard(Zone.HAND, playerA, "Progenitor Mimic");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Progenitor Mimic");
playerA.addTarget("Master Biomancer");
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
execute();

View file

@ -7,25 +7,20 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* 702.109. Exploit
*
* 702.109a Exploit is a triggered ability. Exploit means When this creature enters the battlefield, you may sacrifice a creature.
*
* 702.109b A creature with exploit exploits a creature when the controller of the exploit ability sacrifices a creature as that ability resolves.
*
* You choose whether to sacrifice a creature and which creature to sacrifice as the exploit ability resolves.
* You can sacrifice the creature with exploit if it's still on the battlefield. This will cause its other ability to trigger.
* You can't sacrifice more than one creature to any one exploit ability.
*
* @author LevelX2
*/
public class ExploitTest extends CardTestPlayerBase {
/**
* 702.109. Exploit
*
* 702.109a Exploit is a triggered ability. Exploit means When this creature enters the battlefield, you may sacrifice a creature.
*
* 702.109b A creature with exploit exploits a creature when the controller of the exploit ability sacrifices a creature as that ability resolves.
*
* You choose whether to sacrifice a creature and which creature to sacrifice as the exploit ability resolves.
* You can sacrifice the creature with exploit if it's still on the battlefield. This will cause its other ability to trigger.
* You can't sacrifice more than one creature to any one exploit ability.
*
*/
@Test
public void testNormalUse() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
@ -47,13 +42,12 @@ public class ExploitTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Silumgar Butcher", 1);
assertGraveyardCount(playerA, "Silvercoat Lion", 1);
assertGraveyardCount(playerB, "Thundering Giant", 1);
}
/**
* Test that the Exploit ability won't trigger if the creature with
* exploit left the battlefiled before the Enters the battlefield
* triggered ability resolves.
*
*/
@Test
public void testExploitTriggerWontGo() {
@ -67,11 +61,12 @@ public class ExploitTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Lightning Bolt", 1);
addCard(Zone.BATTLEFIELD, playerB, "Thundering Giant"); // 4/3
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silumgar Butcher");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Silumgar Butcher");
setChoice(playerA, true);
addTarget(playerA, "Silvercoat Lion"); // sacrifice to Exploit
addTarget(playerA, "Thundering Giant"); // Target for the -3/-3
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -79,15 +74,14 @@ public class ExploitTest extends CardTestPlayerBase {
assertGraveyardCount(playerB, "Lightning Bolt", 1);
assertGraveyardCount(playerA, "Silumgar Butcher", 1);
assertGraveyardCount(playerA, "Silvercoat Lion", 1);
assertPermanentCount(playerB, "Thundering Giant", 1);
assertPermanentCount(playerB, "Thundering Giant", 1);
}
/**
* Test that the Exploit ability won't trigger if the creature with
* exploit left the battlefiled before the Enters the battlefield
* triggered ability resolves.
*
*/
@Test
public void testSacrificeCreatureWithExploit() {
@ -108,7 +102,5 @@ public class ExploitTest extends CardTestPlayerBase {
assertLife(playerA, 22);
assertLife(playerB, 18);
}
}

View file

@ -36,9 +36,9 @@ public class FlashbackTest extends CardTestPlayerBase {
}
/**
* Fracturing Gust is bugged. In a match against Affinity, it worked
* properly when cast from hand. When I cast it from graveyard c/o
* Snapcaster Mage flashback, it destroyed my opponent's Darksteel Citadels,
* Fracturing Gust is bugged.
* In a match against Affinity, it worked properly when cast from hand.
* When I cast it from graveyard c/o Snapcaster Mage flashback, it destroyed my opponent's Darksteel Citadels,
* which it did not do when cast from my hand.
*/
@Test
@ -53,9 +53,10 @@ public class FlashbackTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Berserkers' Onslaught", 1);
addCard(Zone.BATTLEFIELD, playerB, "Darksteel Citadel", 1);
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn. The flashback cost is equal to its mana cost.
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn.
// The flashback cost is equal to its mana cost.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage");
setChoice(playerA, "Fracturing Gust");
// Fracturing Gust is the only possible target, it's auto-chosen
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Flashback {2}{G/W}{G/W}{G/W}"); // now snapcaster mage is dead so -13/-13
@ -129,13 +130,14 @@ public class FlashbackTest extends CardTestPlayerBase {
}
/**
* My opponent put Iona on the battlefield using Unburial Rites, but my game
* log didn't show me the color they chose.
* My opponent put Iona on the battlefield using Unburial Rites,
* but my game log didn't show me the color they chose.
*/
@Test
public void testUnburialRites() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 8);
// Return target creature card from your graveyard to the battlefield.
// Flashback {3}{W}
addCard(Zone.HAND, playerA, "Unburial Rites", 1); // Sorcery - {4}{B}
@ -144,12 +146,12 @@ public class FlashbackTest extends CardTestPlayerBase {
// As Iona, Shield of Emeria enters the battlefield, choose a color.
// Your opponents can't cast spells of the chosen color.
addCard(Zone.GRAVEYARD, playerA, "Iona, Shield of Emeria");
// As Lurebound Scarecrow enters the battlefield, choose a color.
// When you control no permanents of the chosen color, sacrifice Lurebound Scarecrow.
addCard(Zone.GRAVEYARD, playerA, "Lurebound Scarecrow"); // Enchantment - {2}{U}
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
addCard(Zone.HAND, playerB, "Lightning Bolt", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Unburial Rites", "Iona, Shield of Emeria");
@ -159,8 +161,6 @@ public class FlashbackTest extends CardTestPlayerBase {
addTarget(playerA, "Lurebound Scarecrow");
setChoice(playerA, "White");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
setStopAt(1, PhaseStep.END_TURN);
execute();
@ -173,7 +173,7 @@ public class FlashbackTest extends CardTestPlayerBase {
}
/**
*
* Check that the Converge ability picks up on the color used when a card is cast for flashback.
*/
@Test
public void testFlashbackWithConverge() {
@ -188,9 +188,10 @@ public class FlashbackTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, "Unified Front"); // {3}{W}
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {W}");
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn. The flashback cost is equal to its mana cost.
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn.
// The flashback cost is equal to its mana cost.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage");
setChoice(playerA, "Unified Front");
// Unified Front is the only possible target for Snapcaster Mage, it's auto-chosen
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Flashback {3}{W}");
@ -232,9 +233,9 @@ public class FlashbackTest extends CardTestPlayerBase {
}
/**
* Ancestral Vision has no casting cost (this is different to a casting cost
* of {0}). Snapcaster Mage, for example, is able to give it flashback
* whilst it is in the graveyard.
* Ancestral Vision has no casting cost (this is different to a casting cost of {0}).
* <p>
* Snapcaster Mage, for example, is able to give it flashback whilst it is in the graveyard.
* <p>
* However the controller should not be able to cast Ancestral Visions from
* the graveyard for {0} mana.
@ -246,7 +247,8 @@ public class FlashbackTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, "Ancestral Vision", 1);
// Flash
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn. The flashback cost is equal to its mana cost.
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn.
// The flashback cost is equal to its mana cost.
addCard(Zone.HAND, playerA, "Snapcaster Mage", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
@ -254,8 +256,7 @@ public class FlashbackTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage");
addTarget(playerA, "Ancestral Vision");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback");
addTarget(playerA, playerA);
checkPlayableAbility("No flashback", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback", false);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -296,9 +297,11 @@ public class FlashbackTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Runic Repetition", 1);
}
/**
* Check that Altar's Reap additional cost (sacrificing a creature) still applies when cast through flashback.
*/
@Test
public void testAltarsReap() {
addCard(Zone.LIBRARY, playerA, "Island", 2);
// As an additional cost to cast Altar's Reap, sacrifice a creature.
// Draw two cards.
@ -310,7 +313,7 @@ public class FlashbackTest extends CardTestPlayerBase {
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn.
// The flashback cost is equal to its mana cost.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage");
setChoice(playerA, "Altar's Reap");
// Altar's Reap is the only possible target for Snapcaster Mages' ability, its auto-chosen.
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Flashback");
setChoice(playerA, "Snapcaster Mage");
@ -343,7 +346,8 @@ public class FlashbackTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Icefall Regent", 1);
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn. The flashback cost is equal to its mana cost.
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn.
// The flashback cost is equal to its mana cost.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage");
addTarget(playerA, "Terminate");
@ -366,24 +370,27 @@ public class FlashbackTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Island", 8);
addCard(Zone.HAND, playerA, "Snapcaster Mage", 1);
// Buyback {5}(You may pay an additional {5} as you cast this spell. If you do, put this card into your hand as it resolves.)
// Buyback {5} (You may pay an additional {5} as you cast this spell.
// If you do, put this card into your hand as it resolves.)
// Draw a card.
addCard(Zone.GRAVEYARD, playerA, "Whispers of the Muse", 1); // {U}
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn. The flashback cost is equal to its mana cost.
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn.
// The flashback cost is equal to its mana cost.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage");
setChoice(playerA, "Whispers of the Muse");
// setChoice(playerA, "Whispers of the Muse");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Flashback"); // Flashback Whispers of the Muse
setChoice(playerA, true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPermanentCount(playerA, "Snapcaster Mage", 1);
assertGraveyardCount(playerA, "Whispers of the Muse", 0);
assertExileCount("Whispers of the Muse", 1);
assertHandCount(playerA, 1);
assertExileCount("Whispers of the Muse", 1);
assertHandCount(playerA, 1);
}
/**
@ -408,28 +415,26 @@ public class FlashbackTest extends CardTestPlayerBase {
assertTappedCount("Island", true, 2);
}
/*
/**
* Bug: Firecat Blitz when cast via Flashback requests sacrificing mountains twice
*
* Firecat Blitz
* {X}{R}{R}
* Sorcery
* Create X 1/1 red Elemental Cat creature tokens with haste. Exile them at the beginning of the next end step.
* Flashback{R}{R}, Sacrifice X Mountains.
*/
@Test
public void firecatBlitzFlashback() {
/*
Firecat Blitz {X}{R}{R}
Sorcery
Create X 1/1 red Elemental Cat creature tokens with haste. Exile them at the beginning of the next end step.
Flashback{R}{R}, Sacrifice X Mountains.
*/
String fCatBlitz = "Firecat Blitz";
String mountain = "Mountain";
addCard(Zone.GRAVEYARD, playerA, fCatBlitz);
addCard(Zone.BATTLEFIELD, playerA, mountain, 6);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback"); // Flashback blitz
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback"); // Firecat
setChoice(playerA, "X=1");
addTarget(playerA, mountain);
// Mountain is auto-sacrificed
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -439,30 +444,31 @@ public class FlashbackTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, mountain, 1);
}
/*
* Reported bug: Battle Screech doesn't flashback (i get the pop up to choose flashback, tap the creatures and nothing happens)
/**
* Reported bug: Battle Screech doesn't flashback
* (I get the pop up to choose flashback, tap the creatures and nothing happens)
*
* Battle Screech
* {2}{W}{W}
* Sorcery
* Create two 1/1 white Bird creature tokens with flying.
* FlashbackTap three untapped white creatures you control.
*/
@Test
public void battleScreechFlashback() {
/*
Battle Screech {2}{W}{W}
Sorcery
Create two 1/1 white Bird creature tokens with flying.
FlashbackTap three untapped white creatures you control.
*/
String bScreech = "Battle Screech";
String bScreech = "Battle Screech";
String eVanguard = "Elite Vanguard"; // {W} 2/1
String yOx = "Yoked Ox"; // {W} 0/4
String wKnight = "White Knight"; // {W}{W} 2/2
String yOx = "Yoked Ox"; // {W} 0/4
String wKnight = "White Knight"; // {W}{W} 2/2
addCard(Zone.GRAVEYARD, playerA, bScreech);
addCard(Zone.BATTLEFIELD, playerA, eVanguard);
addCard(Zone.BATTLEFIELD, playerA, yOx);
addCard(Zone.BATTLEFIELD, playerA, wKnight);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback"); // Flashback Battle Screech
addTarget(playerA, eVanguard + '^' + yOx + '^' + wKnight);
// Only 3 creature under playerA's control, let them get auto-tapped
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -470,23 +476,23 @@ public class FlashbackTest extends CardTestPlayerBase {
assertTapped(eVanguard, true);
assertTapped(yOx, true);
assertTapped(wKnight, true);
assertExileCount(playerA, bScreech, 1); // this fails, but the creatures are tapped as part of paying the cost
assertPermanentCount(playerA, "Bird Token", 2); // if you comment out the above line, this is failing as well
assertExileCount(playerA, bScreech, 1);
assertPermanentCount(playerA, "Bird Token", 2);
}
/*
Reported bug: tried to flashback Dread Return, it allowed me to sac the creatures but the spell did not resolve after the costs had been paid.
It did not allow me to select a creature to return from yard to board.
/**
* Reported bug: Tried to flashback Dread Return,
* it allowed me to sac the creatures but the spell did not resolve after the costs had been paid.
* It did not allow me to select a creature to return from yard to board.
*
* Dread Return
* {2}{B}{B}
* Sorcery
* Return target creature card from your graveyard to the battlefield.
* FlashbackSacrifice three creatures
*/
@Test
public void dreadReturnFlashback() {
/*
Dread Return {2}{B}{B}
Sorcery
Return target creature card from your graveyard to the battlefield.
FlashbackSacrifice three creatures
*/
String dReturn = "Dread Return";
String yOx = "Yoked Ox"; // {W} 0/4
String eVanguard = "Elite Vanguard"; // {W} 2/1
@ -495,13 +501,14 @@ public class FlashbackTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, dReturn);
addCard(Zone.GRAVEYARD, playerA, bSable);
addCard(Zone.BATTLEFIELD, playerA, yOx);
addCard(Zone.BATTLEFIELD, playerA, eVanguard);
addCard(Zone.BATTLEFIELD, playerA, memnite);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback"); // Flashback Dread Return
addTarget(playerA, bSable); // return to battlefield
addTarget(playerA, yOx + '^' + eVanguard + '^' + memnite); // sac 3 creatures
// Only 3 creature under playerA's control, let them be auto-sac'ed to pay
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -514,7 +521,7 @@ public class FlashbackTest extends CardTestPlayerBase {
}
/**
* I can play Force of Will with flashback paying his alternative mana cost.
* I can play Force of Will with flashback paying its alternative mana cost.
* The ruling say no to it, because we only can choose one alternative cost
* to a spell, and the flashback cost is already an alternative cost.
*/
@ -522,9 +529,11 @@ public class FlashbackTest extends CardTestPlayerBase {
public void testSnapcasterMageSpellWithAlternateCost() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
// Creature {1}{U}
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn.
// The flashback cost is equal to its mana cost.
addCard(Zone.HAND, playerA, "Snapcaster Mage", 2); // Creature{1}{U}
addCard(Zone.HAND, playerA, "Snapcaster Mage", 2);
// You may pay 1 life and exile a blue card from your hand rather than pay Force of Will's mana cost.
// Counter target spell.
@ -541,16 +550,27 @@ public class FlashbackTest extends CardTestPlayerBase {
addTarget(playerA, "Lightning Bolt");
setStopAt(1, PhaseStep.END_TURN);
execute();
// TODO: Can't use checkPlayableAbility on Force of Will in this case.
try {
execute();
assertAllCommandsUsed();
Assert.fail("must throw exception on execute");
} catch (Throwable e) {
if (!e.getMessage().contains("Player PlayerA must have 0 actions but found 1")) {
Assert.fail("Should have thrown error about not being able to play Force of Will, but got:\n" + e.getMessage());
}
}
assertPermanentCount(playerA, "Snapcaster Mage", 0);
assertGraveyardCount(playerA, "Snapcaster Mage", 1);
assertGraveyardCount(playerA, "Snapcaster Mage", 1);
assertGraveyardCount(playerA, "Force of Will", 1);
assertGraveyardCount(playerB, "Lightning Bolt", 1);
assertLife(playerA, 20);
}
/**

View file

@ -140,7 +140,9 @@ public class HideawayTest extends CardTestPlayerBase {
@Test
public void testCannotPlayLandIfNotOwnTurn() {
// Hideaway (This land enters the battlefield tapped. When it does, look at the top four cards of your library, exile one face down, then put the rest on the bottom of your library.)
// Hideaway (This land enters the battlefield tapped.
// When it does, look at the top four cards of your library, exile one face down,
// then put the rest on the bottom of your library.)
// {T}: Add {G}.
// {G}, {T}: You may play the exiled card without paying its mana cost if creatures you control have total power 10 or greater.
addCard(Zone.HAND, playerA, "Mosswort Bridge");
@ -150,17 +152,20 @@ public class HideawayTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerA, "Dross Crocodile", 2);// 5/1
setStrictChooseMode(true);
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mosswort Bridge");
setChoice(playerA, "Ghost Quarter");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{G},");
activateAbility(4, PhaseStep.PRECOMBAT_MAIN, playerA, "{G},");
setChoice(playerA, true);
setStopAt(2, PhaseStep.BEGIN_COMBAT);
setStopAt(4, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Ghost Quarter", 0);
assertTapped("Mosswort Bridge", true);
assertTapped("Mosswort Bridge", true); // Tapped from activating the ability
assertPermanentCount(playerA, "Ghost Quarter", 0); // Land couldn't be played since not playerA's turn
}
@Test

View file

@ -76,7 +76,6 @@ public class MadnessTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Raven's Crime", 1);
assertGraveyardCount(playerA, "Arrogant Wurm", 1);
assertHandCount(playerA, 0);
}
@Test
@ -93,19 +92,19 @@ public class MadnessTest extends CardTestPlayerBase {
// Target player discards two cards. If you cast this spell during your main phase, that player discards four cards instead.
addCard(Zone.HAND, playerB, "Haunting Hymn");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Haunting Hymn", playerA);
setChoice(playerA, true); // use madness triggered ability
setChoice(playerA, true); // use madness cast
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Haunting Hymn", playerA);
setChoice(playerA, true); // Can't Vampirefor madness cost
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
setStrictChooseMode(true);
assertGraveyardCount(playerB, "Haunting Hymn", 1);
assertGraveyardCount(playerB, "Haunting Hymn", 1);
assertPermanentCount(playerA, "Vampire Aristocrat", 1);
assertGraveyardCount(playerA, 0);
assertGraveyardCount(playerB, 1);
assertGraveyardCount(playerB, "Haunting Hymn", 1);
}
@Test
@ -113,7 +112,8 @@ public class MadnessTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
// Madness {X}{R}
// Avacyn's Judgment deals 2 damage divided as you choose among any number of target creatures and/or players. If Avacyn's Judgment's madness cost was paid, it deals X damage divided as you choose among those creatures and/or players instead.
// Avacyn's Judgment deals 2 damage divided as you choose among any number of target creatures and/or players.
// If Avacyn's Judgment's madness cost was paid, it deals X damage divided as you choose among those creatures and/or players instead.
addCard(Zone.HAND, playerA, "Avacyn's Judgment", 1);
addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox", 1);
@ -135,7 +135,6 @@ public class MadnessTest extends CardTestPlayerBase {
assertGraveyardCount(playerB, "Haunting Hymn", 1);
assertGraveyardCount(playerA, "Avacyn's Judgment", 1);
assertGraveyardCount(playerB, "Pillarfield Ox", 1);
}
/**

View file

@ -14,10 +14,10 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class ProliferateTest extends CardTestPlayerBase {
/**
* Volt Charge {2}{R} Instant Volt Charge deals 3 damage to target creature
* or player. Proliferate. (You choose any number of permanents and/or
* players with counters on them, then give each another counter of a kind
* already there.)
* Volt Charge
* {2}{R}
* Volt Charge deals 3 damage to any target.
* Proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)
*/
@Test
public void testCastFromHandMovedToExile() {
@ -27,7 +27,7 @@ public class ProliferateTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Volt Charge");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Volt Charge", playerB);
addTarget(playerA, "Chandra, Pyromaster");
setChoice(playerA, "Chandra, Pyromaster");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -36,7 +36,6 @@ public class ProliferateTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Volt Charge", 1);
assertCounterCount("Chandra, Pyromaster", CounterType.LOYALTY, 5); // 4 + 1 from proliferate
}
/**

View file

@ -2,12 +2,13 @@ package org.mage.test.cards.abilities.oneshot.counterspell;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* Force of Will
* Instant, 3UUU
* {@link mage.cards.f.ForceOfWill Force of Will} {3}{U}{U}
* Instant
* You may pay 1 life and exile a blue card from your hand rather than pay Force of Will's mana cost.
* Counter target spell.
*
@ -17,7 +18,6 @@ public class ForceOfWillTest extends CardTestPlayerBase {
/**
* Test that Force of Will can be played with alternate casting costs
*
*/
@Test
public void testWithBlueCardsInHand() {
@ -44,39 +44,47 @@ public class ForceOfWillTest extends CardTestPlayerBase {
assertHandCount(playerB, 1); // One Remand left
assertGraveyardCount(playerB, 1); // Force of Will
assertExileCount("Remand", 1); // one Remand (cost from Force of Will)
}
/**
* Test that Force of Will can'be played with alternate casting costs
* if no blue card is in hand and not enough mana available
*
*/
@Test
public void testWithRedCardsInHand() {
addCard(Zone.HAND, playerA, "Thoughtseize");
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
//
// No Red cards in hand
addCard(Zone.HAND, playerB, "Force of Will");
addCard(Zone.HAND, playerB, "Fireball", 2); // blue card to pay force of will
addCard(Zone.HAND, playerB, "Fireball", 2);
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Thoughtseize", playerB);
playerB.addChoice("Fireball");
playerA.addChoice("Fireball");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Force of Will", "Thoughtseize");
setStopAt(1, PhaseStep.CLEANUP);
execute();
// TODO: Needed since the alternative cost is not being properly check for playability.
try {
execute();
assertAllCommandsUsed();
Assert.fail("must throw exception on execute");
} catch (Throwable e) {
if (!e.getMessage().contains("Can't find available command - activate:Cast Force of Will$target=Thoughtseize")) {
Assert.fail("must throw error about bad targets, but got:\n" + e.getMessage());
}
}
assertLife(playerA, 18);
assertLife(playerB, 20); // losing 1 from Force of Will
assertHandCount(playerA, 0);
assertGraveyardCount(playerA, 1);
assertHandCount(playerB, 2); // 1 Fireball 1 Force of Will
assertHandCount(playerB, 2); // 1 Fireball 1 Force of Will
assertGraveyardCount(playerB, 1); // 1 Fireball discarded because of Thoughseize
}
}

View file

@ -32,7 +32,7 @@ public class HideousEndTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Hideous End");
addCard(Zone.BATTLEFIELD, playerB, "Zombie Goliath");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hideous End", "Zombie Goliath");
checkPlayableAbility("No Non-Black creature", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Hideous", false);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();

View file

@ -8,18 +8,14 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* Crucible of Worlds
* {3}
* Artifact
* You may play lands from your graveyard.
*
* @author BetaSteward
*/
public class CrucibleOfWorldsTest extends CardTestPlayerBase {
/**
* Crucible of Worlds
* Artifact, 3 (3)
* You may play land cards from your graveyard.
*
*/
@Test
public void testPlayLand() {
addCard(Zone.BATTLEFIELD, playerA, "Crucible of Worlds");
@ -32,7 +28,6 @@ public class CrucibleOfWorldsTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Swamp", 1);
assertGraveyardCount(playerA, "Swamp", 0);
}
@Test
@ -42,7 +37,7 @@ public class CrucibleOfWorldsTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, "Plains");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Play Swamp");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Play Plains");
checkPlayableAbility("Can't play Plains", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Play Plains", false);
setStopAt(1, PhaseStep.END_TURN);
execute();
@ -51,7 +46,5 @@ public class CrucibleOfWorldsTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Swamp", 0);
assertPermanentCount(playerA, "Plains", 0);
assertGraveyardCount(playerA, "Plains", 1);
}
}

View file

@ -2,6 +2,7 @@ package org.mage.test.cards.asthough;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBaseWithAIHelps;
@ -25,7 +26,6 @@ public class PlayFromNonHandZoneTest extends CardTestPlayerBaseWithAIHelps {
execute();
assertPowerToughness(playerA, "Worldheart Phoenix", 2, 2);
}
@Test
@ -37,13 +37,21 @@ public class PlayFromNonHandZoneTest extends CardTestPlayerBaseWithAIHelps {
addCard(Zone.GRAVEYARD, playerA, "Worldheart Phoenix");
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Worldheart Phoenix"); // can only be cast by {W}{U}{B}{R}{G}
// can only be cast by {W}{U}{B}{R}{G}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Worldheart Phoenix");
setStopAt(1, PhaseStep.END_COMBAT);
execute();
// TODO: Needed since it shows up as castable to checkPLayableAbility
try {
execute();
} catch (Throwable e) {
if (!e.getMessage().contains("Player PlayerA must have 0 actions but found 1")) {
Assert.fail("Must have thrown error about not being able to cast Worldheart Phoenix, but got:\n" + e.getMessage());
}
}
assertPermanentCount(playerA, "Worldheart Phoenix", 0);
}
@Test
@ -65,20 +73,22 @@ public class PlayFromNonHandZoneTest extends CardTestPlayerBaseWithAIHelps {
execute();
assertPermanentCount(playerA, "Worldheart Phoenix", 1);
}
@Test
public void testNarsetEnlightenedMaster() {
// First strike
// Hexproof
// Whenever Narset, Enlightented Master attacks, exile the top four cards of your library. Until end of turn, you may cast noncreature cards exiled with Narset this turn without paying their mana costs.
// Whenever Narset, Enlightented Master attacks, exile the top four cards of your library.
// Until end of turn, you may cast noncreature cards exiled with Narset this turn without paying their mana costs.
addCard(Zone.BATTLEFIELD, playerB, "Narset, Enlightened Master", 1);
skipInitShuffling();
addCard(Zone.LIBRARY, playerB, "Silvercoat Lion");
addCard(Zone.LIBRARY, playerB, "Abzan Banner");
// Ferocious - If you control a creature with power 4 or greater, you may cast Dragon Grip as though it had flash. (You may cast it any time you could cast an instant.)
// Ferocious - If you control a creature with power 4 or greater,
// you may cast Dragon Grip as though it had flash.
// (You may cast it any time you could cast an instant.)
// Enchant creature
// Enchanted creature gets +2/+0 and has first strike.
addCard(Zone.LIBRARY, playerB, "Dragon Grip");
@ -88,28 +98,31 @@ public class PlayFromNonHandZoneTest extends CardTestPlayerBaseWithAIHelps {
attack(2, playerB, "Narset, Enlightened Master");
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Silvercoat Lion"); // can't be cast from exile
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Abzan Banner"); // can be cast from exile
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Dragon Grip", "Narset, Enlightened Master"); // can be cast from exile
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Peach Garden Oath"); // can be cast from exile
// Can NOT cast from exile
checkPlayableAbility("Can't cast Silvercoat", 2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Cast Silvercoat", false);
// CAN cast from exile
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Abzan Banner");
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Dragon Grip", "Narset, Enlightened Master");
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Peach Garden Oath");
setStopAt(2, PhaseStep.END_TURN);
execute();
assertExileCount("Silvercoat Lion", 1);
assertPermanentCount(playerB, "Abzan Banner", 1);
assertPermanentCount(playerB, "Dragon Grip", 1);
assertGraveyardCount(playerB, "Peach Garden Oath", 1);
assertExileCount(playerB, "Dragon Grip", 0);
assertGraveyardCount(playerB, "Dragon Grip", 0);
assertExileCount(playerB, "Silvercoat Lion", 1);
assertExileCount(playerB, "Dragon Grip", 0);
assertPowerToughness(playerB, "Narset, Enlightened Master", 5, 2);
assertHandCount(playerB, "Plains", 1);
assertLife(playerA, 17);
assertLife(playerB, 22);
assertPermanentCount(playerB, "Dragon Grip", 1);
}
@Test

View file

@ -38,7 +38,6 @@ public class LegendarySorceryTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Akroma, Angel of Wrath", 1);
assertPermanentCount(playerB, "Akroma, Angel of Wrath", 1);
}
@Test
@ -53,13 +52,12 @@ public class LegendarySorceryTest extends CardTestPlayerBase {
// Flying, first strike, vigilance, trample, haste, protection from black and from red
addCard(Zone.BATTLEFIELD, playerB, "Akroma, Angel of Wrath", 1); // Legendary
// can't cast cause you don't have a legendary creature (only opponent have)
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Urza's Ruinous Blast");
// Can't cast cause you don't have a legendary creature (only opponent have)
checkPlayableAbility("Can't cast Legendary Sorcery", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Urza's", false);
//setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
//assertAllCommandsUsed();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Urza's Ruinous Blast", 0);
@ -116,6 +114,5 @@ public class LegendarySorceryTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Akroma, Angel of Wrath", 1);
assertPermanentCount(playerB, "Akroma, Angel of Wrath", 1);
}
}

View file

@ -43,13 +43,15 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Abzan Banner");
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tin Street Hooligan");
addTarget(playerA, "Abzan Banner");
// {G} was not spent, so no target is chosen
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Tin Street Hooligan", 1);
assertPermanentCount(playerB, "Abzan Banner", 1);
}
@Test

View file

@ -57,7 +57,7 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB);
setChoice(playerA, "X=3");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Courser of Kruphix");
setChoice(playerA, "Yes"); // Courser of Kruphix is the only option, say Yes to cast for free
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -89,12 +89,14 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
addCard(Zone.LIBRARY, playerB, "Secret Plans");
skipInitShuffling(); // to keep this card on top of library
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Master of Pearls");
setChoice(playerA, true); // cast it face down as 2/2 creature
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB);
setChoice(playerA, "X=3");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Secret Plans");
setChoice(playerA, "Yes"); // Cast Secret Plan without paying Only one possible target (Secret Plan)
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -132,7 +134,7 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB);
setChoice(playerA, "X=3");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sylvan Library");
setChoice(playerA, "Yes"); // Sylvan Library is the only option, say Yes to cast for free
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
execute();
@ -146,16 +148,15 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
assertHandCount(playerA, 3);
assertLife(playerA, 12);
assertLife(playerB, 20);
}
/**
* I cast a Villainous Wealth in Vintage Cube, and when it came time to cast
* my opponent's cards (Mox Sapphire, Mox Emerald, Brainstorm, Snapcaster
* Mage, Fact or Fiction and a Quicken), it rolled back to before I had cast
* my spell after Quicken resolved. I have the error, but the forums won't
* let me post them. I did find it was replicatable whenever you try to cast
* Quicken off a Villainous Wealth.
* my spell after Quicken resolved.
* I have the error, but the forums won't let me post them.
* I did find it was replicatable whenever you try to cast Quicken off a Villainous Wealth.
*/
@Test
public void testVillainousWealthAndQuicken() {
@ -178,11 +179,19 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
addCard(Zone.LIBRARY, playerB, "Mox Sapphire");
skipInitShuffling(); // to keep this card on top of library
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB);
setChoice(playerA, "X=3");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mox Emerald");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Quicken");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mox Sapphire");
setChoice(playerA, "Mox Emerald");
setChoice(playerA, "Yes");
setChoice(playerA, "Mox Sapphire");
setChoice(playerA, "Yes");
// Quicken is auto-chosen since it's the last of the 3 cards. Only need to say Yes to casting for free.
setChoice(playerA, "Yes");
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
@ -192,6 +201,5 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
assertPermanentCount(playerA, "Mox Emerald", 1);
assertPermanentCount(playerA, "Mox Sapphire", 1);
assertGraveyardCount(playerB, "Quicken", 1);
}
}

View file

@ -14,13 +14,13 @@ public class FlameshadowConjuringTest extends CardTestPlayerBase {
/**
* My opponent ran into an issue with Priest of the Blood Rite being copied
* with Flameshadow Conjuring. Their copy was made and removed correctly at
* the end of the turn, but the "lose two life a turn" trigger still
* happened twice.
* with Flameshadow Conjuring.
* Their copy was made and removed correctly at the end of the turn,
* but the "lose two life a turn" trigger still happened twice.
*
* TODO: Seems like there are too much triggered abilities in
* TriggeredAbilities as the TriggeredAbilities get removed from
* PlayerImpl.removeFromBattlefield()
* TriggeredAbilities as the TriggeredAbilities get removed from
* PlayerImpl.removeFromBattlefield()
*/
@Test
public void testCopyAndItsEffectsRemoved() {
@ -33,7 +33,6 @@ public class FlameshadowConjuringTest extends CardTestPlayerBase {
// When Priest of the Blood Rite enters the battlefield, put a 5/5 black Demon creature token with flying onto the battlefield.
// At the beginning of your upkeep, you lose 2 life.
addCard(Zone.HAND, playerA, "Priest of the Blood Rite", 1); // {3}{B}{B}
setChoice(playerB, true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Priest of the Blood Rite");
setStopAt(3, PhaseStep.UPKEEP);
@ -47,8 +46,8 @@ public class FlameshadowConjuringTest extends CardTestPlayerBase {
}
/**
* I created a token copy of Wurmcoil Engine and sacrificed it. This gave me
* 4 tokens
* I created a token copy of Wurmcoil Engine and sacrificed it.
* This gave me 4 tokens.
*/
@Test
public void testWurmcoilEngine() {
@ -80,7 +79,5 @@ public class FlameshadowConjuringTest extends CardTestPlayerBase {
assertLife(playerA, 26);
assertPermanentCount(playerA, "Phyrexian Wurm Token", 2);
}
}

View file

@ -6,6 +6,15 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.m.MimicVat Mimic Vat}
* {3}
* Artifact
* Imprint Whenever a nontoken creature dies, you may exile that card.
* If you do, return each other card exiled with Mimic Vat to its owners graveyard.
* {3}, {T}: Create a token thats a copy of a card exiled with Mimic Vat.
* It gains haste.
* Exile it at the beginning of the next end step.
*
* @author LevelX2
*/
public class MimicVatTest extends CardTestPlayerBase {
@ -22,8 +31,6 @@ public class MimicVatTest extends CardTestPlayerBase {
@Test
public void TestClone() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
// Imprint - Whenever a nontoken creature dies, you may exile that card. If you do, return each other card exiled with Mimic Vat to its owner's graveyard.
// {3}, {T}: Create a token that's a copy of the exiled card. It gains haste. Exile it at the beginning of the next end step.
addCard(Zone.BATTLEFIELD, playerA, "Mimic Vat", 1); // Artifact {3}
// {2}, {T}, Sacrifice a creature: Draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Phyrexian Vault", 1);
@ -62,8 +69,6 @@ public class MimicVatTest extends CardTestPlayerBase {
@Test
public void TestPhyrexianMetamorph() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
// Imprint - Whenever a nontoken creature dies, you may exile that card. If you do, return each other card exiled with Mimic Vat to its owner's graveyard.
// {3}, {T}: Create a token that's a copy of a card exiled with Mimic Vat. It gains haste. Exile it at the beginning of the next end step.
addCard(Zone.BATTLEFIELD, playerA, "Mimic Vat", 1); // Artifact {3}
// {2}, {T}, Sacrifice a creature: Draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Phyrexian Vault", 1);
@ -76,6 +81,7 @@ public class MimicVatTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phyrexian Metamorph");
setChoice(playerA, true);
setChoice(playerA, "Silvercoat Lion");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Sacrifice a creature");
setChoice(playerA, true);
@ -87,9 +93,8 @@ public class MimicVatTest extends CardTestPlayerBase {
execute();
assertExileCount("Phyrexian Metamorph", 1);
assertPermanentCount(playerB, "Silvercoat Lion", 1);
assertPermanentCount(playerA, "Silvercoat Lion", 1);
assertPermanentCount(playerB, "Silvercoat Lion", 1);
}
/**
@ -100,30 +105,26 @@ public class MimicVatTest extends CardTestPlayerBase {
*/
@Test
public void TestExileFails() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
// Imprint - Whenever a nontoken creature dies, you may exile that card. If you do, return each other card exiled with Mimic Vat to its owner's graveyard.
// {3}, {T}: Create a token that's a copy of a card exiled with Mimic Vat. It gains haste. Exile it at the beginning of the next end step.
addCard(Zone.BATTLEFIELD, playerA, "Mimic Vat", 1); // Artifact {3}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.BATTLEFIELD, playerA, "Mimic Vat", 1);
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
// Exile up to four target cards from a single graveyard.
// Transmute {1}{B}{B}
addCard(Zone.HAND, playerB, "Shred Memory", 1); // Instant {1}{B}
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Silvercoat Lion");
setChoice(playerA, true);
setChoice(playerA, "Silvercoat Lion");
setChoice(playerA, "Yes");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Shred Memory", "Silvercoat Lion", "Whenever a nontoken creature dies");
setChoice(playerA, true);
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}, {T}: Create a token that's a copy of a card exiled with ");
setChoice(playerA, true);
setChoice(playerA, "Silvercoat Lion");
setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute();
@ -133,6 +134,5 @@ public class MimicVatTest extends CardTestPlayerBase {
assertExileCount(playerB, "Silvercoat Lion", 1);
assertPermanentCount(playerA, "Silvercoat Lion", 0);
}
}

View file

@ -8,28 +8,29 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.r.ReversalOfFortune Reversal of Fortune}
* {4}{R}{R}
* Sorcery
* Target opponent reveals their hand.
* You may copy an instant or sorcery card in it.
* If you do, you may cast the copy without paying its mana cost.
*
* @author BetaSteward
*/
public class ReversalOfFortuneTest extends CardTestPlayerBase {
/**
* Reversal of Fortune
* Sorcery, 4RR (6)
* Target opponent reveals their hand. You may copy an instant or sorcery
* card in it. If you do, you may cast the copy without paying its mana cost.
*
*/
@Test
public void testCopyCard() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
addCard(Zone.HAND, playerA, "Reversal of Fortune");
addCard(Zone.HAND, playerB, "Lightning Bolt");
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reversal of Fortune", playerB);
setChoice(playerA, "Lightning Bolt"); // select to copy
setChoice(playerA, true); // cast copy
addTarget(playerA, playerB);
setStopAt(1, PhaseStep.END_TURN);
execute();
@ -38,19 +39,19 @@ public class ReversalOfFortuneTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Lightning Bolt", 0);
assertGraveyardCount(playerB, "Lightning Bolt", 0);
assertLife(playerB, 17);
}
@Test
public void testCopyCardButDontCast() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
addCard(Zone.HAND, playerA, "Reversal of Fortune");
addCard(Zone.HAND, playerB, "Lightning Bolt");
// setStrictChooseMode(true);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reversal of Fortune", playerB);
addTarget(playerA, "Lightning Bolt");
setChoice(playerA, "Lightning Bolt");
setChoice(playerA, false);
setStopAt(1, PhaseStep.END_TURN);
@ -60,7 +61,5 @@ public class ReversalOfFortuneTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Lightning Bolt", 0);
assertGraveyardCount(playerB, "Lightning Bolt", 0);
assertLife(playerB, 20);
}
}

View file

@ -16,7 +16,6 @@ public class SewerNemesisTest extends CardTestPlayerBase {
/**
* BUG: Sewer Nemesis count's all cards in each player's graveyard to determine it's * / *, not just the chosen player's graveyard.
*
*/
@Test
public void test1() {
@ -32,14 +31,11 @@ public class SewerNemesisTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sewer Nemesis");
setChoice(playerA, "PlayerA"); // Starting player
setChoice(playerA, "PlayerA");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA,"Sewer Nemesis", 0);
assertPowerToughness(playerA, "Sewer Nemesis", 4, 4);
}
}

View file

@ -7,6 +7,12 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.b.BreathOfFury Breath of Fury}
* {2}{R}{R}
* Enchantment Aura
* Enchant creature you control
* When enchanted creature deals combat damage to a player, sacrifice it and attach Breath of Fury to a creature you control.
* If you do, untap all creatures you control and after this phase, there is an additional combat phase.
*
* @author LevelX2
*/
@ -14,22 +20,20 @@ public class BreathOfFuryTest extends CardTestPlayerBase {
@Test
public void testMoveEnchantment() {
// Enchant creature you control
// When enchanted creature deals combat damage to a player, sacrifice it and attach Breath of Fury to a creature you control.
// If you do, untap all creatures you control and after this phase, there is an additional combat phase.
addCard(Zone.HAND, playerA, "Breath of Fury", 1); // Enchantment - Aura {2}{R}{R}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox");
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Breath of Fury", "Silvercoat Lion");
attack(3, playerA, "Pillarfield Ox");
attack(3, playerA, "Silvercoat Lion");
attack(3, playerA, "Pillarfield Ox");
addTarget(playerA, "Pillarfield Ox");
setChoice(playerA, "Pillarfield Ox");
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
execute();
@ -40,7 +44,5 @@ public class BreathOfFuryTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Silvercoat Lion", 1);
assertTappedCount("Pillarfield Ox", false, 1);
assertPermanentCount(playerA, "Breath of Fury", 1);
}
}

View file

@ -43,7 +43,6 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
assertLife(playerA, 20);
assertLife(playerB, 17);
}
/**
@ -165,12 +164,12 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, bear1, 1);
addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear1); // do not have any mana
checkPlayableAbility("can't cast bear", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast" + bear1G, false);
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
Assert.assertEquals(0, playerA.getManaPool().getMana().count());
assertPermanentCount(playerA, bear1, 0);
}
@Test
@ -178,12 +177,10 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, bear1, 1);
addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear1); // do not have any mana
checkPlayableAbility("can't cast bear", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast" + bear1G, false);
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
Assert.assertEquals(0, playerA.getManaPool().getMana().count());
assertPermanentCount(playerA, bear1, 0);
}
@Test
@ -205,11 +202,10 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, bear1G, 1);
addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear1G); // have only {W} mana, can't cast
checkPlayableAbility("can't cast bear", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast" + bear1G, false);
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
assertPermanentCount(playerA, bear1G, 0);
}
@Test

View file

@ -4,6 +4,7 @@ package org.mage.test.cards.rules;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@ -11,17 +12,13 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*
* @author LevelX2
*/
/**
* with Melira, Sylvok Outcast on the table and Devoted Druid you can activated
* his untap ability for infinity mana. This shouldn't work like this as its an
* unpayable cost " 601.2g. The player pays the total cost in any order. Partial
* payments are not allowed. Unpayable costs cant be paid"
*/
public class MeliraSylvokOutcastTest extends CardTestPlayerBase {
public class MeliraSylvokOutcastTest extends CardTestPlayerBase {
/**
* Test that the target of Vines of Vastwood can't be the target of spells
* or abilities your opponents control this turn
* with Melira, Sylvok Outcast on the table and Devoted Druid you can activated
* his untap ability for infinity mana. This shouldn't work like this as its an
* unpayable cost " 601.2g. The player pays the total cost in any order. Partial
* payments are not allowed. Unpayable costs cant be paid"
*/
@Test
public void testUnpayableCost() {
@ -37,11 +34,20 @@ public class MeliraSylvokOutcastTest extends CardTestPlayerBase {
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Put a -1/-1 counter on ");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
// TODO: Needed since Melira's ability isn't been caught by the is playable check
try {
execute();
assertAllCommandsUsed();
Assert.fail("must throw exception on execute");
} catch (Throwable e) {
if (!e.getMessage().contains("Player PlayerA must have 0 actions but found 1")) {
Assert.fail("Needed error about not being able to use the Devoted Druid's -1/-1 ability, but got:\n" + e.getMessage());
}
}
assertPowerToughness(playerA, "Devoted Druid", 0, 2);
assertCounterCount("Devoted Druid", CounterType.M1M1, 0);
assertTapped("Devoted Druid", true); // Because untapping can't be paid
}
}

View file

@ -58,8 +58,7 @@ public class NewPerspectivesTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, flameJet);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, newPerspectives);
activateAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "Cycling");
setChoice(playerA, true);
checkPlayableAbility("Can't cycle", 1, PhaseStep.BEGIN_COMBAT, playerA, "Cycling", false);
setStopAt(1, PhaseStep.END_COMBAT);
execute();

View file

@ -6,8 +6,15 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* also tests regenerate and tests that permanents with protection can be
* sacrificed
* {@link mage.cards.f.FiendOfTheShadows Fiend of the Shadows}
* {3}{B}{B}
* Creature Vampire Wizard
* Flying
* Whenever Fiend of the Shadows deals combat damage to a player, that player exiles a card from their hand. You may play that card for as long as it remains exiled.
* Sacrifice a Human: Regenerate Fiend of the Shadows.
* 3/3
*
* Also tests regenerate and tests that permanents with protection can be sacrificed
*
* @author BetaSteward
*/
@ -16,14 +23,15 @@ public class FiendOfTheShadowsTest extends CardTestPlayerBase {
@Test
public void testCard() {
addCard(Zone.BATTLEFIELD, playerA, "White Knight");
// Whenever Fiend of the Shadows deals combat damage to a player, that player exiles a card from their hand. You may play that card for as long as it remains exiled.
// Sacrifice a Human: Regenerate Fiend of the Shadows.
addCard(Zone.BATTLEFIELD, playerA, "Fiend of the Shadows");
addCard(Zone.BATTLEFIELD, playerB, "Mountain");
addCard(Zone.HAND, playerB, "Lightning Bolt");
setStrictChooseMode(true);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice a Human: Regenerate {this}.");
addTarget(playerA, "White Knight");
setChoice(playerA, "White Knight");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", "Fiend of the Shadows");
setStopAt(1, PhaseStep.END_TURN);
@ -38,8 +46,6 @@ public class FiendOfTheShadowsTest extends CardTestPlayerBase {
@Test
public void testCardExile1() {
// Whenever Fiend of the Shadows deals combat damage to a player, that player exiles a card from their hand. You may play that card for as long as it remains exiled.
// Sacrifice a Human: Regenerate Fiend of the Shadows.
addCard(Zone.BATTLEFIELD, playerA, "Fiend of the Shadows");
removeAllCardsFromHand(playerB);
addCard(Zone.HAND, playerB, "Swamp");
@ -80,5 +86,4 @@ public class FiendOfTheShadowsTest extends CardTestPlayerBase {
assertHandCount(playerB, 0);
assertGraveyardCount(playerB, "Lightning Bolt", 1);
}
}

View file

@ -6,13 +6,22 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.h.HavengulLich Havengul Lich}
* {3}{U}{B}
* Creature Zombie Wizard
* {1}: You may cast target creature card in a graveyard this turn.
* When you cast it this turn, Havengul Lich gains all activated abilities of that card until end of turn.
* 4/4
*
* @author BetaSteward
*/
public class HavengulLichTest extends CardTestPlayerBase {
/**
* Check that the ability works as intented.
*/
@Test
public void testCard() {
public void testWorksOnTurn() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.BATTLEFIELD, playerA, "Havengul Lich");
addCard(Zone.GRAVEYARD, playerA, "Prodigal Pyromancer");
@ -32,46 +41,46 @@ public class HavengulLichTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, 0);
}
/**
* Check that the ability only allows you to play the chosen card on the curent turn.
*/
@Test
public void testCard1() {
public void testDoesNotWorkNextTurn() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
addCard(Zone.BATTLEFIELD, playerA, "Havengul Lich");
addCard(Zone.GRAVEYARD, playerA, "Black Cat");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", "Black Cat");
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Black Cat");
checkPlayableAbility("Can't work this turn", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Black", false);
setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Havengul Lich", 1);
assertPermanentCount(playerA, "Black Cat", 0);
assertGraveyardCount(playerA, 1);
}
/**
* Check that Havengul Lich only keeps the abilities for current turn.
*/
@Test
public void testCard2() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
// {1}: You may cast target creature card in a graveyard this turn. When you cast that card this turn, Havengul Lich
// gains all activated abilities of that card until end of turn.
addCard(Zone.BATTLEFIELD, playerA, "Havengul Lich");
// {T}: Prodigal Pyromancer deals 1 damage to any target.
addCard(Zone.GRAVEYARD, playerA, "Prodigal Pyromancer");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}: You may", "Prodigal Pyromancer");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Prodigal Pyromancer");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", playerB);
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", playerB); // only inm turn 1, so Havengul Lich has the abilit ylost now
// Havengul Lich must lose the ability to tap (Prodigal Pyromancer still has summoning sickness)
checkPlayableAbility("Can't tap", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this}", false);
setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 19);
assertPermanentCount(playerA, "Havengul Lich", 1);
assertPermanentCount(playerA, "Prodigal Pyromancer", 1);
assertTapped("Prodigal Pyromancer", true);
assertTapped("Havengul Lich", false);
assertGraveyardCount(playerA, 0);
}
@ -110,7 +119,5 @@ public class HavengulLichTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Havengul Lich", 1);
assertGraveyardCount(playerA, "Perilous Myr", 1);
}
}

View file

@ -7,6 +7,13 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.c.CodespellCleric Codespell Cleric}
* {W}
* Creature Human Cleric
* P/T 1/1
* Vigilance
* When Codespell Cleric enters the battlefield, if it was the second spell you cast this turn, put a +1/+1 counter on target creature.
*
* @author TheElk801
*/
public class CodespellClericTest extends CardTestPlayerBase {
@ -14,6 +21,9 @@ public class CodespellClericTest extends CardTestPlayerBase {
private static final String cleric = "Codespell Cleric";
private static final String relic = "Darksteel Relic";
/**
* No +1/+1 since its the first spell.
*/
@Test
public void testFirstSpell() {
addCard(Zone.BATTLEFIELD, playerA, "Plains");
@ -27,6 +37,9 @@ public class CodespellClericTest extends CardTestPlayerBase {
assertCounterCount(playerA, cleric, CounterType.P1P1, 0);
}
/**
* Put a +1/+1 since it's the second spell.
*/
@Test
public void testSecondSpell() {
addCard(Zone.BATTLEFIELD, playerA, "Plains");
@ -42,6 +55,9 @@ public class CodespellClericTest extends CardTestPlayerBase {
assertCounterCount(playerA, cleric, CounterType.P1P1, 1);
}
/**
* No +1/+1 since its the third spell.
*/
@Test
public void testThirdSpell() {
addCard(Zone.BATTLEFIELD, playerA, "Plains");
@ -50,7 +66,7 @@ public class CodespellClericTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, relic);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, relic);
addTarget(playerA, cleric);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, cleric);
setStopAt(1, PhaseStep.END_TURN);

View file

@ -6,6 +6,15 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.f.FrostpyreArcanist Frostpyre Arcanist}
* {4}{U}
* Creature Giant Wizard
* This spell costs {1} less to cast if you control a Giant or a Wizard.
* When Frostpyre Arcanist enters the battlefield,
* search your library for an instant or sorcery card with the same name as a card in your graveyard,
* reveal it, put it into your hand, then shuffle.
* 2/5
*
* @author TheElk801
*/
public class FrostpyreArcanistTest extends CardTestPlayerBase {
@ -20,10 +29,11 @@ public class FrostpyreArcanistTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, bolt);
addCard(Zone.HAND, playerA, arcanist);
addTarget(playerA, bolt);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcanist);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcanist);
addTarget(playerA, bolt);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
@ -38,8 +48,8 @@ public class FrostpyreArcanistTest extends CardTestPlayerBase {
addCard(Zone.LIBRARY, playerA, bolt);
addCard(Zone.HAND, playerA, arcanist);
addTarget(playerA, bolt);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcanist);
// Let the choice be made automatically since there is no sorcery or instant card in the graveyard.
setStopAt(1, PhaseStep.END_TURN);
execute();

View file

@ -11,10 +11,13 @@ public class FinalPunishmentTest extends CardTestPlayerBase {
final String shock = "Shock";
final String bob = "Dark Confidant";
/**
* Ensure it works for damage from spells.
*/
@Test
public void lifelossBecauseOfDirectDamage() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.HAND, playerA, finalPunishment);
addCard(Zone.HAND, playerA, shock);
@ -24,10 +27,11 @@ public class FinalPunishmentTest extends CardTestPlayerBase {
execute();
assertLife(playerB, 16);
}
/**
* Ensure it works for damage from combat.
*/
@Test
public void lifelossBecauseOfCombat() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
@ -40,21 +44,23 @@ public class FinalPunishmentTest extends CardTestPlayerBase {
execute();
assertLife(playerB, 16);
}
/**
* Ensure it does not count damage that occured in the previous turns.
*/
@Test
public void nolifelossInNextTurn() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.HAND, playerA, finalPunishment);
addCard(Zone.BATTLEFIELD, playerA, bob);
addCard(Zone.HAND, playerA, shock);
attack(1, playerA, bob, playerB);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, finalPunishment, playerB);
setStopAt(2, PhaseStep.END_TURN);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, shock, playerB);
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, finalPunishment, playerB);
setStopAt(3, PhaseStep.END_TURN);
execute();
assertLife(playerB, 18);
}
}

View file

@ -2,35 +2,41 @@ package org.mage.test.cards.single.soi;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* Lambholt Pacifist {1}{G}
* 3/3
* Creature Human Shaman Werewolf
* Lambholt Pacifist cant attack unless you control a creature with power 4 or greater.
* At the beginning of each upkeep, if no spells were cast last turn, transform Lambholt Pacifist.
*
* @author escplan9
*/
public class LambholtPacifistTest extends CardTestPlayerBase {
/*
Lambholt Pacifist {1}{G}
Creature - Human Shaman Werewolf 3/3
Lambholt Pacifist can't attack unless you control a creature with power 4 or greater.
At the beginning of each upkeep, if no spells were cast last turn, transform Lambholt Pacifist.
*/
private final String lambholt = "Lambholt Pacifist";
/**
* An uncrewed vehicle does not count as a creature.
*/
@Test
public void uncrewedVehicle_LambholtCannotAttack() {
/*
Heart of Kiran {2}
Legendary Artifact - Vehicle
Flying, vigilance
Crew 3 (Tap any number of creatures you control with total power 3 or more: This Vehicle becomes an artifact creature until end of turn.)
You may remove a loyalty counter from a planeswalker you control rather than pay Heart of Kiran's crew cost.
*/
Heart of Kiran {2}
4/4
Legendary Artifact - Vehicle
Flying, vigilance
Crew 3 (Tap any number of creatures you control with total power 3 or more:
This Vehicle becomes an artifact creature until end of turn.)
You may remove a loyalty counter from a planeswalker you control rather than pay Heart of Kiran's crew cost.
*/
String heartKiran = "Heart of Kiran";
String orni = "Ornithopter"; // {0} 0/2 flyer - just needs something to cast to prevent lambholt transforming
// Just needs something to cast to prevent lambholt transforming
String orni = "Ornithopter"; // {0} 0/2 flyer
addCard(Zone.HAND, playerA, lambholt);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
@ -43,7 +49,15 @@ public class LambholtPacifistTest extends CardTestPlayerBase {
attack(3, playerA, lambholt);
setStopAt(3, PhaseStep.END_COMBAT);
execute();
try {
execute();
assertAllCommandsUsed();
} catch (Throwable e) {
if (!e.getMessage().contains("Player PlayerA must have 0 actions but found 1")) {
Assert.fail("Should have had error about not being able to attack, but got:\n" + e.getMessage());
}
}
assertPermanentCount(playerB, orni, 1);
assertTapped(lambholt, false);

View file

@ -6,27 +6,25 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* Flailing Drake
* {3}{G}
* Creature Drake
* Flying
* Whenever Flailing Drake blocks or becomes blocked by a creature, that creature gets +1/+1 until end of turn.
* 2/3
*
* @author anonymous
*
* Whenever Flailing Drake blocks or becomes blocked by a creature, that
* creature gets +1/+1 until end of turn.
*/
public class FlailingDrakeTest extends CardTestPlayerBase {
@Test
public void testIncreaseBlocker() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
// Flying
// Whenever Flailing Drake blocks or becomes blocked by a creature, that creature gets +1/+1 until end of turn.
addCard(Zone.BATTLEFIELD, playerA, "Flailing Drake", 1); // Creature {3}{G} 2/3
addCard(Zone.BATTLEFIELD, playerB, "Island", 4);
addCard(Zone.BATTLEFIELD, playerB, "Snapping Drake", 1); // Creature {3}{U} 3/2
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flailing Drake");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Snapping Drake");
attack(3, playerA, "Flailing Drake");
block(3, playerB, "Snapping Drake", "Flailing Drake");
@ -46,9 +44,6 @@ public class FlailingDrakeTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Island", 4);
addCard(Zone.BATTLEFIELD, playerB, "Snapping Drake", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flailing Drake");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Snapping Drake");
attack(4, playerB, "Snapping Drake");
block(4, playerA, "Flailing Drake", "Snapping Drake");
@ -59,5 +54,4 @@ public class FlailingDrakeTest extends CardTestPlayerBase {
//Snapping Drake 4/3
assertPowerToughness(playerB, "Snapping Drake", 4, 3);
}
}

View file

@ -6,11 +6,20 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* Cobra Trap
* {4}{G}{G}
* Instant Trap
* If a noncreature permanent under your control was destroyed this turn by a spell or ability an opponent controlled,
* you may pay {G} rather than pay this spells mana cost.
* Create four 1/1 green Snake creature tokens.
*
* @author BetaSteward
*/
public class CobraTrapTest extends CardTestPlayerBase {
/**
* Cast using the alternative cost.
*/
@Test
public void testCard() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
@ -30,6 +39,9 @@ public class CobraTrapTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Snake Token", 4);
}
/**
* Check that the alternative cost can't be paid if the condition isn't met.
*/
@Test
public void testCardNegative() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
@ -37,13 +49,11 @@ public class CobraTrapTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3);
addCard(Zone.HAND, playerB, "Stone Rain");
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cobra Trap");
checkPlayableAbility("Not enough mana", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cast Cobra", false);
setStopAt(2, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Forest", 2);
assertPermanentCount(playerA, "Snake Token", 0);
}

View file

@ -39,6 +39,8 @@ public class GripOfChaosTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Felidar Guardian");
setChoice(playerA, "When "); // Select order of Felidar trigger
@ -53,7 +55,6 @@ public class GripOfChaosTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.BEGIN_COMBAT);
setStrictChooseMode(true);
execute();
assertPermanentCount(playerA, "Felidar Guardian", 1);

View file

@ -7,18 +7,16 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* Obstinate Baloth {2}{G}{G}
* Creature - Beast
* When Obstinate Baloth enters the battlefield, you gain 4 life.
* If a spell or ability an opponent controls causes you to discard Obstinate Baloth,
* put it onto the battlefield instead of putting it into your graveyard.
*
* @author LevelX2
*/
public class ObstinateBalothTest extends CardTestPlayerBase {
/**
* Obstinate Baloth {2}{G}{G}
* Creature - Beast
* When Obstinate Baloth enters the battlefield, you gain 4 life.
* If a spell or ability an opponent controls causes you to discard Obstinate Baloth, put it onto the battlefield instead of putting it into your graveyard.
*
*/
@Test
public void TestLifeGainIfForcedToDiscard() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
@ -28,7 +26,7 @@ public class ObstinateBalothTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Obstinate Baloth");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raven's Crime", playerB);
setChoice(playerB, "Obstinate Baloth");
// Let choice be autopicked since there is only one option
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -40,11 +38,10 @@ public class ObstinateBalothTest extends CardTestPlayerBase {
assertLife(playerB, 24); // + 4 from Obstinate Baloth entering the battlefield
}
/*
Obstinate Baloth enters the battlefield and will also be sacrificed during the
resolution of Smallpox. So it's triggered ability goes to the stack as the
Obstinate Baloth has already left the battlefield again.
So EntersBattlefieldTriggeredAbility has to work in all zones as a consequence.
/**
* Obstinate Baloth enters the battlefield and will also be sacrificed during the resolution of Smallpox.
* So it's triggered ability goes to the stack as the Obstinate Baloth has already left the battlefield again.
* So EntersBattlefieldTriggeredAbility has to work in all zones as a consequence.
*/
@Test
public void TestWithSmallpox() {
@ -54,9 +51,16 @@ public class ObstinateBalothTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Obstinate Baloth");
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Smallpox");
setChoice(playerB, "Obstinate Baloth"); // comes into play after directly after discard
setChoice(playerB, "Obstinate Baloth"); // and can and has to be sacrificed here
// playerB - Discard a card - Its ability will send it to the battlefield instead of the graveyard
addTarget(playerB, "Obstinate Baloth");
// playerB - Sacrifice a creature
setChoice(playerB, "Obstinate Baloth");
// playerA - Sacrifice a land
setChoice(playerA, "Swamp");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();

View file

@ -7,6 +7,11 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.c.CrawlingSensation Crawling Sensation}
* {2}{G}
* Enchantment
* At the beginning of your upkeep, you may mill two cards.
* Whenever one or more land cards are put into your graveyard from anywhere for the first time each turn, create a 1/1 green Insect creature token.
*
* @author LevelX2
*/
@ -14,18 +19,18 @@ public class OneOrMoreCardsGoToGraveyardTest extends CardTestPlayerBase {
@Test
public void TestCrawlingSensation() {
// At the beginning of your upkeep, you may put the top two cards of your library into your graveyard.
// Whenever one or more land cards are put into your graveyard from anywhere for the first time each turn, put a 1/1 green Insect creature token onto the battlefield.
addCard(Zone.BATTLEFIELD, playerA, "Crawling Sensation");
addCard(Zone.LIBRARY, playerA, "Mountain");
// {T}, Sacrifice Evolving Wilds: Search your library for a basic land card and put it onto the battlefield tapped. Then shuffle your library.
addCard(Zone.HAND, playerA, "Evolving Wilds");
setStrictChooseMode(true);
setChoice(playerA, true);
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Evolving Wilds");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Sacrifice");
setChoice(playerA, "Mountain");
addTarget(playerA, "Mountain");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
@ -33,6 +38,5 @@ public class OneOrMoreCardsGoToGraveyardTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Evolving Wilds", 1);
assertPermanentCount(playerA, "Mountain", 1);
assertPermanentCount(playerA, "Insect Token", 2);
}
}

View file

@ -49,9 +49,10 @@ public class EndStepTriggerTest extends CardTestPlayerBase {
* Hey, I don't know how to submit bugs but in a game I played today I
* sacrificed Child of Alara by casting Bound at the end step of my previous
* opponent's turn, then chose Child as one of the cards to return to my
* hand. My graveyard was empty so that was the only card I chose. Child
* returned to my hand but it did NOT trigger for some reason. Nothing was
* destroyed
* hand.
* My graveyard was empty so that was the only card I chose.
* Child returned to my hand but it did NOT trigger for some reason.
* Nothing was destroyed.
*/
@Test
public void testSacrificeChildOfAlara() {
@ -64,15 +65,19 @@ public class EndStepTriggerTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
addCard(Zone.BATTLEFIELD, playerB, "Forest", 4);
// Bound
// Sacrifice a creature. Return up to X cards from your graveyard to your hand, where X is the number of colors that creature was. Exile this card.
// Sacrifice a creature.
// Return up to X cards from your graveyard to your hand, where X is the number of colors that creature was.
// Exile this card.
// Determined
// Other spells you control can't be countered this turn.
// Draw a card.
// Other spells you control can't be countered this turn.
// Draw a card.
addCard(Zone.HAND, playerB, "Bound // Determined"); // Instant {3}{B}{G} // {G}{U}
setStrictChooseMode(true);
castSpell(1, PhaseStep.END_TURN, playerB, "Bound");
addTarget(playerB, "Child of Alara");
setChoice(playerB, "Child of Alara");
addTarget(playerB, "Child of Alara");
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
execute();

View file

@ -6,19 +6,20 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.k.KaradorGhostChieftain Karador, Ghost Chieftain}
* {5}{W}{B}{G}
* Legendary Creature Centaur Spirit
* This spell costs {1} less to cast for each creature card in your graveyard.
* During each of your turns, you may cast a creature spell from your graveyard.
* 3/4
*
* @author BetaSteward
*/
public class KaradorGhostChieftainTest extends CardTestPlayerBase {
/*
* Karador, Ghost Chieftain
* Legendary Creature Centaur Spirit 3/4, 5WBG (8)
* Karador, Ghost Chieftain costs {1} less to cast for each creature card in your graveyard.
* During each of your turns, you may cast one creature card from your graveyard.
*
*/
// test that can play spell from graveyard
/**
* Test that you can cast a spell from the graveyard.
*/
@Test
public void testPlayFromGraveyard() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
@ -30,12 +31,13 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
this.assertPermanentCount(playerA, "Raging Goblin", 1);
this.assertGraveyardCount(playerA, "Raging Goblin", 0);
assertPermanentCount(playerA, "Raging Goblin", 1);
assertGraveyardCount(playerA, "Raging Goblin", 0);
}
// test that can only play one spell from graveyard
/**
* Test that you can cast from your graveyard.
*/
@Test
public void testPlayOneFromGraveyard() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
@ -48,12 +50,13 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
this.assertPermanentCount(playerA, "Raging Goblin", 1);
this.assertGraveyardCount(playerA, "Raging Goblin", 1);
assertPermanentCount(playerA, "Raging Goblin", 1);
assertGraveyardCount(playerA, "Raging Goblin", 1);
}
// test that can only play one spell from graveyard per turn
/**
* Test that can cast only one spell from your graveyard per turn
*/
@Test
public void testPlayOneFromGraveyardPerTurn() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
@ -61,14 +64,15 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, "Raging Goblin", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raging Goblin");
checkPlayableAbility("Can't cast 2nd spell this turn", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Raging", false);
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Raging Goblin");
checkPlayableAbility("Can't cast 2nd spell this turn", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Raging", false);
setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute();
this.assertPermanentCount(playerA, "Raging Goblin", 2);
this.assertGraveyardCount(playerA, "Raging Goblin", 0);
assertPermanentCount(playerA, "Raging Goblin", 2);
assertGraveyardCount(playerA, "Raging Goblin", 0);
}
}