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.PhaseStep;
import mage.constants.Zone; import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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.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);
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); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();
@ -116,10 +118,9 @@ public class CursesTest extends CardTestPlayerBase {
castSpell(4, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); castSpell(4, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(4, PhaseStep.PRECOMBAT_MAIN, playerB, "Copy Enchantment"); castSpell(4, PhaseStep.PRECOMBAT_MAIN, playerB, "Copy Enchantment");
setChoice(playerB, true); // Choices for Copy Enchantment get auto-chosen
setChoice(playerB, "Curse of Exhaustion");
setChoice(playerB, "targetPlayer=PlayerA"); checkPlayableAbility("Can't cast a 2nd spell", 4, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cast Lightning", false);
castSpell(4, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
setStopAt(4, PhaseStep.END_TURN); setStopAt(4, PhaseStep.END_TURN);
execute(); execute();
@ -151,7 +152,8 @@ public class CursesTest extends CardTestPlayerBase {
setChoice(playerB, "PlayerA"); setChoice(playerB, "PlayerA");
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); 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); setStopAt(2, PhaseStep.END_TURN);
execute(); execute();
@ -292,7 +294,6 @@ public class CursesTest extends CardTestPlayerBase {
@Test @Test
public void cruelRealityHasBothCreatureAndPwChoosePw() { public void cruelRealityHasBothCreatureAndPwChoosePw() {
String ugin = "Ugin, the Spirit Dragon"; String ugin = "Ugin, the Spirit Dragon";
String memnite = "Memnite"; // {0} 1/1 String memnite = "Memnite"; // {0} 1/1
@ -315,7 +316,6 @@ public class CursesTest extends CardTestPlayerBase {
@Test @Test
public void cruelRealityHasBothCreatureAndPwChooseCreature() { public void cruelRealityHasBothCreatureAndPwChooseCreature() {
String ugin = "Ugin, the Spirit Dragon"; String ugin = "Ugin, the Spirit Dragon";
String memnite = "Memnite"; // {0} 1/1 String memnite = "Memnite"; // {0} 1/1
@ -338,7 +338,6 @@ public class CursesTest extends CardTestPlayerBase {
@Test @Test
public void cruelRealityOnlyHasCreatureNoChoiceMade() { public void cruelRealityOnlyHasCreatureNoChoiceMade() {
String memnite = "Memnite"; // {0} 1/1 String memnite = "Memnite"; // {0} 1/1
addCard(Zone.HAND, playerA, cReality); addCard(Zone.HAND, playerA, cReality);
@ -357,7 +356,6 @@ public class CursesTest extends CardTestPlayerBase {
@Test @Test
public void cruelRealityOnlyHasPwNoChoiceMade() { public void cruelRealityOnlyHasPwNoChoiceMade() {
String ugin = "Ugin, the Spirit Dragon"; String ugin = "Ugin, the Spirit Dragon";
addCard(Zone.HAND, playerA, cReality); addCard(Zone.HAND, playerA, cReality);
@ -376,35 +374,40 @@ public class CursesTest extends CardTestPlayerBase {
@Test @Test
public void cruelRealityOnlyHasCreatureTryToChooseNotToSac() { public void cruelRealityOnlyHasCreatureTryToChooseNotToSac() {
String memnite = "Memnite"; // {0} 1/1 String memnite = "Memnite"; // {0} 1/1
addCard(Zone.HAND, playerA, cReality); addCard(Zone.HAND, playerA, cReality);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 7); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 7);
addCard(Zone.BATTLEFIELD, playerB, memnite); addCard(Zone.BATTLEFIELD, playerB, memnite);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cReality, playerB); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cReality, playerB);
setChoice(playerB, false);
setStopAt(2, PhaseStep.PRECOMBAT_MAIN); setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
execute();
assertGraveyardCount(playerB, memnite, 1); try {
assertPermanentCount(playerA, cReality, 1); execute();
assertLife(playerB, 20); 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 @Test
public void cruelRealityNoCreatureOrPwForcesLifeLoss() { public void cruelRealityNoCreatureOrPwForcesLifeLoss() {
String gPrison = "Ghostly Prison"; // {2}{W} enchantment - doesnt matter text for this String gPrison = "Ghostly Prison"; // {2}{W} enchantment - doesnt matter text for this
addCard(Zone.HAND, playerA, cReality); addCard(Zone.HAND, playerA, cReality);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 7); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 7);
addCard(Zone.BATTLEFIELD, playerB, gPrison); addCard(Zone.BATTLEFIELD, playerB, gPrison);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cReality, playerB); 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); setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
execute(); execute();
@ -414,10 +417,10 @@ public class CursesTest extends CardTestPlayerBase {
assertLife(playerB, 15); assertLife(playerB, 15);
} }
/* /**
* Reported bug issue #3326 * 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. * 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 @Test
public void witchbaneOrbDestroysCursesOnETB() { public void witchbaneOrbDestroysCursesOnETB() {

View file

@ -44,7 +44,6 @@ public class MasterBiomancerTest extends CardTestPlayerBase {
@Test @Test
public void testCreatureGetsDoubleCountersFromCorpsejackMenace() { public void testCreatureGetsDoubleCountersFromCorpsejackMenace() {
// a creature enters the battlefield and gets a counter for each point of power of Master Biomancer // 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) // 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/ // 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 * Progenitor Mimic
* Mimic enter the battlefield as a copy of any creature on the battlefield * Creature - Shapeshifter 0/0
* except it gains "At the beginning of your upkeep, if this creature isn't * You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield
* a token, put a token onto the battlefield that's a copy of this * except it gains "At the beginning of your upkeep, if this creature isn't a token,
* creature." * 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 * If Progenitor Mimic comes into play, it gets two +1/+1 counters from the Master Biomancer already in play.
* Master Biomancer already in play. It copies the Master Biomancer and is * It copies the Master Biomancer and is therfore a 4/6 creature.
* therfore a 4/6 creature. The Token generated next round from Progenitor * The Token generated next round from Progenitor Mimic has to get 2 + 4 counters and is therefore a 8/10 creature.
* Mimic has to get 2 + 4 counters and is therefore a 8/10 creature.
*/ */
@Test @Test
public void testWithProgenitorMimic() { 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, "Island", 3);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 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); 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"); addCard(Zone.HAND, playerA, "Progenitor Mimic");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Progenitor Mimic"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Progenitor Mimic");
playerA.addTarget("Master Biomancer");
setStopAt(3, PhaseStep.PRECOMBAT_MAIN); setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
execute(); execute();

View file

@ -7,25 +7,20 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @author LevelX2
*/ */
public class ExploitTest extends CardTestPlayerBase { 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 @Test
public void testNormalUse() { public void testNormalUse() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
@ -47,13 +42,12 @@ public class ExploitTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Silumgar Butcher", 1); assertPermanentCount(playerA, "Silumgar Butcher", 1);
assertGraveyardCount(playerA, "Silvercoat Lion", 1); assertGraveyardCount(playerA, "Silvercoat Lion", 1);
assertGraveyardCount(playerB, "Thundering Giant", 1); assertGraveyardCount(playerB, "Thundering Giant", 1);
} }
/** /**
* Test that the Exploit ability won't trigger if the creature with * Test that the Exploit ability won't trigger if the creature with
* exploit left the battlefiled before the Enters the battlefield * exploit left the battlefiled before the Enters the battlefield
* triggered ability resolves. * triggered ability resolves.
*
*/ */
@Test @Test
public void testExploitTriggerWontGo() { public void testExploitTriggerWontGo() {
@ -67,11 +61,12 @@ public class ExploitTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Lightning Bolt", 1); addCard(Zone.HAND, playerB, "Lightning Bolt", 1);
addCard(Zone.BATTLEFIELD, playerB, "Thundering Giant"); // 4/3 addCard(Zone.BATTLEFIELD, playerB, "Thundering Giant"); // 4/3
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silumgar Butcher"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silumgar Butcher");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Silumgar Butcher"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Silumgar Butcher");
setChoice(playerA, true); setChoice(playerA, true);
addTarget(playerA, "Silvercoat Lion"); // sacrifice to Exploit addTarget(playerA, "Silvercoat Lion"); // sacrifice to Exploit
addTarget(playerA, "Thundering Giant"); // Target for the -3/-3
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -79,15 +74,14 @@ public class ExploitTest extends CardTestPlayerBase {
assertGraveyardCount(playerB, "Lightning Bolt", 1); assertGraveyardCount(playerB, "Lightning Bolt", 1);
assertGraveyardCount(playerA, "Silumgar Butcher", 1); assertGraveyardCount(playerA, "Silumgar Butcher", 1);
assertGraveyardCount(playerA, "Silvercoat Lion", 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 * Test that the Exploit ability won't trigger if the creature with
* exploit left the battlefiled before the Enters the battlefield * exploit left the battlefiled before the Enters the battlefield
* triggered ability resolves. * triggered ability resolves.
*
*/ */
@Test @Test
public void testSacrificeCreatureWithExploit() { public void testSacrificeCreatureWithExploit() {
@ -108,7 +102,5 @@ public class ExploitTest extends CardTestPlayerBase {
assertLife(playerA, 22); assertLife(playerA, 22);
assertLife(playerB, 18); 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 * Fracturing Gust is bugged.
* properly when cast from hand. When I cast it from graveyard c/o * In a match against Affinity, it worked properly when cast from hand.
* Snapcaster Mage flashback, it destroyed my opponent's Darksteel Citadels, * 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. * which it did not do when cast from my hand.
*/ */
@Test @Test
@ -53,9 +53,10 @@ public class FlashbackTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Berserkers' Onslaught", 1); addCard(Zone.BATTLEFIELD, playerA, "Berserkers' Onslaught", 1);
addCard(Zone.BATTLEFIELD, playerB, "Darksteel Citadel", 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"); 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 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 * My opponent put Iona on the battlefield using Unburial Rites,
* log didn't show me the color they chose. * but my game log didn't show me the color they chose.
*/ */
@Test @Test
public void testUnburialRites() { public void testUnburialRites() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 8); addCard(Zone.BATTLEFIELD, playerA, "Plains", 8);
// Return target creature card from your graveyard to the battlefield. // Return target creature card from your graveyard to the battlefield.
// Flashback {3}{W} // Flashback {3}{W}
addCard(Zone.HAND, playerA, "Unburial Rites", 1); // Sorcery - {4}{B} 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. // As Iona, Shield of Emeria enters the battlefield, choose a color.
// Your opponents can't cast spells of the chosen color. // Your opponents can't cast spells of the chosen color.
addCard(Zone.GRAVEYARD, playerA, "Iona, Shield of Emeria"); addCard(Zone.GRAVEYARD, playerA, "Iona, Shield of Emeria");
// As Lurebound Scarecrow enters the battlefield, choose a color. // As Lurebound Scarecrow enters the battlefield, choose a color.
// When you control no permanents of the chosen color, sacrifice Lurebound Scarecrow. // When you control no permanents of the chosen color, sacrifice Lurebound Scarecrow.
addCard(Zone.GRAVEYARD, playerA, "Lurebound Scarecrow"); // Enchantment - {2}{U} addCard(Zone.GRAVEYARD, playerA, "Lurebound Scarecrow"); // Enchantment - {2}{U}
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
addCard(Zone.HAND, playerB, "Lightning Bolt", 1); addCard(Zone.HAND, playerB, "Lightning Bolt", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Unburial Rites", "Iona, Shield of Emeria"); 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"); addTarget(playerA, "Lurebound Scarecrow");
setChoice(playerA, "White"); setChoice(playerA, "White");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
execute(); 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 @Test
public void testFlashbackWithConverge() { public void testFlashbackWithConverge() {
@ -188,9 +188,10 @@ public class FlashbackTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, "Unified Front"); // {3}{W} addCard(Zone.GRAVEYARD, playerA, "Unified Front"); // {3}{W}
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {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"); 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}"); 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 * Ancestral Vision has no casting cost (this is different to a casting cost of {0}).
* of {0}). Snapcaster Mage, for example, is able to give it flashback * <p>
* whilst it is in the graveyard. * Snapcaster Mage, for example, is able to give it flashback whilst it is in the graveyard.
* <p> * <p>
* However the controller should not be able to cast Ancestral Visions from * However the controller should not be able to cast Ancestral Visions from
* the graveyard for {0} mana. * the graveyard for {0} mana.
@ -246,7 +247,8 @@ public class FlashbackTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, "Ancestral Vision", 1); addCard(Zone.GRAVEYARD, playerA, "Ancestral Vision", 1);
// Flash // 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.HAND, playerA, "Snapcaster Mage", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 2); addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
@ -254,8 +256,7 @@ public class FlashbackTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage");
addTarget(playerA, "Ancestral Vision"); addTarget(playerA, "Ancestral Vision");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback"); checkPlayableAbility("No flashback", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback", false);
addTarget(playerA, playerA);
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -296,9 +297,11 @@ public class FlashbackTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Runic Repetition", 1); assertGraveyardCount(playerA, "Runic Repetition", 1);
} }
/**
* Check that Altar's Reap additional cost (sacrificing a creature) still applies when cast through flashback.
*/
@Test @Test
public void testAltarsReap() { public void testAltarsReap() {
addCard(Zone.LIBRARY, playerA, "Island", 2); addCard(Zone.LIBRARY, playerA, "Island", 2);
// As an additional cost to cast Altar's Reap, sacrifice a creature. // As an additional cost to cast Altar's Reap, sacrifice a creature.
// Draw two cards. // 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. // 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. // The flashback cost is equal to its mana cost.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage"); 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"); activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Flashback");
setChoice(playerA, "Snapcaster Mage"); setChoice(playerA, "Snapcaster Mage");
@ -343,7 +346,8 @@ public class FlashbackTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Icefall Regent", 1); 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"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage");
addTarget(playerA, "Terminate"); addTarget(playerA, "Terminate");
@ -366,24 +370,27 @@ public class FlashbackTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Island", 8); addCard(Zone.BATTLEFIELD, playerA, "Island", 8);
addCard(Zone.HAND, playerA, "Snapcaster Mage", 1); 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. // Draw a card.
addCard(Zone.GRAVEYARD, playerA, "Whispers of the Muse", 1); // {U} 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"); 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 activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Flashback"); // Flashback Whispers of the Muse
setChoice(playerA, true);
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();
assertPermanentCount(playerA, "Snapcaster Mage", 1); assertPermanentCount(playerA, "Snapcaster Mage", 1);
assertGraveyardCount(playerA, "Whispers of the Muse", 0); 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); assertTappedCount("Island", true, 2);
} }
/* /**
* Bug: Firecat Blitz when cast via Flashback requests sacrificing mountains twice * 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 @Test
public void firecatBlitzFlashback() { 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 fCatBlitz = "Firecat Blitz";
String mountain = "Mountain"; String mountain = "Mountain";
addCard(Zone.GRAVEYARD, playerA, fCatBlitz); addCard(Zone.GRAVEYARD, playerA, fCatBlitz);
addCard(Zone.BATTLEFIELD, playerA, mountain, 6); 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"); setChoice(playerA, "X=1");
addTarget(playerA, mountain); // Mountain is auto-sacrificed
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -439,30 +444,31 @@ public class FlashbackTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, mountain, 1); 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 @Test
public void battleScreechFlashback() { public void battleScreechFlashback() {
String bScreech = "Battle Screech";
/*
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 eVanguard = "Elite Vanguard"; // {W} 2/1 String eVanguard = "Elite Vanguard"; // {W} 2/1
String yOx = "Yoked Ox"; // {W} 0/4 String yOx = "Yoked Ox"; // {W} 0/4
String wKnight = "White Knight"; // {W}{W} 2/2 String wKnight = "White Knight"; // {W}{W} 2/2
addCard(Zone.GRAVEYARD, playerA, bScreech); addCard(Zone.GRAVEYARD, playerA, bScreech);
addCard(Zone.BATTLEFIELD, playerA, eVanguard); addCard(Zone.BATTLEFIELD, playerA, eVanguard);
addCard(Zone.BATTLEFIELD, playerA, yOx); addCard(Zone.BATTLEFIELD, playerA, yOx);
addCard(Zone.BATTLEFIELD, playerA, wKnight); addCard(Zone.BATTLEFIELD, playerA, wKnight);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback"); // Flashback Battle Screech 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); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -470,23 +476,23 @@ public class FlashbackTest extends CardTestPlayerBase {
assertTapped(eVanguard, true); assertTapped(eVanguard, true);
assertTapped(yOx, true); assertTapped(yOx, true);
assertTapped(wKnight, true); assertTapped(wKnight, true);
assertExileCount(playerA, bScreech, 1); // this fails, but the creatures are tapped as part of paying the cost assertExileCount(playerA, bScreech, 1);
assertPermanentCount(playerA, "Bird Token", 2); // if you comment out the above line, this is failing as well 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. * Reported bug: Tried to flashback Dread Return,
It did not allow me to select a creature to return from yard to board. * 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 @Test
public void dreadReturnFlashback() { 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 dReturn = "Dread Return";
String yOx = "Yoked Ox"; // {W} 0/4 String yOx = "Yoked Ox"; // {W} 0/4
String eVanguard = "Elite Vanguard"; // {W} 2/1 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, dReturn);
addCard(Zone.GRAVEYARD, playerA, bSable); addCard(Zone.GRAVEYARD, playerA, bSable);
addCard(Zone.BATTLEFIELD, playerA, yOx); addCard(Zone.BATTLEFIELD, playerA, yOx);
addCard(Zone.BATTLEFIELD, playerA, eVanguard); addCard(Zone.BATTLEFIELD, playerA, eVanguard);
addCard(Zone.BATTLEFIELD, playerA, memnite); addCard(Zone.BATTLEFIELD, playerA, memnite);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback"); // Flashback Dread Return activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback"); // Flashback Dread Return
addTarget(playerA, bSable); // return to battlefield 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); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); 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 * 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. * to a spell, and the flashback cost is already an alternative cost.
*/ */
@ -522,9 +529,11 @@ public class FlashbackTest extends CardTestPlayerBase {
public void testSnapcasterMageSpellWithAlternateCost() { public void testSnapcasterMageSpellWithAlternateCost() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 1); addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 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. // 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. // 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. // 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. // Counter target spell.
@ -541,16 +550,27 @@ public class FlashbackTest extends CardTestPlayerBase {
addTarget(playerA, "Lightning Bolt"); addTarget(playerA, "Lightning Bolt");
setStopAt(1, PhaseStep.END_TURN); 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); assertPermanentCount(playerA, "Snapcaster Mage", 0);
assertGraveyardCount(playerA, "Snapcaster Mage", 1);
assertGraveyardCount(playerA, "Snapcaster Mage", 1);
assertGraveyardCount(playerA, "Force of Will", 1); assertGraveyardCount(playerA, "Force of Will", 1);
assertGraveyardCount(playerB, "Lightning Bolt", 1); assertGraveyardCount(playerB, "Lightning Bolt", 1);
assertLife(playerA, 20); assertLife(playerA, 20);
} }
/** /**

View file

@ -140,7 +140,9 @@ public class HideawayTest extends CardTestPlayerBase {
@Test @Test
public void testCannotPlayLandIfNotOwnTurn() { 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}. // {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. // {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"); 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, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerA, "Dross Crocodile", 2);// 5/1 addCard(Zone.BATTLEFIELD, playerA, "Dross Crocodile", 2);// 5/1
setStrictChooseMode(true);
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mosswort Bridge"); playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mosswort Bridge");
setChoice(playerA, "Ghost Quarter"); 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(); execute();
assertPermanentCount(playerA, "Ghost Quarter", 0); assertTapped("Mosswort Bridge", true); // Tapped from activating the ability
assertTapped("Mosswort Bridge", true); assertPermanentCount(playerA, "Ghost Quarter", 0); // Land couldn't be played since not playerA's turn
} }
@Test @Test

View file

@ -76,7 +76,6 @@ public class MadnessTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Raven's Crime", 1); assertGraveyardCount(playerA, "Raven's Crime", 1);
assertGraveyardCount(playerA, "Arrogant Wurm", 1); assertGraveyardCount(playerA, "Arrogant Wurm", 1);
assertHandCount(playerA, 0); assertHandCount(playerA, 0);
} }
@Test @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. // 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"); 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); setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Haunting Hymn", playerA);
setChoice(playerA, true); // Can't Vampirefor madness cost
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
setStrictChooseMode(true);
assertGraveyardCount(playerB, "Haunting Hymn", 1);
assertGraveyardCount(playerB, "Haunting Hymn", 1);
assertPermanentCount(playerA, "Vampire Aristocrat", 1); assertPermanentCount(playerA, "Vampire Aristocrat", 1);
assertGraveyardCount(playerA, 0);
assertGraveyardCount(playerB, 1);
assertGraveyardCount(playerB, "Haunting Hymn", 1);
} }
@Test @Test
@ -113,7 +112,8 @@ public class MadnessTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
// Madness {X}{R} // 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.HAND, playerA, "Avacyn's Judgment", 1);
addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox", 1); addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox", 1);
@ -135,7 +135,6 @@ public class MadnessTest extends CardTestPlayerBase {
assertGraveyardCount(playerB, "Haunting Hymn", 1); assertGraveyardCount(playerB, "Haunting Hymn", 1);
assertGraveyardCount(playerA, "Avacyn's Judgment", 1); assertGraveyardCount(playerA, "Avacyn's Judgment", 1);
assertGraveyardCount(playerB, "Pillarfield Ox", 1); assertGraveyardCount(playerB, "Pillarfield Ox", 1);
} }
/** /**

View file

@ -14,10 +14,10 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class ProliferateTest extends CardTestPlayerBase { public class ProliferateTest extends CardTestPlayerBase {
/** /**
* Volt Charge {2}{R} Instant Volt Charge deals 3 damage to target creature * Volt Charge
* or player. Proliferate. (You choose any number of permanents and/or * {2}{R}
* players with counters on them, then give each another counter of a kind * Volt Charge deals 3 damage to any target.
* already there.) * Proliferate. (Choose any number of permanents and/or players, then give each another counter of each kind already there.)
*/ */
@Test @Test
public void testCastFromHandMovedToExile() { public void testCastFromHandMovedToExile() {
@ -27,7 +27,7 @@ public class ProliferateTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Volt Charge"); addCard(Zone.HAND, playerA, "Volt Charge");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Volt Charge", playerB); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Volt Charge", playerB);
addTarget(playerA, "Chandra, Pyromaster"); setChoice(playerA, "Chandra, Pyromaster");
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -36,7 +36,6 @@ public class ProliferateTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Volt Charge", 1); assertGraveyardCount(playerA, "Volt Charge", 1);
assertCounterCount("Chandra, Pyromaster", CounterType.LOYALTY, 5); // 4 + 1 from proliferate 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.PhaseStep;
import mage.constants.Zone; import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; import org.mage.test.serverside.base.CardTestPlayerBase;
/** /**
* Force of Will * {@link mage.cards.f.ForceOfWill Force of Will} {3}{U}{U}
* Instant, 3UUU * Instant
* You may pay 1 life and exile a blue card from your hand rather than pay Force of Will's mana cost. * 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. * 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 that Force of Will can be played with alternate casting costs
*
*/ */
@Test @Test
public void testWithBlueCardsInHand() { public void testWithBlueCardsInHand() {
@ -44,39 +44,47 @@ public class ForceOfWillTest extends CardTestPlayerBase {
assertHandCount(playerB, 1); // One Remand left assertHandCount(playerB, 1); // One Remand left
assertGraveyardCount(playerB, 1); // Force of Will assertGraveyardCount(playerB, 1); // Force of Will
assertExileCount("Remand", 1); // one Remand (cost from 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 * Test that Force of Will can'be played with alternate casting costs
* if no blue card is in hand and not enough mana available * if no blue card is in hand and not enough mana available
*
*/ */
@Test @Test
public void testWithRedCardsInHand() { public void testWithRedCardsInHand() {
addCard(Zone.HAND, playerA, "Thoughtseize"); addCard(Zone.HAND, playerA, "Thoughtseize");
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
//
addCard(Zone.HAND, playerB, "Force of Will");
addCard(Zone.HAND, playerB, "Fireball", 2); // blue card to pay force of will
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Thoughtseize", playerB);
playerB.addChoice("Fireball");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Force of Will", "Thoughtseize");
setStopAt(1, PhaseStep.CLEANUP);
execute();
assertLife(playerA, 18); // No Red cards in hand
addCard(Zone.HAND, playerB, "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);
playerA.addChoice("Fireball");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Force of Will", "Thoughtseize");
setStopAt(1, PhaseStep.CLEANUP);
// 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 assertLife(playerB, 20); // losing 1 from Force of Will
assertHandCount(playerA, 0); assertHandCount(playerB, 2); // 1 Fireball 1 Force of Will
assertGraveyardCount(playerA, 1);
assertHandCount(playerB, 2); // 1 Fireball 1 Force of Will
assertGraveyardCount(playerB, 1); // 1 Fireball discarded because of Thoughseize 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.HAND, playerA, "Hideous End");
addCard(Zone.BATTLEFIELD, playerB, "Zombie Goliath"); 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); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();

View file

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

View file

@ -2,6 +2,7 @@ package org.mage.test.cards.asthough;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.Zone; import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBaseWithAIHelps; import org.mage.test.serverside.base.CardTestPlayerBaseWithAIHelps;
@ -25,7 +26,6 @@ public class PlayFromNonHandZoneTest extends CardTestPlayerBaseWithAIHelps {
execute(); execute();
assertPowerToughness(playerA, "Worldheart Phoenix", 2, 2); assertPowerToughness(playerA, "Worldheart Phoenix", 2, 2);
} }
@Test @Test
@ -37,13 +37,21 @@ public class PlayFromNonHandZoneTest extends CardTestPlayerBaseWithAIHelps {
addCard(Zone.GRAVEYARD, playerA, "Worldheart Phoenix"); addCard(Zone.GRAVEYARD, playerA, "Worldheart Phoenix");
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); 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); 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); assertPermanentCount(playerA, "Worldheart Phoenix", 0);
} }
@Test @Test
@ -65,20 +73,22 @@ public class PlayFromNonHandZoneTest extends CardTestPlayerBaseWithAIHelps {
execute(); execute();
assertPermanentCount(playerA, "Worldheart Phoenix", 1); assertPermanentCount(playerA, "Worldheart Phoenix", 1);
} }
@Test @Test
public void testNarsetEnlightenedMaster() { public void testNarsetEnlightenedMaster() {
// First strike // First strike
// Hexproof // 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); addCard(Zone.BATTLEFIELD, playerB, "Narset, Enlightened Master", 1);
skipInitShuffling(); skipInitShuffling();
addCard(Zone.LIBRARY, playerB, "Silvercoat Lion"); addCard(Zone.LIBRARY, playerB, "Silvercoat Lion");
addCard(Zone.LIBRARY, playerB, "Abzan Banner"); 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 // Enchant creature
// Enchanted creature gets +2/+0 and has first strike. // Enchanted creature gets +2/+0 and has first strike.
addCard(Zone.LIBRARY, playerB, "Dragon Grip"); addCard(Zone.LIBRARY, playerB, "Dragon Grip");
@ -88,28 +98,31 @@ public class PlayFromNonHandZoneTest extends CardTestPlayerBaseWithAIHelps {
attack(2, playerB, "Narset, Enlightened Master"); attack(2, playerB, "Narset, Enlightened Master");
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Silvercoat Lion"); // can't be cast from exile // Can NOT cast from exile
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Abzan Banner"); // can be cast from exile checkPlayableAbility("Can't cast Silvercoat", 2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Cast Silvercoat", false);
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 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); setStopAt(2, PhaseStep.END_TURN);
execute(); execute();
assertExileCount("Silvercoat Lion", 1);
assertPermanentCount(playerB, "Abzan Banner", 1); assertPermanentCount(playerB, "Abzan Banner", 1);
assertPermanentCount(playerB, "Dragon Grip", 1);
assertGraveyardCount(playerB, "Peach Garden Oath", 1); assertGraveyardCount(playerB, "Peach Garden Oath", 1);
assertExileCount(playerB, "Dragon Grip", 0);
assertGraveyardCount(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); assertPowerToughness(playerB, "Narset, Enlightened Master", 5, 2);
assertHandCount(playerB, "Plains", 1); assertHandCount(playerB, "Plains", 1);
assertLife(playerA, 17); assertLife(playerA, 17);
assertLife(playerB, 22); assertLife(playerB, 22);
assertPermanentCount(playerB, "Dragon Grip", 1);
} }
@Test @Test

View file

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

View file

@ -57,7 +57,7 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB);
setChoice(playerA, "X=3"); 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); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -89,12 +89,14 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
addCard(Zone.LIBRARY, playerB, "Secret Plans"); addCard(Zone.LIBRARY, playerB, "Secret Plans");
skipInitShuffling(); // to keep this card on top of library skipInitShuffling(); // to keep this card on top of library
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Master of Pearls"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Master of Pearls");
setChoice(playerA, true); // cast it face down as 2/2 creature setChoice(playerA, true); // cast it face down as 2/2 creature
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB);
setChoice(playerA, "X=3"); 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); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -132,7 +134,7 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB);
setChoice(playerA, "X=3"); 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); setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
execute(); execute();
@ -146,16 +148,15 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
assertHandCount(playerA, 3); assertHandCount(playerA, 3);
assertLife(playerA, 12); assertLife(playerA, 12);
assertLife(playerB, 20); assertLife(playerB, 20);
} }
/** /**
* I cast a Villainous Wealth in Vintage Cube, and when it came time to cast * 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 * 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 * 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 * my spell after Quicken resolved.
* let me post them. I did find it was replicatable whenever you try to cast * I have the error, but the forums won't let me post them.
* Quicken off a Villainous Wealth. * I did find it was replicatable whenever you try to cast Quicken off a Villainous Wealth.
*/ */
@Test @Test
public void testVillainousWealthAndQuicken() { public void testVillainousWealthAndQuicken() {
@ -178,11 +179,19 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
addCard(Zone.LIBRARY, playerB, "Mox Sapphire"); addCard(Zone.LIBRARY, playerB, "Mox Sapphire");
skipInitShuffling(); // to keep this card on top of library skipInitShuffling(); // to keep this card on top of library
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB);
setChoice(playerA, "X=3"); setChoice(playerA, "X=3");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mox Emerald");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Quicken"); setChoice(playerA, "Mox Emerald");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mox Sapphire"); 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); setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute(); execute();
@ -192,6 +201,5 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
assertPermanentCount(playerA, "Mox Emerald", 1); assertPermanentCount(playerA, "Mox Emerald", 1);
assertPermanentCount(playerA, "Mox Sapphire", 1); assertPermanentCount(playerA, "Mox Sapphire", 1);
assertGraveyardCount(playerB, "Quicken", 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 * 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 * with Flameshadow Conjuring.
* the end of the turn, but the "lose two life a turn" trigger still * Their copy was made and removed correctly at the end of the turn,
* happened twice. * but the "lose two life a turn" trigger still happened twice.
* *
* TODO: Seems like there are too much triggered abilities in * TODO: Seems like there are too much triggered abilities in
* TriggeredAbilities as the TriggeredAbilities get removed from * TriggeredAbilities as the TriggeredAbilities get removed from
* PlayerImpl.removeFromBattlefield() * PlayerImpl.removeFromBattlefield()
*/ */
@Test @Test
public void testCopyAndItsEffectsRemoved() { 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. // 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. // At the beginning of your upkeep, you lose 2 life.
addCard(Zone.HAND, playerA, "Priest of the Blood Rite", 1); // {3}{B}{B} 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"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Priest of the Blood Rite");
setStopAt(3, PhaseStep.UPKEEP); 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 * I created a token copy of Wurmcoil Engine and sacrificed it.
* 4 tokens * This gave me 4 tokens.
*/ */
@Test @Test
public void testWurmcoilEngine() { public void testWurmcoilEngine() {
@ -80,7 +79,5 @@ public class FlameshadowConjuringTest extends CardTestPlayerBase {
assertLife(playerA, 26); assertLife(playerA, 26);
assertPermanentCount(playerA, "Phyrexian Wurm Token", 2); assertPermanentCount(playerA, "Phyrexian Wurm Token", 2);
} }
} }

View file

@ -6,6 +6,15 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @author LevelX2
*/ */
public class MimicVatTest extends CardTestPlayerBase { public class MimicVatTest extends CardTestPlayerBase {
@ -22,8 +31,6 @@ public class MimicVatTest extends CardTestPlayerBase {
@Test @Test
public void TestClone() { public void TestClone() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 6); 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} addCard(Zone.BATTLEFIELD, playerA, "Mimic Vat", 1); // Artifact {3}
// {2}, {T}, Sacrifice a creature: Draw a card. // {2}, {T}, Sacrifice a creature: Draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Phyrexian Vault", 1); addCard(Zone.BATTLEFIELD, playerA, "Phyrexian Vault", 1);
@ -62,8 +69,6 @@ public class MimicVatTest extends CardTestPlayerBase {
@Test @Test
public void TestPhyrexianMetamorph() { public void TestPhyrexianMetamorph() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 6); 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} addCard(Zone.BATTLEFIELD, playerA, "Mimic Vat", 1); // Artifact {3}
// {2}, {T}, Sacrifice a creature: Draw a card. // {2}, {T}, Sacrifice a creature: Draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Phyrexian Vault", 1); addCard(Zone.BATTLEFIELD, playerA, "Phyrexian Vault", 1);
@ -76,6 +81,7 @@ public class MimicVatTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phyrexian Metamorph"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phyrexian Metamorph");
setChoice(playerA, true); setChoice(playerA, true);
setChoice(playerA, "Silvercoat Lion"); setChoice(playerA, "Silvercoat Lion");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Sacrifice a creature"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Sacrifice a creature");
setChoice(playerA, true); setChoice(playerA, true);
@ -87,9 +93,8 @@ public class MimicVatTest extends CardTestPlayerBase {
execute(); execute();
assertExileCount("Phyrexian Metamorph", 1); assertExileCount("Phyrexian Metamorph", 1);
assertPermanentCount(playerB, "Silvercoat Lion", 1);
assertPermanentCount(playerA, "Silvercoat Lion", 1); assertPermanentCount(playerA, "Silvercoat Lion", 1);
assertPermanentCount(playerB, "Silvercoat Lion", 1);
} }
/** /**
@ -100,30 +105,26 @@ public class MimicVatTest extends CardTestPlayerBase {
*/ */
@Test @Test
public void TestExileFails() { public void TestExileFails() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
// 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. addCard(Zone.BATTLEFIELD, playerA, "Mimic Vat", 1);
// {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.HAND, playerA, "Lightning Bolt", 1); addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2); addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
// Exile up to four target cards from a single graveyard. // Exile up to four target cards from a single graveyard.
// Transmute {1}{B}{B} // Transmute {1}{B}{B}
addCard(Zone.HAND, playerB, "Shred Memory", 1); // Instant {1}{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"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Silvercoat Lion");
setChoice(playerA, true); setChoice(playerA, "Yes");
setChoice(playerA, "Silvercoat Lion");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Shred Memory", "Silvercoat Lion", "Whenever a nontoken creature dies"); 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 "); 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); setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -133,6 +134,5 @@ public class MimicVatTest extends CardTestPlayerBase {
assertExileCount(playerB, "Silvercoat Lion", 1); assertExileCount(playerB, "Silvercoat Lion", 1);
assertPermanentCount(playerA, "Silvercoat Lion", 0); assertPermanentCount(playerA, "Silvercoat Lion", 0);
} }
} }

