diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index c8aeb94461..0362f8ffb6 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -600,7 +600,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * @param gameZone {@link mage.constants.Zone} to add cards to. * @param player {@link Player} to add cards for. Use either playerA or * playerB. - * @param cardName Card name in string format. + * @param cardName Card name or set:card * @param count Amount of cards to be added. * @param tapped In case gameZone is Battlefield, determines whether * permanent should be tapped. In case gameZone is other @@ -617,14 +617,32 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement aliasName = cardName.substring(cardName.indexOf(ALIAS_PREFIX) + ALIAS_PREFIX.length()); cardName = cardName.substring(0, cardName.indexOf(ALIAS_PREFIX)); } - // one card = one alias, massive adds can use auto-name if (!useAliasMultiNames && !aliasName.isEmpty() && player.getAliasByName(aliasName) != null) { Assert.fail("Can't add card " + cardName + " - alias " + aliasName + " already exists for " + player.getName()); } - // game tests don't need cards from a specific set, so it can be from any set - CardInfo cardInfo = CardRepository.instance.findCard(cardName, true); + // set code for + String setCode = ""; + String setLookup = CardUtil.substring(cardName, CardUtil.TESTS_SET_CODE_LOOKUP_LENGTH); + if (setLookup.contains(":")) { + setCode = setLookup.substring(0, setLookup.indexOf(":")); + cardName = cardName.substring(setCode.length() + 1); + } + + CardInfo cardInfo; + if (setCode.isEmpty()) { + // fast search for any set's card + cardInfo = CardRepository.instance.findCard(cardName, true); + } else { + // normal search for specific set's card + cardInfo = CardRepository.instance.findCardWithPreferredSetAndNumber(cardName, setCode, null); + Assert.assertNotNull("[TEST] Couldn't find a card:" + cardName + " from specific set: " + setCode, cardInfo); + Assert.assertEquals("[TEST] Found card from wrong set. Found: " + cardInfo.getSetCode() + ":" + cardInfo.getName() + + ", but need " + setCode + ":" + cardName, + setCode, cardInfo.getSetCode()); + } + if (cardInfo == null) { throw new IllegalArgumentException("[TEST] Couldn't find a card: " + cardName); } @@ -788,8 +806,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement if (!isObjectHaveTargetNameOrAlias(player, permanent, cardName) || !permanent.getControllerId().equals(player.getId())) { continue; } - int powerFound = checkBaseValues ? permanent.getPower().getModifiedBaseValue() : permanent.getPower().getValue(); - int toughnessFound = checkBaseValues ? permanent.getToughness().getModifiedBaseValue() : permanent.getToughness().getValue(); + int powerFound = checkBaseValues ? permanent.getPower().getModifiedBaseValue() : permanent.getPower().getValue(); + int toughnessFound = checkBaseValues ? permanent.getToughness().getModifiedBaseValue() : permanent.getToughness().getValue(); count++; if (scope == Filter.ComparisonScope.All) { @@ -830,7 +848,6 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } - /** * {@inheritDoc} */ diff --git a/Mage.Tests/src/test/java/org/mage/test/testapi/AddCardApiTest.java b/Mage.Tests/src/test/java/org/mage/test/testapi/AddCardApiTest.java new file mode 100644 index 0000000000..ff78a37a06 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/testapi/AddCardApiTest.java @@ -0,0 +1,55 @@ +package org.mage.test.testapi; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author JayDi85 + */ +public class AddCardApiTest extends CardTestPlayerBase { + + @Test + public void test_CardName_Normal() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 3); + addCard(Zone.BATTLEFIELD, playerA, "Memorial to Glory", 1); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Plains", 3); + assertPermanentCount(playerA, "Memorial to Glory", 1); + } + + @Test(expected = IllegalArgumentException.class) + public void test_CardName_RaiseErrorOnUnknownCard() { + addCard(Zone.BATTLEFIELD, playerA, "xxx", 1); + } + + @Test + public void test_CardNameWithSetCode_Normal() { + addCard(Zone.BATTLEFIELD, playerA, "40K:Memorial to Glory", 2); + addCard(Zone.BATTLEFIELD, playerA, "PANA:Plains", 2); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Memorial to Glory", 2); + getBattlefieldCards(playerA).stream() + .filter(card -> card.getName().equals("Memorial to Glory")) + .forEach(card -> Assert.assertEquals("40K", card.getExpansionSetCode())); + + assertPermanentCount(playerA, "Plains", 2); + getBattlefieldCards(playerA).stream() + .filter(card -> card.getName().equals("Plains")) + .forEach(card -> Assert.assertEquals("PANA", card.getExpansionSetCode())); + } + + @Test(expected = org.junit.ComparisonFailure.class) + public void test_CardNameWithSetCode_RaiseErrorOnUnknownSet() { + addCard(Zone.BATTLEFIELD, playerA, "SS4:Plains", 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/testapi/TestAliases.java b/Mage.Tests/src/test/java/org/mage/test/testapi/AliasesApiTest.java similarity index 99% rename from Mage.Tests/src/test/java/org/mage/test/testapi/TestAliases.java rename to Mage.Tests/src/test/java/org/mage/test/testapi/AliasesApiTest.java index 52c0fe80c3..19b6226953 100644 --- a/Mage.Tests/src/test/java/org/mage/test/testapi/TestAliases.java +++ b/Mage.Tests/src/test/java/org/mage/test/testapi/AliasesApiTest.java @@ -14,7 +14,7 @@ import org.mage.test.serverside.base.CardTestPlayerBase; /** * @author JayDi85 */ -public class TestAliases extends CardTestPlayerBase { +public class AliasesApiTest extends CardTestPlayerBase { @Test public void test_NamesEquals() { diff --git a/Mage.Tests/src/test/java/org/mage/test/testapi/TestAPITest.java b/Mage.Tests/src/test/java/org/mage/test/testapi/CastApiTest.java similarity index 97% rename from Mage.Tests/src/test/java/org/mage/test/testapi/TestAPITest.java rename to Mage.Tests/src/test/java/org/mage/test/testapi/CastApiTest.java index d8ebb0897d..e1daced499 100644 --- a/Mage.Tests/src/test/java/org/mage/test/testapi/TestAPITest.java +++ b/Mage.Tests/src/test/java/org/mage/test/testapi/CastApiTest.java @@ -10,7 +10,7 @@ import org.mage.test.serverside.base.CardTestPlayerBase; /** * @author noxx */ -public class TestAPITest extends CardTestPlayerBase { +public class CastApiTest extends CardTestPlayerBase { /** * Tests that it is possible to cast two instants in a row. diff --git a/Mage.Tests/src/test/java/org/mage/test/testapi/TestPlayerExpectedErrorsTest.java b/Mage.Tests/src/test/java/org/mage/test/testapi/PlayerExpectedErrorsApiTest.java similarity index 90% rename from Mage.Tests/src/test/java/org/mage/test/testapi/TestPlayerExpectedErrorsTest.java rename to Mage.Tests/src/test/java/org/mage/test/testapi/PlayerExpectedErrorsApiTest.java index cb7756e34f..9883e20024 100644 --- a/Mage.Tests/src/test/java/org/mage/test/testapi/TestPlayerExpectedErrorsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/testapi/PlayerExpectedErrorsApiTest.java @@ -1,4 +1,3 @@ - package org.mage.test.testapi; import junit.framework.TestCase; @@ -11,10 +10,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; /** + * Tests the expected errors for illegal attacks/blocks or other moves when writing tests for players + * * @author Simown */ -// Tests the expected errors for illegal attacks/blocks or other moves when writing tests for players -public class TestPlayerExpectedErrorsTest extends CardTestPlayerBase { + +public class PlayerExpectedErrorsApiTest extends CardTestPlayerBase { @Test public void blockerNotFoundTest() { @@ -113,7 +114,7 @@ public class TestPlayerExpectedErrorsTest extends CardTestPlayerBase { try { execute(); fail("Expected exception not thrown"); - } catch(UnsupportedOperationException ue) { + } catch (UnsupportedOperationException ue) { TestCase.assertEquals("PlayerA can't block on turn 1 as it is their turn", ue.getMessage()); } } @@ -132,7 +133,7 @@ public class TestPlayerExpectedErrorsTest extends CardTestPlayerBase { try { execute(); - } catch(UnsupportedOperationException ue) { + } catch (UnsupportedOperationException ue) { TestCase.assertEquals("PlayerB can't block on turn 6 as it is their turn", ue.getMessage()); } } @@ -147,7 +148,7 @@ public class TestPlayerExpectedErrorsTest extends CardTestPlayerBase { try { execute(); - } catch(UnsupportedOperationException ue) { + } catch (UnsupportedOperationException ue) { TestCase.assertEquals("PlayerA can't attack on turn 2 as it is not their turn", ue.getMessage()); } @@ -163,7 +164,7 @@ public class TestPlayerExpectedErrorsTest extends CardTestPlayerBase { try { execute(); - } catch(UnsupportedOperationException ue) { + } catch (UnsupportedOperationException ue) { TestCase.assertEquals("PlayerB can't attack on turn 1 as it is not their turn", ue.getMessage()); } @@ -188,7 +189,7 @@ public class TestPlayerExpectedErrorsTest extends CardTestPlayerBase { try { execute(); fail("Expected exception not thrown"); - } catch(UnsupportedOperationException ue) { + } catch (UnsupportedOperationException ue) { TestCase.assertEquals("Nemesis of Mortals cannot block Leafcrown Dryad it is already blocking the maximum amount of creatures.", ue.getMessage()); } } @@ -215,11 +216,11 @@ public class TestPlayerExpectedErrorsTest extends CardTestPlayerBase { @Test public void minimumBlockNotReachedTest() { - /* Underworld Cerberus {3}{B}{3} 6/6 - * Underworld Cerberus can't be blocked except by three or more creatures. - * Cards in graveyards can't be the targets of spells or abilities. - * When Underworld Cerberus dies, exile it and each player returns all creature cards from their graveyard to their hand. - */ + /* Underworld Cerberus {3}{B}{3} 6/6 + * Underworld Cerberus can't be blocked except by three or more creatures. + * Cards in graveyards can't be the targets of spells or abilities. + * When Underworld Cerberus dies, exile it and each player returns all creature cards from their graveyard to their hand. + */ addCard(Zone.BATTLEFIELD, playerA, "Underworld Cerberus"); addCard(Zone.BATTLEFIELD, playerB, "Memnite", 2); // 1/1 @@ -232,7 +233,7 @@ public class TestPlayerExpectedErrorsTest extends CardTestPlayerBase { try { execute(); fail("Expected exception not thrown"); - } catch(UnsupportedOperationException e) { + } catch (UnsupportedOperationException e) { assertEquals("Underworld Cerberus is blocked by 2 creature(s). It has to be blocked by 3 or more.", e.getMessage()); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/testapi/WaitStackResolvedTest.java b/Mage.Tests/src/test/java/org/mage/test/testapi/WaitStackResolvedApiTest.java similarity index 98% rename from Mage.Tests/src/test/java/org/mage/test/testapi/WaitStackResolvedTest.java rename to Mage.Tests/src/test/java/org/mage/test/testapi/WaitStackResolvedApiTest.java index 474f0100f8..ecf8652d3d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/testapi/WaitStackResolvedTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/testapi/WaitStackResolvedApiTest.java @@ -8,7 +8,7 @@ import org.mage.test.serverside.base.CardTestPlayerBase; /** * @author JayDi85 */ -public class WaitStackResolvedTest extends CardTestPlayerBase { +public class WaitStackResolvedApiTest extends CardTestPlayerBase { @Test public void test_Spells() { diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index a938aedbc5..7716504726 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -964,6 +964,12 @@ public class VerifyCardDataTest { cardNames.add(cardInfo.getName()); } + // CHECK: set code must be compatible with tests commands format + // how-to fix: increase lookup lenth + if (set.getCode().length() + 1 > CardUtil.TESTS_SET_CODE_LOOKUP_LENGTH) { + errorsList.add("Error: set code too big for test commads lookup: " + set.getCode() + ", lookup length: " + CardUtil.TESTS_SET_CODE_LOOKUP_LENGTH); + } + boolean containsDoubleSideCards = false; Map cardNumbers = new HashMap<>(); for (ExpansionSet.SetCardInfo cardInfo : set.getSetCardInfo()) { @@ -989,6 +995,12 @@ public class VerifyCardDataTest { errorsList.add("Error: card name or number contains non-ascii symbols: " + set.getCode() + " - " + set.getName() + " - " + card.getName() + " - " + card.getCardNumber()); } + // CHECK: card name must not contain : symbol due set:name commands format in test engine + // (if it exists then decrease TESTS_SET_CODE_LOOKUP_LENGTH) + if (CardUtil.substring(card.getName(), CardUtil.TESTS_SET_CODE_LOOKUP_LENGTH).contains(":")) { + errorsList.add("Error: card name can't contain : symbol: " + set.getCode() + " - " + set.getName() + " - " + card.getName() + " - " + card.getCardNumber()); + } + // CHECK: card number must start with 09-aZ symbols (wrong symbol example: *123) // if you found card with number like *123 then report it to scryfall to fix to 123* if (!Character.isLetterOrDigit(card.getCardNumber().charAt(0))) { diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index dbb6c6437f..3039e5fd19 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -77,6 +77,8 @@ public final class CardUtil { "put", "return", "exile", "discard", "sacrifice", "remove", "tap", "reveal", "pay" ); + public static final int TESTS_SET_CODE_LOOKUP_LENGTH = 10; // search set code in commands like "set:card_name" + /** * Increase spell or ability cost to be paid. * @@ -1741,4 +1743,18 @@ public final class CardUtil { throw new IllegalArgumentException("Can't use KeySet as param, use new LinkedHashSet<>(data.keySet()) instead"); } } + + /** + * Don't raise exception, so must be used instead standard substring calls all the time + * + * @param str + * @param maxLength + * @return + */ + public static String substring(String str, int maxLength) { + if (str == null || str.isEmpty()) { + return str; + } + return str.substring(0, Math.min(str.length(), maxLength)); + } }