diff --git a/forge-core/src/main/java/forge/ImageKeys.java b/forge-core/src/main/java/forge/ImageKeys.java index fe9360ab7a8..77553a9bd53 100644 --- a/forge-core/src/main/java/forge/ImageKeys.java +++ b/forge-core/src/main/java/forge/ImageKeys.java @@ -2,13 +2,11 @@ package forge; import forge.item.PaperCard; import forge.util.FileUtil; -import forge.util.ImageUtil; import forge.util.TextUtil; import org.apache.commons.lang3.StringUtils; import java.io.File; -import java.util.HashMap; -import java.util.Map; +import java.util.*; public final class ImageKeys { public static final String CARD_PREFIX = "c:"; @@ -68,9 +66,8 @@ public final class ImageKeys { } public static File getImageFile(String key) { - if (StringUtils.isEmpty(key)) { + if (StringUtils.isEmpty(key)) return null; - } final String dir; final String filename; @@ -220,14 +217,35 @@ public final class ImageKeys { //shortcut for determining if a card image exists for a given card //should only be called from PaperCard.hasImage() + static HashMap> cachedContent=new HashMap<>(); public static boolean hasImage(PaperCard pc) { Boolean editionHasImage = editionImageLookup.get(pc.getEdition()); if (editionHasImage == null) { String setFolder = getSetFolder(pc.getEdition()); editionHasImage = FileUtil.isDirectoryWithFiles(CACHE_CARD_PICS_DIR + setFolder); editionImageLookup.put(pc.getEdition(), editionHasImage); + if (editionHasImage){ + File f = new File(CACHE_CARD_PICS_DIR + setFolder); // no need to check this, otherwise editionHasImage would be false! + HashSet setFolderContent = new HashSet<>(); + for (String filename : Arrays.asList(f.list())) { + // TODO: should this use FILE_EXTENSIONS ? + if (!filename.endsWith(".jpg") && !filename.endsWith(".png")) + continue; // not image - not interested + setFolderContent.add(filename.split("\\.")[0]); // get rid of any full or fullborder + } + cachedContent.put(setFolder, setFolderContent); + } } + String[] keyParts = pc.getImageKeyFromSet().split(File.separator); + HashSet content = cachedContent.getOrDefault(keyParts[0], null); //avoid checking for file if edition doesn't have any images - return editionHasImage && getImageFile(ImageUtil.getImageKey(pc, false, true)) != null; + return editionHasImage && hitCache(content, keyParts[1]); + } + + private static boolean hitCache(HashSet cache, String filename){ + if (cache == null || cache.isEmpty()) + return false; + final String keyPrefix = filename.split("\\.")[0]; + return cache.contains(keyPrefix); } } diff --git a/forge-core/src/main/java/forge/card/CardDb.java b/forge-core/src/main/java/forge/card/CardDb.java index f573c618792..b0a390a896e 100644 --- a/forge-core/src/main/java/forge/card/CardDb.java +++ b/forge-core/src/main/java/forge/card/CardDb.java @@ -90,6 +90,12 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { this.collectorNumber = collectorNumber; } + public static String compose(String cardName, boolean isFoil){ + if (isFoil) + return cardName+foilSuffix; + return cardName; + } + public static String compose(String cardName, String setCode) { setCode = setCode != null ? setCode : ""; cardName = cardName != null ? cardName : ""; @@ -135,7 +141,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } private static boolean isArtIndex(String s) { - return StringUtils.isNumeric(s) && s.length() == 1; + return StringUtils.isNumeric(s) && s.length() <= 2 ; // only artIndex between 1-99 } private static boolean isSetCode(String s) { @@ -462,15 +468,15 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } // 2. Card lookup in edition with specified filter didn't work. - // So now check whether the cards exists in the DB first, + // So now check whether the cards exist in the DB first, // and select pick the card based on current SetPreference policy as a fallback Collection cards = getAllCards(request.cardName); - if (cards == null) + if (cards.isEmpty()) // Never null being this a view in MultiMap return null; // Either No Edition has been specified OR as a fallback in case of any error! // get card using the default card art preference - result = getCardFromEditions(request.cardName, this.defaultCardArtPreference, request.artIndex); - return result != null && request.isFoil ? result.getFoiled() : result; + String cardRequest = CardRequest.compose(request.cardName, request.isFoil); + return getCardFromEditions(cardRequest, this.defaultCardArtPreference, request.artIndex); } /* @@ -510,9 +516,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { cardName = cardNameRequest.cardName; isFoil = isFoil || cardNameRequest.isFoil; - List cards = getAllCards(cardName); - // Look for Code or Code2 to make the retrieval more robust - List candidates = Lists.newArrayList(Iterables.filter(cards, new Predicate() { + List candidates = getAllCards(cardName, new Predicate() { @Override public boolean apply(PaperCard c) { boolean artIndexFilter = true; @@ -526,21 +530,17 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { collectorNumberFilter = (c.getCollectorNumber().equals(collectorNumber)); return setFilter && artIndexFilter && collectorNumberFilter; } - })); + }); if (candidates.isEmpty()) return null; - PaperCard candidate = candidates.get(0); + Iterator candidatesIterator = candidates.iterator(); + PaperCard candidate = candidatesIterator.next(); // Before returning make sure that actual candidate has Image. // If not, try to replace current candidate with one having image, // so to align this implementation with old one. - if (!candidate.hasImage()) { - for (PaperCard card : candidates) { - if (card.hasImage()) { - candidate = card; - break; // found, ready to go - } - } + while (!candidate.hasImage() && candidatesIterator.hasNext()) { + candidate = candidatesIterator.next(); } return isFoil ? candidate.getFoiled() : candidate; } @@ -567,8 +567,8 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } @Override - public PaperCard getCardFromEditions(final String cardName, final CardArtPreference artPreference, int artIndex) { - return this.tryToGetCardFromEditions(cardName, artPreference, artIndex); + public PaperCard getCardFromEditions(final String cardInfo, final CardArtPreference artPreference, int artIndex) { + return this.tryToGetCardFromEditions(cardInfo, artPreference, artIndex); } /* @@ -634,38 +634,52 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { if (cr.artIndex != artIndex && artIndex > IPaperCard.DEFAULT_ART_INDEX ) cr.artIndex = artIndex; // 2nd cond. is to verify that some actual value has been passed in. - List cards = getAllCards(cr.cardName); + List cards; if (releaseDate != null) { - cards = Lists.newArrayList(Iterables.filter(cards, new Predicate() { + cards = getAllCards(cr.cardName, new Predicate() { @Override public boolean apply(PaperCard c) { + if (c.getArtIndex() != cr.artIndex) + return false; // not interested anyway! CardEdition ed = editions.get(c.getEdition()); + if (ed == null) return false; if (releasedBeforeFlag) return ed.getDate().before(releaseDate); else return ed.getDate().after(releaseDate); } - })); - } + }); + } else // filter candidates based on requested artIndex + cards = getAllCards(cr.cardName, new Predicate() { + @Override + public boolean apply(PaperCard card) { + return card.getArtIndex() == cr.artIndex; + } + }); - if (cards.size() == 0) // Don't bother continuing! No card has been found! - return null; + if (cards.size() == 1) // if only one candidate, there much else we should do + return cr.isFoil ? cards.get(0).getFoiled() : cards.get(0); /* 2. Retrieve cards based of [Frame]Set Preference ================================================ */ - // Collect the list of all editions found for target card - LinkedHashSet cardEditions = new LinkedHashSet<>(); + List cardEditions = new ArrayList<>(); + Map candidatesCard = new HashMap<>(); for (PaperCard card : cards) { String setCode = card.getEdition(); + CardEdition ed; if (setCode.equals(CardEdition.UNKNOWN.getCode())) - cardEditions.add(CardEdition.UNKNOWN); - else { - CardEdition ed = editions.get(card.getEdition()); - if (ed != null) - cardEditions.add(ed); + ed = CardEdition.UNKNOWN; + else + ed = editions.get(card.getEdition()); + if (ed != null) { + cardEditions.add(ed); + candidatesCard.put(setCode, card); } } + if (cardEditions.isEmpty()) + return null; // nothing to do + // Filter Cards Editions based on set preferences List acceptedEditions = Lists.newArrayList(Iterables.filter(cardEditions, new Predicate() { @Override @@ -681,26 +695,24 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { If this happens, we won't try to iterate over an empty list. Instead, we will fall back to original lists of editions (unfiltered, of course) AND STILL sorted according to chosen art preference. */ - if (acceptedEditions.size() == 0) + if (acceptedEditions.isEmpty()) acceptedEditions.addAll(cardEditions); - Collections.sort(acceptedEditions); // CardEdition correctly sort by (release) date - if (artPref.latestFirst) - Collections.reverse(acceptedEditions); // newest editions first - PaperCard candidate = null; - for (CardEdition ed : acceptedEditions) { - PaperCard cardFromSet = getCardFromSet(cr.cardName, ed, cr.artIndex, cr.isFoil); - if (candidate == null && cardFromSet != null) - // save the first card found, as the last backup in case no other candidate *with image* will be found - candidate = cardFromSet; - - if (cardFromSet != null && cardFromSet.hasImage()) { - candidate = cardFromSet; - break; // we're done here: found card **with Image** - } + if (acceptedEditions.size() > 1) { + Collections.sort(acceptedEditions); // CardEdition correctly sort by (release) date + if (artPref.latestFirst) + Collections.reverse(acceptedEditions); // newest editions first } - //If any, we're sure that at least one candidate is always returned nevertheless it has image or not - return candidate; // any foil request already handled in getCardFromSet + + final Iterator editionIterator = acceptedEditions.iterator(); + CardEdition ed = editionIterator.next(); + PaperCard candidate = candidatesCard.get(ed.getCode()); + while (!candidate.hasImage() && editionIterator.hasNext()) { + ed = editionIterator.next(); + candidate = candidatesCard.get(ed.getCode()); + } + //If any, we're sure that at least one candidate is always returned despite it having any image + return cr.isFoil ? candidate.getFoiled() : candidate; } @Override @@ -716,18 +728,16 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { } @Override - public int getArtCount(String cardName, String setName) { - if (cardName == null || setName == null) + public int getArtCount(String cardName, String setCode) { + if (cardName == null || setCode == null) return 0; - Collection cards = getAllCards(cardName); - if (null == cards || cards.size() == 0) - return 0; - int artCount = 0; - for (PaperCard pc : cards) { - if (pc.getEdition().equalsIgnoreCase(setName)) - artCount++; - } - return artCount; + Collection cardsInSet = getAllCards(cardName, new Predicate() { + @Override + public boolean apply(PaperCard card) { + return card.getEdition().equalsIgnoreCase(setCode); + } + }); + return cardsInSet.size(); } // returns a list of all cards from their respective latest (or preferred) editions @@ -834,6 +844,11 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { return Lists.newArrayList(Iterables.filter(getAllCards(), predicate)); } + @Override + public List getAllCards(final String cardName, Predicate predicate){ + return Lists.newArrayList(Iterables.filter(getAllCards(cardName), predicate)); + } + /** * Returns a modifiable list of cards matching the given predicate */ @@ -1006,29 +1021,33 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { // 1. generate all paper cards from edition data we have (either explicit, or found in res/editions, or add to unknown edition) List paperCards = new ArrayList<>(); if (null == whenItWasPrinted || whenItWasPrinted.isEmpty()) { - // TODO Not performant Each time we "putCard" we loop through ALL CARDS IN ALL editions + // @friarsol: Not performant Each time we "putCard" we loop through ALL CARDS IN ALL editions + // @leriomaggio: DONE! re-using here the same strategy implemented for lazy-loading! for (CardEdition e : editions.getOrderedEditions()) { int artIdx = IPaperCard.DEFAULT_ART_INDEX; - for (CardInSet cis : e.getAllCardsInSet()) { - if (!cis.name.equals(cardName)) { - continue; - } - paperCards.add(new PaperCard(rules, e.getCode(), cis.rarity, artIdx++)); - } + for (CardInSet cis : e.getCardInSet(cardName)) + paperCards.add(new PaperCard(rules, e.getCode(), cis.rarity, artIdx++, false, + cis.collectorNumber, cis.artistName)); } } else { String lastEdition = null; int artIdx = 0; for (Pair tuple : whenItWasPrinted) { if (!tuple.getKey().equals(lastEdition)) { - artIdx = IPaperCard.DEFAULT_ART_INDEX; + artIdx = IPaperCard.DEFAULT_ART_INDEX; // reset artIndex lastEdition = tuple.getKey(); } CardEdition ed = editions.get(lastEdition); - if (null == ed) { + if (ed == null) { continue; } - paperCards.add(new PaperCard(rules, lastEdition, tuple.getValue(), artIdx++)); + List cardsInSet = ed.getCardInSet(cardName); + if (cardsInSet.isEmpty()) + continue; + int cardInSetIndex = Math.max(artIdx-1, 0); // make sure doesn't go below zero + CardInSet cds = cardsInSet.get(cardInSetIndex); // use ArtIndex to get the right Coll. Number + paperCards.add(new PaperCard(rules, lastEdition, tuple.getValue(), artIdx++, false, + cds.collectorNumber, cds.artistName)); } } if (paperCards.isEmpty()) { diff --git a/forge-core/src/main/java/forge/card/CardEdition.java b/forge-core/src/main/java/forge/card/CardEdition.java index 995086dad64..9df2546479f 100644 --- a/forge-core/src/main/java/forge/card/CardEdition.java +++ b/forge-core/src/main/java/forge/card/CardEdition.java @@ -373,6 +373,13 @@ public final class CardEdition implements Comparable { } private ListMultimap cardsInSetLookupMap = null; + + /** + * Get all the CardInSet instances with the input card name. + * @param cardName Name of the Card to look for. + * @return A List of all the CardInSet instances for a given name. + * If not fount, an Empty sequence (view) will be returned instead! + */ public List getCardInSet(String cardName){ if (cardsInSetLookupMap == null) { // initialise diff --git a/forge-core/src/main/java/forge/card/ICardDatabase.java b/forge-core/src/main/java/forge/card/ICardDatabase.java index 64646109a46..b158404d320 100644 --- a/forge-core/src/main/java/forge/card/ICardDatabase.java +++ b/forge-core/src/main/java/forge/card/ICardDatabase.java @@ -79,6 +79,7 @@ public interface ICardDatabase extends Iterable { Collection getAllCards(); Collection getAllCards(String cardName); Collection getAllCards(Predicate predicate); + Collection getAllCards(String cardName,Predicate predicate); Collection getAllCards(CardEdition edition); Collection getUniqueCards(); diff --git a/forge-core/src/main/java/forge/item/IPaperCard.java b/forge-core/src/main/java/forge/item/IPaperCard.java index 8ce1fa895e4..36ad4812e54 100644 --- a/forge-core/src/main/java/forge/item/IPaperCard.java +++ b/forge-core/src/main/java/forge/item/IPaperCard.java @@ -20,6 +20,7 @@ public interface IPaperCard extends InventoryItem, Serializable { String NO_COLLECTOR_NUMBER = "N.A."; // Placeholder for No-Collection number available int DEFAULT_ART_INDEX = 1; int NO_ART_INDEX = -1; // Placeholder when NO ArtIndex is Specified + String NO_ARTIST_NAME = ""; /** * Number of filters based on CardPrinted values. diff --git a/forge-core/src/main/java/forge/item/PaperCard.java b/forge-core/src/main/java/forge/item/PaperCard.java index 36ceceb3ad8..6cf473f85ed 100644 --- a/forge-core/src/main/java/forge/item/PaperCard.java +++ b/forge-core/src/main/java/forge/item/PaperCard.java @@ -25,6 +25,7 @@ import forge.card.CardEdition; import forge.card.CardRarity; import forge.card.CardRules; import forge.util.CardTranslation; +import forge.util.ImageUtil; import forge.util.Localizer; import forge.util.TextUtil; @@ -52,7 +53,7 @@ public final class PaperCard implements Comparable, InventoryItemFro By default the attribute is marked as "unset" so that it could be retrieved and set. (see getCollectorNumber()) */ - private String collectorNumber = null; + private String collectorNumber; private final String artist; private final int artIndex; private final boolean foil; @@ -75,18 +76,6 @@ public final class PaperCard implements Comparable, InventoryItemFro @Override public String getCollectorNumber() { - /* The collectorNumber attribute is managed in a property-like fashion. - By default it is marked as "unset" (-1), which integrates with all constructors - invocations not including this as an extra parameter. In this way, the new - attribute could be added to the API with minimum disruption to code - throughout the other packages. - If "unset", the corresponding collectorNumber will be retrieved - from the corresponding CardEdition (see retrieveCollectorNumber) - * */ - if (collectorNumber == null) { - collectorNumber = this.retrieveCollectorNumber(); - } - return collectorNumber; } @@ -152,6 +141,13 @@ public final class PaperCard implements Comparable, InventoryItemFro return hasImage; } + private String imageKeyFromSet = null; + public String getImageKeyFromSet() { + if (this.imageKeyFromSet == null) + this.imageKeyFromSet = ImageUtil.getImageKey(this, false, true); + return imageKeyFromSet; + } + /** * Lambda to get rules for selects from list of printed cards. */ @@ -169,15 +165,12 @@ public final class PaperCard implements Comparable, InventoryItemFro }; public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0){ - this(rules0, edition0, rarity0, IPaperCard.DEFAULT_ART_INDEX); + this(rules0, edition0, rarity0, IPaperCard.DEFAULT_ART_INDEX, false, + IPaperCard.NO_COLLECTOR_NUMBER, IPaperCard.NO_ARTIST_NAME); } - public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0, final int artIndex0) { - this(rules0, edition0, rarity0, artIndex0, false, ""); - } - - public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0, final int artIndex0, - final boolean foil0, final String artist0) { + public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0, + final int artIndex0, final boolean foil0, final String collectorNumber0, final String artist0) { if (rules0 == null || edition0 == null || rarity0 == null) { throw new IllegalArgumentException("Cannot create card without rules, edition or rarity"); } @@ -187,16 +180,8 @@ public final class PaperCard implements Comparable, InventoryItemFro artIndex = Math.max(artIndex0, IPaperCard.DEFAULT_ART_INDEX); foil = foil0; rarity = rarity0; - artist = (artist0 != null ? artist0 : ""); - } - - public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0, - final int artIndex0, final boolean foil0, final String collectorNumber0, final String artist) { - this(rules0, edition0, rarity0, artIndex0, foil0, artist); - if ((collectorNumber0 == null) || (collectorNumber0.length() == 0)) - collectorNumber = IPaperCard.NO_COLLECTOR_NUMBER; - else - collectorNumber = collectorNumber0; + artist = (artist0 != null ? artist0 : IPaperCard.NO_ARTIST_NAME); + collectorNumber = (collectorNumber0 != null) && (collectorNumber0.length() > 0) ? collectorNumber0 : IPaperCard.NO_COLLECTOR_NUMBER; } // Want this class to be a key for HashTable @@ -268,10 +253,14 @@ public final class PaperCard implements Comparable, InventoryItemFro return CardEdition.CardInSet.getSortableCollectorNumber(collectorNumber); } + private String sortableCNKey = null; public String getCollectorNumberSortingKey(){ - // Hardly the case, but just invoke getter rather than direct - // attribute to be sure that collectorNumber has been retrieved already! - return makeCollectorNumberSortingKey(getCollectorNumber()); + if (sortableCNKey == null) { + // Hardly the case, but just invoke getter rather than direct + // attribute to be sure that collectorNumber has been retrieved already! + sortableCNKey = makeCollectorNumberSortingKey(getCollectorNumber()); + } + return sortableCNKey; } @@ -309,32 +298,6 @@ public final class PaperCard implements Comparable, InventoryItemFro rarity = pc.getRarity(); } - // FIXME: @leriomaggio - remember to get rid of this method once and for all :) - private String retrieveCollectorNumber() { - StaticData data = StaticData.instance(); - CardEdition edition = data.getEditions().get(this.edition); - if (edition == null) { - edition = data.getCustomEditions().get(this.edition); - if (edition == null) // don't bother continuing - non-existing card! - return NO_COLLECTOR_NUMBER; - } - int artIndexCount = 0; - String collectorNumberInEdition = ""; - for (CardEdition.CardInSet card : edition.getAllCardsInSet()) { - if (card.name.equalsIgnoreCase(this.name)) { - artIndexCount += 1; - if (artIndexCount == this.artIndex) { - collectorNumberInEdition = card.collectorNumber; - break; - } - } - } - // CardEdition stores collectorNumber as a String, which is null if there isn't any. - // In this case, the NO_COLLECTOR_NUMBER value (i.e. 0) is returned. - return ((collectorNumberInEdition != null) && (collectorNumberInEdition.length() > 0)) ? - collectorNumberInEdition : NO_COLLECTOR_NUMBER; - } - @Override public String getImageKey(boolean altState) { String imageKey = ImageKeys.CARD_PREFIX + name + CardDb.NameSetSeparator diff --git a/forge-core/src/main/java/forge/util/FileUtil.java b/forge-core/src/main/java/forge/util/FileUtil.java index 64cbdfedf1b..a969b6367b5 100644 --- a/forge-core/src/main/java/forge/util/FileUtil.java +++ b/forge-core/src/main/java/forge/util/FileUtil.java @@ -78,8 +78,10 @@ public final class FileUtil { } public static boolean isDirectoryWithFiles(final String path) { + if (path == null) return false; final File f = new File(path); - return f.exists() && f.isDirectory() && f.list().length > 0; + final String[] fileList = f.list(); + return fileList!=null && fileList.length > 0; } public static boolean ensureDirectoryExists(final String path) { diff --git a/forge-core/src/main/java/forge/util/ImageUtil.java b/forge-core/src/main/java/forge/util/ImageUtil.java index d8b67d03b2c..5b2c0488e6a 100644 --- a/forge-core/src/main/java/forge/util/ImageUtil.java +++ b/forge-core/src/main/java/forge/util/ImageUtil.java @@ -56,7 +56,7 @@ public class ImageUtil { int artIdx = cp.getArtIndex() - 1; if (hasManyPictures) { if (cntPictures <= artIdx) // prevent overflow - artIdx = cntPictures == 0 ? 0 : artIdx % cntPictures; + artIdx = artIdx % cntPictures; s.append(artIdx + 1); } diff --git a/forge-gui-desktop/src/main/java/forge/ImageCache.java b/forge-gui-desktop/src/main/java/forge/ImageCache.java index ebd3e486c5e..c0ccc099fe3 100644 --- a/forge-gui-desktop/src/main/java/forge/ImageCache.java +++ b/forge-gui-desktop/src/main/java/forge/ImageCache.java @@ -184,7 +184,7 @@ public class ImageCache { if (useArtCrop) { if (ipc != null && ipc.getRules().getSplitType() == CardSplitType.Flip) { // Art crop will always use front face as image key for flip cards - imageKey = ImageUtil.getImageKey((PaperCard) ipc, false, true); + imageKey = ((PaperCard) ipc).getImageKeyFromSet(); // ImageUtil.getImageKey((PaperCard) ipc, false, true); } imageKey = TextUtil.fastReplace(imageKey, ".full", ".artcrop"); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java index df6040d1d3b..15df28f0886 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java @@ -536,13 +536,7 @@ public abstract class ACEditorBase fullDbCardNames = new TreeSet<>(); + + @Override + @BeforeMethod + public void setup() { + super.setup(); + Collection uniqueCards = this.cardDb.getUniqueCards(); + for (PaperCard card : uniqueCards) + this.fullDbCardNames.add(card.getName()); + } + + @Test + public void testBenchmarkFullDbGetCardLegacyImplementation() { + int nRuns = 100; + long averageTime = 0; + long minTime = 10000; // 10 secs + long maxTime = 0; + for (int r = 1; r <= nRuns; r++) { + long start = System.currentTimeMillis(); + for (String name : this.fullDbCardNames) { + PaperCard card = this.legacyCardDb.getCard(name); + assertNotNull(card); + } + long timeRun = System.currentTimeMillis() - start; + averageTime += timeRun; + if (timeRun < minTime) + minTime = timeRun; + if (timeRun > maxTime) + maxTime = timeRun; + } + System.out.println("[LEGACY] Total Time (in sec): " + ((double) averageTime)/ 1000); + System.out.println("[LEGACY] Average Time (in sec): " + ((double) averageTime / nRuns)/ 1000); + System.out.println("[LEGACY] Best Time (in sec): " + ((double) minTime)/ 1000); + System.out.println("[LEGACY] Worst Time (in sec): " + ((double) maxTime)/ 1000); + } + + @Test + public void testBenchmarkFullDbGetCardNewDbImplementation() { + int nRuns = 100; + long averageTime = 0; + long minTime = 10000; // 10 secs + long maxTime = 0; + for (int r = 1; r <= nRuns; r++) { + long start = System.currentTimeMillis(); + for (String name : this.fullDbCardNames) { + PaperCard card = this.cardDb.getCard(name); + assertNotNull(card); + } + long timeRun = System.currentTimeMillis() - start; + averageTime += timeRun; + if (timeRun < minTime) + minTime = timeRun; + if (timeRun > maxTime) + maxTime = timeRun; + } + System.out.println("[NEW] Total Time (in sec): " + ((double) averageTime)/ 1000); + System.out.println("[NEW] Average Time (in sec): " + ((double) averageTime / nRuns)/ 1000); + System.out.println("[NEW] Best Time (in sec): " + ((double) minTime)/ 1000); + System.out.println("[NEW] Worst Time (in sec): " + ((double) maxTime)/ 1000); + } + + @Test + public void testGetCardFullDbNewImplementationToProfile(){ + for (String name : this.fullDbCardNames) { + PaperCard card = this.cardDb.getCard(name); + assertNotNull(card); + } + } + + @Test + public void testGetCardFullDbLegacyImplementationToProfile(){ + for (String name : this.fullDbCardNames) { + PaperCard card = this.legacyCardDb.getCard(name); + assertNotNull(card); + } + } +} diff --git a/forge-gui-desktop/src/test/java/forge/card/CardDbTestCase.java b/forge-gui-desktop/src/test/java/forge/card/CardDbTestCase.java index 8a30919020a..e2bd0bdff47 100644 --- a/forge-gui-desktop/src/test/java/forge/card/CardDbTestCase.java +++ b/forge-gui-desktop/src/test/java/forge/card/CardDbTestCase.java @@ -1,5 +1,6 @@ package forge.card; +import com.google.common.base.Predicate; import forge.StaticData; import forge.item.IPaperCard; import forge.item.PaperCard; @@ -10,7 +11,10 @@ import org.testng.annotations.Test; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; +import java.util.List; import static org.testng.Assert.*; @@ -101,6 +105,44 @@ public class CardDbTestCase extends ForgeCardMockTestCase { this.legacyCardDb = new LegacyCardDb(data.getCommonCards().getAllCards(), data.getEditions()); } + /* + * TEST FOR GET ALL CARDS + */ + + @Test + public void testGetAllCardsWithName(){ + List allCounterSpellPrints = this.cardDb.getAllCards(this.cardNameCounterspell); + assertNotNull(allCounterSpellPrints); + for (PaperCard card : allCounterSpellPrints) + assertEquals(card.getName(), this.cardNameCounterspell); + } + + @Test + public void testGetAllCardsThatWerePrintedInSets(){ + List allowedSets = new ArrayList<>(); + allowedSets.add(this.latestArtShivanDragonEdition); + Predicate wasPrinted = (Predicate) this.cardDb.wasPrintedInSets(allowedSets); + List allCardsInSet = this.cardDb.getAllCards(wasPrinted); + assertNotNull(allCardsInSet); + } + + @Test void testGetAllCardsOfaGivenNameAndLegalInSets(){ + List allowedSets = new ArrayList<>(Arrays.asList(this.editionsCounterspell)); + Predicate printedInSets = (Predicate) this.cardDb.wasPrintedInSets(allowedSets); + List allCounterSpellsInSets = this.cardDb.getAllCards(this.cardNameCounterspell, printedInSets); + assertNotNull(allCounterSpellsInSets); + assertTrue(allCounterSpellsInSets.size() > 0); + assertTrue(allCounterSpellsInSets.size() > 1); + for (PaperCard card : allCounterSpellsInSets) { + assertEquals(card.getName(), this.cardNameCounterspell); + } + } + + + /* + * TEST FOR CARD RETRIEVAL METHODS + */ + @Test public void testGetCardByName() { PaperCard legacyCard = this.legacyCardDb.getCard(cardNameShivanDragon); @@ -2019,6 +2061,30 @@ public class CardDbTestCase extends ForgeCardMockTestCase { assertEquals(legacyAinokCard, ainokCard); } + @Test + public void testGetIslandsFromEditionsWithSpecificArtIndex(){ + String cardName = "Island"; + assertEquals(this.cardDb.getCardArtPreference(), CardDb.CardArtPreference.LATEST_ART_ALL_EDITIONS); + PaperCard islandLatest = this.cardDb.getCardFromEditions(cardName, CardDb.CardArtPreference.LATEST_ART_ALL_EDITIONS, 12); + assertNotNull(islandLatest); + assertEquals(islandLatest.getName(), "Island"); + assertEquals(islandLatest.getEdition(), "SLD"); + assertEquals(islandLatest.getArtIndex(), 12); + + // PALP + PaperCard islandOriginal = this.cardDb.getCardFromEditions(cardName, CardDb.CardArtPreference.ORIGINAL_ART_CORE_EXPANSIONS_REPRINT_ONLY, 12); + assertNotNull(islandOriginal); + assertEquals(islandOriginal.getName(), "Island"); + assertEquals(islandOriginal.getEdition(), "SLD"); + assertEquals(islandOriginal.getArtIndex(), 12); + } + + @Test + public void testMaxArtCountForBasicLand(){ + int maxArtIndex = this.cardDb.getMaxArtIndex("Island"); + assertEquals(maxArtIndex, 13); + } + } diff --git a/forge-gui-desktop/src/test/java/forge/card/CardRequestTestCase.java b/forge-gui-desktop/src/test/java/forge/card/CardRequestTestCase.java index 4279de97001..444e55ab937 100644 --- a/forge-gui-desktop/src/test/java/forge/card/CardRequestTestCase.java +++ b/forge-gui-desktop/src/test/java/forge/card/CardRequestTestCase.java @@ -128,7 +128,7 @@ public class CardRequestTestCase { request = CardRequest.fromString(requestString); assertEquals(request.cardName, cardName); assertEquals(request.edition, edition); - assertEquals(request.artIndex, IPaperCard.DEFAULT_ART_INDEX); + assertEquals(request.artIndex, 20); assertEquals(request.collectorNumber, IPaperCard.NO_COLLECTOR_NUMBER); @@ -215,4 +215,15 @@ public class CardRequestTestCase { assertNotEquals(request.artIndex, newRequest.artIndex); } + @Test + public void testCreatingCardRequestWithArtIndexGreaterThanNine(){ + String requestString = CardRequest.compose("Island", "SLD", 13); + CardRequest request = CardRequest.fromString(requestString); + + assertEquals(request.cardName, "Island"); + assertEquals(request.edition, "SLD"); + assertEquals(request.artIndex, 13); + assertEquals(request.collectorNumber, IPaperCard.NO_COLLECTOR_NUMBER); + } + } \ No newline at end of file diff --git a/forge-gui-desktop/src/test/java/forge/card/ForgeCardMockTestCase.java b/forge-gui-desktop/src/test/java/forge/card/ForgeCardMockTestCase.java index 3f54907726a..61acc9cd91a 100644 --- a/forge-gui-desktop/src/test/java/forge/card/ForgeCardMockTestCase.java +++ b/forge-gui-desktop/src/test/java/forge/card/ForgeCardMockTestCase.java @@ -5,6 +5,7 @@ import forge.ImageKeys; import forge.Singletons; import forge.StaticData; import forge.gamesimulationtests.util.CardDatabaseHelper; +import forge.item.PaperCard; import forge.localinstance.properties.ForgeConstants; import forge.localinstance.properties.ForgePreferences; import forge.model.FModel; @@ -133,6 +134,9 @@ public class ForgeCardMockTestCase extends PowerMockTestCase { PowerMockito.mockStatic(ImageKeys.class); initForgeConstants(); + // Always Has Image (there is a separated test case to cover the opposite case) + PowerMockito.when(ImageKeys.hasImage(Mockito.any(PaperCard.class))).thenReturn(true); + //Mocking some more static stuff PowerMockito.mockStatic(Singletons.class); PowerMockito.mockStatic(FModel.class); diff --git a/forge-gui-desktop/src/test/java/forge/card/LegacyCardDb.java b/forge-gui-desktop/src/test/java/forge/card/LegacyCardDb.java index 70c656dcce9..876910c870d 100644 --- a/forge-gui-desktop/src/test/java/forge/card/LegacyCardDb.java +++ b/forge-gui-desktop/src/test/java/forge/card/LegacyCardDb.java @@ -183,7 +183,7 @@ public class LegacyCardDb { } public PaperCard getFoiled(PaperCard card0) { - return new PaperCard(card0.getRules(), card0.getEdition(), card0.getRarity(), card0.getArtIndex(), true, card0.getArtist()); + return card0.getFoiled(); } public PaperCard getCardFromEdition(final String cardName, LegacySetPreference fromSet) {