View file

@ -8,28 +8,29 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @author BetaSteward
*/ */
public class ReversalOfFortuneTest extends CardTestPlayerBase { 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 @Test
public void testCopyCard() { public void testCopyCard() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
addCard(Zone.HAND, playerA, "Reversal of Fortune"); addCard(Zone.HAND, playerA, "Reversal of Fortune");
addCard(Zone.HAND, playerB, "Lightning Bolt"); addCard(Zone.HAND, playerB, "Lightning Bolt");
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reversal of Fortune", playerB); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reversal of Fortune", playerB);
setChoice(playerA, "Lightning Bolt"); // select to copy setChoice(playerA, "Lightning Bolt"); // select to copy
setChoice(playerA, true); // cast copy setChoice(playerA, true); // cast copy
addTarget(playerA, playerB);
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();
@ -38,19 +39,19 @@ public class ReversalOfFortuneTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Lightning Bolt", 0); assertGraveyardCount(playerA, "Lightning Bolt", 0);
assertGraveyardCount(playerB, "Lightning Bolt", 0); assertGraveyardCount(playerB, "Lightning Bolt", 0);
assertLife(playerB, 17); assertLife(playerB, 17);
} }
@Test @Test
public void testCopyCardButDontCast() { public void testCopyCardButDontCast() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
addCard(Zone.HAND, playerA, "Reversal of Fortune"); addCard(Zone.HAND, playerA, "Reversal of Fortune");
addCard(Zone.HAND, playerB, "Lightning Bolt"); addCard(Zone.HAND, playerB, "Lightning Bolt");
// setStrictChooseMode(true); setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reversal of Fortune", playerB); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reversal of Fortune", playerB);
addTarget(playerA, "Lightning Bolt"); setChoice(playerA, "Lightning Bolt");
setChoice(playerA, false); setChoice(playerA, false);
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
@ -60,7 +61,5 @@ public class ReversalOfFortuneTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Lightning Bolt", 0); assertGraveyardCount(playerA, "Lightning Bolt", 0);
assertGraveyardCount(playerB, "Lightning Bolt", 0); assertGraveyardCount(playerB, "Lightning Bolt", 0);
assertLife(playerB, 20); 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. * BUG: Sewer Nemesis count's all cards in each player's graveyard to determine it's * / *, not just the chosen player's graveyard.
*
*/ */
@Test @Test
public void test1() { public void test1() {
@ -32,14 +31,11 @@ public class SewerNemesisTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sewer Nemesis"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sewer Nemesis");
setChoice(playerA, "PlayerA"); // Starting player setChoice(playerA, "PlayerA"); // Starting player
setChoice(playerA, "PlayerA");
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
assertGraveyardCount(playerA,"Sewer Nemesis", 0); assertGraveyardCount(playerA,"Sewer Nemesis", 0);
assertPowerToughness(playerA, "Sewer Nemesis", 4, 4); assertPowerToughness(playerA, "Sewer Nemesis", 4, 4);
} }
} }

