164 lines
6.8 KiB
C#
164 lines
6.8 KiB
C#
using PkmnLib.Dynamic.Models;
|
|
using PkmnLib.Dynamic.ScriptHandling;
|
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Moves;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Side;
|
|
using PkmnLib.Static;
|
|
using PkmnLib.Static.Utils;
|
|
|
|
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
|
|
|
|
/// <summary>
|
|
/// Tests for the <see cref="Defog"/> move script.
|
|
/// Gen VII Bulbapedia behavior: "Defog lowers the target's evasion by one stage" and clears field effects:
|
|
/// "It removes Spikes, Toxic Spikes, Stealth Rock, and Sticky Web from both sides, while Light Screen,
|
|
/// Reflect, Safeguard, Mist, and Aurora Veil are cleared from the target's side only."
|
|
/// </summary>
|
|
public class DefogTests
|
|
{
|
|
/// <summary>
|
|
/// Creates a fully mocked test setup where the target is on side 1 and the user on side 0.
|
|
/// </summary>
|
|
private static (Defog script, IExecutingMove move, IPokemon target, IScriptSet targetSideScripts, IScriptSet
|
|
userSideScripts) CreateTestSetup()
|
|
{
|
|
var script = new Defog();
|
|
var move = Substitute.For<IExecutingMove>();
|
|
|
|
var userSideScripts = Substitute.For<IScriptSet>();
|
|
var userSide = Substitute.For<IBattleSide>();
|
|
userSide.VolatileScripts.Returns(userSideScripts);
|
|
var targetSideScripts = Substitute.For<IScriptSet>();
|
|
var targetSide = Substitute.For<IBattleSide>();
|
|
targetSide.VolatileScripts.Returns(targetSideScripts);
|
|
|
|
var battle = Substitute.For<IBattle>();
|
|
battle.Sides.Returns(new[] { userSide, targetSide });
|
|
|
|
var user = Substitute.For<IPokemon>();
|
|
var userBattleData = Substitute.For<IPokemonBattleData>();
|
|
userBattleData.Battle.Returns(battle);
|
|
userBattleData.SideIndex.Returns((byte)0);
|
|
user.BattleData.Returns(userBattleData);
|
|
move.User.Returns(user);
|
|
|
|
var target = Substitute.For<IPokemon>();
|
|
var targetBattleData = Substitute.For<IPokemonBattleData>();
|
|
targetBattleData.Battle.Returns(battle);
|
|
targetBattleData.SideIndex.Returns((byte)1);
|
|
target.BattleData.Returns(targetBattleData);
|
|
|
|
return (script, move, target, targetSideScripts, userSideScripts);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Light Screen, Reflect, Safeguard, Mist, and Aurora Veil are cleared from the target's
|
|
/// side only." The screen and protection effects (<see cref="LightScreenEffect"/>,
|
|
/// <see cref="ReflectEffect"/>, <see cref="SafeguardEffect"/>, <see cref="MistEffect"/>) are removed
|
|
/// from the target's side.
|
|
/// </summary>
|
|
[Test, Arguments("light_screen"), Arguments("reflect"), Arguments("safe_guard"), Arguments("mist")]
|
|
public async Task OnSecondaryEffect_ScreenOnTargetSide_RemovesEffectFromTargetSide(string scriptName)
|
|
{
|
|
// Arrange
|
|
var (script, move, target, targetSideScripts, _) = CreateTestSetup();
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
targetSideScripts.Received(1).Remove(new StringKey(scriptName));
|
|
await Assert.That(targetSideScripts.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "Remove")).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "It removes Spikes, Toxic Spikes, Stealth Rock, and Sticky Web" — the entry hazards
|
|
/// (<see cref="SpikesEffect"/>, <see cref="ToxicSpikesEffect"/>, <see cref="StealthRockEffect"/>,
|
|
/// <see cref="StickyWebEffect"/>) are removed from the target's side.
|
|
/// </summary>
|
|
[Test, Arguments("spikes"), Arguments("toxic_spikes"), Arguments("stealth_rock"), Arguments("sticky_web")]
|
|
public async Task OnSecondaryEffect_HazardOnTargetSide_RemovesHazardFromTargetSide(string scriptName)
|
|
{
|
|
// Arrange
|
|
var (script, move, target, targetSideScripts, _) = CreateTestSetup();
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
targetSideScripts.Received(1).Remove(new StringKey(scriptName));
|
|
await Assert.That(targetSideScripts.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "Remove")).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia (Generations VI and VII): "It removes Spikes, Toxic Spikes, Stealth Rock, and Sticky Web
|
|
/// from both sides" — the entry hazards must also be removed from the user's own side.
|
|
/// </summary>
|
|
[Test, Arguments("spikes"), Arguments("toxic_spikes"), Arguments("stealth_rock"), Arguments("sticky_web")]
|
|
public async Task OnSecondaryEffect_HazardOnUserSide_RemovesHazardFromUserSide(string scriptName)
|
|
{
|
|
// Arrange
|
|
var (script, move, target, _, userSideScripts) = CreateTestSetup();
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
userSideScripts.Received(1).Remove(new StringKey(scriptName));
|
|
await Assert.That(userSideScripts.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "Remove")).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia (Generations VI and VII): "Light Screen, Reflect, Safeguard, Mist, and Aurora Veil are
|
|
/// cleared from the target's side only." The <see cref="AuroraVeilEffect"/> must be removed as well.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_AuroraVeilOnTargetSide_RemovesAuroraVeilFromTargetSide()
|
|
{
|
|
// Arrange
|
|
var (script, move, target, targetSideScripts, _) = CreateTestSetup();
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
targetSideScripts.Received(1).Remove(new StringKey("aurora_veil"));
|
|
await Assert.That(targetSideScripts.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "Remove")).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Defog lowers the target's evasion by one stage". Neither the script nor the move data
|
|
/// applies the evasion drop, so the target's evasion is never lowered.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_Always_LowersTargetEvasionByOneStage()
|
|
{
|
|
// Arrange
|
|
var (script, move, target, _, _) = CreateTestSetup();
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
await Assert.That(target.ReceivedCalls().Any(c =>
|
|
c.GetMethodInfo().Name == "ChangeStatBoost" && (Statistic)c.GetArguments()[0]! == Statistic.Evasion &&
|
|
(sbyte)c.GetArguments()[1]! == -1)).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Technical test: without battle data (outside of battle) the secondary effect does nothing and does
|
|
/// not throw.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_TargetHasNoBattleData_DoesNotThrow()
|
|
{
|
|
// Arrange
|
|
var script = new Defog();
|
|
var move = Substitute.For<IExecutingMove>();
|
|
var target = Substitute.For<IPokemon>();
|
|
target.BattleData.Returns((IPokemonBattleData?)null);
|
|
|
|
// Act & Assert
|
|
await Assert.That(() => script.OnSecondaryEffect(move, target, 0)).ThrowsNothing();
|
|
}
|
|
} |