Files
PkmnLib.NET/Plugins/PkmnLib.Plugin.Gen7.Tests/Scripts/Moves/BestowTests.cs
Deukhoofd cc091d5327
Some checks failed
Build / Build (push) Failing after 35s
Update TUnit, warning cleanup
2026-07-05 13:46:57 +02:00

175 lines
5.9 KiB
C#

using PkmnLib.Dynamic.Models;
using PkmnLib.Plugin.Gen7.Scripts.Moves;
using PkmnLib.Static;
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
/// <summary>
/// Tests for the <see cref="Bestow"/> move script.
/// Gen VII Bulbapedia behavior: "The user transfers its held item to the target. It fails if the user has no
/// held item, the target already has a held item, or the target is behind a substitute. [...] Items given away
/// in Trainer battles return to the original Pokémon after the battle."
/// </summary>
public class BestowTests
{
private static (Bestow script, IExecutingMove move, IPokemon user, IPokemon target, IHitData hitData)
CreateTestSetup(IItem? userItem, IItem? targetItem)
{
var script = new Bestow();
var move = Substitute.For<IExecutingMove>();
var target = Substitute.For<IPokemon>();
var hitData = Substitute.For<IHitData>();
move.GetHitData(target, 0).Returns(hitData);
target.HeldItem.Returns(targetItem);
var user = Substitute.For<IPokemon>();
user.HeldItem.Returns(userItem);
user.RemoveHeldItemForBattle().Returns(userItem);
move.User.Returns(user);
return (script, move, user, target, hitData);
}
/// <summary>
/// Bulbapedia: "The user transfers its held item to the target."
/// The target ends up holding the user's item.
/// </summary>
[Test]
public void OnSecondaryEffect_TargetHasNoItem_TargetReceivesUsersItem()
{
// Arrange
var userItem = Substitute.For<IItem>();
var (script, move, _, target, _) = CreateTestSetup(userItem, null);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
_ = target.Received(1).ForceSetHeldItem(userItem);
}
/// <summary>
/// Bulbapedia: "The user transfers its held item to the target."
/// A successful transfer does not fail the move.
/// </summary>
[Test]
public void OnSecondaryEffect_TargetHasNoItem_MoveDoesNotFail()
{
// Arrange
var userItem = Substitute.For<IItem>();
var (script, move, _, target, hitData) = CreateTestSetup(userItem, null);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
hitData.DidNotReceive().Fail();
}
/// <summary>
/// Bulbapedia: "Items given away in Trainer battles return to the original Pokémon after the battle."
/// The item is taken from the user through <see cref="IPokemon.RemoveHeldItemForBattle"/>, which only
/// removes the item for the duration of the battle.
/// </summary>
[Test]
public void OnSecondaryEffect_TargetHasNoItem_UserItemIsRemovedForBattleOnly()
{
// Arrange
var userItem = Substitute.For<IItem>();
var (script, move, user, target, _) = CreateTestSetup(userItem, null);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
user.Received(1).RemoveHeldItemForBattle();
}
/// <summary>
/// Bulbapedia: "It fails if the user has no held item".
/// </summary>
[Test]
public void OnSecondaryEffect_UserHasNoHeldItem_MoveFails()
{
// Arrange
var (script, move, _, target, hitData) = CreateTestSetup(null, null);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
hitData.Received(1).Fail();
}
/// <summary>
/// Bulbapedia: "It fails if the user has no held item".
/// When the move fails, no item is given to the target.
/// </summary>
[Test]
public void OnSecondaryEffect_UserHasNoHeldItem_TargetDoesNotReceiveAnItem()
{
// Arrange
var (script, move, _, target, _) = CreateTestSetup(null, null);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
_ = target.DidNotReceive().ForceSetHeldItem(Arg.Any<IItem>());
}
/// <summary>
/// Bulbapedia: "It fails if [...] the target already has a held item".
/// </summary>
[Test]
public void OnSecondaryEffect_TargetAlreadyHasHeldItem_MoveFails()
{
// Arrange
var (script, move, _, target, hitData) = CreateTestSetup(Substitute.For<IItem>(), Substitute.For<IItem>());
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
hitData.Received(1).Fail();
}
/// <summary>
/// Bulbapedia: "It fails if [...] the target already has a held item".
/// The target's own held item is left untouched by the failed move.
/// </summary>
[Test]
public void OnSecondaryEffect_TargetAlreadyHasHeldItem_TargetItemIsNotReplaced()
{
// Arrange
var (script, move, _, target, _) = CreateTestSetup(Substitute.For<IItem>(), Substitute.For<IItem>());
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
target.DidNotReceive().ForceSetHeldItem(Arg.Any<IItem>());
}
/// <summary>
/// Bulbapedia: "It fails if [...] the target already has a held item".
/// A failed Bestow must not cost the user its held item: the item is either never taken from the user, or
/// it is given back after the failure check.
/// </summary>
[Test]
public async Task OnSecondaryEffect_TargetAlreadyHasHeldItem_UserKeepsItsHeldItem()
{
// Arrange
var userItem = Substitute.For<IItem>();
var (script, move, user, target, _) = CreateTestSetup(userItem, Substitute.For<IItem>());
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert - the user still holds its item: it was either never removed, or restored after the failure.
var removed = user.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "RemoveHeldItemForBattle");
var restored = user.ReceivedCalls().Any(c =>
c.GetMethodInfo().Name == "ForceSetHeldItem" && ReferenceEquals(c.GetArguments()[0], userItem));
await Assert.That(!removed || restored).IsTrue();
}
}