From dcaa0b98347499874e6683ff3220d34e41e1115b Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Thu, 17 Jul 2025 09:31:39 +0400 Subject: [PATCH] tests: added verify tests for emblems (class naming and package, constructor, image data, related to #13853) --- .../java/mage/verify/VerifyCardDataTest.java | 60 +++++++++++++++++++ .../game/command/emblems/RadiationEmblem.java | 8 +++ .../game/command/emblems/TheRingEmblem.java | 11 ++++ .../command/emblems/XmageHelperEmblem.java | 8 +++ 4 files changed, 87 insertions(+) diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index b7288c54536..8fd29459c10 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -40,7 +40,9 @@ import mage.filter.predicate.Predicates; import mage.game.FakeGame; import mage.game.Game; import mage.game.command.Dungeon; +import mage.game.command.Emblem; import mage.game.command.Plane; +import mage.game.command.emblems.EmblemOfCard; import mage.game.draft.DraftCube; import mage.game.permanent.token.Token; import mage.game.permanent.token.TokenImpl; @@ -1697,6 +1699,64 @@ public class VerifyCardDataTest { } } + @Test + // TODO: add same images verify for tokens/dungeons and other + // TODO: add same verify for Speed and other new command objects + public void test_checkMissingEmblemsData() { + Collection errorsList = new ArrayList<>(); + + // prepare DBs + CardScanner.scan(); + + Reflections reflections = new Reflections("mage."); + Set> emblemClassesList = reflections.getSubTypesOf(Emblem.class).stream() + .filter(c -> !c.equals(EmblemOfCard.class)) // ignore emblem card + .collect(Collectors.toSet()); + + // 1. correct class name + for (Class emblemClass : emblemClassesList) { + if (!emblemClass.getName().endsWith("Emblem")) { + String className = extractShortClass(emblemClass); + errorsList.add("Error: emblem class must ends with Emblem: " + className + " from " + emblemClass.getName()); + } + } + + // 2. correct package + for (Class emblemClass : emblemClassesList) { + String fullClass = emblemClass.getName(); + if (!fullClass.startsWith("mage.game.command.emblems.")) { + String className = extractShortClass(emblemClass); + errorsList.add("Error: emblem must be stored in mage.game.command.emblems package: " + className + " from " + emblemClass.getName()); + } + } + + // 3. correct constructor + MageObject fakeObject = CardRepository.instance.findCard("Forest").createCard(); + for (Class emblemClass : emblemClassesList) { + String className = extractShortClass(emblemClass); + Emblem emblem; + try { + emblem = (Emblem) createNewObject(emblemClass); + + // 4. correct tokens-database (image) + try { + emblem.setSourceObjectAndInitImage(fakeObject); + } catch (Throwable e) { + e.printStackTrace(); + errorsList.add("Error: can't setup emblem's image data - make sure tokens-database.txt has it: " + className + " from " + emblemClass.getName()); + } + } catch (Throwable e) { + e.printStackTrace(); + errorsList.add("Error: can't create emblem with default constructor: " + className + " from " + emblemClass.getName()); + } + } + + printMessages(errorsList); + if (errorsList.size() > 0) { + Assert.fail("Found emblem errors: " + errorsList.size()); + } + } + @Test @Ignore // experimental test to find potentially fail conditions with NPE see https://github.com/magefree/mage/issues/13752 diff --git a/Mage/src/main/java/mage/game/command/emblems/RadiationEmblem.java b/Mage/src/main/java/mage/game/command/emblems/RadiationEmblem.java index 7f72bf4b36c..c401b0d2bfb 100644 --- a/Mage/src/main/java/mage/game/command/emblems/RadiationEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/RadiationEmblem.java @@ -1,5 +1,6 @@ package mage.game.command.emblems; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.condition.Condition; import mage.abilities.effects.OneShotEffect; @@ -34,6 +35,13 @@ public class RadiationEmblem extends Emblem { Zone.ALL, TargetController.YOU, new RadiationEffect(), false ).withInterveningIf(RadiationCondition.instance).setTriggerPhrase("At the beginning of each player's precombat main phase, ")); + // radiation don't have source, so image can be initialized immediately + setSourceObjectAndInitImage(null); + } + + @Override + public void setSourceObjectAndInitImage(MageObject sourceObject) { + this.sourceObject = sourceObject; TokenInfo foundInfo = TokenRepository.instance.findPreferredTokenInfoForXmage(TokenRepository.XMAGE_IMAGE_NAME_RADIATION, null); if (foundInfo != null) { this.setExpansionSetCode(foundInfo.getSetCode()); diff --git a/Mage/src/main/java/mage/game/command/emblems/TheRingEmblem.java b/Mage/src/main/java/mage/game/command/emblems/TheRingEmblem.java index e5fb21ccf99..225f5f55f23 100644 --- a/Mage/src/main/java/mage/game/command/emblems/TheRingEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/TheRingEmblem.java @@ -1,5 +1,6 @@ package mage.game.command.emblems; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; @@ -40,11 +41,21 @@ public final class TheRingEmblem extends Emblem { filter.add(TheRingEmblemPredicate.instance); } + public TheRingEmblem() { + this((UUID) null); // require for verify test + } + public TheRingEmblem(UUID controllerId) { super("The Ring"); this.setControllerId(controllerId); // ring don't have source, so image can be initialized immediately + setSourceObjectAndInitImage(null); + } + + @Override + public void setSourceObjectAndInitImage(MageObject sourceObject) { + this.sourceObject = sourceObject; TokenInfo foundInfo = TokenRepository.instance.findPreferredTokenInfoForXmage(TokenRepository.XMAGE_IMAGE_NAME_THE_RING, null); if (foundInfo != null) { this.setExpansionSetCode(foundInfo.getSetCode()); diff --git a/Mage/src/main/java/mage/game/command/emblems/XmageHelperEmblem.java b/Mage/src/main/java/mage/game/command/emblems/XmageHelperEmblem.java index d4f396adaa8..d051f212ef6 100644 --- a/Mage/src/main/java/mage/game/command/emblems/XmageHelperEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/XmageHelperEmblem.java @@ -1,5 +1,6 @@ package mage.game.command.emblems; +import mage.MageObject; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.InfoEffect; import mage.abilities.hint.Hint; @@ -20,6 +21,13 @@ public class XmageHelperEmblem extends Emblem { super("Helper Emblem"); this.frameStyle = FrameStyle.M15_NORMAL; + // helper don't have source, so image can be initialized immediately + setSourceObjectAndInitImage(null); + } + + @Override + public void setSourceObjectAndInitImage(MageObject sourceObject) { + this.sourceObject = sourceObject; TokenInfo foundInfo = TokenRepository.instance.findPreferredTokenInfoForXmage(TokenRepository.XMAGE_IMAGE_NAME_HELPER_EMBLEM, null); if (foundInfo != null) { this.setExpansionSetCode(foundInfo.getSetCode());