From 7d3ff0551dfb1a7124c5b80d7f1386a72abdbff6 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 23 Jul 2015 15:58:10 +0200 Subject: [PATCH] Added a test. --- .../sets/magicorigins/NissaSageAnimist.java | 1 - .../sets/zendikar/QuestForTheGravelord.java | 4 +- .../test/cards/planeswalker/UginTest.java | 91 +++++++++++++++++++ .../java/org/mage/test/player/TestPlayer.java | 3 + .../base/impl/CardTestPlayerAPIImpl.java | 13 ++- Mage/src/mage/game/GameImpl.java | 15 ++- 6 files changed, 117 insertions(+), 10 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/planeswalker/UginTest.java diff --git a/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java b/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java index 6f256623cda..7959cf7f6b3 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java +++ b/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java @@ -67,7 +67,6 @@ public class NissaSageAnimist extends CardImpl { this.color.setGreen(true); this.nightCard = true; - this.canTransform = true; this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); diff --git a/Mage.Sets/src/mage/sets/zendikar/QuestForTheGravelord.java b/Mage.Sets/src/mage/sets/zendikar/QuestForTheGravelord.java index 540570e9664..ddba7cf5ceb 100644 --- a/Mage.Sets/src/mage/sets/zendikar/QuestForTheGravelord.java +++ b/Mage.Sets/src/mage/sets/zendikar/QuestForTheGravelord.java @@ -32,7 +32,6 @@ import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.Zone; import mage.MageInt; -import mage.ObjectColor; import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.RemoveCountersSourceCost; @@ -53,7 +52,6 @@ public class QuestForTheGravelord extends CardImpl { super(ownerId, 108, "Quest for the Gravelord", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{B}"); this.expansionSetCode = "ZEN"; - // Whenever a creature dies, you may put a quest counter on Quest for the Gravelord. this.addAbility(new DiesCreatureTriggeredAbility(new AddCountersSourceEffect(CounterType.QUEST.createInstance()), true)); // Remove three quest counters from Quest for the Gravelord and sacrifice it: Put a 5/5 black Zombie Giant creature token onto the battlefield. @@ -86,4 +84,4 @@ class ZombieToken extends Token { power = new MageInt(5); toughness = new MageInt(5); } -} \ No newline at end of file +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/planeswalker/UginTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/planeswalker/UginTest.java new file mode 100644 index 00000000000..bc396fbfd04 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/planeswalker/UginTest.java @@ -0,0 +1,91 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.cards.planeswalker; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.CounterType; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class UginTest extends CardTestPlayerBase { + + @Test + public void testCard() { + // +2: Ugin, the Spirit Dragon deals 3 damage to target creature or player. + // -X: Exile each permanent with converted mana cost X or less that's one or more colors. + // -10: You gain 7 life, draw 7 cards, then put up to seven permanent cards from your hand onto the battlefield. + addCard(Zone.BATTLEFIELD, playerA, "Ugin, the Spirit Dragon"); // starts with 7 Loyality counters + // Whenever a creature dies, you may put a quest counter on Quest for the Gravelord. + addCard(Zone.BATTLEFIELD, playerA, "Quest for the Gravelord"); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + + addCard(Zone.LIBRARY, playerB, "Forest", 2); + addCard(Zone.BATTLEFIELD, playerB, "Forest", 6); + // When Nissa, Vastwood Seer enters the battlefield, you may search your library for a basic Forest card, reveal it, put it into your hand, then shuffle your library. + // Whenever a land enters the battlefield under your control, if you control seven or more lands, exile Nissa, then return her to the battlefield transformed under her owner's control. + // +1: Reveal the top card of your library. If it's a land card, put it onto the battlefield. Otherwise, put it into your hand. + // -2: Put a legendary 4/4 green Elemental creature token named Ashaya, the Awoken World onto the battlefield. + // -7: Untap up to six target lands. They become 6/6 Elemental creatures. They're still lands. + addCard(Zone.HAND, playerB, "Nissa, Vastwood Seer"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {source} deals 3 damage to target creature or player.", playerB); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Nissa, Vastwood Seer"); + playLand(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Forest"); + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "-2: Put a legendary 4/4 green Elemental creature token named Ashaya, the Awoken World onto the battlefield."); + + attack(3, playerA, "Silvercoat Lion"); + block(3, playerB, "Ashaya, the Awoken World", "Silvercoat Lion"); + + activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "-X: Exile each permanent with converted mana cost X or less that's one or more colors"); + setChoice(playerA, "X=0"); + + setStopAt(3, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Ugin, the Spirit Dragon", 1); + assertCounterCount("Ugin, the Spirit Dragon", CounterType.LOYALTY, 9); // 7 + 2 - 0 + + assertGraveyardCount(playerA, "Silvercoat Lion", 1); + assertPermanentCount(playerB, "Ashaya, the Awoken World", 0); + + assertExileCount("Nissa, Vastwood Seer", 1); + + assertCounterCount("Quest for the Gravelord", CounterType.QUEST, 1); + + assertLife(playerA, 20); + assertLife(playerB, 17); + + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 683c11da3e7..4b8baa125c1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -253,6 +253,9 @@ public class TestPlayer implements Player { int targetsSet = 0; for (Player player : game.getPlayers().values()) { if (player.getName().equals(target)) { + if (ability.getTargets().isEmpty()) { + throw new UnsupportedOperationException("Ability has no targets, but there is a player target set - " + ability.toString()); + } ability.getTargets().get(0).addTarget(player.getId(), ability, game); targetsSet++; break; diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index 25b40da1869..d40b5113bff 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -219,6 +219,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * * @param player {@link Player} to remove all library cards from. */ + @Override public void removeAllCardsFromLibrary(TestPlayer player) { getCommands(player).put(Zone.LIBRARY, "clear"); } @@ -241,6 +242,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * playerB. * @param cardName Card name in string format. */ + @Override public void addCard(Zone gameZone, TestPlayer player, String cardName) { addCard(gameZone, player, cardName, 1, false); } @@ -254,6 +256,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * @param cardName Card name in string format. * @param count Amount of cards to be added. */ + @Override public void addCard(Zone gameZone, TestPlayer player, String cardName, int count) { addCard(gameZone, player, cardName, count, false); } @@ -270,6 +273,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * permanent should be tapped. In case gameZone is other than Battlefield, * {@link IllegalArgumentException} is thrown */ + @Override public void addCard(Zone gameZone, TestPlayer player, String cardName, int count, boolean tapped) { if (gameZone.equals(Zone.BATTLEFIELD)) { @@ -324,6 +328,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * @param player {@link Player} to set life count for. * @param life Life count to set. */ + @Override public void setLife(TestPlayer player, int life) { getCommands(player).put(Zone.OUTSIDE, "life:" + String.valueOf(life)); } @@ -714,16 +719,16 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement /** * Assert whether X permanents of the same name are tapped or not. * - * @param cardName Name of the permanent that should be checked. - * @param tapped Whether the permanent is tapped or not - * @param count The amount of this permanents that should be tapped + * @param cardName Name of the permanent that should be checked. + * @param tapped Whether the permanent is tapped or not + * @param count The amount of this permanents that should be tapped */ public void assertTappedCount(String cardName, boolean tapped, int count) throws AssertionError { int tappedAmount = 0; Permanent found = null; for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents()) { if (permanent.getName().equals(cardName)) { - if(permanent.isTapped() == tapped) { + if (permanent.isTapped() == tapped) { tappedAmount++; } found = permanent; diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 07fb43d5805..b14cd2908a0 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -44,6 +44,7 @@ import java.util.Random; import java.util.Set; import java.util.Stack; import java.util.UUID; +import mage.MageException; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; @@ -1173,6 +1174,7 @@ public abstract class GameImpl implements Game, Serializable { @Override public void playPriority(UUID activePlayerId, boolean resuming) { + int errorContinueCounter = 0; int bookmark = 0; clearAllBookmarks(); try { @@ -1239,11 +1241,19 @@ public abstract class GameImpl implements Game, Serializable { } } catch (Exception ex) { logger.fatal("Game exception gameId: " + getId(), ex); - ex.printStackTrace(); this.fireErrorEvent("Game exception occurred: ", ex); restoreState(bookmark, ""); bookmark = 0; - continue; + Player activePlayer = this.getPlayer(getActivePlayerId()); + if (errorContinueCounter > 15) { + throw new MageException("Iterated player priority after game exception too often, game ends!"); + } + if (activePlayer != null && !activePlayer.isTestMode()) { + errorContinueCounter++; + continue; + } else { + throw new MageException("Error in testclass"); + } } state.getPlayerList().getNext(); } @@ -1251,6 +1261,7 @@ public abstract class GameImpl implements Game, Serializable { } catch (Exception ex) { logger.fatal("Game exception ", ex); this.fireErrorEvent("Game exception occurred: ", ex); + this.end(); } finally { resetLKI(); clearAllBookmarks();