Tests: improved addCard command, now it can add card from specific set (use 40K:Plains as card name param, #10139)

This commit is contained in:
Oleg Agafonov 2023-03-23 23:05:33 +04:00
parent 92706d23cb
commit d019acbd55
8 changed files with 125 additions and 24 deletions

View file

@ -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}
*/

View file

@ -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);
}
}

View file

@ -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() {

View file

@ -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.

View file

@ -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());
}
}

View file

@ -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() {

View file

@ -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<String, String> 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))) {

View file

@ -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));
}
}