using PkmnLib.Dynamic.Models;
using PkmnLib.Dynamic.Models.Choices;
using PkmnLib.Dynamic.ScriptHandling;
using PkmnLib.Plugin.Gen7.Common;
using PkmnLib.Plugin.Gen7.Scripts.Moves;
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
using PkmnLib.Static.Moves;
using PkmnLib.Static.Utils;
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
///
/// Tests for the script, and the it registers on its user.
/// Behavior is verified against the Bulbapedia page for Follow Me (Generation VII).
///
public class FollowMeTests
{
/// The side the center of attention and its ally are on.
private const byte CenterSide = 0;
/// The side the attacking opponents are on.
private const byte OpposingSide = 1;
///
/// A two-sided battle, each side carrying its own .
///
private sealed class Arena
{
public IBattle Battle { get; } = Substitute.For();
public IBattleSide[] Sides { get; } = [CreateSide(), CreateSide()];
private static IBattleSide CreateSide()
{
var side = Substitute.For();
side.VolatileScripts.Returns(Substitute.For());
return side;
}
}
///
/// Creates a mocked Pokémon standing on the given side of the given .
///
private static IBattlePokemon CreatePokemon(Arena arena, byte sideIndex)
{
var pokemon = Substitute.For();
pokemon.Volatile.Returns(Substitute.For());
pokemon.SideIndex.Returns(sideIndex);
pokemon.BattleSide.Returns(arena.Sides[sideIndex]);
pokemon.Battle.Returns(arena.Battle);
return pokemon;
}
///
/// Creates a mocked move choice made by the given Pokémon, using the named move.
///
private static IMoveChoice CreateMoveChoice(IBattlePokemon user, string moveName = "tackle",
bool noRedirection = false)
{
var moveData = Substitute.For();
moveData.Name.Returns(new StringKey(moveName));
moveData.HasFlag(MoveFlags.NoRedirection).Returns(noRedirection);
var learnedMove = Substitute.For();
learnedMove.MoveData.Returns(moveData);
var moveChoice = Substitute.For();
moveChoice.User.Returns(user);
moveChoice.ChosenMove.Returns(learnedMove);
return moveChoice;
}
///
/// Returns the script that was handed to or
/// on the given set, or null if the set never received one.
///
private static Script? RegisteredScript(IScriptSet set)
{
foreach (var call in set.ReceivedCalls())
{
var arguments = call.GetArguments();
switch (call.GetMethodInfo().Name)
{
case "Add" when arguments[0] is Script script:
return script;
case "StackOrAdd" when arguments[1] is Func