From 089ff267a7573e884013d2ebb3d1599292015ebc Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 6 Nov 2023 12:11:59 +0400 Subject: [PATCH] tests: added additional check for Karn Liberated (related to #11081) --- Mage.Sets/src/mage/cards/k/KarnLiberated.java | 8 +++---- .../continuous/CommandersGameRestartTest.java | 21 +++++++++++++++++++ .../mage/constants/CommanderCardType.java | 2 +- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/cards/k/KarnLiberated.java b/Mage.Sets/src/mage/cards/k/KarnLiberated.java index a8b86091f7e..94b62499d21 100644 --- a/Mage.Sets/src/mage/cards/k/KarnLiberated.java +++ b/Mage.Sets/src/mage/cards/k/KarnLiberated.java @@ -79,14 +79,14 @@ class KarnLiberatedEffect extends OneShotEffect { if (sourceObject == null) { return false; } - List cards = new ArrayList<>(); + List exiledCards = new ArrayList<>(); for (ExileZone zone : game.getExile().getExileZones()) { exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); if (zone.getId().equals(exileId)) { for (Card card : zone.getCards(game)) { if (!card.hasSubtype(SubType.AURA, game) && card.isPermanent(game)) { - cards.add(card); + exiledCards.add(card); } } } @@ -113,7 +113,7 @@ class KarnLiberatedEffect extends OneShotEffect { for (Card card : game.getCards()) { if (card.isOwnedBy(player.getId()) && !card.isCopy() // no copies && !player.getSideboard().contains(card.getId()) - && !cards.contains(card)) { // not the exiled cards + && !exiledCards.contains(card)) { if (game.getCommandersIds(player, CommanderCardType.ANY, false).contains(card.getId())) { game.addCommander(new Commander(card)); // TODO: check restart and init // no needs in initCommander call -- it's used on game startup (init) @@ -127,7 +127,7 @@ class KarnLiberatedEffect extends OneShotEffect { player.init(game); } } - for (Card card : cards) { + for (Card card : exiledCards) { game.getState().setZone(card.getId(), Zone.EXILED); game.getExile().add(exileId, sourceObject.getIdName(), card); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/CommandersGameRestartTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/CommandersGameRestartTest.java index 9efb9514327..4267fd0989b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/CommandersGameRestartTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/CommandersGameRestartTest.java @@ -4,6 +4,8 @@ import mage.constants.CommanderCardType; import mage.constants.PhaseStep; import mage.constants.Zone; import mage.counters.CounterType; +import mage.players.Player; +import mage.view.GameView; import mage.watchers.common.CommanderPlaysCountWatcher; import org.junit.Assert; import org.junit.Test; @@ -16,6 +18,19 @@ import java.util.UUID; */ public class CommandersGameRestartTest extends CardTestCommander4PlayersWithAIHelps { + private void checkGameView() { + // miss CommanderInfoWatcher check, see https://github.com/magefree/mage/issues/11081 + // original watcher code don't raise game error on miss watcher, but test must fail - so it uses direct key search here + GameView gameView = getGameView(playerA); + Assert.assertNotNull(gameView); + for (Player player : currentGame.getPlayers().values()) { + for (UUID commanderId : currentGame.getCommandersIds(player, CommanderCardType.ANY, false)) { + String needWatcherKey = commanderId + "CommanderInfoWatcher"; + Assert.assertNotNull("Watchers must be init with game card all the time, miss " + needWatcherKey, currentGame.getState().getWatcher(needWatcherKey)); + } + } + } + @Test public void test_KarnLiberated_Manual() { // Player order: A -> D -> C -> B @@ -28,12 +43,15 @@ public class CommandersGameRestartTest extends CardTestCommander4PlayersWithAIHe addCard(Zone.BATTLEFIELD, playerA, "Karn Liberated", 1); // prepare commander + runCode("check", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> checkGameView()); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears"); waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA); checkPermanentCount("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 1); + runCode("check", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> checkGameView()); // prepare karn addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Karn Liberated", CounterType.LOYALTY, 20); + runCode("check", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> checkGameView()); // check watcher before restart runCode("before restart", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> { @@ -45,6 +63,7 @@ public class CommandersGameRestartTest extends CardTestCommander4PlayersWithAIHe // game restart activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-14: "); waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA); + runCode("check", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> checkGameView()); setStopAt(1, PhaseStep.END_TURN); setStrictChooseMode(true); @@ -54,6 +73,8 @@ public class CommandersGameRestartTest extends CardTestCommander4PlayersWithAIHe UUID commanderId = currentGame.getCommandersIds(playerA, CommanderCardType.ANY, false).stream().findFirst().orElse(null); CommanderPlaysCountWatcher watcher = currentGame.getState().getWatcher(CommanderPlaysCountWatcher.class); Assert.assertEquals("commander tax must be x0", 0, watcher.getPlaysCount(commanderId)); + // + checkGameView(); assertPermanentCount(playerA, 0); // no cards on battle after game restart } diff --git a/Mage/src/main/java/mage/constants/CommanderCardType.java b/Mage/src/main/java/mage/constants/CommanderCardType.java index 2d9ccd5e661..421d588827b 100644 --- a/Mage/src/main/java/mage/constants/CommanderCardType.java +++ b/Mage/src/main/java/mage/constants/CommanderCardType.java @@ -5,7 +5,7 @@ package mage.constants; * Cards that reference "your commander" instead reference "your Oathbreaker." *

* So in card rules text contains "commander" then you must use COMMANDER_OR_OATHBREAKER. - * If you card must look to command zone (e.g. target any card) then you must use ANY + * If your card must look to command zone (e.g. target any card) then you must use ANY * * @author JayDi85 */