Move all battle state from IPokemon to an ephemeral IBattlePokemon wrapper
This commit is contained in:
@@ -22,12 +22,12 @@ public class ForestsCurseTests
|
||||
/// Creates a fully mocked test setup for Forest's Curse tests. The target is in battle, with a mocked
|
||||
/// battle library chain that can resolve the Grass type identifier.
|
||||
/// </summary>
|
||||
private static (ForestsCurse script, IExecutingMove move, IPokemon target, IHitData hitData) CreateTestSetup(
|
||||
private static (ForestsCurse script, IExecutingMove move, IBattlePokemon target, IHitData hitData) CreateTestSetup(
|
||||
bool grassTypeInLibrary = true, TypeIdentifier[]? targetTypes = null)
|
||||
{
|
||||
var script = new ForestsCurse();
|
||||
var move = Substitute.For<IExecutingMove>();
|
||||
var target = Substitute.For<IPokemon>();
|
||||
var target = Substitute.For<IBattlePokemon>();
|
||||
var hitData = Substitute.For<IHitData>();
|
||||
move.GetHitData(target, 0).Returns(hitData);
|
||||
|
||||
@@ -47,18 +47,16 @@ public class ForestsCurseTests
|
||||
library.StaticLibrary.Returns(staticLibrary);
|
||||
var battle = Substitute.For<IBattle>();
|
||||
battle.Library.Returns(library);
|
||||
var battleData = Substitute.For<IPokemonBattleData>();
|
||||
battleData.Battle.Returns(battle);
|
||||
target.BattleData.Returns(battleData);
|
||||
target.Battle.Returns(battle);
|
||||
target.Types.Returns(targetTypes ?? [NormalType]);
|
||||
|
||||
return (script, move, target, hitData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to extract the type passed to the target's <see cref="IPokemon.AddType"/> call.
|
||||
/// Helper to extract the type passed to the target's <see cref="IBattlePokemon.AddType"/> call.
|
||||
/// </summary>
|
||||
private static TypeIdentifier? GetAddedType(IPokemon target)
|
||||
private static TypeIdentifier? GetAddedType(IBattlePokemon target)
|
||||
{
|
||||
var call = target.ReceivedCalls().FirstOrDefault(c => c.GetMethodInfo().Name == "AddType");
|
||||
return call != null ? (TypeIdentifier)call.GetArguments()[0]! : null;
|
||||
@@ -85,7 +83,7 @@ public class ForestsCurseTests
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: the Grass type is added "in addition to the Pokémon's original type(s)".
|
||||
/// The target's original types may not be replaced, so <see cref="IPokemon.SetTypes"/> must not be used.
|
||||
/// The target's original types may not be replaced, so <see cref="IBattlePokemon.SetTypes"/> must not be used.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task OnSecondaryEffect_TargetInBattle_OriginalTypesNotReplaced()
|
||||
@@ -117,24 +115,6 @@ public class ForestsCurseTests
|
||||
await Assert.That(hitData.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "Fail")).IsTrue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the target has no <see cref="IPokemon.BattleData"/>, the script cannot resolve the type library,
|
||||
/// so no type may be added.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task OnSecondaryEffect_NullBattleData_DoesNotAddType()
|
||||
{
|
||||
// Arrange
|
||||
var (script, move, target, _) = CreateTestSetup();
|
||||
target.BattleData.Returns((IPokemonBattleData?)null);
|
||||
|
||||
// Act
|
||||
script.OnSecondaryEffect(move, target, 0);
|
||||
|
||||
// Assert
|
||||
await Assert.That(target.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "AddType")).IsFalse();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Technical test: when the type library cannot resolve the Grass type identifier, the script must
|
||||
/// bail out without adding a type.
|
||||
@@ -158,8 +138,8 @@ public class ForestsCurseTests
|
||||
/// A target whose Ghost type was added by <see cref="TrickOrTreat"/> must end up with the Grass type and
|
||||
/// without the Ghost type, while keeping its original type. The mocked target uses a real
|
||||
/// <see cref="ScriptSet"/> for its volatile scripts, so the <c>HasHadTypeAddedEffect</c> marker set by
|
||||
/// Trick-or-Treat is visible to Forest's Curse, and reacts to <see cref="IPokemon.AddType"/> and
|
||||
/// <see cref="IPokemon.RemoveType"/> with a backing type list, mirroring the real Pokemon implementation,
|
||||
/// Trick-or-Treat is visible to Forest's Curse, and reacts to <see cref="IBattlePokemon.AddType"/> and
|
||||
/// <see cref="IBattlePokemon.RemoveType"/> with a backing type list, mirroring the real Pokemon implementation,
|
||||
/// so the resulting type list is observable.
|
||||
/// </summary>
|
||||
[Test]
|
||||
@@ -169,7 +149,7 @@ public class ForestsCurseTests
|
||||
var forestsCurse = new ForestsCurse();
|
||||
var trickOrTreat = new TrickOrTreat();
|
||||
var move = Substitute.For<IExecutingMove>();
|
||||
var target = Substitute.For<IPokemon>();
|
||||
var target = Substitute.For<IBattlePokemon>();
|
||||
|
||||
var typeLibrary = Substitute.For<IReadOnlyTypeLibrary>();
|
||||
typeLibrary.TryGetTypeIdentifier(new StringKey("grass"), out Arg.Any<TypeIdentifier>()).Returns(x =>
|
||||
@@ -189,9 +169,7 @@ public class ForestsCurseTests
|
||||
var battle = Substitute.For<IBattle>();
|
||||
battle.Library.Returns(library);
|
||||
move.Battle.Returns(battle);
|
||||
var battleData = Substitute.For<IPokemonBattleData>();
|
||||
battleData.Battle.Returns(battle);
|
||||
target.BattleData.Returns(battleData);
|
||||
target.Battle.Returns(battle);
|
||||
|
||||
// Real script set so the HasHadTypeAddedEffect marker added by Trick-or-Treat is visible
|
||||
// to Forest's Curse.
|
||||
|
||||
Reference in New Issue
Block a user