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

@@ -17,28 +17,19 @@ public class BeakBlastTests
/// <summary>
/// Creates a fully mocked setup for driving <see cref="BeakBlast.OnBeforeTurnStart"/>.
/// </summary>
private static (BeakBlast script, ITurnChoice choice, IPokemon user, IScriptSet volatileSet, EventHook eventHook)
CreateChargeSetup(bool hasBattleData = true)
private static (BeakBlast script, ITurnChoice choice, IBattlePokemon user, IScriptSet volatileSet, EventHook
eventHook) CreateChargeSetup()
{
var script = new BeakBlast();
var user = Substitute.For<IPokemon>();
var user = Substitute.For<IBattlePokemon>();
user.GetScripts().Returns(_ => new ScriptIterator(Array.Empty<IEnumerable<ScriptContainer>>()));
IScriptSet volatileSet = new ScriptSet(user);
user.Volatile.Returns(volatileSet);
var eventHook = new EventHook();
if (hasBattleData)
{
var battle = Substitute.For<IBattle>();
battle.EventHook.Returns(eventHook);
var battleData = Substitute.For<IPokemonBattleData>();
battleData.Battle.Returns(battle);
user.BattleData.Returns(battleData);
}
else
{
user.BattleData.Returns((IPokemonBattleData?)null);
}
var battle = Substitute.For<IBattle>();
battle.EventHook.Returns(eventHook);
user.Battle.Returns(battle);
var choice = Substitute.For<ITurnChoice>();
choice.User.Returns(user);
@@ -85,24 +76,7 @@ public class BeakBlastTests
// Assert
await Assert.That(capturedEvent).IsNotNull();
await Assert.That(capturedEvent!.Message).IsEqualTo("beak_blast_charge");
await Assert.That((IPokemon)capturedEvent.Parameters!["user"]).IsEqualTo(user);
}
/// <summary>
/// Technical test: a Pokémon without <see cref="IPokemon.BattleData"/> is not in battle, so no charging
/// phase starts.
/// </summary>
[Test]
public async Task OnBeforeTurnStart_NoBattleData_DoesNotAddChargeEffect()
{
// Arrange
var (script, choice, _, volatileSet, _) = CreateChargeSetup(false);
// Act
script.OnBeforeTurnStart(choice);
// Assert
await Assert.That(volatileSet.Get<BeakBlastEffect>()).IsNull();
await Assert.That((IBattlePokemon)capturedEvent.Parameters!["user"]).IsEqualTo(user);
}
/// <summary>
@@ -115,8 +89,8 @@ public class BeakBlastTests
// Arrange
var script = new BeakBlast();
var move = Substitute.For<IExecutingMove>();
var target = Substitute.For<IPokemon>();
var user = Substitute.For<IPokemon>();
var target = Substitute.For<IBattlePokemon>();
var user = Substitute.For<IBattlePokemon>();
user.GetScripts().Returns(_ => new ScriptIterator(Array.Empty<IEnumerable<ScriptContainer>>()));
IScriptSet volatileSet = new ScriptSet(user);
user.Volatile.Returns(volatileSet);
@@ -133,26 +107,26 @@ public class BeakBlastTests
/// <summary>
/// Creates a fully mocked setup for driving <see cref="BeakBlastEffect.OnIncomingHit"/>.
/// </summary>
private static (BeakBlastEffect effect, IExecutingMove move, IPokemon target, IPokemon attacker)
private static (BeakBlastEffect effect, IExecutingMove move, IBattlePokemon target, IBattlePokemon attacker)
CreateIncomingHitSetup(bool isContact)
{
var effect = new BeakBlastEffect();
var move = Substitute.For<IExecutingMove>();
var target = Substitute.For<IPokemon>();
var target = Substitute.For<IBattlePokemon>();
var hitData = Substitute.For<IHitData>();
hitData.IsContact.Returns(isContact);
move.GetHitData(target, 0).Returns(hitData);
var attacker = Substitute.For<IPokemon>();
var attacker = Substitute.For<IBattlePokemon>();
move.User.Returns(attacker);
return (effect, move, target, attacker);
}
/// <summary>
/// Helper to extract the status name from a Pokémon's received <see cref="IPokemon.SetStatus"/> calls.
/// Helper to extract the status name from a Pokémon's received <see cref="IBattlePokemon.SetStatus"/> calls.
/// </summary>
private static string? GetStatusSet(IPokemon pokemon)
private static string? GetStatusSet(IBattlePokemon pokemon)
{
var call = pokemon.ReceivedCalls().FirstOrDefault(c => c.GetMethodInfo().Name == "SetStatus");
return call != null ? ((StringKey)call.GetArguments()[0]!).ToString() : null;