using PkmnLib.Dynamic.Models;
using PkmnLib.Plugin.Gen7.Scripts.Moves;
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
///
/// Tests for the move script.
/// Gen VII Bulbapedia behavior: "the user faints upon using this move", and from Generation VI onwards
/// "Explosion returns to damaging the target before the user faints."
///
public class ExplosionTests
{
private static (Explosion script, IExecutingMove move, IPokemon user) CreateTestSetup(uint currentHealth)
{
var script = new Explosion();
var move = Substitute.For();
var user = Substitute.For();
user.CurrentHealth.Returns(currentHealth);
move.User.Returns(user);
return (script, move, user);
}
///
/// Helper to extract the damage amount from the user's received Damage calls.
///
private static uint? GetDamageAmount(IPokemon user)
{
var call = user.ReceivedCalls().FirstOrDefault(c => c.GetMethodInfo().Name == "Damage");
return call != null ? (uint)call.GetArguments()[0]! : null;
}
///
/// Bulbapedia: "the user faints upon using this move" — after the hits are dealt, the user takes at
/// least its full current HP in damage, guaranteeing it faints.
///
[Test]
public async Task OnAfterHits_UserTakesAtLeastItsCurrentHealthInDamage()
{
// Arrange
var (script, move, user) = CreateTestSetup(100);
// Act
script.OnAfterHits(move, Substitute.For());
// Assert
var damage = GetDamageAmount(user);
await Assert.That(damage).IsNotNull();
await Assert.That(damage!.Value).IsGreaterThanOrEqualTo(100u);
}
///
/// Bulbapedia: "Sturdy, Focus Band, and Focus Sash do not prevent user fainting." The self-inflicted
/// faint is indirect damage (), not move damage, so hold-on effects
/// that watch for move damage do not apply.
///
[Test]
public async Task OnAfterHits_UsesMiscDamageSource()
{
// Arrange
var (script, move, user) = CreateTestSetup(100);
// Act
script.OnAfterHits(move, Substitute.For());
// Assert
var call = user.ReceivedCalls().First(c => c.GetMethodInfo().Name == "Damage");
await Assert.That((DamageSource)call.GetArguments()[1]!).IsEqualTo(DamageSource.Misc);
}
}