View file

@ -7,6 +7,12 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @author LevelX2
*/ */
@ -14,22 +20,20 @@ public class BreathOfFuryTest extends CardTestPlayerBase {
@Test @Test
public void testMoveEnchantment() { 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.HAND, playerA, "Breath of Fury", 1); // Enchantment - Aura {2}{R}{R}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox"); addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox");
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Breath of Fury", "Silvercoat Lion"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Breath of Fury", "Silvercoat Lion");
attack(3, playerA, "Pillarfield Ox");
attack(3, playerA, "Silvercoat Lion"); attack(3, playerA, "Silvercoat Lion");
attack(3, playerA, "Pillarfield Ox");
addTarget(playerA, "Pillarfield Ox"); setChoice(playerA, "Pillarfield Ox");
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN); setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
execute(); execute();
@ -40,7 +44,5 @@ public class BreathOfFuryTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Silvercoat Lion", 1); assertGraveyardCount(playerA, "Silvercoat Lion", 1);
assertTappedCount("Pillarfield Ox", false, 1); assertTappedCount("Pillarfield Ox", false, 1);
assertPermanentCount(playerA, "Breath of Fury", 1); assertPermanentCount(playerA, "Breath of Fury", 1);
} }
} }

View file

@ -43,7 +43,6 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
assertLife(playerA, 20); assertLife(playerA, 20);
assertLife(playerB, 17); assertLife(playerB, 17);
} }
/** /**
@ -165,12 +164,12 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, bear1, 1); addCard(Zone.HAND, playerA, bear1, 1);
addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 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); setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute(); execute();
Assert.assertEquals(0, playerA.getManaPool().getMana().count()); Assert.assertEquals(0, playerA.getManaPool().getMana().count());
assertPermanentCount(playerA, bear1, 0);
} }
@Test @Test
@ -178,12 +177,10 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, bear1, 1); addCard(Zone.HAND, playerA, bear1, 1);
addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 2); 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); setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute(); execute();
Assert.assertEquals(0, playerA.getManaPool().getMana().count());
assertPermanentCount(playerA, bear1, 0);
} }
@Test @Test
@ -205,11 +202,10 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, bear1G, 1); addCard(Zone.HAND, playerA, bear1G, 1);
addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 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); setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute(); execute();
assertPermanentCount(playerA, bear1G, 0);
} }
@Test @Test

View file

@ -4,6 +4,7 @@ package org.mage.test.cards.rules;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.Zone; import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; import org.mage.test.serverside.base.CardTestPlayerBase;
@ -11,17 +12,13 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
* *
* @author LevelX2 * @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 * with Melira, Sylvok Outcast on the table and Devoted Druid you can activated
* or abilities your opponents control this turn * 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 @Test
public void testUnpayableCost() { public void testUnpayableCost() {
@ -37,11 +34,20 @@ public class MeliraSylvokOutcastTest extends CardTestPlayerBase {
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Put a -1/-1 counter on "); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Put a -1/-1 counter on ");
setStopAt(1, PhaseStep.BEGIN_COMBAT); 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); assertPowerToughness(playerA, "Devoted Druid", 0, 2);
assertCounterCount("Devoted Druid", CounterType.M1M1, 0); assertCounterCount("Devoted Druid", CounterType.M1M1, 0);
assertTapped("Devoted Druid", true); // Because untapping can't be paid 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); addCard(Zone.HAND, playerA, flameJet);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, newPerspectives); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, newPerspectives);
activateAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "Cycling"); checkPlayableAbility("Can't cycle", 1, PhaseStep.BEGIN_COMBAT, playerA, "Cycling", false);
setChoice(playerA, true);
setStopAt(1, PhaseStep.END_COMBAT); setStopAt(1, PhaseStep.END_COMBAT);
execute(); execute();

View file

@ -6,8 +6,15 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; import org.mage.test.serverside.base.CardTestPlayerBase;
/** /**
* also tests regenerate and tests that permanents with protection can be * {@link mage.cards.f.FiendOfTheShadows Fiend of the Shadows}
* sacrificed * {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 * @author BetaSteward
*/ */
@ -16,14 +23,15 @@ public class FiendOfTheShadowsTest extends CardTestPlayerBase {
@Test @Test
public void testCard() { public void testCard() {
addCard(Zone.BATTLEFIELD, playerA, "White Knight"); 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, playerA, "Fiend of the Shadows");
addCard(Zone.BATTLEFIELD, playerB, "Mountain"); addCard(Zone.BATTLEFIELD, playerB, "Mountain");
addCard(Zone.HAND, playerB, "Lightning Bolt"); addCard(Zone.HAND, playerB, "Lightning Bolt");
setStrictChooseMode(true);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice a Human: Regenerate {this}."); 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"); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", "Fiend of the Shadows");
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
@ -38,8 +46,6 @@ public class FiendOfTheShadowsTest extends CardTestPlayerBase {
@Test @Test
public void testCardExile1() { 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"); addCard(Zone.BATTLEFIELD, playerA, "Fiend of the Shadows");
removeAllCardsFromHand(playerB); removeAllCardsFromHand(playerB);
addCard(Zone.HAND, playerB, "Swamp"); addCard(Zone.HAND, playerB, "Swamp");
@ -80,5 +86,4 @@ public class FiendOfTheShadowsTest extends CardTestPlayerBase {
assertHandCount(playerB, 0); assertHandCount(playerB, 0);
assertGraveyardCount(playerB, "Lightning Bolt", 1); assertGraveyardCount(playerB, "Lightning Bolt", 1);
} }
} }

