Added verify tests for watchers copy;

This commit is contained in:
Oleg Agafonov 2019-05-18 10:58:30 +04:00
parent 85c6528d2d
commit e80ba6383f
3 changed files with 59 additions and 32 deletions

View file

@ -1,16 +1,12 @@
package mage.cards.w; package mage.cards.w;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.Mana; import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.effects.common.ManaEffect; import mage.abilities.effects.common.ManaEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.mana.SimpleManaAbility; import mage.abilities.mana.SimpleManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
@ -26,14 +22,17 @@ import mage.game.permanent.Permanent;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.watchers.Watcher; import mage.watchers.Watcher;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/** /**
*
* @author Styxo * @author Styxo
*/ */
public final class WookieeMystic extends CardImpl { public final class WookieeMystic extends CardImpl {
public WookieeMystic(UUID ownerId, CardSetInfo setInfo) { public WookieeMystic(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}{G}{W}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}{W}");
this.subtype.add(SubType.WOOKIEE); this.subtype.add(SubType.WOOKIEE);
this.subtype.add(SubType.SHAMAN); this.subtype.add(SubType.SHAMAN);
this.power = new MageInt(2); this.power = new MageInt(2);
@ -45,21 +44,21 @@ public final class WookieeMystic extends CardImpl {
ManaEffect effect = new BasicManaEffect(mana); ManaEffect effect = new BasicManaEffect(mana);
effect.setText("Add {R}. If that mana is spent on a creature spell, it enters the battlefield with a +1/+1 counter on it"); effect.setText("Add {R}. If that mana is spent on a creature spell, it enters the battlefield with a +1/+1 counter on it");
Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
this.addAbility(ability, new WookieeMysticWatcher(ability)); this.addAbility(ability, new WookieeMysticWatcher().withParams(ability));
mana = Mana.GreenMana(1); mana = Mana.GreenMana(1);
mana.setFlag(true); mana.setFlag(true);
effect = new BasicManaEffect(mana); effect = new BasicManaEffect(mana);
effect.setText("Add {G}. If that mana is spent on a creature spell, it enters the battlefield with a +1/+1 counter on it"); effect.setText("Add {G}. If that mana is spent on a creature spell, it enters the battlefield with a +1/+1 counter on it");
ability = new SimpleManaAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); ability = new SimpleManaAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
this.addAbility(ability, new WookieeMysticWatcher(ability)); this.addAbility(ability, new WookieeMysticWatcher().withParams(ability));
mana = Mana.WhiteMana(1); mana = Mana.WhiteMana(1);
mana.setFlag(true); mana.setFlag(true);
effect = new BasicManaEffect(mana); effect = new BasicManaEffect(mana);
effect.setText("Add {W}. If that mana is spent on a creature spell, it enters the battlefield with a +1/+1 counter on it"); effect.setText("Add {W}. If that mana is spent on a creature spell, it enters the battlefield with a +1/+1 counter on it");
ability = new SimpleManaAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); ability = new SimpleManaAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
this.addAbility(ability, new WookieeMysticWatcher(ability)); this.addAbility(ability, new WookieeMysticWatcher().withParams(ability));
} }
public WookieeMystic(final WookieeMystic card) { public WookieeMystic(final WookieeMystic card) {
@ -74,23 +73,16 @@ public final class WookieeMystic extends CardImpl {
class WookieeMysticWatcher extends Watcher { class WookieeMysticWatcher extends Watcher {
private final Ability source; private Ability source;
private final List<UUID> creatures = new ArrayList<>(); private List<UUID> creatures = new ArrayList<>();
WookieeMysticWatcher(Ability source) { WookieeMysticWatcher() {
super(WatcherScope.CARD); super(WatcherScope.CARD);
}
Watcher withParams(Ability source) {
this.source = source; this.source = source;
} return this;
WookieeMysticWatcher(final WookieeMysticWatcher watcher) {
super(watcher);
this.creatures.addAll(watcher.creatures);
this.source = watcher.source;
}
@Override
public WookieeMysticWatcher copy() {
return new WookieeMysticWatcher(this);
} }
@Override @Override

View file

@ -414,7 +414,7 @@ public class VerifyCardDataTest {
} }
@Test @Test
@Ignore // TODO: enable it on copy() methods removing //@Ignore // TODO: enable it on copy() methods removing
public void checkWatcherCopyMethods() { public void checkWatcherCopyMethods() {
Collection<String> errorsList = new ArrayList<>(); Collection<String> errorsList = new ArrayList<>();
@ -424,6 +424,13 @@ public class VerifyCardDataTest {
Set<Class<? extends Watcher>> watcherClassesList = reflections.getSubTypesOf(Watcher.class); Set<Class<? extends Watcher>> watcherClassesList = reflections.getSubTypesOf(Watcher.class);
for (Class<? extends Watcher> watcherClass : watcherClassesList) { for (Class<? extends Watcher> watcherClass : watcherClassesList) {
// only watcher class can be extended (e.g. final)
if (!watcherClass.getSuperclass().equals(Watcher.class)) {
errorsList.add("error, only Watcher class can be extended: " + watcherClass.getName());
}
// no copy methods
try { try {
Method m = watcherClass.getMethod("copy"); Method m = watcherClass.getMethod("copy");
if (!m.getGenericReturnType().getTypeName().equals("T")) { if (!m.getGenericReturnType().getTypeName().equals("T")) {
@ -432,6 +439,34 @@ public class VerifyCardDataTest {
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
errorsList.add("error, can't find copy() method in watcher class: " + watcherClass.getName()); errorsList.add("error, can't find copy() method in watcher class: " + watcherClass.getName());
} }
// no constructor for copy
try {
Constructor<? extends Watcher> constructor = watcherClass.getDeclaredConstructor(watcherClass);
errorsList.add("error, copy constructor is not allowed in watcher class: " + watcherClass.getName());
} catch (NoSuchMethodException e) {
// all fine, no needs in copy constructors
}
// errors on create
try {
Constructor<? extends Watcher> constructor = watcherClass.getDeclaredConstructor();
constructor.setAccessible(true);
Watcher w1 = constructor.newInstance();
// errors on copy
try {
Watcher w2 = w1.copy();
if (w2 == null) {
errorsList.add("error, can't copy watcher with unknown error, look at error logs above: " + watcherClass.getName());
}
} catch (Exception e) {
errorsList.add("error, can't copy watcher: " + watcherClass.getName() + " (" + e.getMessage() + ")");
}
} catch (Exception e) {
errorsList.add("error, can't create watcher: " + watcherClass.getName() + " (" + e.getMessage() + ")");
}
} }
printMessages(warningsList); printMessages(warningsList);

View file

@ -1,10 +1,7 @@
package mage.watchers; package mage.watchers;
import mage.Mana;
import mage.constants.WatcherScope; import mage.constants.WatcherScope;
import mage.game.Game; import mage.game.Game;
import mage.game.turn.Step;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -26,8 +23,7 @@ public abstract class Watcher implements Serializable {
protected UUID controllerId; protected UUID controllerId;
protected UUID sourceId; protected UUID sourceId;
protected boolean condition; protected boolean condition;
protected final WatcherScope scope; protected WatcherScope scope;
public Watcher(WatcherScope scope) { public Watcher(WatcherScope scope) {
this.scope = scope; this.scope = scope;
@ -81,11 +77,15 @@ public abstract class Watcher implements Serializable {
return getClass().getSimpleName(); return getClass().getSimpleName();
} }
public void setScope(WatcherScope scope) {
this.scope = scope;
}
public abstract void watch(GameEvent event, Game game); public abstract void watch(GameEvent event, Game game);
public <T extends Watcher> T copy() { public <T extends Watcher> T copy() {
try { try {
List<?> constructors = Arrays.asList(this.getClass().getConstructors()); List<?> constructors = Arrays.asList(this.getClass().getDeclaredConstructors()); // needs private constructor
if (constructors.size() > 1) { if (constructors.size() > 1) {
logger.error(getClass().getSimpleName() + " has multiple constructors"); logger.error(getClass().getSimpleName() + " has multiple constructors");
return null; return null;