Move all battle state from IPokemon to an ephemeral IBattlePokemon wrapper

This commit is contained in:
2026-08-28 15:20:26 +02:00
parent 942be8eaeb
commit 8a2733a0a9
859 changed files with 4408 additions and 5331 deletions

View File

@@ -13,28 +13,25 @@ namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
/// </summary>
public class MagneticFluxTests
{
private static (MagneticFlux script, IExecutingMove move, IPokemon user) CreateTestSetup(
params IPokemon?[] sidePokemon)
private static (MagneticFlux script, IExecutingMove move, IBattlePokemon user) CreateTestSetup(
params IBattlePokemon?[] sidePokemon)
{
var script = new MagneticFlux();
var side = Substitute.For<IBattleSide>();
side.Pokemon.Returns(sidePokemon);
var battleData = Substitute.For<IPokemonBattleData>();
battleData.BattleSide.Returns(side);
var user = Substitute.For<IPokemon>();
user.BattleData.Returns(battleData);
var user = Substitute.For<IBattlePokemon>();
var move = Substitute.For<IExecutingMove>();
user.BattleSide.Returns(side);
move.User.Returns(user);
return (script, move, user);
}
private static IPokemon CreatePokemonWithAbility(string? abilityName)
private static IBattlePokemon CreatePokemonWithAbility(string? abilityName)
{
var pokemon = Substitute.For<IPokemon>();
var pokemon = Substitute.For<IBattlePokemon>();
if (abilityName is null)
{
pokemon.ActiveAbility.Returns((IAbility?)null);
@@ -55,7 +52,7 @@ public class MagneticFluxTests
/// cannot be bound by <c>Arg.Any</c> (its parameterless constructor initializes a fresh id, so it
/// never equals the matcher's default value).
/// </summary>
private static List<object?[]> GetStatBoostCalls(IPokemon pokemon) =>
private static List<object?[]> GetStatBoostCalls(IBattlePokemon pokemon) =>
pokemon.ReceivedCalls().Where(c => c.GetMethodInfo().Name == "ChangeStatBoost").Select(c => c.GetArguments())
.ToList();
@@ -72,7 +69,7 @@ public class MagneticFluxTests
var (script, move, _) = CreateTestSetup(ally);
// Act
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
script.OnSecondaryEffect(move, Substitute.For<IBattlePokemon>(), 0);
// Assert
var calls = GetStatBoostCalls(ally);
@@ -95,7 +92,7 @@ public class MagneticFluxTests
var (script, move, _) = CreateTestSetup(ally);
// Act
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
script.OnSecondaryEffect(move, Substitute.For<IBattlePokemon>(), 0);
// Assert
var calls = GetStatBoostCalls(ally);
@@ -118,7 +115,7 @@ public class MagneticFluxTests
var (script, move, _) = CreateTestSetup(ally);
// Act
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
script.OnSecondaryEffect(move, Substitute.For<IBattlePokemon>(), 0);
// Assert
await Assert.That(GetStatBoostCalls(ally).Count).IsEqualTo(0);
@@ -136,7 +133,7 @@ public class MagneticFluxTests
var (script, move, _) = CreateTestSetup(ally);
// Act
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
script.OnSecondaryEffect(move, Substitute.For<IBattlePokemon>(), 0);
// Assert
await Assert.That(GetStatBoostCalls(ally).Count).IsEqualTo(0);
@@ -154,10 +151,10 @@ public class MagneticFluxTests
var ability = Substitute.For<IAbility>();
ability.Name.Returns(new StringKey("plus"));
user.ActiveAbility.Returns(ability);
user.BattleData!.BattleSide.Pokemon.Returns(new IPokemon?[] { user });
user.BattleSide.Pokemon.Returns(new IBattlePokemon?[] { user });
// Act
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
script.OnSecondaryEffect(move, Substitute.For<IBattlePokemon>(), 0);
// Assert
var calls = GetStatBoostCalls(user);
@@ -177,7 +174,7 @@ public class MagneticFluxTests
var (script, move, _) = CreateTestSetup(ally);
// Act
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
script.OnSecondaryEffect(move, Substitute.For<IBattlePokemon>(), 0);
// Assert
var calls = GetStatBoostCalls(ally);
@@ -198,7 +195,7 @@ public class MagneticFluxTests
var (script, move, _) = CreateTestSetup(plusAlly, minusAlly);
// Act
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
script.OnSecondaryEffect(move, Substitute.For<IBattlePokemon>(), 0);
// Assert
await Assert.That(GetStatBoostCalls(plusAlly).Count).IsEqualTo(2);
@@ -217,28 +214,9 @@ public class MagneticFluxTests
var (script, move, _) = CreateTestSetup(null, ally);
// Act
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
script.OnSecondaryEffect(move, Substitute.For<IBattlePokemon>(), 0);
// Assert
await Assert.That(GetStatBoostCalls(ally).Count).IsEqualTo(2);
}
/// <summary>
/// Technical test: when the user has no <see cref="IPokemon.BattleData"/> (it is not in a battle),
/// the script does nothing instead of throwing.
/// </summary>
[Test]
public async Task OnSecondaryEffect_NullBattleData_DoesNothing()
{
// Arrange
var script = new MagneticFlux();
var user = Substitute.For<IPokemon>();
user.BattleData.Returns((IPokemonBattleData?)null);
var move = Substitute.For<IExecutingMove>();
move.User.Returns(user);
// Act & Assert - should not throw
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
await Assert.That(GetStatBoostCalls(user).Count).IsEqualTo(0);
}
}