Many more tests and fixes
All checks were successful
Build / Build (push) Successful in 3m12s

This commit is contained in:
2026-08-27 17:11:12 +02:00
parent 32b3ef9c4a
commit d2a82b5fe3
204 changed files with 20255 additions and 242 deletions

View File

@@ -0,0 +1,102 @@
using PkmnLib.Dynamic.Models;
using PkmnLib.Plugin.Gen7.Scripts.Moves;
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
/// <summary>
/// Tests for the <see cref="FinalGambit"/> move script.
/// Bulbapedia: "Final Gambit causes the user to faint, and the target receives damage equal to the user's
/// remaining HP before using Final Gambit."
/// </summary>
public class FinalGambitTests
{
/// <summary>
/// Creates a fully mocked test setup for Final Gambit tests.
/// </summary>
private static (FinalGambit script, IExecutingMove move, IPokemon user, IPokemon target) CreateTestSetup(
uint userCurrentHealth)
{
var script = new FinalGambit();
var move = Substitute.For<IExecutingMove>();
var user = Substitute.For<IPokemon>();
user.CurrentHealth.Returns(userCurrentHealth);
move.User.Returns(user);
var target = Substitute.For<IPokemon>();
return (script, move, user, target);
}
/// <summary>
/// Helper to extract the damage amount from the user's received Damage calls.
/// </summary>
private static uint? GetDamageAmount(IPokemon pokemon)
{
var call = pokemon.ReceivedCalls().FirstOrDefault(c => c.GetMethodInfo().Name == "Damage");
return call != null ? (uint)call.GetArguments()[0]! : null;
}
/// <summary>
/// Helper to extract the damage source from the user's received Damage calls.
/// </summary>
private static DamageSource? GetDamageSource(IPokemon pokemon)
{
var call = pokemon.ReceivedCalls().FirstOrDefault(c => c.GetMethodInfo().Name == "Damage");
return call != null ? (DamageSource)call.GetArguments()[1]! : null;
}
/// <summary>
/// Bulbapedia: "the target receives damage equal to the user's remaining HP before using Final Gambit."
/// The move damage is replaced with the user's current HP, regardless of what the damage formula produced.
/// </summary>
[Test, Arguments(1u), Arguments(150u), Arguments(400u)]
public async Task ChangeMoveDamage_SetsDamageToUserRemainingHp(uint userCurrentHealth)
{
// Arrange
var (script, move, _, target) = CreateTestSetup(userCurrentHealth);
uint damage = 9999;
// Act
script.ChangeMoveDamage(move, target, 0, ref damage);
// Assert
await Assert.That(damage).IsEqualTo(userCurrentHealth);
}
/// <summary>
/// Bulbapedia: "Final Gambit causes the user to faint".
/// After the move hits, the user takes at least its full remaining HP as damage, so it always faints.
/// </summary>
[Test]
public async Task OnSecondaryEffect_MoveHits_UserTakesAtLeastItsRemainingHpAsDamage()
{
// Arrange
const uint currentHealth = 100;
var (script, move, user, target) = CreateTestSetup(currentHealth);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert - the self-damage is at least the user's remaining HP, so the user faints
var damage = GetDamageAmount(user);
await Assert.That(damage).IsNotNull();
await Assert.That(damage!.Value >= currentHealth).IsTrue();
}
/// <summary>
/// Bulbapedia: "The move's side effect is not considered as inflicting damage to the user, and so if the
/// user is holding a Focus Band, Focus Sash, or has Sturdy, they will not activate and the user will
/// still faint."
/// The self-inflicted faint is therefore indirect damage (<see cref="DamageSource.Misc"/>), not move damage.
/// </summary>
[Test]
public async Task OnSecondaryEffect_MoveHits_SelfFaintUsesMiscDamageSource()
{
// Arrange
var (script, move, user, target) = CreateTestSetup(100);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(GetDamageSource(user)!.Value).IsEqualTo(DamageSource.Misc);
}
}