From 889c1125e809ae042367e8b27f064088ec0d305a Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 10 Apr 2024 21:55:43 +0400 Subject: [PATCH] refactor: improved deck import, added docs and miss tests for dek-files; --- .../decks/exporter/MtgArenaDeckExporter.java | 4 +- .../decks/exporter/MtgOnlineDeckExporter.java | 2 +- .../decks/exporter/XmageDeckExporter.java | 10 +-- .../decks/exporter/XmageInfoDeckExporter.java | 14 ++-- .../mage/cards/decks/importer/CardLookup.java | 3 + .../cards/decks/importer/CodDeckImporter.java | 16 ++-- .../cards/decks/importer/DckDeckImporter.java | 10 ++- .../cards/decks/importer/DecDeckImporter.java | 12 ++- .../cards/decks/importer/DeckImporter.java | 3 + .../cards/decks/importer/DekDeckImporter.java | 25 ++++-- .../decks/importer/DraftLogImporter.java | 3 + .../decks/importer/JsonDeckImporter.java | 11 ++- .../cards/decks/importer/MWSDeckImporter.java | 2 + .../cards/decks/importer/MtgaImporter.java | 37 +++++---- .../decks/importer/MtgjsonDeckImporter.java | 4 +- .../cards/decks/importer/O8dDeckImporter.java | 4 +- .../decks/importer/PlainTextDeckImporter.java | 2 + .../cards/decks/importer/TxtDeckImporter.java | 4 +- .../cards/decks/importer/XmlDeckImporter.java | 3 + Mage/src/test/data/importer/testdeck.cod | 4 +- Mage/src/test/data/importer/testdeck.dek | 10 +++ Mage/src/test/data/importer/testdeck.mtga | 4 +- .../decks/importer/CodDeckImportTest.java | 13 ++-- .../decks/importer/DecDeckImportTest.java | 4 +- .../decks/importer/DekDeckImportTest.java | 45 +++++++++++ .../decks/importer/DraftLogImporterTest.java | 4 +- .../cards/decks/importer/FakeCardLookup.java | 78 +++++++++---------- .../decks/importer/MtgaImporterTest.java | 10 +-- .../decks/importer/MtgjsonDeckImportTest.java | 6 +- .../decks/importer/MwsDeckImportTest.java | 4 +- .../decks/importer/O8dDeckImportTest.java | 4 +- .../cards/decks/importer/TestDeckChecker.java | 7 +- 32 files changed, 238 insertions(+), 124 deletions(-) create mode 100644 Mage/src/test/data/importer/testdeck.dek create mode 100644 Mage/src/test/java/mage/cards/decks/importer/DekDeckImportTest.java diff --git a/Mage/src/main/java/mage/cards/decks/exporter/MtgArenaDeckExporter.java b/Mage/src/main/java/mage/cards/decks/exporter/MtgArenaDeckExporter.java index 68073ae2ccc..6511456ea64 100644 --- a/Mage/src/main/java/mage/cards/decks/exporter/MtgArenaDeckExporter.java +++ b/Mage/src/main/java/mage/cards/decks/exporter/MtgArenaDeckExporter.java @@ -38,13 +38,13 @@ public class MtgArenaDeckExporter extends DeckExporter { for (DeckCardInfo card : sourceCards) { String setCode = card.getSetCode().toUpperCase(Locale.ENGLISH); setCode = SET_CODE_REPLACEMENTS.getOrDefault(setCode, setCode); - String name = card.getCardName() + " (" + setCode + ") " + card.getCardNum(); + String name = card.getCardName() + " (" + setCode + ") " + card.getCardNumber(); String code = prefix + name; int curAmount = amount.getOrDefault(code, 0); if (curAmount == 0) { res.add(name); } - amount.put(code, curAmount + card.getQuantity()); + amount.put(code, curAmount + card.getAmount()); } return res; } diff --git a/Mage/src/main/java/mage/cards/decks/exporter/MtgOnlineDeckExporter.java b/Mage/src/main/java/mage/cards/decks/exporter/MtgOnlineDeckExporter.java index 5cf545b9116..bf37fcba076 100644 --- a/Mage/src/main/java/mage/cards/decks/exporter/MtgOnlineDeckExporter.java +++ b/Mage/src/main/java/mage/cards/decks/exporter/MtgOnlineDeckExporter.java @@ -38,7 +38,7 @@ public class MtgOnlineDeckExporter extends DeckExporter { if (curAmount == 0) { res.add(card.getCardName()); } - amount.put(code, curAmount + card.getQuantity()); + amount.put(code, curAmount + card.getAmount()); } return res; } diff --git a/Mage/src/main/java/mage/cards/decks/exporter/XmageDeckExporter.java b/Mage/src/main/java/mage/cards/decks/exporter/XmageDeckExporter.java index c3e18fe023d..4ddb0088660 100644 --- a/Mage/src/main/java/mage/cards/decks/exporter/XmageDeckExporter.java +++ b/Mage/src/main/java/mage/cards/decks/exporter/XmageDeckExporter.java @@ -40,7 +40,7 @@ public class XmageDeckExporter extends DeckExporter { if (curAmount == 0) { deckMain.add(card); } - amount.put(code, curAmount + card.getQuantity()); + amount.put(code, curAmount + card.getAmount()); } // sideboard for (DeckCardInfo card : deck.getSideboard()) { @@ -49,15 +49,15 @@ public class XmageDeckExporter extends DeckExporter { if (curAmount == 0) { deckSideboard.add(card); } - amount.put(code, curAmount + card.getQuantity()); + amount.put(code, curAmount + card.getAmount()); } // cards print for (DeckCardInfo card : deckMain) { - out.printf("%d [%s:%s] %s%n", amount.get("M@" + card.getCardKey()), card.getSetCode(), card.getCardNum(), card.getCardName()); + out.printf("%d [%s:%s] %s%n", amount.get("M@" + card.getCardKey()), card.getSetCode(), card.getCardNumber(), card.getCardName()); } for (DeckCardInfo card : deckSideboard) { - out.printf("SB: %d [%s:%s] %s%n", amount.get("S@" + card.getCardKey()), card.getSetCode(), card.getCardNum(), card.getCardName()); + out.printf("SB: %d [%s:%s] %s%n", amount.get("S@" + card.getCardKey()), card.getSetCode(), card.getCardNumber(), card.getCardName()); } // layout print @@ -86,7 +86,7 @@ public class XmageDeckExporter extends DeckExporter { out.print("("); for (int i = 0; i < stack.size(); ++i) { DeckCardInfo info = stack.get(i); - out.printf("[%s:%s]", info.getSetCode(), info.getCardNum()); + out.printf("[%s:%s]", info.getSetCode(), info.getCardNumber()); if (i != stack.size() - 1) { out.print(","); } diff --git a/Mage/src/main/java/mage/cards/decks/exporter/XmageInfoDeckExporter.java b/Mage/src/main/java/mage/cards/decks/exporter/XmageInfoDeckExporter.java index 052be059628..6169811b46b 100644 --- a/Mage/src/main/java/mage/cards/decks/exporter/XmageInfoDeckExporter.java +++ b/Mage/src/main/java/mage/cards/decks/exporter/XmageInfoDeckExporter.java @@ -43,7 +43,7 @@ public class XmageInfoDeckExporter extends DeckExporter { if (curAmount == 0) { deckMain.add(card); } - amount.put(code, curAmount + card.getQuantity()); + amount.put(code, curAmount + card.getAmount()); } // Sideboard @@ -53,16 +53,16 @@ public class XmageInfoDeckExporter extends DeckExporter { if (curAmount == 0) { deckSideboard.add(card); } - amount.put(code, curAmount + card.getQuantity()); + amount.put(code, curAmount + card.getAmount()); } // Cards print for (DeckCardInfo card : deckMain) { CardInfo cardInfo = CardRepository.instance.findCard(card.getCardName()); if (cardInfo == null) { - out.printf("%d [%s:%s] %s%n\n", amount.get("M@" + card.getCardKey()), card.getSetCode(), card.getCardNum(), card.getCardName()); + out.printf("%d [%s:%s] %s%n\n", amount.get("M@" + card.getCardKey()), card.getSetCode(), card.getCardNumber(), card.getCardName()); } else { - out.printf("%d [%s:%s] %s ;; %s ;; %s ;; %d %n", amount.get("M@" + card.getCardKey()), card.getSetCode(), card.getCardNum(), card.getCardName(), + out.printf("%d [%s:%s] %s ;; %s ;; %s ;; %d %n", amount.get("M@" + card.getCardKey()), card.getSetCode(), card.getCardNumber(), card.getCardName(), cardInfo.getColor().getDescription(), cardInfo.getTypes().toString(), cardInfo.getManaValue()); } } @@ -70,9 +70,9 @@ public class XmageInfoDeckExporter extends DeckExporter { for (DeckCardInfo card : deckSideboard) { CardInfo cardInfo = CardRepository.instance.findCard(card.getCardName()); if (cardInfo == null) { - out.printf("SB: %d [%s:%s] %s%n\n", amount.get("S@" + card.getCardKey()), card.getSetCode(), card.getCardNum(), card.getCardName()); + out.printf("SB: %d [%s:%s] %s%n\n", amount.get("S@" + card.getCardKey()), card.getSetCode(), card.getCardNumber(), card.getCardName()); } else { - out.printf("SB: %d [%s:%s] %s ;; %s ;; %s ;; %d %n", amount.get("S@" + card.getCardKey()), card.getSetCode(), card.getCardNum(), card.getCardName(), + out.printf("SB: %d [%s:%s] %s ;; %s ;; %s ;; %d %n", amount.get("S@" + card.getCardKey()), card.getSetCode(), card.getCardNumber(), card.getCardName(), cardInfo.getColor().getDescription(), cardInfo.getTypes().toString(), cardInfo.getManaValue()); } } @@ -103,7 +103,7 @@ public class XmageInfoDeckExporter extends DeckExporter { out.print("("); for (int i = 0; i < stack.size(); ++i) { DeckCardInfo info = stack.get(i); - out.printf("[%s:%s]", info.getSetCode(), info.getCardNum()); + out.printf("[%s:%s]", info.getSetCode(), info.getCardNumber()); if (i != stack.size() - 1) { out.print(","); } diff --git a/Mage/src/main/java/mage/cards/decks/importer/CardLookup.java b/Mage/src/main/java/mage/cards/decks/importer/CardLookup.java index 12c0fcba5c0..e67c672b9af 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/CardLookup.java +++ b/Mage/src/main/java/mage/cards/decks/importer/CardLookup.java @@ -7,6 +7,9 @@ import mage.cards.repository.CardRepository; import java.util.List; import java.util.Optional; +/** + * Deck import: helper class to mock cards repository + */ public class CardLookup { public static final CardLookup instance = new CardLookup(); diff --git a/Mage/src/main/java/mage/cards/decks/importer/CodDeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/CodDeckImporter.java index 383f917ef2f..7d75dc94f7a 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/CodDeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/CodDeckImporter.java @@ -13,12 +13,15 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +/** + * Deck import: Cockatrice app + */ public class CodDeckImporter extends XmlDeckImporter { /** - * @param filename + * @param fileName * @param errorMessages - * @param saveAutoFixedFile do not supported for current format + * @param saveAutoFixedFile do not support for current format * @return */ @Override @@ -43,7 +46,7 @@ public class CodDeckImporter extends XmlDeckImporter { return decklist; } catch (Exception e) { logger.error("Error loading deck", e); - errorMessages.append("There was an error loading the deck."); + errorMessages.append("There was an error loading the deck: " + e.getMessage()); return new DeckCardLists(); } } @@ -66,9 +69,12 @@ public class CodDeckImporter extends XmlDeckImporter { Optional cardInfo = lookup.lookupCardInfo(name); if (cardInfo.isPresent()) { CardInfo info = cardInfo.get(); + int amount = getQuantityFromNode(node); + DeckCardInfo.makeSureCardAmountFine(amount, info.getName()); return Collections.nCopies( - getQuantityFromNode(node), - new DeckCardInfo(info.getName(), info.getCardNumber(), info.getSetCode())).stream(); + amount, + new DeckCardInfo(info.getName(), info.getCardNumber(), info.getSetCode()) + ).stream(); } else { errors.append("Could not find card: '").append(name).append("'\n"); return Stream.empty(); diff --git a/Mage/src/main/java/mage/cards/decks/importer/DckDeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/DckDeckImporter.java index 2a7ce420e0d..a84b4da5e82 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/DckDeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/DckDeckImporter.java @@ -15,7 +15,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * Original xmage's deck format (uses by deck editor) + * Deck import: native xmage format (uses by deck editor) * * @author North */ @@ -39,7 +39,7 @@ public class DckDeckImporter extends PlainTextDeckImporter { if (line.isEmpty() || line.startsWith("#")) { return; } - + line = CardNameUtil.normalizeCardName(line); // AUTO-FIX apply (if card number was fixed before then it can be replaced in layout or other lines too) @@ -61,6 +61,8 @@ public class DckDeckImporter extends PlainTextDeckImporter { String cardNum = m.group(4); String cardName = m.group(5); + DeckCardInfo.makeSureCardAmountFine(count, cardName); + cardNum = cardNum == null ? "" : cardNum.trim(); setCode = setCode == null ? "" : setCode.trim(); cardName = cardName == null ? "" : cardName.trim(); @@ -128,9 +130,9 @@ public class DckDeckImporter extends PlainTextDeckImporter { if (deckCardInfo != null) { for (int i = 0; i < count; i++) { if (!sideboard) { - deckList.getCards().add(deckCardInfo); + deckList.getCards().add(deckCardInfo.copy()); } else { - deckList.getSideboard().add(deckCardInfo); + deckList.getSideboard().add(deckCardInfo.copy()); } } } diff --git a/Mage/src/main/java/mage/cards/decks/importer/DecDeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/DecDeckImporter.java index d39befaf380..0ec494d82b1 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/DecDeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/DecDeckImporter.java @@ -7,6 +7,10 @@ import mage.cards.repository.CardInfo; import java.util.Optional; /** + * Deck import: Decked Builder, Apprentice and old Magic Online + *

