using PkmnLib.Dynamic.Models;
using PkmnLib.Plugin.Gen7.Scripts.Moves;
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
///
/// Tests for the move script.
/// Gen VII Bulbapedia behavior: "First Impression inflicts damage. It has a priority of +2, and is used
/// before moves of lower priority. First Impression always fails if it is used after the first turn the
/// user is out, or if the move is called by Instruct."
///
public class FirstImpressionTests
{
///
/// Creates a fully mocked test setup for First Impression tests, with the user having switched in on
/// while the battle is on .
///
private static (FirstImpression script, IExecutingMove move, IBattlePokemon user) CreateTestSetup(uint switchInTurn,
uint currentTurn)
{
var script = new FirstImpression();
var move = Substitute.For();
var user = Substitute.For();
var battle = Substitute.For();
battle.CurrentTurnNumber.Returns(currentTurn);
user.Battle.Returns(battle);
user.SwitchInTurn.Returns(switchInTurn);
move.User.Returns(user);
return (script, move, user);
}
///
/// Bulbapedia: "First Impression always fails if it is used after the first turn the user is out".
/// On the turn the user switched in, the move is allowed to execute.
///
[Test]
public async Task StopBeforeMove_UsedOnSwitchInTurn_MoveIsNotStopped()
{
// Arrange
var (script, move, _) = CreateTestSetup(3, 3);
var stop = false;
// Act
script.StopBeforeMove(move, ref stop);
// Assert
await Assert.That(stop).IsFalse();
}
///
/// Bulbapedia: "First Impression always fails if it is used after the first turn the user is out".
/// One turn after switching in, the move is stopped.
///
[Test]
public async Task StopBeforeMove_UsedTurnAfterSwitchIn_MoveIsStopped()
{
// Arrange
var (script, move, _) = CreateTestSetup(1, 2);
var stop = false;
// Act
script.StopBeforeMove(move, ref stop);
// Assert
await Assert.That(stop).IsTrue();
}
///
/// Bulbapedia: "First Impression always fails if it is used after the first turn the user is out".
/// The move only executes when the current turn is the turn the user switched in, regardless of
/// the absolute turn numbers.
///
[Test, Arguments(1u, 1u, false), Arguments(1u, 2u, true), Arguments(4u, 4u, false), Arguments(2u, 7u, true)]
public async Task StopBeforeMove_SwitchInTurnVersusCurrentTurn_StopsOnlyAfterFirstTurnOut(uint switchInTurn,
uint currentTurn, bool expectedStop)
{
// Arrange
var (script, move, _) = CreateTestSetup(switchInTurn, currentTurn);
var stop = false;
// Act
script.StopBeforeMove(move, ref stop);
// Assert
await Assert.That(stop).IsEqualTo(expectedStop);
}
}