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

This commit is contained in:
Alex Vasile 2022-05-29 21:03:57 -06:00
parent 80f6db1245
commit 01be1b1a6b
34 changed files with 419 additions and 285 deletions

View file

@ -8,47 +8,49 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.l.LinvalaKeeperOfSilence Linvala, Keeper of Silence}
* {2}{W}{W}
* Legendary Creature Angel
* Flying
* Activated abilities of creatures your opponents control cant be activated.
*
* Created by Derek M on 3/6/2017.
*/
public class LinvalaKeeperOfSilenceTest extends CardTestPlayerBase {
/*
* Reported bug: Linvala, Keeper of Silence, played by my opponent, did not prevent me from activating abilities with the "tap" symbol.
* Examples included Jagged-Scar Archers and Imperious Perfect;
/**
* Reported bug: Linvala, Keeper of Silence, played by my opponent,
* did not prevent me from activating abilities with the "tap" symbol.
* Examples included Jagged-Scar Archers and Imperious Perfect;
*/
@Test
public void linvalaSilencesActivatedAbilities()
{
public void linvalaSilencesActivatedAbilities() {
String linvala = "Linvala, Keeper of Silence";
String jScarArcher = "Jagged-Scar Archers";
String imperiousPerfect = "Imperious Perfect";
/*
Linvala, Keeper of Silence {2}{W}{W}
Legendary Creature - Angel 3/4
Flying
Activated abilities of creatures your opponents control can't be activated.
*/
addCard(Zone.BATTLEFIELD, playerA, linvala);
/*
{1}{G}{G} Elf Archer * / *
Jagged-Scar Archers's power and toughness are each equal to the number of Elves you control.
Tap: Jagged-Scar Archers deals damage equal to its power to target creature with flying.
*/
* {1}{G}{G} Elf Archer * / *
* Jagged-Scar Archers's power and toughness are each equal to the number of Elves you control.
* Tap: Jagged-Scar Archers deals damage equal to its power to target creature with flying.
*/
addCard(Zone.BATTLEFIELD, playerB, jScarArcher);
/*
{2}{G} Creature - Elf Warrior 2/2
Other Elf creatures you control get +1/+1.
{G}, Tap: Create a 1/1 green Elf Warrior creature token.
*/
* {2}{G} Creature - Elf Warrior 2/2 Other
* Elf creatures you control get +1/+1.
* {G}, Tap: Create a 1/1 green Elf Warrior creature token.
*/
addCard(Zone.BATTLEFIELD, playerB, imperiousPerfect);
addCard(Zone.BATTLEFIELD, playerB, "Forest", 2);
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{G}:"); // Imperious Perfect: create 1/1 elf warrior token
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerB, "Jagged", linvala); // Jagged-scar: deal damage to Linvala equal to elves in play
// Imperious Perfect: create 1/1 elf warrior token
checkPlayableAbility("Can't use activated abilities", 2, PhaseStep.PRECOMBAT_MAIN, playerB, "{G}:", false);
// Jagged-scar: deal damage to Linvala equal to elves in play
checkPlayableAbility("Can't use activated abilities", 2, PhaseStep.PRECOMBAT_MAIN, playerB, "Jagged", false);
setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute();

View file

@ -20,14 +20,12 @@ public class SearchEntersBattlefieldTest extends CardTestPlayerBase {
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Verdant Catacombs");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Pay");
setChoice(playerA, "Forest");
addTarget(playerA, "Forest");
setStopAt(1, PhaseStep.END_TURN);
execute();
assertGraveyardCount(playerA, "Verdant Catacombs", 1);
assertPermanentCount(playerA, "Forest", 1);
assertTapped("Forest", false);
}
}

View file

@ -89,7 +89,8 @@ public class JumpStartTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Experimental Frenzy");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Direct Current with jump-start", playerB);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
checkPlayableAbility("Can't cast lightning bolt", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cast Lightning", false);
// castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
setStopAt(1, PhaseStep.END_TURN);
execute();
@ -99,12 +100,9 @@ public class JumpStartTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Direct Current", 0);
assertExileCount(playerA, "Direct Current", 1);
assertHandCount(playerA, "Lightning Bolt", 1); // prevented to cast from hand by Experimental Frenzy
assertGraveyardCount(playerA, "Lightning Bolt", 1); // Discarded by using jump-start
assertLife(playerA, 20);
assertLife(playerB, 18);
}
}

View file

@ -553,13 +553,13 @@ public class KickerTest extends CardTestPlayerBase {
assertAllCommandsUsed();
}
/**
* Bug: When I cast Orim's Chant with Kicker cost, the player can play spells
* anyway during the turn.
* It seems like the kicker cost trigger an "instead" creatures can't attack.
*/
@Test
public void test_Single_OrimsChants() {
// bug:
// When I cast Orim's Chant with Kicker cost, the player can play spells
// anyway during the turn. It seems like the kicker cost trigger an
// "instead" creatures can't attack.
addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin", 1); // Haste 1/1
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
// Kicker {W} (You may pay an additional {W} as you cast this spell.)
@ -577,11 +577,19 @@ public class KickerTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
// attack must be restricted, so no attack commands available
//setStrictChooseMode(true);
// Attack must be restricted, so no attack commands available
setStopAt(1, PhaseStep.END_TURN);
execute();
//assertAllCommandsUsed();
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 attack with Raging Golin, but got:\n" + e.getMessage());
}
}
assertGraveyardCount(playerA, "Orim's Chant", 1);
assertGraveyardCount(playerB, "Lightning Bolt", 0);

View file

@ -87,31 +87,4 @@ public class MiracleTest extends CardTestPlayerBase {
assertLife(playerB, 15);
}
/**
* Test that you can't cast a card by miracle if you put it back to library before casting
*/
@Test
public void testMiracleWontWorkFromLibrary() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.LIBRARY, playerA, "Plains");
addCard(Zone.LIBRARY, playerA, "Forest");
addCard(Zone.LIBRARY, playerA, "Thunderous Wrath");
addCard(Zone.HAND, playerA, "Brainstorm");
skipInitShuffling();
castSpell(1, PhaseStep.UPKEEP, playerA, "Brainstorm");
addTarget(playerA, "Thunderous Wrath");
addTarget(playerA, "Plains");
addTarget(playerA, playerB);
setStopAt(1, PhaseStep.DRAW);
execute();
// check Thunderous Wrath was not played
assertLife(playerA, 20);
assertLife(playerB, 20);
}
}

View file

