using PkmnLib.Dynamic.Models; using PkmnLib.Plugin.Gen7.Scripts.Moves; using PkmnLib.Static; using PkmnLib.Static.Moves; namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves; /// /// Tests for the move script. /// Behavior is verified against the Bulbapedia page for Foul Play (Generation VII behavior). /// public class FoulPlayTests { /// /// Creates a fully mocked test setup for Foul Play tests, with a target whose (boosted) offensive /// stats are set to the given values. /// private static (FoulPlay script, IExecutingMove move, IPokemon target) CreateTestSetup(MoveCategory category, uint targetAttack, uint targetSpecialAttack) { var script = new FoulPlay(); var move = Substitute.For(); var useMove = Substitute.For(); useMove.Category.Returns(category); move.UseMove.Returns(useMove); var target = Substitute.For(); target.BoostedStats.Returns(new StatisticSet(100, targetAttack, 80, targetSpecialAttack, 80, 80)); var user = Substitute.For(); move.User.Returns(user); return (script, move, target); } /// /// Bulbapedia: "Foul Play inflicts damage. It uses the target's Attack stat to calculate damage instead /// of the user's." /// The offensive stat value (initially the user's Attack) must be replaced by the target's Attack. /// [Test, Arguments(50u), Arguments(150u), Arguments(400u)] public async Task ChangeOffensiveStatValue_PhysicalMove_UsesTargetsAttackInsteadOfUsers(uint targetAttack) { // Arrange var (script, move, target) = CreateTestSetup(MoveCategory.Physical, targetAttack, 80); uint value = 100; // The user's own Attack stat, which must be discarded. // Act script.ChangeOffensiveStatValue(move, target, 0, 200, new StatisticSet(), Statistic.Attack, ref value); // Assert await Assert.That(value).IsEqualTo(targetAttack); } /// /// Bulbapedia: "The target's Attack stat stage-modifiers are applied (rather than the user's)". /// The stat used must be the target's boosted Attack (, which includes /// stat stages), not its flat Attack (). /// [Test] public async Task ChangeOffensiveStatValue_PhysicalMove_TargetStatStagesApplied() { // Arrange - the target's flat Attack is 100, but its stat stages boost it to 400. var (script, move, target) = CreateTestSetup(MoveCategory.Physical, 400, 80); target.FlatStats.Returns(new StatisticSet(100, 100, 80, 80, 80, 80)); uint value = 100; // Act script.ChangeOffensiveStatValue(move, target, 0, 200, new StatisticSet(), Statistic.Attack, ref value); // Assert await Assert.That(value).IsEqualTo(400u); } /// /// Technical test: the script generically supports special moves by using the target's Special Attack /// instead. (Foul Play itself is a physical move; Bulbapedia: "It uses the target's Attack stat to /// calculate damage instead of the user's.") /// [Test] public async Task ChangeOffensiveStatValue_SpecialMove_UsesTargetsSpecialAttack() { // Arrange var (script, move, target) = CreateTestSetup(MoveCategory.Special, 150, 240); uint value = 100; // Act script.ChangeOffensiveStatValue(move, target, 0, 200, new StatisticSet(), Statistic.SpecialAttack, ref value); // Assert await Assert.That(value).IsEqualTo(240u); } }