View file

@ -6,13 +6,22 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @author BetaSteward
*/ */
public class HavengulLichTest extends CardTestPlayerBase { public class HavengulLichTest extends CardTestPlayerBase {
/**
* Check that the ability works as intented.
*/
@Test @Test
public void testCard() { public void testWorksOnTurn() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.BATTLEFIELD, playerA, "Havengul Lich"); addCard(Zone.BATTLEFIELD, playerA, "Havengul Lich");
addCard(Zone.GRAVEYARD, playerA, "Prodigal Pyromancer"); addCard(Zone.GRAVEYARD, playerA, "Prodigal Pyromancer");
@ -32,46 +41,46 @@ public class HavengulLichTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, 0); assertGraveyardCount(playerA, 0);
} }
/**
* Check that the ability only allows you to play the chosen card on the curent turn.
*/
@Test @Test
public void testCard1() { public void testDoesNotWorkNextTurn() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
addCard(Zone.BATTLEFIELD, playerA, "Havengul Lich"); addCard(Zone.BATTLEFIELD, playerA, "Havengul Lich");
addCard(Zone.GRAVEYARD, playerA, "Black Cat"); addCard(Zone.GRAVEYARD, playerA, "Black Cat");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}", "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); setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute(); execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Havengul Lich", 1); assertPermanentCount(playerA, "Havengul Lich", 1);
assertPermanentCount(playerA, "Black Cat", 0); assertPermanentCount(playerA, "Black Cat", 0);
assertGraveyardCount(playerA, 1); assertGraveyardCount(playerA, 1);
} }
/**
* Check that Havengul Lich only keeps the abilities for current turn.
*/
@Test @Test
public void testCard2() { public void testCard2() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); 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"); addCard(Zone.BATTLEFIELD, playerA, "Havengul Lich");
// {T}: Prodigal Pyromancer deals 1 damage to any target. // {T}: Prodigal Pyromancer deals 1 damage to any target.
addCard(Zone.GRAVEYARD, playerA, "Prodigal Pyromancer"); addCard(Zone.GRAVEYARD, playerA, "Prodigal Pyromancer");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}: You may", "Prodigal Pyromancer"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}: You may", "Prodigal Pyromancer");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "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); setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute(); execute();
assertLife(playerA, 20);
assertLife(playerB, 19);
assertPermanentCount(playerA, "Havengul Lich", 1); assertPermanentCount(playerA, "Havengul Lich", 1);
assertPermanentCount(playerA, "Prodigal Pyromancer", 1); assertPermanentCount(playerA, "Prodigal Pyromancer", 1);
assertTapped("Prodigal Pyromancer", true);
assertTapped("Havengul Lich", false);
assertGraveyardCount(playerA, 0); assertGraveyardCount(playerA, 0);
} }
@ -110,7 +119,5 @@ public class HavengulLichTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Havengul Lich", 1); assertPermanentCount(playerA, "Havengul Lich", 1);
assertGraveyardCount(playerA, "Perilous Myr", 1); assertGraveyardCount(playerA, "Perilous Myr", 1);
} }
} }

