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, IBattlePokemon 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);
}
}