tests: added verify tests for emblems (class naming and package, constructor, image data, related to #13853)

This commit is contained in:
Oleg Agafonov 2025-07-17 09:31:39 +04:00
parent 925ef86c22
commit dcaa0b9834
4 changed files with 87 additions and 0 deletions

View file

@ -40,7 +40,9 @@ import mage.filter.predicate.Predicates;
import mage.game.FakeGame; import mage.game.FakeGame;
import mage.game.Game; import mage.game.Game;
import mage.game.command.Dungeon; import mage.game.command.Dungeon;
import mage.game.command.Emblem;
import mage.game.command.Plane; import mage.game.command.Plane;
import mage.game.command.emblems.EmblemOfCard;
import mage.game.draft.DraftCube; import mage.game.draft.DraftCube;
import mage.game.permanent.token.Token; import mage.game.permanent.token.Token;
import mage.game.permanent.token.TokenImpl; 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<String> errorsList = new ArrayList<>();
// prepare DBs
CardScanner.scan();
Reflections reflections = new Reflections("mage.");
Set<Class<? extends Emblem>> emblemClassesList = reflections.getSubTypesOf(Emblem.class).stream()
.filter(c -> !c.equals(EmblemOfCard.class)) // ignore emblem card
.collect(Collectors.toSet());
// 1. correct class name
for (Class<? extends Emblem> 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<? extends Emblem> 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<? extends Emblem> 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 @Test
@Ignore @Ignore
// experimental test to find potentially fail conditions with NPE see https://github.com/magefree/mage/issues/13752 // experimental test to find potentially fail conditions with NPE see https://github.com/magefree/mage/issues/13752

View file

@ -1,5 +1,6 @@
package mage.game.command.emblems; package mage.game.command.emblems;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -34,6 +35,13 @@ public class RadiationEmblem extends Emblem {
Zone.ALL, TargetController.YOU, new RadiationEffect(), false Zone.ALL, TargetController.YOU, new RadiationEffect(), false
).withInterveningIf(RadiationCondition.instance).setTriggerPhrase("At the beginning of each player's precombat main phase, ")); ).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); TokenInfo foundInfo = TokenRepository.instance.findPreferredTokenInfoForXmage(TokenRepository.XMAGE_IMAGE_NAME_RADIATION, null);
if (foundInfo != null) { if (foundInfo != null) {
this.setExpansionSetCode(foundInfo.getSetCode()); this.setExpansionSetCode(foundInfo.getSetCode());

View file

@ -1,5 +1,6 @@
package mage.game.command.emblems; package mage.game.command.emblems;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
@ -40,11 +41,21 @@ public final class TheRingEmblem extends Emblem {
filter.add(TheRingEmblemPredicate.instance); filter.add(TheRingEmblemPredicate.instance);
} }
public TheRingEmblem() {
this((UUID) null); // require for verify test
}
public TheRingEmblem(UUID controllerId) { public TheRingEmblem(UUID controllerId) {
super("The Ring"); super("The Ring");
this.setControllerId(controllerId); this.setControllerId(controllerId);
// ring don't have source, so image can be initialized immediately // 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); TokenInfo foundInfo = TokenRepository.instance.findPreferredTokenInfoForXmage(TokenRepository.XMAGE_IMAGE_NAME_THE_RING, null);
if (foundInfo != null) { if (foundInfo != null) {
this.setExpansionSetCode(foundInfo.getSetCode()); this.setExpansionSetCode(foundInfo.getSetCode());

View file

@ -1,5 +1,6 @@
package mage.game.command.emblems; package mage.game.command.emblems;
import mage.MageObject;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.InfoEffect;
import mage.abilities.hint.Hint; import mage.abilities.hint.Hint;
@ -20,6 +21,13 @@ public class XmageHelperEmblem extends Emblem {
super("Helper Emblem"); super("Helper Emblem");
this.frameStyle = FrameStyle.M15_NORMAL; 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); TokenInfo foundInfo = TokenRepository.instance.findPreferredTokenInfoForXmage(TokenRepository.XMAGE_IMAGE_NAME_HELPER_EMBLEM, null);
if (foundInfo != null) { if (foundInfo != null) {
this.setExpansionSetCode(foundInfo.getSetCode()); this.setExpansionSetCode(foundInfo.getSetCode());