View file

@ -7,6 +7,13 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @author TheElk801
*/ */
public class CodespellClericTest extends CardTestPlayerBase { 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 cleric = "Codespell Cleric";
private static final String relic = "Darksteel Relic"; private static final String relic = "Darksteel Relic";
/**
* No +1/+1 since its the first spell.
*/
@Test @Test
public void testFirstSpell() { public void testFirstSpell() {
addCard(Zone.BATTLEFIELD, playerA, "Plains"); addCard(Zone.BATTLEFIELD, playerA, "Plains");
@ -27,6 +37,9 @@ public class CodespellClericTest extends CardTestPlayerBase {
assertCounterCount(playerA, cleric, CounterType.P1P1, 0); assertCounterCount(playerA, cleric, CounterType.P1P1, 0);
} }
/**
* Put a +1/+1 since it's the second spell.
*/
@Test @Test
public void testSecondSpell() { public void testSecondSpell() {
addCard(Zone.BATTLEFIELD, playerA, "Plains"); addCard(Zone.BATTLEFIELD, playerA, "Plains");
@ -42,6 +55,9 @@ public class CodespellClericTest extends CardTestPlayerBase {
assertCounterCount(playerA, cleric, CounterType.P1P1, 1); assertCounterCount(playerA, cleric, CounterType.P1P1, 1);
} }
/**
* No +1/+1 since its the third spell.
*/
@Test @Test
public void testThirdSpell() { public void testThirdSpell() {
addCard(Zone.BATTLEFIELD, playerA, "Plains"); 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);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, relic); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, relic);
addTarget(playerA, cleric);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, cleric); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, cleric);
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);

