using PkmnLib.Dynamic.Models; using PkmnLib.Plugin.Gen7.Scripts.Moves; using PkmnLib.Static; namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves; /// /// Tests for the move script. /// Gen VII Bulbapedia behavior: "Flail inflicts damage and has no additional effect. Its power is based on /// the user's current HP as a percentage of its maximum HP, which is higher the lower the user's HP is." /// The power tiers (all generations except IV) are: 20 power at HP ≥ 68.8%, 40 at 35.4% ≤ HP < 68.8%, /// 80 at 20.8% ≤ HP < 35.4%, 100 at 10.4% ≤ HP < 20.8%, 150 at 4.2% ≤ HP < 10.4%, and /// 200 at HP < 4.2%. These percentages correspond to the tiers of floor(48 × current HP / max HP). /// public class FlailTests { /// /// Creates a fully mocked test setup for Flail tests with the user at the given current and maximum HP. /// private static (Flail script, IExecutingMove move, IPokemon target) CreateTestSetup(uint currentHp, uint maxHp) { var script = new Flail(); var move = Substitute.For(); var target = Substitute.For(); var user = Substitute.For(); user.CurrentHealth.Returns(currentHp); user.BoostedStats.Returns(new StatisticSet(maxHp, 0, 0, 0, 0, 0)); move.User.Returns(user); return (script, move, target); } /// /// Bulbapedia: Flail's power is 20 when the user's HP is at least 68.8% of its maximum. /// A user at full health uses the weakest power tier. /// [Test] public async Task ChangeBasePower_UserAtFullHealth_PowerIs20() { // Arrange var (script, move, target) = CreateTestSetup(100, 100); ushort basePower = 20; // Act script.ChangeBasePower(move, target, 0, ref basePower); // Assert await Assert.That(basePower).IsEqualTo((ushort)20); } /// /// Bulbapedia: Flail's power is 200 when the user's HP is below 4.2% of its maximum. /// A user at 1 HP uses the strongest power tier. /// [Test] public async Task ChangeBasePower_UserAtOneHp_PowerIs200() { // Arrange var (script, move, target) = CreateTestSetup(1, 100); ushort basePower = 20; // Act script.ChangeBasePower(move, target, 0, ref basePower); // Assert await Assert.That(basePower).IsEqualTo((ushort)200); } /// /// Bulbapedia: "Its power is based on the user's current HP as a percentage of its maximum HP, which is /// higher the lower the user's HP is". These rows cover the extremes of the table: full health /// (HP ≥ 68.8% → 20 power) and nearly fainted (HP < 4.2% → 200 power). /// [Test, Arguments(100u, 100u, 20), Arguments(4u, 100u, 200), Arguments(1u, 100u, 200)] // 48/48 -> 20 // floor(1.92) = 1 -> 200 // floor(0.48) = 0 -> 200 public async Task ChangeBasePower_HpAtExtremes_MatchesFlailPowerTable(uint currentHp, uint maxHp, int expectedPower) { // Arrange var (script, move, target) = CreateTestSetup(currentHp, maxHp); ushort basePower = 20; // Act script.ChangeBasePower(move, target, 0, ref basePower); // Assert await Assert.That(basePower).IsEqualTo((ushort)expectedPower); } /// /// Bulbapedia: "Its power is based on the user's current HP as a percentage of its maximum HP, which is /// higher the lower the user's HP is", following the tiers 20 (HP ≥ 68.8%), 40 (35.4% ≤ HP < 68.8%), /// 80 (20.8% ≤ HP < 35.4%), 100 (10.4% ≤ HP < 20.8%), 150 (4.2% ≤ HP < 10.4%) and 200 (HP < 4.2%). /// The rows cover both boundary values of every tier, verifying the integer arithmetic of /// floor(48 × current HP / max HP). /// [Test, Arguments(69u, 100u, 20), Arguments(68u, 100u, 40), Arguments(36u, 100u, 40), Arguments(35u, 100u, 80), Arguments(21u, 100u, 80), Arguments(20u, 100u, 100), Arguments(11u, 100u, 100), Arguments(10u, 100u, 150), Arguments(5u, 100u, 150), Arguments(150u, 300u, 40), Arguments(24u, 48u, 40), Arguments(7u, 48u, 100)] public async Task ChangeBasePower_HpFractionOfMax_MatchesFlailPowerTable(uint currentHp, uint maxHp, int expectedPower) { // Arrange var (script, move, target) = CreateTestSetup(currentHp, maxHp); ushort basePower = 20; // Act script.ChangeBasePower(move, target, 0, ref basePower); // Assert await Assert.That(basePower).IsEqualTo((ushort)expectedPower); } }