using PkmnLib.Dynamic.Models;
using PkmnLib.Dynamic.Models.Choices;
using PkmnLib.Plugin.Gen7.Scripts.Moves;
using PkmnLib.Static.Moves;
using PkmnLib.Static.Utils;
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
///
/// Tests for the move script.
/// Gen VII Bulbapedia behavior: "Copycat causes the user to use the last move that was used in the battle
/// (even if the last move was by the user)." The move fails if no prior move occurred, and certain moves
/// (such as Counter or Copycat itself) cannot be copied.
///
public class CopycatTests
{
private static (Copycat script, IMoveChoice choice) CreateTestSetup(string? lastMoveName)
{
var script = new Copycat();
var user = Substitute.For();
var battleData = Substitute.For();
if (lastMoveName == null)
{
battleData.LastMoveChoice.Returns((IMoveChoice?)null);
}
else
{
var moveData = Substitute.For();
moveData.Name.Returns(new StringKey(lastMoveName));
var learnedMove = Substitute.For();
learnedMove.MoveData.Returns(moveData);
var lastChoice = Substitute.For();
lastChoice.ChosenMove.Returns(learnedMove);
battleData.LastMoveChoice.Returns(lastChoice);
}
user.BattleData.Returns(battleData);
var choice = Substitute.For();
choice.User.Returns(user);
return (script, choice);
}
///
/// Bulbapedia: "Copycat causes the user to use the last move that was used in the battle".
///
[Test]
public async Task ChangeMove_LastMoveIsCopyable_ChangesMoveToLastMove()
{
// Arrange
var (script, choice) = CreateTestSetup("tackle");
StringKey moveName = "copycat";
// Act
script.ChangeMove(choice, ref moveName);
// Assert
await Assert.That(moveName).IsEqualTo(new StringKey("tackle"));
choice.DidNotReceive().Fail();
}
///
/// Bulbapedia: "The move fails if no prior move occurred."
///
[Test]
public async Task ChangeMove_NoMoveUsedYet_Fails()
{
// Arrange
var (script, choice) = CreateTestSetup(null);
StringKey moveName = "copycat";
// Act
script.ChangeMove(choice, ref moveName);
// Assert
choice.Received(1).Fail();
await Assert.That(moveName).IsEqualTo(new StringKey("copycat"));
}
///
/// Bulbapedia lists moves Copycat cannot copy (e.g. Counter, Copycat itself, Protect). If the last
/// used move is one of those, Copycat fails.
///
[Test, Arguments("counter"), Arguments("copycat"), Arguments("protect")]
public async Task ChangeMove_LastMoveNotCopyable_Fails(string lastMove)
{
// Arrange
var (script, choice) = CreateTestSetup(lastMove);
StringKey moveName = "copycat";
// Act
script.ChangeMove(choice, ref moveName);
// Assert
choice.Received(1).Fail();
await Assert.That(moveName).IsEqualTo(new StringKey("copycat"));
}
///
/// Technical test: outside of battle (no battle data) there is no last move, so Copycat fails.
///
[Test]
public void ChangeMove_NoBattleData_Fails()
{
// Arrange
var script = new Copycat();
var user = Substitute.For();
user.BattleData.Returns((IPokemonBattleData?)null);
var choice = Substitute.For();
choice.User.Returns(user);
StringKey moveName = "copycat";
// Act
script.ChangeMove(choice, ref moveName);
// Assert
choice.Received(1).Fail();
}
}