@ -396,13 +396,12 @@ public class SoulbondKeywordTest extends CardTestPlayerBase {
Assert.assertEquals(eliteVanguard.getPairedCard(), null);
}
/*
/**
* Reported bug: Soulbond should use the stack, but unable to use instant speed removal since no trigger occurs
*/
@Test
// Soulbond does not currently use the stack, so this test will fail until then
public void testRespondToSoulboundWithRemoval() {
// When Palinchron enters the battlefield, untap up to seven lands.
// {2}{U}{U}: Return Palinchron to its owner's hand.
addCard(Zone.BATTLEFIELD, playerA, "Palinchron"); // 4/5 flying

View file

@ -19,7 +19,6 @@ public class SpliceOnArcaneTest extends CardTestPlayerBase {
*/
@Test
public void testSpliceThroughTheBreach() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
// Sorcery - Arcane {R}
// Lava Spike deals 3 damage to target player.
@ -33,7 +32,7 @@ public class SpliceOnArcaneTest extends CardTestPlayerBase {
// activate splice: yes -> card with splice ability -> new target for spliced ability
setChoice(playerA, true);
addTarget(playerA, "Through the Breach");
addTarget(playerA, "Silvercoat Lion"); // target for spliced ability: put from hand to battlefield
setChoice(playerA, "Silvercoat Lion"); // target for spliced ability: put from hand to battlefield
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -83,11 +82,12 @@ public class SpliceOnArcaneTest extends CardTestPlayerBase {
/**
* Nourishing Shoal's interaction with Splicing Through the Breach is
* bugged. You should still need to pay 2RR as an additional cost, which is
* bugged.
* You should still need to pay 2RR as an additional cost, which is
* not affected by the alternate casting method of Shoal, but you are able
* to Splice it for free. This is a very relevant bug right now due to the
* appearance of the deck over the weekend, and it makes the deck absurdly
* powerful.
* to Splice it for free.
* This is a very relevant bug right now due to the appearance of the deck
* over the weekend, and it makes the deck absurdly powerful.
*/
@Test
public void testSpliceThroughTheBreach2() {
@ -105,7 +105,7 @@ public class SpliceOnArcaneTest extends CardTestPlayerBase {
// activate splice: yes -> card with splice ability -> new target for spliced ability
setChoice(playerA, true);
addTarget(playerA, "Through the Breach");
addTarget(playerA, "Silvercoat Lion"); // target for spliced ability: put from hand to battlefield
setChoice(playerA, "Silvercoat Lion"); // target for spliced ability: put from hand to battlefield
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();

View file

@ -24,15 +24,9 @@ public class RuneflareTrapTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Runeflare Trap");
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Runeflare Trap", playerA);
checkPlayableAbility("Can't Runeflare Trap", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Cast Runeflare", false);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertHandCount(playerB, "Runeflare Trap", 1);
}
}

View file

@ -7,6 +7,11 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.s.SatyrFiredancer Satyr Firedancer}
* {1}{R}
* Enchantment Creature Satyr
* Whenever an instant or sorcery spell you control deals damage to an opponent,
* Satyr Firedancer deals that much damage to target creature that player controls.
*
* @author LevelX2
*/
@ -14,7 +19,6 @@ public class SatyrFiredancerTest extends CardTestPlayerBase {
@Test
public void testDamageFromInstantToPlayer() {
// Whenever an instant or sorcery spell you control deals damage to an opponent, Satyr Firedancer deals that much damage to target creature that player controls.
addCard(Zone.BATTLEFIELD, playerA, "Satyr Firedancer");
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.HAND, playerA, "Lightning Bolt");
@ -34,44 +38,46 @@ public class SatyrFiredancerTest extends CardTestPlayerBase {
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
}
/**
* Check that Satyr won't trigger from combat damage.
*/
@Test
public void testDamageFromAttackWontTrigger() {
// Whenever an instant or sorcery spell you control deals damage to an opponent, Satyr Firedancer deals that much damage to target creature that player controls.
addCard(Zone.BATTLEFIELD, playerA, "Satyr Firedancer");
addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox", 1);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
setStrictChooseMode(true);
attack(1, playerA, "Pillarfield Ox");
addTarget(playerA, "Silvercoat Lion");
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 18);
assertGraveyardCount(playerB, "Silvercoat Lion", 0);
assertPermanentCount(playerB, "Silvercoat Lion", 1);
}
/**
* Check that Satyr doesn't trigger from an ability.
*/
@Test
public void testDamageFromOtherCreature() {
// Whenever an instant or sorcery spell you control deals damage to an opponent, Satyr Firedancer deals that much damage to target creature that player controls.
public void testDamageFromAbility() {
addCard(Zone.BATTLEFIELD, playerA, "Satyr Firedancer");
// {T}: Prodigal Pyromancer deals 1 damage to any target.
addCard(Zone.BATTLEFIELD, playerA, "Prodigal Pyromancer", 1);
setStrictChooseMode(true);
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {this} deals", playerB);
addTarget(playerA, playerB);
setStopAt(3, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 19);
}
@Test

View file

@ -76,13 +76,15 @@ public class SpendOtherManaTest extends CardTestPlayerBase {
* of Nissa in play. Pretty sure Oath is working usually, so here were the
* conditions in my game:
* <p>
* -Cast Dark Petition with spell mastery -Attempt to cast Nissa, Voice of
* Zendikar using the triple black mana from Dark Petition
* 1. Cast Dark Petition with spell mastery
* 2. Attempt to cast Nissa, Voice of Zendikar using the triple black mana from Dark Petition
*/
@Test
public void testOathOfNissaWithDarkPetition() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
// When Oath of Nissa enters the battlefield, look at the top three cards of your library. You may reveal a creature, land, or planeswalker card from among them and put it into your hand. Put the rest on the bottom of your library in any order.
// When Oath of Nissa enters the battlefield, look at the top three cards of your library.
// You may reveal a creature, land, or planeswalker card from among them and put it into your hand.
// Put the rest on the bottom of your library in any order.
// You may spend mana as though it were mana of any color to cast planeswalker spells.
addCard(Zone.BATTLEFIELD, playerA, "Oath of Nissa");
addCard(Zone.GRAVEYARD, playerA, "Lightning Bolt", 2);
@ -97,7 +99,8 @@ public class SpendOtherManaTest extends CardTestPlayerBase {
addCard(Zone.LIBRARY, playerA, "Nissa, Voice of Zendikar"); // {1}{G}{G}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dark Petition");
setChoice(playerA, "Nissa, Voice of Zendikar");
addTarget(playerA, "Nissa, Voice of Zendikar");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Nissa, Voice of Zendikar");
setStopAt(1, PhaseStep.BEGIN_COMBAT);

View file

@ -11,21 +11,21 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*/
public class ImprisonedInTheMoonTest extends CardTestPlayerBase {
/*
* Reported bug: Urza land enchanted with Imprisoned In the Moon incorrectly makes it so other Urza lands only tap for 1 <> .
/**
* Reported bug: Urza land enchanted with Imprisoned In the Moon incorrectly makes it so other Urza lands only tap for 1 <>.
*
* Card ruling: https://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=414360
* If the enchanted permanent is a land and has land types, it retains those types even though it loses any intrinsic mana abilities associated with them.
* For example, a Plains enchanted by Imprisoned in the Moon is still a Plains, but it can't tap for {W}, only for {C}.
*/
*/
@Test
public void testEnchantUrzaLand() {
// Imprisoned in the Moon - Enchantment - Aura - {2}{U}
// Enchant creature, land, or planeswalker
// Enchanted permanent is a colorless land with "Tap: Add Colorless" and loses all other card types and abilities.
addCard(Zone.HAND, playerA, "Imprisoned in the Moon", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
addCard(Zone.BATTLEFIELD, playerB, "Urza's Mine", 1);
addCard(Zone.BATTLEFIELD, playerB, "Urza's Tower", 1);
addCard(Zone.BATTLEFIELD, playerB, "Urza's Power Plant", 1);
@ -36,14 +36,13 @@ public class ImprisonedInTheMoonTest extends CardTestPlayerBase {
addTarget(playerA, "Urza's Mine");
// 6 total mana available - 3 from Tower, 2 from Powerplant, 1 from enchanted Mine
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Wurmcoil Engine");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Bonesplitter");
checkPlayableAbility("Can't cast Bonesplitter", 2, PhaseStep.PRECOMBAT_MAIN, playerB, "Cast Bonesplitter", false);
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Imprisoned in the Moon", 1);
assertPermanentCount(playerB, "Wurmcoil Engine", 1);
assertHandCount(playerB,"Wurmcoil Engine", 0);
assertHandCount(playerB, "Bonesplitter", 1); // should never be cast - wurmcoil uses up all mana
assertPermanentCount(playerB, "Bonesplitter", 0);
}
}

View file

@ -83,10 +83,10 @@ public class LoosingAbilitiesTest extends CardTestPlayerBase {
}
/**
* Yixlid Jailer works incorrectly with reanimation spelss - I cast Unearth
* Yixlid Jailer works incorrectly with reanimation spels - I cast Unearth
* targeting Seasoned Pyromancer with a Yixlid Jailer in play, but didnt get
* the Pyromancer's ETB trigger. This is a bug as Jailer only affaects cards
* when they are on the battle field
* the Pyromancer's ETB trigger.
* This is a bug as Jailer only affaects cards when they are on the battlefield.
*/
@Test
public void testYixlidJailerAndETBEffects() {
@ -103,9 +103,14 @@ public class LoosingAbilitiesTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Unearth", 1); // Sorcery {B}
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Yixlid Jailer");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Unearth");
// Target card for Unearth
addTarget(playerB, "Seasoned Pyromancer");
// Discard 2 cards for Seasoned Pyromancer
setChoice(playerB, "Lightning Bolt^Lightning Bolt");
setStopAt(2, PhaseStep.BEGIN_COMBAT);

View file

@ -16,11 +16,12 @@ public class SerraAscendantTest extends CardTestPlayerBase {
/**
* The game goes on; they play Serra Ascendant on turn one, pass the
* turn, you play your newly unbanned Wild Nacatl with a Stomping Ground and
* also pass the turn. On turn 2, they cast a Martyr of Sands and sacrifice
* it, revealing 3 white cards to gain 9 life and end up at 29. They go to
* the combat phase, declare Serra as an attacker, and you happily block
* him, thinking that this is such a bad move from them. After the damage is
* dealt, the Serra is still there, bigger than ever.
* also pass the turn.
* On turn 2, they cast a Martyr of Sands and sacrifice it,
* revealing 3 white cards to gain 9 life and end up at 29.
* They go to the combat phase, declare Serra as an attacker, and you happily block
* him, thinking that this is such a bad move from them.
* After the damage is dealt, the Serra is still there, bigger than ever.
*/
@Test
public void testSilence() {
@ -44,7 +45,9 @@ public class SerraAscendantTest extends CardTestPlayerBase {
playLand(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Plains");
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Martyr of Sands");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}, You may reveal X white cards from your hand");
setChoice(playerA,"X=3");
setChoice(playerA, "Silvercoat Lion");
setChoice(playerA, "Silvercoat Lion");
setChoice(playerA, "Silvercoat Lion");
attack(3, playerA, "Serra Ascendant");
block(3, playerB, "Wild Nacatl", "Serra Ascendant");
@ -62,7 +65,5 @@ public class SerraAscendantTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Serra Ascendant", 1);
assertPowerToughness(playerA, "Serra Ascendant", 6, 6);
}
}

View file

@ -7,6 +7,10 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.s.Silence Silence}
* {W}
* Instant
* Your opponents cant cast spells this turn.
*
* @author LevelX2
*/
@ -23,15 +27,11 @@ public class SilenceTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.UPKEEP, playerA, "Silence");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Silvercoat Lion");
checkPlayableAbility("Can't cast spell", 2, PhaseStep.PRECOMBAT_MAIN, playerB, "Cast Silvercoat", false);
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA, "Silence", 1);
assertHandCount(playerB, "Silvercoat Lion", 1);
assertPermanentCount(playerB, "Silvercoat Lion", 0);
}
}

View file

@ -2,6 +2,7 @@ package org.mage.test.cards.continuous;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@ -20,7 +21,18 @@ public class SplitSecondTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Counterspell", "Sudden Shock");
setStopAt(1, PhaseStep.END_TURN);
execute();
// TODO: Needed, see https://github.com/magefree/mage/issues/8973
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 trying to use Counterspell, but got:\n" + e.getMessage());
}
}
assertHandCount(playerA, "Counterspell", 1);
assertGraveyardCount(playerA, "Sudden Shock", 1);

View file

@ -66,10 +66,10 @@ public class PlayCardsFromGraveyardTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, "Ancestral Vision");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Yawgmoth's Will");
// you may not suspend it from graveyard
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Suspend");
// You may not suspend it from graveyard
checkPlayableAbility("Can't suspend", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Suspend", false);
// It may not be possible to cast it from graveyard
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ancestral Vision");
checkPlayableAbility("Can't cast 0 cost cards", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Ancestral", false);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -85,5 +85,4 @@ public class PlayCardsFromGraveyardTest extends CardTestPlayerBase {
assertLife(playerA, 20);
assertLife(playerB, 20);
}
}

View file

@ -7,17 +7,18 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.i.IsochronScepter Isochron Scepter}
* {2}
* Artifact
* Imprint When Isochron Scepter enters the battlefield, you may exile an instant card with mana value 2 or less from your hand.
* {2}, {T}: You may copy the exiled card. If you do, you may cast the copy without paying its mana cost.
*
* @author BetaSteward
*/
public class IsochronScepterTest extends CardTestPlayerBase {
/**
* Isochron Scepter Artifact, 2 (2) Imprint When Isochron Scepter enters
* the battlefield, you may exile an instant card with converted mana cost 2
* or less from your hand. {2}, {T}: You may copy the exiled card. If you
* do, you may cast the copy without paying its mana cost.
*
* Test that the imprinting works.
*/
@Test
public void testImprint() {
@ -25,8 +26,11 @@ public class IsochronScepterTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Isochron Scepter");
addCard(Zone.HAND, playerA, "Lightning Bolt");
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Isochron Scepter");
addTarget(playerA, "Lightning Bolt");
setChoice(playerA, "Yes");
setChoice(playerA, "Lightning Bolt");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -34,9 +38,11 @@ public class IsochronScepterTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Isochron Scepter", 1);
assertExileCount("Lightning Bolt", 1);
assertLife(playerB, 20);
}
/**
* Test that the exiled card can be cpied.
*/
@Test
public void testCopyCard() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
@ -68,7 +74,8 @@ public class IsochronScepterTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Lightning Bolt");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Isochron Scepter");
addTarget(playerA, "Lightning Bolt");
setChoice(playerA, "Lightning Bolt");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2}, {T}:");
setChoice(playerA, true);
setChoice(playerA, false);
@ -105,7 +112,7 @@ public class IsochronScepterTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Isochron Scepter");
addTarget(playerA, "Angel's Grace");
setChoice(playerA, "Angel's Grace");
attack(2, playerB, "Dross Crocodile");
attack(2, playerB, "Dross Crocodile");
@ -142,7 +149,6 @@ public class IsochronScepterTest extends CardTestPlayerBase {
* Resolving a Silence cast from exile via Isochron Scepter during my
* opponent's upkeep does not prevent that opponent from casting spells that
* turn.
*
*/
@Test
public void testSilence() {
@ -154,13 +160,13 @@ public class IsochronScepterTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Isochron Scepter");
addTarget(playerA, "Silence");
setChoice(playerA, "Silence");
activateAbility(2, PhaseStep.UPKEEP, playerA, "{2}, {T}:");
setChoice(playerA, true);
setChoice(playerA, true);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Silvercoat Lion");
checkPlayableAbility("Can't cast Silvercoat", 2, PhaseStep.PRECOMBAT_MAIN, playerB, "Cast Silvercoat", false);
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();

View file

@ -56,14 +56,10 @@ public class FluctuatorTest extends CardTestPlayerBase {
// Cycling abilities you activate cost you up to {2} less to activate.
addCard(Zone.BATTLEFIELD, playerA, "Fluctuator");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cycling");
setChoice(playerA, "2"); // reduce 1 generic mana
checkPlayableAbility("Can't cycle", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cycling", false);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA, "Akroma's Vengeance", 0);
assertHandCount(playerA, 1);
}
/**

View file

@ -73,12 +73,12 @@ public class OptionalSacrificeTests extends CardTestPlayerBase {
*/
@Test
public void testGlintHawkNoArtifactControlled() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
addCard(Zone.HAND, playerA, "Glint Hawk");
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Glint Hawk");
setChoice(playerA, false);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -151,12 +151,12 @@ public class OptionalSacrificeTests extends CardTestPlayerBase {
*/
@Test
public void testDrakeFamiliarNoEnchantmentControlled() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
addCard(Zone.HAND, playerA, "Drake Familiar");
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Drake Familiar");
setChoice(playerA, false);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();

View file

@ -84,17 +84,16 @@ public class SpreadingSeasTest extends CardTestPlayerBase {
}
/**
* https://github.com/magefree/mage/issues/4529 Some spell effects that
* effect the use of mana abilities on lands are inoperative. Example
* Spreading Seas transforms enchanted land into an island and it loses all
* other abilities. The AI does not recognize this and is able to use all
* abilities of the enchanted land including all previous mana abilities and
* activated abilities, in addition to now also being an island due to
* Spreading Sea's effect.
* https://github.com/magefree/mage/issues/4529
* Some spell effects that effect the use of mana abilities on lands are inoperative.
* Example, Spreading Seas transforms enchanted land into an island and it loses all
* other abilities.
* The AI does not recognize this and is able to use all abilities of the enchanted
* land including all previous mana abilities and activated abilities,
* in addition to now also being an island due to Spreading Sea's effect.
*/
@Test
public void testSpreadingRemovesOtherAbilities() {
// Enchant land
// When Spreading Seas enters the battlefield, draw a card.
// Enchanted land is an Island.
@ -107,7 +106,8 @@ public class SpreadingSeasTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Spreading Seas", "Kher Keep");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "{1}{R}"); // Ability should not be available
// Kher Keep loses all abilit
checkPlayableAbility("", 1, PhaseStep.POSTCOMBAT_MAIN, playerB, "{1}{R}", false);
setStopAt(1, PhaseStep.END_TURN);
execute();

View file

@ -20,7 +20,7 @@ public class GainProtectionTest extends CardTestPlayerBase {
setChoice(playerA, "Green");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Apostle's Blessing", "Elite Vanguard");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Titanic Growth", "Elite Vanguard");
checkPlayableAbility("Can't cast Titanic", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cast Titanic", false);
setStopAt(1, PhaseStep.END_TURN);
execute();
@ -74,13 +74,15 @@ public class GainProtectionTest extends CardTestPlayerBase {
public void testGainProtectionByEnchantment() {
addCard(Zone.BATTLEFIELD, playerB, "Plains", 5);
// Flying
// When Brago, King Eternal deals combat damage to a player, exile any number of target nonland permanents you control, then return those cards to the battlefield under their owner's control.
// When Brago, King Eternal deals combat damage to a player,
// exile any number of target nonland permanents you control,
// then return those cards to the battlefield under their owner's control.
addCard(Zone.BATTLEFIELD, playerB, "Brago, King Eternal");
// Enchant creature
// When Pentarch Ward enters the battlefield, draw a card.
// As Pentarch Ward enters the battlefield, choose a color.
// Enchanted creature has protection from the chosen color. This effect doesn't remove Pentarch Ward.
addCard(Zone.HAND, playerB, "Pentarch Ward");// "{2}{W}"
addCard(Zone.HAND, playerB, "Pentarch Ward"); // "{2}{W}"
// Enchant creature
// Enchanted creature gets +1/+1 and has "Whenever this creature attacks, tap target creature defending player controls."
addCard(Zone.HAND, playerB, "Grasp of the Hieromancer");
@ -88,9 +90,9 @@ public class GainProtectionTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Pentarch Ward", "Brago, King Eternal");
setChoice(playerB, "White");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Grasp of the Hieromancer", "Brago, King Eternal");
checkPlayableAbility("Has protection", 2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Cast Grasp", false);
setStopAt(2, PhaseStep.BEGIN_COMBAT);
setStopAt(2, PhaseStep.END_TURN);
execute();
assertPermanentCount(playerB, "Pentarch Ward", 1);
@ -99,29 +101,32 @@ public class GainProtectionTest extends CardTestPlayerBase {
}
/**
* Pentarch Ward on Brago naming white. Brago combat trigger resolves
* blinking Pentarch Ward. Brago retains protection from white even though
* Pentarch Ward is now exiled, making him unable to be re-enchanted by
* Pentarch Ward.
* Pentarch Ward on Brago naming white.
* Brago combat trigger resolves blinking Pentarch Ward.
* Brago retains protection from white even though Pentarch Ward is now exiled,
* making him unable to be re-enchanted by Pentarch Ward.
*/
@Test
public void testGainLooseProtectionByEnchantment() {
addCard(Zone.BATTLEFIELD, playerB, "Plains", 3);
// Flying
// When Brago, King Eternal deals combat damage to a player, exile any number of target nonland permanents you control, then return those cards to the battlefield under their owner's control.
// When Brago, King Eternal deals combat damage to a player,
// exile any number of target nonland permanents you control,
// then return those cards to the battlefield under their owner's control.
addCard(Zone.BATTLEFIELD, playerB, "Brago, King Eternal");
// Enchant creature
// When Pentarch Ward enters the battlefield, draw a card.
// As Pentarch Ward enters the battlefield, choose a color.
// Enchanted creature has protection from the chosen color. This effect doesn't remove Pentarch Ward.
addCard(Zone.HAND, playerB, "Pentarch Ward");// "{2}{W}"
// Enchanted creature has protection from the chosen color.
// This effect doesn't remove Pentarch Ward.
addCard(Zone.HAND, playerB, "Pentarch Ward"); // "{2}{W}"
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Pentarch Ward", "Brago, King Eternal");
setChoice(playerB, "White");
attack(2, playerB, "Brago, King Eternal");
addTarget(playerB, "Pentarch Ward");
addTarget(playerB, "Brago, King Eternal");
setChoice(playerB, "Brago, King Eternal");
setStopAt(2, PhaseStep.END_COMBAT);
execute();

View file

@ -3,6 +3,7 @@ package org.mage.test.cards.replacement;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@ -134,8 +135,7 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
}
/**
* Doubling Season doesn't create two tokens from opponent's Rite of Raging
* Storm
* Doubling Season doesn't create two tokens from opponent's Rite of Raging Storm
*/
@Test
public void testDoubleRiteOfRagingStorm() {
@ -149,8 +149,6 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rite of the Raging Storm");
attack(2, playerB, "Lightning Rager"); // Can't attack
attack(3, playerA, "Lightning Rager");
attack(3, playerA, "Lightning Rager");
@ -163,7 +161,6 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
assertLife(playerB, 10);
assertLife(playerA, 20);
}
@Test
@ -182,15 +179,20 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
attack(2, playerB, "Lightning Rager:1"); // Can't attack
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
execute();
try {
execute();
assertAllCommandsUsed();
Assert.fail("must throw exception on execute");
} catch (Throwable e) {
if (!e.getMessage().contains("Player PlayerB must have 0 actions but found 2")) {
Assert.fail("Should have thrown error about cannot attack, but got:\n" + e.getMessage());
}
}
assertPermanentCount(playerA, "Rite of the Raging Storm", 1);
assertPermanentCount(playerB, "Lightning Rager", 2);
assertLife(playerB, 20);
assertLife(playerA, 20);
}
/**

View file

@ -14,7 +14,6 @@ public class PanharmoniconTest extends CardTestPlayerBase {
/**
* Check that Panharmonicon adds EtB triggers correctly.
*
*/
@Test
public void testAddsTrigger() {
@ -37,7 +36,6 @@ public class PanharmoniconTest extends CardTestPlayerBase {
/**
* Check that Panharmonicon doesn't add to opponents' triggers.
*
*/
@Test
public void testDoesntAddOpponentsTriggers() {
@ -60,7 +58,6 @@ public class PanharmoniconTest extends CardTestPlayerBase {
/**
* Check that Panharmonicon doesn't add to lands triggers.
*
*/
@Test
public void testDoesntAddLandsTriggers() {
@ -79,7 +76,6 @@ public class PanharmoniconTest extends CardTestPlayerBase {
/**
* Check that Panharmonicon doesn't add to non-permanents triggers.
*
*/
@Test
public void testDoesntAddNonPermanentsTriggers() {
@ -91,9 +87,11 @@ public class PanharmoniconTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Scion of Ugin");
addCard(Zone.BATTLEFIELD, playerA, "Plains", 6);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Scion of Ugin");
setChoice(playerA, false); // Return Bladewing's Thrall from your graveyard to the battlefield?
setChoice(playerA, true); // Should not get run since there is only one trigger.
// There should only be one trigger, so no need for another choice
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();

View file

@ -3,6 +3,7 @@ package org.mage.test.cards.restriction;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@ -34,7 +35,17 @@ public class CantAttackTest extends CardTestPlayerBase {
attack(3, playerA, "Myr Enforcer");
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
execute();
try {
execute();
assertAllCommandsUsed();
Assert.fail("must throw exception on execute");
} catch (Throwable e) {
if (!e.getMessage().contains("Player PlayerB must have 0 actions but found 1")) {
Assert.fail("Should have thrown error about not being able to attack, but got:\n" + e.getMessage());
}
}
assertLife(playerA, 8); // 8 + 4
assertLife(playerB, 14); // 4 + 2
@ -53,15 +64,25 @@ public class CantAttackTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); // 2/2
addCard(Zone.BATTLEFIELD, playerB, "Harbor Serpent"); // 5/5
attack(2, playerB, "Harbor Serpent");
attack(2, playerB, "Harbor Serpent"); // Can't attack since there are only 4 Islands
attack(2, playerB, "Silvercoat Lion");
playLand(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Island");
attack(3, playerA, "Harbor Serpent");
attack(3, playerA, "Harbor Serpent"); // Should be able to attack
attack(3, playerA, "Silvercoat Lion");
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
execute();
try {
execute();
assertAllCommandsUsed();
Assert.fail("must throw exception on execute");
} catch (Throwable e) {
if (!e.getMessage().contains("Player PlayerB must have 0 actions but found 1")) {
Assert.fail("Should have thrown error about not being able to attack, but got:\n" + e.getMessage());
}
}
assertLife(playerB, 13);
assertLife(playerA, 18);
@ -82,7 +103,17 @@ public class CantAttackTest extends CardTestPlayerBase {
attack(2, playerB, "Silvercoat Lion", playerA);
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
execute();
try {
execute();
assertAllCommandsUsed();
Assert.fail("must throw exception on execute");
} catch (Throwable e) {
if (!e.getMessage().contains("Player PlayerB must have 0 actions but found 1")) {
Assert.fail("Should have thrown error about not being able to attack, but got:\n" + e.getMessage());
}
}
assertLife(playerA, 20);
@ -114,7 +145,10 @@ public class CantAttackTest extends CardTestPlayerBase {
assertTapped("Battle-Mad Ronin", false);
}
// Orzhov Advokist's ability does not work. Your opponents get the counters but they can still attack you.
/**
* Orzhov Advokist's ability does not work.
* Your opponents get the counters but they can still attack you.
*/
@Test
public void testOrzhovAdvokist() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
@ -127,11 +161,20 @@ public class CantAttackTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Orzhov Advokist");
setChoice(playerA, true);
setChoice(playerB, true);
attack(2, playerB, "Silvercoat Lion");
attack(2, playerB, "Silvercoat Lion"); // Can't attack since they put a +1/+1 counter
attack(4, playerB, "Silvercoat Lion");
setStopAt(4, PhaseStep.POSTCOMBAT_MAIN);
execute();
try {
execute();
assertAllCommandsUsed();
Assert.fail("must throw exception on execute");
} catch (Throwable e) {
if (!e.getMessage().contains("Player PlayerB must have 0 actions but found 1")) {
Assert.fail("Should have thrown error about not being able to attack, but got:\n" + e.getMessage());
}
}
assertPermanentCount(playerA, "Orzhov Advokist", 1);
assertPowerToughness(playerA, "Orzhov Advokist", 3, 6);
@ -140,8 +183,8 @@ public class CantAttackTest extends CardTestPlayerBase {
assertPowerToughness(playerB, "Silvercoat Lion", 4, 4);
}
/*
Reported bug: Medomai was able to attack on an extra turn when cheated into play.
/**
* Reported bug: Medomai was able to attack on an extra turn when cheated into play.
*/
@Test
public void testMedomaiShouldNotAttackOnExtraTurns() {
@ -157,9 +200,14 @@ public class CantAttackTest extends CardTestPlayerBase {
/*
Cauldron Dance {4}{B}{R} Instant
Cast Cauldron Dance only during combat.
Return target creature card from your graveyard to the battlefield. That creature gains haste. Return it to your hand at the beginning of the next end step.
You may put a creature card from your hand onto the battlefield. That creature gains haste. Its controller sacrifices it at the beginning of the next end step.
Cast Cauldron Dance only during combat.
Return target creature card from your graveyard to the battlefield.
That creature gains haste.
Return it to your hand at the beginning of the next end step.
You may put a creature card from your hand onto the battlefield.
That creature gains haste.
Its controller sacrifices it at the beginning of the next end step.
*/
String cDance = "Cauldron Dance";
String dBlade = "Doom Blade"; // {1}{B} instant destroy target creature
@ -178,9 +226,19 @@ public class CantAttackTest extends CardTestPlayerBase {
addTarget(playerA, medomai);
attack(2, playerA, medomai);
// medomai should not have been allowed to attack, but returned to hand at beginning of next end step still
// Medomai should not have been allowed to attack, but returned to hand at beginning of next end step still
setStopAt(2, PhaseStep.END_TURN);
execute();
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 attack, but got:\n" + e.getMessage());
}
}
assertLife(playerB, 16); // one hit from medomai
assertGraveyardCount(playerA, dBlade, 1);
@ -217,7 +275,17 @@ public class CantAttackTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, eFirecraft, playerB);
setStopAt(2, PhaseStep.END_TURN);
execute();
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 attack, but got:\n" + e.getMessage());
}
}
assertLife(playerB, 12); // 1 hit from medomai and firecraft = 8 damage
assertGraveyardCount(playerA, eFirecraft, 1);
@ -394,7 +462,17 @@ public class CantAttackTest extends CardTestPlayerBase {
attack(3, playerA, "Admiral Beckett Brass"); // Can't attack
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
execute();
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 attack, but got:\n" + e.getMessage());
}
}
assertPermanentCount(playerA, "Opportunistic Dragon", 1);
assertPermanentCount(playerA, "Admiral Beckett Brass", 1);
@ -430,7 +508,17 @@ public class CantAttackTest extends CardTestPlayerBase {
attack(4, playerB, "Admiral Beckett Brass"); // Can attack again
setStopAt(4, PhaseStep.POSTCOMBAT_MAIN);
execute();
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 attack, but got:\n" + e.getMessage());
}
}
assertGraveyardCount(playerB, "Terror", 1);
assertGraveyardCount(playerA, "Opportunistic Dragon", 1);

View file

@ -6,14 +6,26 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.d.DuskDawn Dusk}
* {2}{W}{W}
* Sorcery
* Destroy all creatures with power 3 or greater.
*
* {@link mage.cards.d.DuskDawn Dawn}
* {3}{W}{W}
* Sorcery
* Aftermath (Cast this spell only from your graveyard. Then exile it.)
* Return all creature cards with power 2 or less from your graveyard to your hand.
*
* @author Quercitron
*/
public class DuskDawnTest extends CardTestPlayerBase {
/**
* Test that you can properly cast Dusk (regular part) from hand
*/
@Test
public void testCastDusk() {
//Cast dusk from hand
addCard(Zone.BATTLEFIELD, playerB, "Watchwolf");
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.HAND, playerA, "Dusk // Dawn");
@ -22,19 +34,24 @@ public class DuskDawnTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.END_TURN);
execute();
assertTappedCount("Plains", true, 4); // check that we paid the right side's mana
// check that we paid the right side's mana
assertTappedCount("Plains", true, 4);
assertPermanentCount(playerB, "Watchwolf", 0);
assertGraveyardCount(playerB, "Watchwolf", 1);
assertGraveyardCount(playerA, "Dusk // Dawn", 1);
}
/**
* Test that you cannot cast Dusk (Reguar part) from graveyard.
*/
@Test
public void testCastDuskFromGraveyardFail() {
//Fail to cast dusk from graveyard
addCard(Zone.BATTLEFIELD, playerB, "Watchwolf");
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
addCard(Zone.GRAVEYARD, playerA, "Dusk // Dawn");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dusk");
checkPlayableAbility("Can't cast Dusk", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Dusk", false);
setStopAt(1, PhaseStep.END_TURN);
execute();
@ -44,12 +61,11 @@ public class DuskDawnTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Dusk // Dawn", 1);
}
/**
* Test that you can cast Dawn (Aftermath part) from graveyard.
*/
@Test
public void testCastDawnFromGraveyard() {
// Dusk
// Destroy all creatures with power 3 or greater.
// Dawn
// Return all creature cards with power less than or equal to 2 from your graveyard to your hand.
addCard(Zone.GRAVEYARD, playerA, "Dusk // Dawn");
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.GRAVEYARD, playerA, "Devoted Hero");
@ -59,34 +75,32 @@ public class DuskDawnTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.END_TURN);
execute();
// Dusk dawn should have been cast and exiled
// devoted hero should be in the hand
// watchwolf should still be in the yard
assertHandCount(playerA, "Devoted Hero", 1);
assertGraveyardCount(playerA, "Devoted Hero", 0);
assertGraveyardCount(playerA, "Watchwolf", 1);
// Dusk // Dawn should have been cast and exiled
assertExileCount(playerA, "Dusk // Dawn", 1);
assertGraveyardCount(playerA, "Dusk // Dawn", 0);
// Devoted hero should be in the hand
assertHandCount(playerA, "Devoted Hero", 1);
assertGraveyardCount(playerA, "Devoted Hero", 0);
// Watchwolf should still be in the graveyard
assertGraveyardCount(playerA, "Watchwolf", 1);
}
// Fail to cast Dawn (Aftermath part) from hand
/**
* Test that you can't cast Dawn (Aftermath part) from hand.
*/
@Test
public void testCastDawnFail() {
// Dusk {2}{W}{W}
// Destroy all creatures with power 3 or greater.
// Dawn {3}{W}{W}
// Return all creature cards with power less than or equal to 2 from your graveyard to your hand.
addCard(Zone.HAND, playerA, "Dusk // Dawn");
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.GRAVEYARD, playerA, "Devoted Hero"); // Creature 1/2 {W}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dawn");
checkPlayableAbility("Can't cast Dawn", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Dawn", false);
setStopAt(1, PhaseStep.END_TURN);
execute();
// Dusk dawn shouldn't have been cast and devoted hero should still be in the yard
assertHandCount(playerA, "Dusk // Dawn", 1);
assertGraveyardCount(playerA, "Devoted Hero", 1);
}
}

View file

@ -6,6 +6,11 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.n.NephaliaAcademy Nephalia Academy}
* Land
* If a spell or ability an opponent controls causes you to discard a card,
* you may reveal that card and put it on top of your library instead of putting it anywhere else.
* {T}: Add {C}.
*
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
@ -18,9 +23,6 @@ public class NephaliaAcademyTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Duress", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
// Nephalia Academy - Land <>
// If a spell or ability an opponent controls causes you to discard a card,
// you may reveal that card and put it on top of your library instead of putting it anywhere else.
addCard(Zone.HAND, playerB, "Giant Growth", 1); // discard fodder
addCard(Zone.BATTLEFIELD, playerB, "Nephalia Academy", 1);
@ -43,9 +45,6 @@ public class NephaliaAcademyTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Duress", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
// Nephalia Academy - Land <>
// If a spell or ability an opponent controls causes you to discard a card,
// you may reveal that card and put it on top of your library instead of putting it anywhere else.
addCard(Zone.HAND, playerB, "Giant Growth", 1); // discard fodder
addCard(Zone.BATTLEFIELD, playerB, "Nephalia Academy", 1);
@ -62,10 +61,6 @@ public class NephaliaAcademyTest extends CardTestPlayerBase {
@Test
public void testShouldNotApplyToOwnDiscardSpell() {
// Nephalia Academy - Land <>
// If a spell or ability an opponent controls causes you to discard a card,
// you may reveal that card and put it on top of your library instead of putting it anywhere else.
addCard(Zone.BATTLEFIELD, playerA, "Nephalia Academy", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
addCard(Zone.HAND, playerA, "Memnite", 1); // discard fodder
@ -74,9 +69,11 @@ public class NephaliaAcademyTest extends CardTestPlayerBase {
// Draw three cards. Then discard a card.
addCard(Zone.HAND, playerA, "Sift", 1);
setStrictChooseMode(true);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sift");
setChoice(playerA, true); // should not be given the option to use Nephalia Academy replacement effect
setChoice(playerA, "Memnite");
// should not be given the option to use Nephalia Academy replacement effect
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();

View file

@ -6,11 +6,19 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* {@link mage.cards.k.KarfellHarbinger Karfell Harbinger}
* {1}{U}
* Creature Zombie Wizard
* {T}: Add {U}. Spend this mana only to foretell a card from your hand or cast an instant or sorcery spell.
*
* @author TheElk801
*/
public class KarfellHarbingerTest extends CardTestPlayerBase {
/**
* Test that spending the money on Foretell works.
*/
@Test
public void testForetellMana() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
@ -27,6 +35,9 @@ public class KarfellHarbingerTest extends CardTestPlayerBase {
assertHandCount(playerA, "Augury Raven", 0);
}
/**
* Test that spending the mana on an instant works.
*/
@Test
public void testSpellMana() {
addCard(Zone.BATTLEFIELD, playerA, "Karfell Harbinger");
@ -42,12 +53,15 @@ public class KarfellHarbingerTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Obsessive Search", 1);
}
/**
* Test that you can't use the mana on something else.
*/
@Test
public void testOtherMana() {
addCard(Zone.BATTLEFIELD, playerA, "Karfell Harbinger");
addCard(Zone.HAND, playerA, "Flying Men");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Flying Men");
checkPlayableAbility("can't cast flying man", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Flying", false);
setStopAt(1, PhaseStep.END_TURN);
execute();

View file

@ -24,11 +24,10 @@ public class NeedleDropTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shock", playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shock", "Hill Giant");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Needle Drop", playerA);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Needle Drop", playerB);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Needle Drop", playerA);
// castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Needle Drop", playerB); // TODO: This should produce an error but doesn't (playerA isn't a valid target)
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Needle Drop", "Hill Giant");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Needle Drop", "Flying Men");
setStopAt(1, PhaseStep.END_TURN);
execute();
@ -36,7 +35,6 @@ public class NeedleDropTest extends CardTestPlayerBase {
assertLife(playerA, 17);
assertLife(playerB, 20);
assertPermanentCount(playerB, "Hill Giant", 0);
assertPermanentCount(playerB, "Flying Men", 1);
}
@Test
@ -51,8 +49,7 @@ public class NeedleDropTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shock", playerB);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shock", "Hill Giant");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Needle Drop", playerB);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Needle Drop", "Hill Giant");
checkPlayableAbility("Can't Needle Drop", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Needle Drop", false);
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
execute();
@ -61,5 +58,4 @@ public class NeedleDropTest extends CardTestPlayerBase {
assertLife(playerB, 18);
assertPermanentCount(playerB, "Hill Giant", 1);
}
}

View file

@ -6,6 +6,12 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* Idol of Endurance
* {2}{W}
* Artifact
* When Idol of Endurance enters the battlefield, exile all creature cards with mana value 3 or less from your graveyard until Idol of Endurance leaves the battlefield.
* {1}{W}, {T}: Until end of turn, you may cast a creature spell from among cards exiled with Idol of Endurance without paying its mana cost.
*
* @author TheElk801
*/
public class IdolOfEnduranceTest extends CardTestPlayerBase {
@ -18,6 +24,9 @@ public class IdolOfEnduranceTest extends CardTestPlayerBase {
private static final String pnhrmcn = "Panharmonicon";
private static final String bnyrdwrm = "Boneyard Wurm";
/**
* Test that you can cast a spell for free from those exiled
*/
@Test
public void testIdolCast() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
@ -26,8 +35,12 @@ public class IdolOfEnduranceTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, idol);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
// Exile the Squire
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W}");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
// Play for free
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sqr);
setStopAt(1, PhaseStep.END_TURN);
@ -37,6 +50,9 @@ public class IdolOfEnduranceTest extends CardTestPlayerBase {
assertPermanentCount(playerA, sqr, 1);
}
/**
* Test that you can only cast 1 spell per activation.
*/
@Test
public void testIdolCast2() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
@ -45,21 +61,22 @@ public class IdolOfEnduranceTest extends CardTestPlayerBase {
addCard(Zone.GRAVEYARD, playerA, glrskr);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, idol);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W}");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
// Cast the first spell
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sqr);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, glrskr);
// Ensure that you can't cast the second spell
checkPlayableAbility("Can't cast 2nd", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + glrskr, false);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPermanentCount(playerA, sqr, 1);
assertPermanentCount(playerA, glrskr, 0);
}
@Test

View file

@ -41,6 +41,13 @@ public class MoraugFuryOfAkoumTest extends CardTestPlayerBase {
attack(1, playerA, corpse);
}
/**
* If the landfall ability resolves during your precombat main phase,
* the additional combat phase will happen before your regular combat phase.
* Youll untap creatures you control at the beginning of the additional combat
* but not at the beginning of your regular combat.
* (2020-09-25)
*/
@Test
public void testPrecombatLandfall() {
makeCombatCounter();
@ -54,11 +61,16 @@ public class MoraugFuryOfAkoumTest extends CardTestPlayerBase {
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, mountain);
attackWithAttackers();
// untap trigger already happened, creatures are still tapped and can't attack again
attackWithAttackers(); // 0 damage
setStopAt(1, PhaseStep.END_TURN);
execute();
// untap trigger already happened, creatures are still tapped and can't attack again
assertTapped(lion, true);
assertTapped(bear, true);
assertTapped(corpse, true);
assertLife(playerA, 20 + 2);
assertLife(playerB, 100 - 9 - 0);
}

View file

@ -181,24 +181,28 @@ public class EntersTheBattlefieldTriggerTest extends CardTestPlayerBase {
*/
@Test
public void testWildPair() {
// Whenever a creature enters the battlefield, if you cast it from your hand, you may search your library for a creature card with the same total power and toughness and put it onto the battlefield. If you do, shuffle your library.
// Whenever a creature enters the battlefield, if you cast it from your hand,
// you may search your library for a creature card with the same total power and toughness and put it onto the battlefield.
// If you do, shuffle your library.
addCard(Zone.BATTLEFIELD, playerA, "Wild Pair");
addCard(Zone.HAND, playerA, "Silvercoat Lion", 1);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
setChoice(playerA, "Silvercoat Lion");
addCard(Zone.LIBRARY, playerA, "Silvercoat Lion");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion");
setChoice(playerA, "Yes"); // Yes for Wild Pair to find another creature
// Silvercoat Lion is the only other choice, let it be auto-chosen
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Silvercoat Lion", 2);
}
// Test self trigger
/**
* Test self trigger for Noxious Ghoul.
*/
@Test
public void testNoxiousGhoul1() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);

View file

@ -43,5 +43,4 @@ public class ChronozoaTest extends CardTestPlayerBase {
assertHandCount(playerA, 0);
}
}

View file

@ -21,7 +21,7 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase {
* Test that you can cast a spell from the graveyard.
*/
@Test
public void testPlayFromGraveyard() {
public void testCastFromGraveyard() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
addCard(Zone.BATTLEFIELD, playerA, "Karador, Ghost Chieftain");
addCard(Zone.GRAVEYARD, playerA, "Raging Goblin");
@ -35,25 +35,6 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Raging Goblin", 0);
}
/**
* Test that you can cast from your graveyard.
*/
@Test
public void testPlayOneFromGraveyard() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
addCard(Zone.BATTLEFIELD, playerA, "Karador, Ghost Chieftain");
addCard(Zone.GRAVEYARD, playerA, "Raging Goblin", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raging Goblin");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raging Goblin");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Raging Goblin", 1);
assertGraveyardCount(playerA, "Raging Goblin", 1);
}
/**
* Test that can cast only one spell from your graveyard per turn
*/

View file

@ -111,9 +111,10 @@ public class MyriadTest extends CardTestMultiPlayerBase {
addCard(Zone.BATTLEFIELD, playerC, "Pillarfield Ox", 1);
addCard(Zone.BATTLEFIELD, playerC, "Grizzly Bears", 1);
// Equipped creature has myriad.(Whenever this creature attacks, for each opponent other than the defending player,
// put a token that's a copy of this creature onto the battlefield tapped and attacking that player or a planeswalker
// they control. Exile those tokens at the end of combat.)
// Equipped creature has myriad. (Whenever this creature attacks, for each opponent other than the defending
// player, put a token that's a copy of this creature onto the battlefield tapped
// and attacking that player or a planeswalker they control.
// Exile those tokens at the end of combat.)
// Equip {4}
addCard(Zone.BATTLEFIELD, playerD, "Blade of Selves");
addCard(Zone.BATTLEFIELD, playerD, "Island", 4);
@ -123,20 +124,27 @@ public class MyriadTest extends CardTestMultiPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerD, "Man-o'-War");
addTarget(playerD, "Silvercoat Lion");
activateAbility(6, PhaseStep.PRECOMBAT_MAIN, playerD, "Equip", "Man-o'-War");
attack(6, playerD, "Man-o'-War", playerC);
setChoice(playerD, "Yes"); // for playerB
setChoice(playerD, "Yes"); // for playerA
addTarget(playerD, "Silvercoat Lion");
addTarget(playerD, "Pillarfield Ox");
addTarget(playerD, "Grizzly Bears");
setStopAt(6, PhaseStep.POSTCOMBAT_MAIN);
execute();
// Tokens exiled, only original left
assertPermanentCount(playerD, "Man-o'-War", 1);
assertPermanentCount(playerC, "Silvercoat Lion", 0);
assertPermanentCount(playerC, "Pillarfield Ox", 0);
assertPermanentCount(playerC, "Grizzly Bears", 1); // not in range
// Returned to hand by Man-o'-War
assertPermanentCount(playerC, "Silvercoat Lion", 0); // 1 by original and 1 by token
assertPermanentCount(playerC, "Pillarfield Ox", 0); // by token
// Still on the battlefield since only 3 Man-o'-War triggers
assertPermanentCount(playerC, "Grizzly Bears", 1);
assertHandCount(playerC, "Silvercoat Lion", 2);
assertHandCount(playerC, "Pillarfield Ox", 1);