diff --git a/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java b/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java index d282dbc1a9..bfae2666eb 100644 --- a/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java @@ -152,6 +152,30 @@ public class BoosterGenerationTest extends MageTestBase { } } + @Test + public void testColdSnap_BoosterMustHaveOneSnowLand() { + for (int i = 0; i < 10; i++) { + List booster = Coldsnap.getInstance().createBooster(); + assertTrue("coldsnap's booster must contain 1 snow covered land", booster.stream().anyMatch(card -> card.isBasic() && card.getName().startsWith("Snow-Covered "))); + } + } + + @Test + public void testMastersEditionII_BoosterMustHaveOneSnowLand() { + for (int i = 0; i < 10; i++) { + List booster = MastersEditionII.getInstance().createBooster(); + assertTrue("Master Editions II's booster must contain 1 snow covered land", booster.stream().anyMatch(card -> card.isBasic() && card.getName().startsWith("Snow-Covered "))); + } + } + + @Test + public void testBattlebond_BoosterMustHaveOneLand() { + for (int i = 0; i < 10; i++) { + List booster = Coldsnap.getInstance().createBooster(); + assertTrue("battlebond's booster must contain 1 land", booster.stream().anyMatch(card -> card.isBasic() && card.isLand())); + } + } + private static String str(List cards) { StringBuilder sb = new StringBuilder("["); Iterator iterator = cards.iterator(); diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 3882476d58..7dc7c4fa76 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -4,10 +4,12 @@ import mage.ObjectColor; import mage.cards.*; import mage.cards.basiclands.BasicLand; import mage.constants.CardType; +import mage.constants.Constants; import mage.constants.Rarity; import mage.constants.SuperType; import mage.game.permanent.token.Token; import mage.game.permanent.token.TokenImpl; +import mage.util.CardUtil; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -42,12 +44,12 @@ public class VerifyCardDataTest { skipCheckLists.put(listName, new LinkedHashSet<>()); } - private static void skipListAddName(String listName, String name) { - skipCheckLists.get(listName).add(name); + private static void skipListAddName(String listName, String set, String name) { + skipCheckLists.get(listName).add(set + " - " + name); } - private static boolean skipListHaveName(String listName, String name) { - return skipCheckLists.get(listName).contains(name); + private static boolean skipListHaveName(String listName, String set, String name) { + return skipCheckLists.get(listName).contains(set + " - " + name); } static { @@ -55,8 +57,8 @@ public class VerifyCardDataTest { // power-toughness skipListCreate("PT"); - skipListAddName("PT", "Garbage Elemental"); // UST - skipListAddName("PT", "Infinity Elemental"); // UST + skipListAddName("PT", "UST", "Garbage Elemental"); + skipListAddName("PT", "UST", "Infinity Elemental"); // color skipListCreate("COLOR"); @@ -96,15 +98,16 @@ public class VerifyCardDataTest { } private void warn(Card card, String message) { - System.out.println("Warning: " + message + " for " + card.getName() + " (" + card.getExpansionSetCode() + ")"); + outputMessages.add("Warning: " + message + " for " + card.getExpansionSetCode() + " - " + card.getName() + " - " + card.getCardNumber()); } private void fail(Card card, String category, String message) { failed++; - System.out.println("Error: (" + category + ") " + message + " for " + card.getName() + " (" + card.getExpansionSetCode() + ")"); + outputMessages.add("Error: (" + category + ") " + message + " for " + card.getExpansionSetCode() + " - " + card.getName() + " - " + card.getCardNumber()); } private int failed = 0; + private ArrayList outputMessages = new ArrayList<>(); @Test public void verifyCards() throws IOException { @@ -117,8 +120,10 @@ public class VerifyCardDataTest { check(card, tokens); } } + + printMessages(outputMessages); if (failed > 0) { - Assert.fail(failed + " Errors"); + Assert.fail(failed + " errors in verify"); } } @@ -256,12 +261,22 @@ public class VerifyCardDataTest { } } - private void printMessages(Collection list) { - for (String mes : list) { + private void printMessages(Collection list, boolean sorted) { + + ArrayList sortedList = new ArrayList<>(list); + if (sorted) { + sortedList.sort(String::compareTo); + } + + for (String mes : sortedList) { System.out.println(mes); } } + private void printMessages(Collection list) { + printMessages(list, true); + } + private String extractShortClass(Class tokenClass) { String origin = tokenClass.getName(); if (origin.contains("$")) { @@ -273,6 +288,114 @@ public class VerifyCardDataTest { } } + @Test + public void checkMissingSetData() { + Collection errorsList = new ArrayList<>(); + Collection warningsList = new ArrayList<>(); + + Collection sets = Sets.getInstance().values(); + + // 1. wrong set class names + for (ExpansionSet set : sets) { + String className = extractShortClass(set.getClass()); + String needClassName = set.getName() + //.replaceAll("Duel Decks", "") + .replaceAll("&", "And") + .replaceAll(" vs. ", " Vs ") // for more friendly class name generation in logs TODO: replace to CamelCase transform instead custom words + .replaceAll(" the ", " The ") + .replaceAll(" and ", " And ") + .replaceAll(" of ", " Of ") + .replaceAll(" to ", " To ") + .replaceAll(" for ", " For ") + .replaceAll(" into ", " Into ") + .replaceAll(" over ", " Over ") + .replaceAll("[ .+-/:\"']", ""); + + //if (!className.toLowerCase(Locale.ENGLISH).equals(needClassName.toLowerCase(Locale.ENGLISH))) { + if (!className.equals(needClassName)) { + errorsList.add("error, set's class name must be equal to set name: " + + className + " from " + set.getClass().getName() + ", caption: " + set.getName() + ", need name: " + needClassName); + } + } + + // 2. wrong basic lands settings (it's for lands search, not booster construct) + Map skipLandCheck = new HashMap<>(); + for (ExpansionSet set : sets) { + if (skipLandCheck.containsKey(set.getName())) { + continue; + } + + Boolean needLand = set.hasBasicLands(); + Boolean foundedLand = false; + Map foundLandsList = new HashMap<>(); + for (ExpansionSet.SetCardInfo card : set.getSetCardInfo()) { + if (isBasicLandName(card.getName())) { + foundedLand = true; + int count = foundLandsList.getOrDefault(card.getName(), 0); + foundLandsList.put(card.getName(), count + 1); + } + } + + String landNames = foundLandsList.entrySet().stream() + .map(p -> (p.getKey() + " - " + p.getValue().toString())) + .sorted().collect(Collectors.joining(", ")); + + if (needLand && !foundedLand) { + errorsList.add("error, found set with wrong hasBasicLands - it's true, but haven't land cards: " + set.getCode() + " in " + set.getClass().getName()); + } + + if (!needLand && foundedLand) { + errorsList.add("error, found set with wrong hasBasicLands - it's false, but have land cards: " + set.getCode() + " in " + set.getClass().getName() + ", lands: " + landNames); + } + + // TODO: add test to check num cards (hasBasicLands and numLand > 0) + } + + // TODO: add test to check num cards for rarity (rarityStats > 0 and numRarity > 0) + + printMessages(warningsList); + printMessages(errorsList); + if (errorsList.size() > 0) { + Assert.fail("Founded set errors: " + errorsList.size()); + } + } + + @Test + public void checkMissingCardData() { + Collection errorsList = new ArrayList<>(); + Collection warningsList = new ArrayList<>(); + + Collection sets = Sets.getInstance().values(); + + + // 1. wrong UsesVariousArt settings (set have duplicated card name without that setting -- e.g. cards will have same image) + for (ExpansionSet set : sets) { + + // double names + Map doubleNames = new HashMap<>(); + for (ExpansionSet.SetCardInfo card : set.getSetCardInfo()) { + int count = doubleNames.getOrDefault(card.getName(), 0); + doubleNames.put(card.getName(), count + 1); + } + + // check + for (ExpansionSet.SetCardInfo card : set.getSetCardInfo()) { + boolean cardHaveDoubleName = (doubleNames.getOrDefault(card.getName(), 0) > 1); + boolean cardHaveVariousSetting = card.getGraphicInfo() == null ? false : card.getGraphicInfo().getUsesVariousArt(); + + if(cardHaveDoubleName && !cardHaveVariousSetting) { + errorsList.add("error, founded double card names, but UsesVariousArt is not true: " + set.getCode() + " - " + set.getName() + " - " + card.getName() + " - " + card.getCardNumber()); + } + } + } + + printMessages(warningsList); + printMessages(errorsList); + if (errorsList.size() > 0) { + Assert.fail("Founded card errors: " + errorsList.size()); + } + } + @Test @Ignore // TODO: enable test after massive token fixes public void checkMissingTokenData() { @@ -440,7 +563,7 @@ public class VerifyCardDataTest { } private void checkColors(Card card, JsonCard ref) { - if (skipListHaveName("COLOR", card.getName())) { + if (skipListHaveName("COLOR", card.getExpansionSetCode(), card.getName())) { return; } @@ -460,7 +583,7 @@ public class VerifyCardDataTest { } private void checkSubtypes(Card card, JsonCard ref) { - if (skipListHaveName("SUBTYPE", card.getName())) { + if (skipListHaveName("SUBTYPE", card.getExpansionSetCode(), card.getName())) { return; } @@ -469,7 +592,7 @@ public class VerifyCardDataTest { // fix names (e.g. Urza’s to Urza's) if (expected != null && expected.contains("Urza’s")) { expected = new ArrayList<>(expected); - for (ListIterator it = ((List) expected).listIterator(); it.hasNext();) { + for (ListIterator it = ((List) expected).listIterator(); it.hasNext(); ) { if (it.next().equals("Urza’s")) { it.set("Urza's"); } @@ -482,7 +605,7 @@ public class VerifyCardDataTest { } private void checkSupertypes(Card card, JsonCard ref) { - if (skipListHaveName("SUPERTYPE", card.getName())) { + if (skipListHaveName("SUPERTYPE", card.getExpansionSetCode(), card.getName())) { return; } @@ -492,23 +615,8 @@ public class VerifyCardDataTest { } } - private void checkTypes(Card card, JsonCard ref) { - if (skipListHaveName("TYPE", card.getName())) { - return; - } - - Collection expected = ref.types; - List type = new ArrayList<>(); - for (CardType cardType : card.getCardType()) { - type.add(cardType.toString()); - } - if (!eqSet(type, expected)) { - fail(card, "types", type + " != " + expected); - } - } - private void checkMissingAbilities(Card card, JsonCard ref) { - if (skipListHaveName("MISSING_ABILITIES", card.getName())) { + if (skipListHaveName("MISSING_ABILITIES", card.getExpansionSetCode(), card.getName())) { return; } @@ -533,6 +641,21 @@ public class VerifyCardDataTest { } } + private void checkTypes(Card card, JsonCard ref) { + if (skipListHaveName("TYPE", card.getExpansionSetCode(), card.getName())) { + return; + } + + Collection expected = ref.types; + List type = new ArrayList<>(); + for (CardType cardType : card.getCardType()) { + type.add(cardType.toString()); + } + if (!eqSet(type, expected)) { + fail(card, "types", type + " != " + expected); + } + } + private static boolean eqSet(Collection a, Collection b) { if (a == null || a.isEmpty()) { return b == null || b.isEmpty(); @@ -541,7 +664,7 @@ public class VerifyCardDataTest { } private void checkPT(Card card, JsonCard ref) { - if (skipListHaveName("PT", card.getName())) { + if (skipListHaveName("PT", card.getExpansionSetCode(), card.getName())) { return; } @@ -561,7 +684,7 @@ public class VerifyCardDataTest { } private void checkCost(Card card, JsonCard ref) { - if (skipListHaveName("COST", card.getName())) { + if (skipListHaveName("COST", card.getExpansionSetCode(), card.getName())) { return; } @@ -579,7 +702,7 @@ public class VerifyCardDataTest { } private void checkNumbers(Card card, JsonCard ref) { - if (skipListHaveName("NUMBER", card.getName())) { + if (skipListHaveName("NUMBER", card.getExpansionSetCode(), card.getName())) { return; }