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,131 @@
using PkmnLib.Dynamic.Models;
using PkmnLib.Plugin.Gen7.Scripts.Moves;
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
using PkmnLib.Static.Utils;
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
/// <summary>
/// Tests for the <see cref="FreezeShock"/> move script.
/// Gen VII Bulbapedia behavior: "Freeze Shock deals damage and has a 30% chance of paralyzing the target."
/// Freeze Shock is a two-turn move: the generic charge-turn handling lives in the shared base charge move
/// class, so these tests only cover the concrete logic of <see cref="FreezeShock"/> itself (its paralysis
/// secondary effect and the charge volatile it creates).
/// </summary>
public class FreezeShockTests
{
/// <summary>
/// Creates a fully mocked test setup for Freeze Shock secondary effect tests.
/// </summary>
private static (FreezeShock script, IExecutingMove move, IPokemon target, IPokemon user, IBattleRandom random)
CreateTestSetup()
{
var script = new FreezeShock();
var move = Substitute.For<IExecutingMove>();
var user = Substitute.For<IPokemon>();
move.User.Returns(user);
var battle = Substitute.For<IBattle>();
var random = Substitute.For<IBattleRandom>();
battle.Random.Returns(random);
var battleData = Substitute.For<IPokemonBattleData>();
battleData.Battle.Returns(battle);
var target = Substitute.For<IPokemon>();
target.BattleData.Returns(battleData);
return (script, move, target, user, random);
}
/// <summary>
/// Bulbapedia: "Freeze Shock deals damage and has a 30% chance of paralyzing the target."
/// When the effect chance roll succeeds, the target is paralyzed by the user.
/// </summary>
[Test]
public async Task OnSecondaryEffect_EffectChanceSucceeds_ParalyzesTarget()
{
// Arrange
var (script, move, target, user, random) = CreateTestSetup();
random.EffectChance(30, move, target, 0).Returns(true);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
target.Received(1).SetStatus(new StringKey("paralyzed"), user);
await Assert.That(target.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "SetStatus")).IsTrue();
}
/// <summary>
/// Bulbapedia: "a 30% chance of paralyzing the target."
/// When the effect chance roll fails, the target is not paralyzed.
/// </summary>
[Test]
public async Task OnSecondaryEffect_EffectChanceFails_DoesNotParalyzeTarget()
{
// Arrange
var (script, move, target, _, random) = CreateTestSetup();
random.EffectChance(30, move, target, 0).Returns(false);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(target.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "SetStatus")).IsFalse();
}
/// <summary>
/// Bulbapedia: "a 30% chance of paralyzing the target."
/// The paralysis roll is made with exactly a 30% chance.
/// </summary>
[Test]
public async Task OnSecondaryEffect_ParalysisRoll_UsesThirtyPercentChance()
{
// Arrange
var (script, move, target, _, random) = CreateTestSetup();
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
random.Received(1).EffectChance(30, move, target, 0);
await Assert.That(random.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "EffectChance")).IsTrue();
}
/// <summary>
/// Technical test: outside of battle (no battle data on the target) the secondary effect does nothing
/// and does not throw.
/// </summary>
[Test]
public async Task OnSecondaryEffect_TargetHasNoBattleData_DoesNotParalyzeTarget()
{
// 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 == "SetStatus")).IsFalse();
}
/// <summary>
/// Bulbapedia: the user is "cloaked in a freezing light" on the charge turn and attacks on the following
/// turn. The concrete script provides the <see cref="RequireChargeEffect"/> volatile that forces the user
/// to execute Freeze Shock on the second turn.
/// </summary>
[Test]
public async Task CreateVolatile_ReturnsRequireChargeEffect()
{
// Arrange
var script = new FreezeShock();
var user = Substitute.For<IPokemon>();
// Act
var chargeEffect = script.CreateVolatile(user);
// Assert
await Assert.That(chargeEffect).IsNotNull();
}
}