154 lines
5.2 KiB
C#
154 lines
5.2 KiB
C#
using PkmnLib.Dynamic.Models;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Moves;
|
|
using PkmnLib.Static.Species;
|
|
using PkmnLib.Static.Utils;
|
|
|
|
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
|
|
|
|
/// <summary>
|
|
/// Tests for the <see cref="Entrainment"/> move script.
|
|
/// Gen VII Bulbapedia behavior: "Entrainment changes the target's Ability to match the user's." It fails
|
|
/// if both Pokémon already share the same Ability, if the target's Ability cannot be changed (e.g.
|
|
/// Truant, Multitype, Stance Change, Comatose, Disguise), or if the user's Ability cannot be copied
|
|
/// (e.g. Trace, Illusion, Imposter, Power Construct).
|
|
/// </summary>
|
|
public class EntrainmentTests
|
|
{
|
|
/// <summary>
|
|
/// Creates a mocked ability that reports the given flags as set.
|
|
/// </summary>
|
|
private static IAbility CreateAbility(params string[] flags)
|
|
{
|
|
var ability = Substitute.For<IAbility>();
|
|
foreach (var flag in flags)
|
|
ability.HasFlag(new StringKey(flag)).Returns(true);
|
|
return ability;
|
|
}
|
|
|
|
private static (Entrainment script, IExecutingMove move, IPokemon target, IHitData hitData) CreateTestSetup(
|
|
IAbility? userAbility, IAbility? targetAbility)
|
|
{
|
|
var script = new Entrainment();
|
|
var move = Substitute.For<IExecutingMove>();
|
|
var target = Substitute.For<IPokemon>();
|
|
var hitData = Substitute.For<IHitData>();
|
|
move.GetHitData(target, 0).Returns(hitData);
|
|
|
|
var user = Substitute.For<IPokemon>();
|
|
user.ActiveAbility.Returns(userAbility);
|
|
move.User.Returns(user);
|
|
target.ActiveAbility.Returns(targetAbility);
|
|
|
|
return (script, move, target, hitData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Entrainment changes the target's Ability to match the user's."
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_DifferentAbilities_ChangesTargetAbilityToUsers()
|
|
{
|
|
// Arrange
|
|
var userAbility = CreateAbility();
|
|
var (script, move, target, hitData) = CreateTestSetup(userAbility, CreateAbility());
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
target.Received(1).ChangeAbility(userAbility);
|
|
hitData.DidNotReceive().Fail();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "The move fails if both Pokémon already share the same Ability."
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_SameAbility_FailsHit()
|
|
{
|
|
// Arrange
|
|
var sharedAbility = CreateAbility();
|
|
var (script, move, target, hitData) = CreateTestSetup(sharedAbility, sharedAbility);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
hitData.Received(1).Fail();
|
|
target.DidNotReceiveWithAnyArgs().ChangeAbility(default!);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "The move fails if the user has: Trace, Forecast, Flower Gift, Zen Mode, Illusion,
|
|
/// Imposter, [...]" — abilities that cannot be copied prevent Entrainment from working.
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_UserAbilityCantBeCopied_FailsHit()
|
|
{
|
|
// Arrange
|
|
var userAbility = CreateAbility("cant_be_copied");
|
|
var (script, move, target, hitData) = CreateTestSetup(userAbility, CreateAbility());
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
hitData.Received(1).Fail();
|
|
target.DidNotReceiveWithAnyArgs().ChangeAbility(default!);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "The move cannot affect Pokémon with these Abilities: Truant, Multitype, Stance
|
|
/// Change, [...]" — a target whose ability cannot be changed prevents Entrainment from working.
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_TargetAbilityCantBeChanged_FailsHit()
|
|
{
|
|
// Arrange
|
|
var targetAbility = CreateAbility("cant_be_changed");
|
|
var (script, move, target, hitData) = CreateTestSetup(CreateAbility(), targetAbility);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
hitData.Received(1).Fail();
|
|
target.DidNotReceiveWithAnyArgs().ChangeAbility(default!);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Entrainment changes the target's Ability to match the user's" — without a user
|
|
/// ability there is nothing to copy, so the move fails.
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_UserHasNoAbility_FailsHit()
|
|
{
|
|
// Arrange
|
|
var (script, move, target, hitData) = CreateTestSetup(null, CreateAbility());
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
hitData.Received(1).Fail();
|
|
target.DidNotReceiveWithAnyArgs().ChangeAbility(default!);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Technical test: a target without an active ability cannot have it validated for replacement, so
|
|
/// the move fails rather than throwing.
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_TargetHasNoAbility_FailsHit()
|
|
{
|
|
// Arrange
|
|
var (script, move, target, hitData) = CreateTestSetup(CreateAbility(), null);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
hitData.Received(1).Fail();
|
|
target.DidNotReceiveWithAnyArgs().ChangeAbility(default!);
|
|
}
|
|
} |