119 lines
4.1 KiB
C#
119 lines
4.1 KiB
C#
using PkmnLib.Dynamic.Models;
|
|
using PkmnLib.Dynamic.ScriptHandling;
|
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Moves;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Side;
|
|
using PkmnLib.Static.Moves;
|
|
|
|
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
|
|
|
|
/// <summary>
|
|
/// Tests for the <see cref="CraftyShield"/> move script and the <see cref="CraftyShieldEffect"/> it
|
|
/// applies. Gen VII Bulbapedia behavior: "Crafty Shield protects all Pokémon on the user's side of the
|
|
/// field from status moves."
|
|
/// </summary>
|
|
public class CraftyShieldTests
|
|
{
|
|
private static (CraftyShield script, IExecutingMove move, IScriptSet sideVolatile) CreateTestSetup()
|
|
{
|
|
var script = new CraftyShield();
|
|
|
|
var side = Substitute.For<IBattleSide>();
|
|
// Use a real script set so the side script added by Crafty Shield can be inspected afterwards.
|
|
var sideVolatile = new ScriptSet(side);
|
|
side.VolatileScripts.Returns(sideVolatile);
|
|
side.GetScripts().Returns(_ => new ScriptIterator(new List<IEnumerable<ScriptContainer>>()));
|
|
|
|
var battle = Substitute.For<IBattle>();
|
|
battle.Sides.Returns(new[] { side });
|
|
var battleData = Substitute.For<IPokemonBattleData>();
|
|
battleData.Battle.Returns(battle);
|
|
battleData.SideIndex.Returns((byte)0);
|
|
|
|
var user = Substitute.For<IPokemon>();
|
|
user.BattleData.Returns(battleData);
|
|
var move = Substitute.For<IExecutingMove>();
|
|
move.User.Returns(user);
|
|
|
|
return (script, move, sideVolatile);
|
|
}
|
|
|
|
private static IExecutingMove CreateExecutingMoveOfCategory(MoveCategory category)
|
|
{
|
|
var useMove = Substitute.For<IMoveData>();
|
|
useMove.Category.Returns(category);
|
|
var move = Substitute.For<IExecutingMove>();
|
|
move.UseMove.Returns(useMove);
|
|
return move;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Crafty Shield protects all Pokémon on the user's side of the field" — using the move
|
|
/// attaches the <see cref="CraftyShieldEffect"/> to the user's side.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_Used_AddsCraftyShieldEffectToUsersSide()
|
|
{
|
|
// Arrange
|
|
var (script, move, sideVolatile) = CreateTestSetup();
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
|
|
|
|
// Assert
|
|
await Assert.That(sideVolatile.Contains(ScriptUtils.ResolveName<CraftyShieldEffect>())).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: the shield protects "from status moves" — an incoming status move is stopped.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task CraftyShieldEffect_StatusMove_IsStopped()
|
|
{
|
|
// Arrange
|
|
var effect = new CraftyShieldEffect();
|
|
var move = CreateExecutingMoveOfCategory(MoveCategory.Status);
|
|
var stop = false;
|
|
|
|
// Act
|
|
effect.StopBeforeMove(move, ref stop);
|
|
|
|
// Assert
|
|
await Assert.That(stop).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: Crafty Shield only blocks status moves — damaging moves go through it unhindered.
|
|
/// </summary>
|
|
[Test, Arguments(MoveCategory.Physical), Arguments(MoveCategory.Special)]
|
|
public async Task CraftyShieldEffect_DamagingMove_IsNotStopped(MoveCategory category)
|
|
{
|
|
// Arrange
|
|
var effect = new CraftyShieldEffect();
|
|
var move = CreateExecutingMoveOfCategory(category);
|
|
var stop = false;
|
|
|
|
// Act
|
|
effect.StopBeforeMove(move, ref stop);
|
|
|
|
// Assert
|
|
await Assert.That(stop).IsFalse();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Technical test: outside of battle (no battle data) no shield can be raised and nothing happens.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_NoBattleData_DoesNothing()
|
|
{
|
|
// Arrange
|
|
var (script, move, sideVolatile) = CreateTestSetup();
|
|
move.User.BattleData.Returns((IPokemonBattleData?)null);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
|
|
|
|
// Assert - no effect is added
|
|
await Assert.That(sideVolatile.Contains(ScriptUtils.ResolveName<CraftyShieldEffect>())).IsFalse();
|
|
}
|
|
} |