View file

@ -6,6 +6,15 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @author TheElk801
*/ */
public class FrostpyreArcanistTest extends CardTestPlayerBase { public class FrostpyreArcanistTest extends CardTestPlayerBase {
@ -20,10 +29,11 @@ public class FrostpyreArcanistTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, bolt); addCard(Zone.GRAVEYARD, playerA, bolt);
addCard(Zone.HAND, playerA, arcanist); addCard(Zone.HAND, playerA, arcanist);
addTarget(playerA, bolt);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcanist);
setStrictChooseMode(true); setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcanist);
addTarget(playerA, bolt);
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();
assertAllCommandsUsed(); assertAllCommandsUsed();
@ -38,8 +48,8 @@ public class FrostpyreArcanistTest extends CardTestPlayerBase {
addCard(Zone.LIBRARY, playerA, bolt); addCard(Zone.LIBRARY, playerA, bolt);
addCard(Zone.HAND, playerA, arcanist); addCard(Zone.HAND, playerA, arcanist);
addTarget(playerA, bolt);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcanist); 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); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();

View file

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

View file

@ -2,35 +2,41 @@ package org.mage.test.cards.single.soi;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.Zone; import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @author escplan9
*/ */
public class LambholtPacifistTest extends CardTestPlayerBase { 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"; private final String lambholt = "Lambholt Pacifist";
/**
* An uncrewed vehicle does not count as a creature.
*/
@Test @Test
public void uncrewedVehicle_LambholtCannotAttack() { public void uncrewedVehicle_LambholtCannotAttack() {
/* /*
Heart of Kiran {2} Heart of Kiran {2}
Legendary Artifact - Vehicle 4/4
Flying, vigilance Legendary Artifact - Vehicle
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.) Flying, vigilance
You may remove a loyalty counter from a planeswalker you control rather than pay Heart of Kiran's crew cost. 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 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.HAND, playerA, lambholt);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
@ -39,11 +45,19 @@ public class LambholtPacifistTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lambholt); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lambholt);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, orni); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, orni);
attack(3, playerA, lambholt); attack(3, playerA, lambholt);
setStopAt(3, PhaseStep.END_COMBAT); 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); assertPermanentCount(playerB, orni, 1);
assertTapped(lambholt, false); assertTapped(lambholt, false);

View file

@ -6,27 +6,25 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @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 { public class FlailingDrakeTest extends CardTestPlayerBase {
@Test @Test
public void testIncreaseBlocker() { public void testIncreaseBlocker() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4); 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, playerA, "Flailing Drake", 1); // Creature {3}{G} 2/3
addCard(Zone.BATTLEFIELD, playerB, "Island", 4); addCard(Zone.BATTLEFIELD, playerB, "Island", 4);
addCard(Zone.BATTLEFIELD, playerB, "Snapping Drake", 1); // Creature {3}{U} 3/2 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"); attack(3, playerA, "Flailing Drake");
block(3, playerB, "Snapping Drake", "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, "Island", 4);
addCard(Zone.BATTLEFIELD, playerB, "Snapping Drake", 1); 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"); attack(4, playerB, "Snapping Drake");
block(4, playerA, "Flailing Drake", "Snapping Drake"); block(4, playerA, "Flailing Drake", "Snapping Drake");
@ -59,5 +54,4 @@ public class FlailingDrakeTest extends CardTestPlayerBase {
//Snapping Drake 4/3 //Snapping Drake 4/3
assertPowerToughness(playerB, "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; 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 * @author BetaSteward
*/ */
public class CobraTrapTest extends CardTestPlayerBase { public class CobraTrapTest extends CardTestPlayerBase {
/**
* Cast using the alternative cost.
*/
@Test @Test
public void testCard() { public void testCard() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
@ -30,6 +39,9 @@ public class CobraTrapTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Snake Token", 4); assertPermanentCount(playerA, "Snake Token", 4);
} }
/**
* Check that the alternative cost can't be paid if the condition isn't met.
*/
@Test @Test
public void testCardNegative() { public void testCardNegative() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
@ -37,13 +49,11 @@ public class CobraTrapTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3);
addCard(Zone.HAND, playerB, "Stone Rain"); 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); setStopAt(2, PhaseStep.END_TURN);
execute(); execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Forest", 2); assertPermanentCount(playerA, "Forest", 2);
assertPermanentCount(playerA, "Snake Token", 0); 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, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Felidar Guardian"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Felidar Guardian");
setChoice(playerA, "When "); // Select order of Felidar trigger setChoice(playerA, "When "); // Select order of Felidar trigger
@ -53,7 +55,6 @@ public class GripOfChaosTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
setStrictChooseMode(true);
execute(); execute();
assertPermanentCount(playerA, "Felidar Guardian", 1); assertPermanentCount(playerA, "Felidar Guardian", 1);

View file

@ -7,18 +7,16 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @author LevelX2
*/ */
public class ObstinateBalothTest extends CardTestPlayerBase { 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 @Test
public void TestLifeGainIfForcedToDiscard() { public void TestLifeGainIfForcedToDiscard() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
@ -28,7 +26,7 @@ public class ObstinateBalothTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Obstinate Baloth"); addCard(Zone.HAND, playerB, "Obstinate Baloth");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raven's Crime", playerB); 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); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -40,11 +38,10 @@ public class ObstinateBalothTest extends CardTestPlayerBase {
assertLife(playerB, 24); // + 4 from Obstinate Baloth entering the battlefield assertLife(playerB, 24); // + 4 from Obstinate Baloth entering the battlefield
} }
/* /**
Obstinate Baloth enters the battlefield and will also be sacrificed during the * Obstinate Baloth enters the battlefield and will also be sacrificed during the resolution of Smallpox.
resolution of Smallpox. So it's triggered ability goes to the stack as the * So it's triggered ability goes to the stack as the Obstinate Baloth has already left the battlefield again.
Obstinate Baloth has already left the battlefield again. * So EntersBattlefieldTriggeredAbility has to work in all zones as a consequence.
So EntersBattlefieldTriggeredAbility has to work in all zones as a consequence.
*/ */
@Test @Test
public void TestWithSmallpox() { public void TestWithSmallpox() {
@ -54,9 +51,16 @@ public class ObstinateBalothTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Obstinate Baloth"); addCard(Zone.HAND, playerB, "Obstinate Baloth");
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Smallpox"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Smallpox");
setChoice(playerB, "Obstinate Baloth"); // comes into play after directly after discard // playerB - Discard a card - Its ability will send it to the battlefield instead of the graveyard
setChoice(playerB, "Obstinate Baloth"); // and can and has to be sacrificed here addTarget(playerB, "Obstinate Baloth");
// playerB - Sacrifice a creature
setChoice(playerB, "Obstinate Baloth");
// playerA - Sacrifice a land
setChoice(playerA, "Swamp");
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();

View file

@ -7,6 +7,11 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @author LevelX2
*/ */
@ -14,18 +19,18 @@ public class OneOrMoreCardsGoToGraveyardTest extends CardTestPlayerBase {
@Test @Test
public void TestCrawlingSensation() { 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.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. // {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"); addCard(Zone.HAND, playerA, "Evolving Wilds");
setStrictChooseMode(true);
setChoice(playerA, true);
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Evolving Wilds"); playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Evolving Wilds");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Sacrifice"); activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Sacrifice");
setChoice(playerA, "Mountain"); addTarget(playerA, "Mountain");
setStopAt(2, PhaseStep.BEGIN_COMBAT); setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -33,6 +38,5 @@ public class OneOrMoreCardsGoToGraveyardTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Evolving Wilds", 1); assertGraveyardCount(playerA, "Evolving Wilds", 1);
assertPermanentCount(playerA, "Mountain", 1); assertPermanentCount(playerA, "Mountain", 1);
assertPermanentCount(playerA, "Insect Token", 2); 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 * 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 * 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 * 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 * hand.
* returned to my hand but it did NOT trigger for some reason. Nothing was * My graveyard was empty so that was the only card I chose.
* destroyed * Child returned to my hand but it did NOT trigger for some reason.
* Nothing was destroyed.
*/ */
@Test @Test
public void testSacrificeChildOfAlara() { public void testSacrificeChildOfAlara() {
@ -64,15 +65,19 @@ public class EndStepTriggerTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1); addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
addCard(Zone.BATTLEFIELD, playerB, "Forest", 4); addCard(Zone.BATTLEFIELD, playerB, "Forest", 4);
// Bound // 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 // Determined
// Other spells you control can't be countered this turn. // Other spells you control can't be countered this turn.
// Draw a card. // Draw a card.
addCard(Zone.HAND, playerB, "Bound // Determined"); // Instant {3}{B}{G} // {G}{U} addCard(Zone.HAND, playerB, "Bound // Determined"); // Instant {3}{B}{G} // {G}{U}
setStrictChooseMode(true);
castSpell(1, PhaseStep.END_TURN, playerB, "Bound"); castSpell(1, PhaseStep.END_TURN, playerB, "Bound");
addTarget(playerB, "Child of Alara"); addTarget(playerB, "Child of Alara");
setChoice(playerB, "Child of Alara"); addTarget(playerB, "Child of Alara");
setStopAt(2, PhaseStep.PRECOMBAT_MAIN); setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
execute(); execute();

View file

@ -6,19 +6,20 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; 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 * @author BetaSteward
*/ */
public class KaradorGhostChieftainTest extends CardTestPlayerBase { public class KaradorGhostChieftainTest extends CardTestPlayerBase {
/*
* Karador, Ghost Chieftain /**
* Legendary Creature Centaur Spirit 3/4, 5WBG (8) * Test that you can cast a spell from the graveyard.
* 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 @Test
public void testPlayFromGraveyard() { public void testPlayFromGraveyard() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
@ -30,12 +31,13 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
this.assertPermanentCount(playerA, "Raging Goblin", 1); assertPermanentCount(playerA, "Raging Goblin", 1);
this.assertGraveyardCount(playerA, "Raging Goblin", 0); assertGraveyardCount(playerA, "Raging Goblin", 0);
} }
// test that can only play one spell from graveyard /**
* Test that you can cast from your graveyard.
*/
@Test @Test
public void testPlayOneFromGraveyard() { public void testPlayOneFromGraveyard() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
@ -48,12 +50,13 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
this.assertPermanentCount(playerA, "Raging Goblin", 1); assertPermanentCount(playerA, "Raging Goblin", 1);
this.assertGraveyardCount(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 @Test
public void testPlayOneFromGraveyardPerTurn() { public void testPlayOneFromGraveyardPerTurn() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
@ -61,14 +64,15 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, "Raging Goblin", 2); addCard(Zone.GRAVEYARD, playerA, "Raging Goblin", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raging Goblin"); 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"); 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); setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute(); execute();
this.assertPermanentCount(playerA, "Raging Goblin", 2); assertPermanentCount(playerA, "Raging Goblin", 2);
this.assertGraveyardCount(playerA, "Raging Goblin", 0); assertGraveyardCount(playerA, "Raging Goblin", 0);
} }
} }