+ * Outdated, see actual format in TxtDeckImporter + * * @author BetaSteward_at_googlemail.com */ public class DecDeckImporter extends PlainTextDeckImporter { @@ -34,11 +38,13 @@ public class DecDeckImporter extends PlainTextDeckImporter { sbMessage.append("Could not find card: '").append(lineName).append("' at line ").append(lineCount).append('\n'); } else { CardInfo cardInfo = cardLookup.get(); + DeckCardInfo.makeSureCardAmountFine(num, cardInfo.getName()); + DeckCardInfo deckCardInfo = new DeckCardInfo(cardInfo.getName(), cardInfo.getCardNumber(), cardInfo.getSetCode()); for (int i = 0; i < num; i++) { - if (!sideboard) { - deckList.getCards().add(new DeckCardInfo(cardInfo.getName(), cardInfo.getCardNumber(), cardInfo.getSetCode())); + if (sideboard) { + deckList.getSideboard().add(deckCardInfo.copy()); } else { - deckList.getSideboard().add(new DeckCardInfo(cardInfo.getName(), cardInfo.getCardNumber(), cardInfo.getSetCode())); + deckList.getCards().add(deckCardInfo.copy()); } } } diff --git a/Mage/src/main/java/mage/cards/decks/importer/DeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/DeckImporter.java index 6372ecaf2f6..33bace18b4f 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/DeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/DeckImporter.java @@ -7,6 +7,9 @@ import java.io.File; import java.util.Locale; import java.util.Scanner; +/** + * Deck import: base class for all importers + */ public abstract class DeckImporter { public static class FixedInfo { diff --git a/Mage/src/main/java/mage/cards/decks/importer/DekDeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/DekDeckImporter.java index 95a689fdf87..92c7df9a6cf 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/DekDeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/DekDeckImporter.java @@ -3,34 +3,45 @@ package mage.cards.decks.importer; import mage.cards.decks.DeckCardInfo; import mage.cards.decks.DeckCardLists; import mage.cards.repository.CardInfo; -import mage.cards.repository.CardRepository; /** - * Created by royk on 11-Sep-16. + * Deck import: MTGO xml format + *

+ * Outdated, see actual format in TxtDeckImporter + * + * @author royk */ public class DekDeckImporter extends PlainTextDeckImporter { @Override protected void readLine(String line, DeckCardLists deckList, FixedInfo fixedInfo) { - if (line.isEmpty() || line.startsWith("#") || !line.contains(" Integer cardCount = Integer.parseInt(extractAttribute(line, "Quantity")); String cardName = extractAttribute(line, "Name"); + DeckCardInfo.makeSureCardAmountFine(cardCount, cardName); + + // fix double faces name to be compatible with xmage + // Refuse/Cooperate -> Refuse // Cooperate + if (!cardName.contains("//") && cardName.contains("/")) { + cardName = cardName.replace("/", " // "); + } + boolean isSideboard = "true".equals(extractAttribute(line, "Sideboard")); - CardInfo cardInfo = CardRepository.instance.findPreferredCoreExpansionCard(cardName); + CardInfo cardInfo = getCardLookup().lookupCardInfo(cardName).orElse(null); if (cardInfo == null) { sbMessage.append("Could not find card: '").append(cardName).append("' at line ").append(lineCount).append('\n'); } else { + DeckCardInfo deckCardInfo = new DeckCardInfo(cardInfo.getName(), cardInfo.getCardNumber(), cardInfo.getSetCode()); for (int i = 0; i < cardCount; i++) { - DeckCardInfo deckCardInfo = new DeckCardInfo(cardInfo.getName(), cardInfo.getCardNumber(), cardInfo.getSetCode()); if (isSideboard) { - deckList.getSideboard().add(deckCardInfo); + deckList.getSideboard().add(deckCardInfo.copy()); } else { - deckList.getCards().add(deckCardInfo); + deckList.getCards().add(deckCardInfo.copy()); } } } diff --git a/Mage/src/main/java/mage/cards/decks/importer/DraftLogImporter.java b/Mage/src/main/java/mage/cards/decks/importer/DraftLogImporter.java index 13906503567..aea081ed5c7 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/DraftLogImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/DraftLogImporter.java @@ -7,6 +7,9 @@ import mage.cards.repository.CardInfo; import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * Deck import: xmage draft logs + */ public class DraftLogImporter extends PlainTextDeckImporter { private static final Pattern SET_PATTERN = Pattern.compile("------ (\\p{Alnum}+) ------$"); diff --git a/Mage/src/main/java/mage/cards/decks/importer/JsonDeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/JsonDeckImporter.java index 1502f291333..60fb0da17e2 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/JsonDeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/JsonDeckImporter.java @@ -1,20 +1,25 @@ package mage.cards.decks.importer; -import com.google.gson.*; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; import mage.cards.decks.DeckCardLists; import java.io.File; import java.io.FileReader; /** - * @author github: timhae + * Deck import: helper class for all json base formats + * TODO: improve files structure + * + * @author timhae */ public abstract class JsonDeckImporter extends DeckImporter { protected StringBuilder sbMessage = new StringBuilder(); /** - * @param fileName file to import + * @param fileName file to import * @param errorMessages you can setup output messages to showup to user * @param saveAutoFixedFile do not supported for that format * @return decks list diff --git a/Mage/src/main/java/mage/cards/decks/importer/MWSDeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/MWSDeckImporter.java index b1e9e522551..94220902879 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/MWSDeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/MWSDeckImporter.java @@ -5,6 +5,8 @@ import mage.cards.decks.DeckCardLists; import mage.cards.repository.CardInfo; /** + * Deck import: Magic Workstation app + * * @author BetaSteward_at_googlemail.com */ public class MWSDeckImporter extends PlainTextDeckImporter { diff --git a/Mage/src/main/java/mage/cards/decks/importer/MtgaImporter.java b/Mage/src/main/java/mage/cards/decks/importer/MtgaImporter.java index 6a81c9a53d6..7399b77d1fe 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/MtgaImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/MtgaImporter.java @@ -9,12 +9,14 @@ import mage.cards.repository.CardInfo; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; import static mage.cards.decks.CardNameUtil.CARD_NAME_PATTERN; +/** + * Deck import: MTGA official app + */ public class MtgaImporter extends PlainTextDeckImporter { private static final Map SET_REMAPPING = ImmutableMap.of("DAR", "DOM"); @@ -32,9 +34,9 @@ public class MtgaImporter extends PlainTextDeckImporter { @Override protected void readLine(String line, DeckCardLists deckList, FixedInfo fixedInfo) { - + line = line.trim(); - + if (line.equals("Deck")) { return; } @@ -45,30 +47,33 @@ public class MtgaImporter extends PlainTextDeckImporter { } Matcher pattern = MTGA_PATTERN.matcher(CardNameUtil.normalizeCardName(line)); - + if (!pattern.matches()) { sbMessage.append("Error reading '").append(line).append("'\n"); return; } - - Optional found; + + CardInfo found; int count = Integer.parseInt(pattern.group(1)); - String name = pattern.group(2); + String name = pattern.group(2); if (pattern.group(3) != null && pattern.group(4) != null) { String set = SET_REMAPPING.getOrDefault(pattern.group(3), pattern.group(3)); String cardNumber = pattern.group(4); - found = lookup.lookupCardInfo(name, set, cardNumber); + found = lookup.lookupCardInfo(name, set, cardNumber).orElse(null); } else { - found = lookup.lookupCardInfo(name); + found = lookup.lookupCardInfo(name).orElse(null); } - - if (!found.isPresent()) { - sbMessage.append("Cound not find card for '").append(line).append("'\n"); - } else { - final List zone = sideboard ? deckList.getSideboard() : deckList.getCards(); - found.ifPresent(card -> zone.addAll(Collections.nCopies(count, - new DeckCardInfo(card.getName(), card.getCardNumber(), card.getSetCode())))); + + if (found == null) { + sbMessage.append("Could not find card for '").append(line).append("'\n"); + return; } + + DeckCardInfo.makeSureCardAmountFine(count, found.getName()); + + List zone = sideboard ? deckList.getSideboard() : deckList.getCards(); + DeckCardInfo deckCardInfo = new DeckCardInfo(found.getName(), found.getCardNumber(), found.getSetCode()); + zone.addAll(Collections.nCopies(count, deckCardInfo.copy())); } } diff --git a/Mage/src/main/java/mage/cards/decks/importer/MtgjsonDeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/MtgjsonDeckImporter.java index 5a0cc5371ea..2f2f5932598 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/MtgjsonDeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/MtgjsonDeckImporter.java @@ -12,7 +12,9 @@ import java.util.Optional; /** - * @author github: timhae + * Deck import: mtgjson service + * + * @author timhae */ public class MtgjsonDeckImporter extends JsonDeckImporter { diff --git a/Mage/src/main/java/mage/cards/decks/importer/O8dDeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/O8dDeckImporter.java index b0dd99ea74a..96fdb210c80 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/O8dDeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/O8dDeckImporter.java @@ -13,6 +13,9 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +/** + * Deck import: OCTGN app + */ public class O8dDeckImporter extends XmlDeckImporter { /** @@ -72,5 +75,4 @@ public class O8dDeckImporter extends XmlDeckImporter { } }; } - } diff --git a/Mage/src/main/java/mage/cards/decks/importer/PlainTextDeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/PlainTextDeckImporter.java index a8c1e70a79d..ee5d71ebac3 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/PlainTextDeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/PlainTextDeckImporter.java @@ -10,6 +10,8 @@ import java.util.List; import java.util.Scanner; /** + * Deck import: helper class for all text base formats + * * @author BetaSteward_at_googlemail.com */ public abstract class PlainTextDeckImporter extends DeckImporter { diff --git a/Mage/src/main/java/mage/cards/decks/importer/TxtDeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/TxtDeckImporter.java index 6a499e086f2..ccf4b7dcb13 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/TxtDeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/TxtDeckImporter.java @@ -12,7 +12,9 @@ import java.util.Locale; import java.util.Set; /** - * @author BetaSteward_at_googlemail.com + * Deck import: text deck, compatible with MTGO and many other apps/services + * + * @author BetaSteward_at_googlemail.com, JayDi85 */ public class TxtDeckImporter extends PlainTextDeckImporter { diff --git a/Mage/src/main/java/mage/cards/decks/importer/XmlDeckImporter.java b/Mage/src/main/java/mage/cards/decks/importer/XmlDeckImporter.java index 01e1d81862c..440e2de7512 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/XmlDeckImporter.java +++ b/Mage/src/main/java/mage/cards/decks/importer/XmlDeckImporter.java @@ -18,6 +18,9 @@ import java.util.List; import static javax.xml.xpath.XPathConstants.NODESET; +/** + * Deck import: helper class for all xml base formats + */ public abstract class XmlDeckImporter extends DeckImporter { private final XPathFactory xpathFactory = XPathFactory.newInstance(); diff --git a/Mage/src/test/data/importer/testdeck.cod b/Mage/src/test/data/importer/testdeck.cod index c90d63f6767..cbe0a6f552a 100644 --- a/Mage/src/test/data/importer/testdeck.cod +++ b/Mage/src/test/data/importer/testdeck.cod @@ -1,10 +1,10 @@ - Deck Name + Deck Name Some comments in here. - + diff --git a/Mage/src/test/data/importer/testdeck.dek b/Mage/src/test/data/importer/testdeck.dek new file mode 100644 index 00000000000..1826c6757b6 --- /dev/null +++ b/Mage/src/test/data/importer/testdeck.dek @@ -0,0 +1,10 @@ + + 0 + 0 + + + + + + + \ No newline at end of file diff --git a/Mage/src/test/data/importer/testdeck.mtga b/Mage/src/test/data/importer/testdeck.mtga index 3c4fc724012..fe31c404b5b 100644 --- a/Mage/src/test/data/importer/testdeck.mtga +++ b/Mage/src/test/data/importer/testdeck.mtga @@ -1,4 +1,4 @@ -1 Niv-Mizzet Reborn (WAR) 208 +2 Niv-Mizzet Reborn (WAR) 208 1 Teferi, Time Raveler (WAR) 221 1 Dovin's Veto (WAR) 193 1 Knight of Autumn (GRN) 183 @@ -6,5 +6,5 @@ 1 Forest (XLN) 277 1 Teferi, Hero of Dominaria (DAR) 207 -1 Unmoored Ego (GRN) 212 +3 Unmoored Ego (GRN) 212 1 Beacon Bolt (GRN) 154 diff --git a/Mage/src/test/java/mage/cards/decks/importer/CodDeckImportTest.java b/Mage/src/test/java/mage/cards/decks/importer/CodDeckImportTest.java index c087b837ce8..cc0554d8edc 100644 --- a/Mage/src/test/java/mage/cards/decks/importer/CodDeckImportTest.java +++ b/Mage/src/test/java/mage/cards/decks/importer/CodDeckImportTest.java @@ -1,12 +1,11 @@ package mage.cards.decks.importer; import mage.cards.decks.DeckCardLists; +import org.junit.Assert; import org.junit.Test; import java.nio.file.Paths; -import static org.junit.Assert.assertEquals; - public class CodDeckImportTest { private static final FakeCardLookup LOOKUP = new FakeCardLookup(false) @@ -29,16 +28,14 @@ public class CodDeckImportTest { errors, false ); - assertEquals("Deck Name", deck.getName()); + Assert.assertEquals("Could not find card: '@#$NOT A REAL CARD NAME@#$'\n", errors.toString()); + Assert.assertEquals("Deck Name", deck.getName()); TestDeckChecker.checker() .addMain("Forest", 12) - .addMain("Razorverge Thicket", 100) + .addMain("Razorverge Thicket", 5) .addMain("Avacyn's Pilgrim", 1) .addSide("War Priest of Thune", 3) - .verify(deck, 113, 3); - - assertEquals("Could not find card: '@#$NOT A REAL CARD NAME@#$'\n", errors.toString()); + .verify(deck, 18, 3); } - } diff --git a/Mage/src/test/java/mage/cards/decks/importer/DecDeckImportTest.java b/Mage/src/test/java/mage/cards/decks/importer/DecDeckImportTest.java index 8dd592af013..225ad1df5e8 100644 --- a/Mage/src/test/java/mage/cards/decks/importer/DecDeckImportTest.java +++ b/Mage/src/test/java/mage/cards/decks/importer/DecDeckImportTest.java @@ -1,6 +1,7 @@ package mage.cards.decks.importer; import mage.cards.decks.DeckCardLists; +import org.junit.Assert; import org.junit.Test; import java.nio.file.Paths; @@ -26,6 +27,7 @@ public class DecDeckImportTest { false ); + Assert.assertEquals("", errors.toString()); TestDeckChecker.checker() .addMain("Masticore", 4) .addMain("Metalworker", 4) @@ -49,8 +51,6 @@ public class DecDeckImportTest { .addSide("Mishra's Helix", 1) .addSide("Rising Waters", 2) .verify(deck, 60, 15); - - assertEquals("", errors.toString()); } } diff --git a/Mage/src/test/java/mage/cards/decks/importer/DekDeckImportTest.java b/Mage/src/test/java/mage/cards/decks/importer/DekDeckImportTest.java new file mode 100644 index 00000000000..396669f96ea --- /dev/null +++ b/Mage/src/test/java/mage/cards/decks/importer/DekDeckImportTest.java @@ -0,0 +1,45 @@ +package mage.cards.decks.importer; + +import mage.cards.decks.DeckCardLists; +import org.junit.Assert; +import org.junit.Test; + +import java.nio.file.Paths; + +public class DekDeckImportTest { + + private static final FakeCardLookup LOOKUP = new FakeCardLookup(false) + .addCard("Nezumi Shortfang") + .addCard("Kessig Prowler") + .addCard("Murderous Rider") + .addCard("Refuse // Cooperate") + .addCard("Riverglide Pathway") + .addCard("Dead // Gone"); + + @Test + public void testImport() { + DekDeckImporter importer = new DekDeckImporter() { + @Override + public CardLookup getCardLookup() { + return LOOKUP; + } + }; + StringBuilder errors = new StringBuilder(); + DeckCardLists deck = importer.importDeck( + Paths.get("src", "test", "data", "importer", "testdeck.dek").toString(), + errors, + false + ); + + Assert.assertEquals("", errors.toString()); + TestDeckChecker.checker() + .addMain("Nezumi Shortfang", 2) + .addMain("Kessig Prowler", 1) + .addMain("Murderous Rider", 1) + .addMain("Refuse // Cooperate", 1) + .addSide("Riverglide Pathway", 2) + .addSide("Dead // Gone", 1) + .verify(deck, 5, 3); + } + +} diff --git a/Mage/src/test/java/mage/cards/decks/importer/DraftLogImporterTest.java b/Mage/src/test/java/mage/cards/decks/importer/DraftLogImporterTest.java index 38a044e8150..dc0e79792ec 100644 --- a/Mage/src/test/java/mage/cards/decks/importer/DraftLogImporterTest.java +++ b/Mage/src/test/java/mage/cards/decks/importer/DraftLogImporterTest.java @@ -1,6 +1,7 @@ package mage.cards.decks.importer; import mage.cards.decks.DeckCardLists; +import org.junit.Assert; import org.junit.Test; import java.nio.file.Paths; @@ -26,6 +27,7 @@ public class DraftLogImporterTest { false ); + Assert.assertEquals("", errors.toString()); TestDeckChecker.checker() .addMain("Raging Ravine", 1) .addMain("Fiery Temper", 1) @@ -73,8 +75,6 @@ public class DraftLogImporterTest { .addMain("Just the Wind", 1) .addMain("Flight of Fancy", 1) .verify(deck, 45, 0); - - assertEquals("", errors.toString()); } } \ No newline at end of file diff --git a/Mage/src/test/java/mage/cards/decks/importer/FakeCardLookup.java b/Mage/src/test/java/mage/cards/decks/importer/FakeCardLookup.java index 105f0707853..c655b8fff16 100644 --- a/Mage/src/test/java/mage/cards/decks/importer/FakeCardLookup.java +++ b/Mage/src/test/java/mage/cards/decks/importer/FakeCardLookup.java @@ -1,54 +1,54 @@ package mage.cards.decks.importer; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; +import java.util.*; + +/** + * Tests only: mock of card repository for deck import tests + * TODO: move that tests from Mage to Test project + */ public class FakeCardLookup extends CardLookup { - private final Map lookup = new HashMap<>(); - private final boolean alwaysMatches; + private final Map lookup = new HashMap<>(); + private final boolean alwaysMatches; - public FakeCardLookup() { - this(true); - } - - public FakeCardLookup(boolean alwaysMatches) { - this.alwaysMatches = alwaysMatches; - } - - public FakeCardLookup addCard(String cardName) { - lookup.put(cardName, new CardInfo() {{ - name = cardName; - }}); - return this; - } - - public Optional lookupCardInfo(String cardName) { - CardInfo card = lookup.get(cardName); - if (card != null) { - return Optional.of(card); + public FakeCardLookup() { + this(true); } - if (alwaysMatches) { - return Optional.of(new CardInfo() {{ - name = cardName; - }}); + public FakeCardLookup(boolean alwaysMatches) { + this.alwaysMatches = alwaysMatches; } - return Optional.empty(); - } + public FakeCardLookup addCard(String cardName) { + lookup.put(cardName, new CardInfo() {{ + name = cardName; + }}); + return this; + } - @Override - public List lookupCardInfo(CardCriteria criteria) { - return lookupCardInfo(criteria.getName()) - .map(Collections::singletonList) - .orElse(Collections.emptyList()); - } + public Optional lookupCardInfo(String cardName) { + CardInfo card = lookup.get(cardName); + if (card != null) { + return Optional.of(card); + } + + if (alwaysMatches) { + return Optional.of(new CardInfo() {{ + name = cardName; + }}); + } + + return Optional.empty(); + } + + @Override + public List lookupCardInfo(CardCriteria criteria) { + return lookupCardInfo(criteria.getName()) + .map(Collections::singletonList) + .orElse(Collections.emptyList()); + } } diff --git a/Mage/src/test/java/mage/cards/decks/importer/MtgaImporterTest.java b/Mage/src/test/java/mage/cards/decks/importer/MtgaImporterTest.java index 54632b4fd63..865dae482f5 100644 --- a/Mage/src/test/java/mage/cards/decks/importer/MtgaImporterTest.java +++ b/Mage/src/test/java/mage/cards/decks/importer/MtgaImporterTest.java @@ -1,6 +1,7 @@ package mage.cards.decks.importer; import mage.cards.decks.DeckCardLists; +import org.junit.Assert; import org.junit.Test; import java.nio.file.Paths; @@ -26,8 +27,9 @@ public class MtgaImporterTest { false ); + Assert.assertEquals("", errors.toString()); TestDeckChecker.checker() - .addMain("Niv-Mizzet Reborn", 1) + .addMain("Niv-Mizzet Reborn", 2) .addMain("Teferi, Time Raveler", 1) .addMain("Dovin's Veto", 1) .addMain("Knight of Autumn", 1) @@ -35,12 +37,10 @@ public class MtgaImporterTest { .addMain("Forest", 1) .addMain("Teferi, Hero of Dominaria", 1) - .addSide("Unmoored Ego", 1) + .addSide("Unmoored Ego", 3) .addSide("Beacon Bolt", 1) - .verify(deck, 7, 2); - - assertEquals("", errors.toString()); + .verify(deck, 8, 4); } } \ No newline at end of file diff --git a/Mage/src/test/java/mage/cards/decks/importer/MtgjsonDeckImportTest.java b/Mage/src/test/java/mage/cards/decks/importer/MtgjsonDeckImportTest.java index 00d28cae702..77cd0736a58 100644 --- a/Mage/src/test/java/mage/cards/decks/importer/MtgjsonDeckImportTest.java +++ b/Mage/src/test/java/mage/cards/decks/importer/MtgjsonDeckImportTest.java @@ -1,6 +1,7 @@ package mage.cards.decks.importer; import mage.cards.decks.DeckCardLists; +import org.junit.Assert; import org.junit.Test; import java.nio.file.Paths; @@ -27,7 +28,8 @@ public class MtgjsonDeckImportTest { errors, false ); - assertEquals("Arcane Tempo", deck.getName()); + Assert.assertEquals("Arcane Tempo", deck.getName()); + Assert.assertEquals("", errors.toString()); TestDeckChecker.checker() .addMain("Goblin Electromancer", 4) .addMain("Crackling Drake", 4) @@ -57,8 +59,6 @@ public class MtgjsonDeckImportTest { .addSide("Disdainful Stroke", 2) // .verify(deck, 60, 15); - - assertEquals("", errors.toString()); } } diff --git a/Mage/src/test/java/mage/cards/decks/importer/MwsDeckImportTest.java b/Mage/src/test/java/mage/cards/decks/importer/MwsDeckImportTest.java index f449e1f7105..9f60457c69c 100644 --- a/Mage/src/test/java/mage/cards/decks/importer/MwsDeckImportTest.java +++ b/Mage/src/test/java/mage/cards/decks/importer/MwsDeckImportTest.java @@ -1,6 +1,7 @@ package mage.cards.decks.importer; import mage.cards.decks.DeckCardLists; +import org.junit.Assert; import org.junit.Test; import java.nio.file.Paths; @@ -26,6 +27,7 @@ public class MwsDeckImportTest { false ); + Assert.assertEquals("", errors.toString()); TestDeckChecker.checker() .addMain("Mutavault", 4) .addMain("Plains", 18) @@ -49,8 +51,6 @@ public class MwsDeckImportTest { .addSide("Rootborn Defenses", 3) .verify(deck, 60, 15); - - assertEquals("", errors.toString()); } } diff --git a/Mage/src/test/java/mage/cards/decks/importer/O8dDeckImportTest.java b/Mage/src/test/java/mage/cards/decks/importer/O8dDeckImportTest.java index c5a51c30d69..9f35681abd3 100644 --- a/Mage/src/test/java/mage/cards/decks/importer/O8dDeckImportTest.java +++ b/Mage/src/test/java/mage/cards/decks/importer/O8dDeckImportTest.java @@ -1,6 +1,7 @@ package mage.cards.decks.importer; import mage.cards.decks.DeckCardLists; +import org.junit.Assert; import org.junit.Test; import java.nio.file.Paths; @@ -26,12 +27,11 @@ public class O8dDeckImportTest { false ); + Assert.assertEquals("", errors.toString()); TestDeckChecker.checker() .addMain("Forest", 1) .addSide("Island", 2) .verify(deck, 1, 2); - - assertEquals("", errors.toString()); } } diff --git a/Mage/src/test/java/mage/cards/decks/importer/TestDeckChecker.java b/Mage/src/test/java/mage/cards/decks/importer/TestDeckChecker.java index e444a05efad..f0b5546dd30 100644 --- a/Mage/src/test/java/mage/cards/decks/importer/TestDeckChecker.java +++ b/Mage/src/test/java/mage/cards/decks/importer/TestDeckChecker.java @@ -8,6 +8,12 @@ import java.util.List; import static org.junit.Assert.assertEquals; +/** + * Tests only: helper class to test decks + *

+ * See decks format examples under download button + * at fandom wiki page + */ public class TestDeckChecker { private final List main = new ArrayList<>(); @@ -48,5 +54,4 @@ public class TestDeckChecker { public static TestDeckChecker checker() { return new TestDeckChecker(); } - }