Files
PkmnLib.NET/Plugins/PkmnLib.Plugin.Gen7.Tests/Scripts/Moves/DragonAscentTests.cs

106 lines
3.7 KiB
C#

using PkmnLib.Dynamic.Events;
using PkmnLib.Dynamic.Models;
using PkmnLib.Plugin.Gen7.Scripts.Moves;
using PkmnLib.Static;
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
/// <summary>
/// Tests for the <see cref="DragonAscent"/> move script.
/// Gen VII Bulbapedia behavior: "Dragon Ascent inflicts damage and then lowers the user's Defense stat
/// and Special Defense stat by one stage each."
/// </summary>
public class DragonAscentTests
{
private static (DragonAscent script, IExecutingMove move, IPokemon user) CreateTestSetup()
{
var script = new DragonAscent();
var move = Substitute.For<IExecutingMove>();
var user = Substitute.For<IPokemon>();
move.User.Returns(user);
return (script, move, user);
}
/// <summary>
/// Helper checking whether the given Pokémon received a ChangeStatBoost call for the given stat with
/// a one-stage self-inflicted, non-forced drop.
/// </summary>
private static bool ReceivedSelfInflictedDrop(IPokemon pokemon, Statistic stat) =>
pokemon.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "ChangeStatBoost" &&
(Statistic)c.GetArguments()[0]! == stat && (sbyte)c.GetArguments()[1]! == -1 &&
(bool)c.GetArguments()[2]! && !(bool)c.GetArguments()[3]!);
/// <summary>
/// Bulbapedia: "lowers the user's Defense stat [...] by one stage". The stat change is self-inflicted
/// and not forced.
/// </summary>
[Test]
public async Task OnSecondaryEffect_MoveHits_LowersUserDefenseByOneStage()
{
// Arrange
var (script, move, user) = CreateTestSetup();
var target = Substitute.For<IPokemon>();
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(ReceivedSelfInflictedDrop(user, Statistic.Defense)).IsTrue();
}
/// <summary>
/// Bulbapedia: "lowers the user's [...] Special Defense stat by one stage". The stat change is
/// self-inflicted and not forced.
/// </summary>
[Test]
public async Task OnSecondaryEffect_MoveHits_LowersUserSpecialDefenseByOneStage()
{
// Arrange
var (script, move, user) = CreateTestSetup();
var target = Substitute.For<IPokemon>();
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(ReceivedSelfInflictedDrop(user, Statistic.SpecialDefense)).IsTrue();
}
/// <summary>
/// Bulbapedia: the drop hits the user's stats, not the target's. The target's stat stages are left
/// untouched.
/// </summary>
[Test]
public async Task OnSecondaryEffect_MoveHits_DoesNotChangeTargetStats()
{
// Arrange
var (script, move, _) = CreateTestSetup();
var target = Substitute.For<IPokemon>();
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(target.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "ChangeStatBoost")).IsFalse();
}
/// <summary>
/// Both stat drops are reported under the same event batch, so they display as a single combined
/// event.
/// </summary>
[Test]
public async Task OnSecondaryEffect_MoveHits_BothStatDropsShareEventBatch()
{
// Arrange
var (script, move, user) = CreateTestSetup();
var target = Substitute.For<IPokemon>();
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
var batchIds = user.ReceivedCalls().Where(c => c.GetMethodInfo().Name == "ChangeStatBoost")
.Select(c => (EventBatchId)c.GetArguments()[4]!).Distinct().ToList();
await Assert.That(batchIds.Count).IsEqualTo(1);
}
}