Files
PkmnLib.NET/Plugins/PkmnLib.Plugin.Gen7.Tests/Scripts/Moves/EmbargoTests.cs
2026-07-05 19:45:40 +02:00

126 lines
4.4 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.Pokemon;
using PkmnLib.Static;
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
/// <summary>
/// Tests for the <see cref="Embargo"/> move script and its <see cref="EmbargoEffect"/>.
/// Gen VII Bulbapedia behavior: "For five turns, the target's held item has its effects negated and its
/// Trainer cannot use items from the Bag on it."
/// </summary>
public class EmbargoTests
{
/// <summary>
/// Creates a target Pokémon whose volatile scripts are a real <see cref="ScriptSet"/>.
/// </summary>
private static (IPokemon target, IScriptSet targetVolatile) CreateTarget()
{
var target = Substitute.For<IPokemon>();
target.GetScripts().Returns(_ => new ScriptIterator(Array.Empty<IEnumerable<ScriptContainer>>()));
IScriptSet targetVolatile = new ScriptSet(target);
target.Volatile.Returns(targetVolatile);
return (target, targetVolatile);
}
/// <summary>
/// Bulbapedia: "For five turns, the target's held item has its effects negated" — using the move
/// attaches the <see cref="EmbargoEffect"/> to the target.
/// </summary>
[Test]
public async Task OnSecondaryEffect_AddsEmbargoEffectToTarget()
{
// Arrange
var script = new Embargo();
var move = Substitute.For<IExecutingMove>();
var (target, targetVolatile) = CreateTarget();
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(targetVolatile.Contains(ScriptUtils.ResolveName<EmbargoEffect>())).IsTrue();
}
/// <summary>
/// Bulbapedia: the target's "Trainer cannot use items from the Bag on it" and its held item is
/// negated — the effect prevents held item consumption.
/// </summary>
[Test]
public async Task PreventHeldItemConsume_EffectActive_ConsumptionPrevented()
{
// Arrange
var effect = new EmbargoEffect();
var prevented = false;
// Act
effect.PreventHeldItemConsume(Substitute.For<IPokemon>(), Substitute.For<IItem>(), ref prevented);
// Assert
await Assert.That(prevented).IsTrue();
}
/// <summary>
/// Bulbapedia: the effect lasts "for five turns" — after four end-of-turn ticks it is still active.
/// </summary>
[Test]
public async Task OnEndTurn_FourTurnsPassed_EffectStillActive()
{
// Arrange
var (target, targetVolatile) = CreateTarget();
var effect = new EmbargoEffect();
targetVolatile.Add(effect);
// Act
for (var i = 0; i < 4; i++)
effect.OnEndTurn(target, Substitute.For<IBattle>());
// Assert
await Assert.That(targetVolatile.Contains(ScriptUtils.ResolveName<EmbargoEffect>())).IsTrue();
}
/// <summary>
/// Bulbapedia: the effect lasts "for five turns" — after the fifth end-of-turn tick it removes itself.
/// </summary>
[Test]
public async Task OnEndTurn_FiveTurnsPassed_EffectRemovesItself()
{
// Arrange
var (target, targetVolatile) = CreateTarget();
var effect = new EmbargoEffect();
targetVolatile.Add(effect);
// Act
for (var i = 0; i < 5; i++)
effect.OnEndTurn(target, Substitute.For<IBattle>());
// Assert
await Assert.That(targetVolatile.Contains(ScriptUtils.ResolveName<EmbargoEffect>())).IsFalse();
}
/// <summary>
/// Bulbapedia: "For five turns" — using Embargo again on an already affected target restarts the
/// five turn duration (the effect stacks by resetting its counter).
/// </summary>
[Test]
public async Task Stack_UsedAgain_DurationResetsToFiveTurns()
{
// Arrange
var (target, targetVolatile) = CreateTarget();
var effect = new EmbargoEffect();
targetVolatile.Add(effect);
for (var i = 0; i < 3; i++)
effect.OnEndTurn(target, Substitute.For<IBattle>());
// Act - Embargo is used again, restarting the duration
effect.Stack();
for (var i = 0; i < 4; i++)
effect.OnEndTurn(target, Substitute.For<IBattle>());
// Assert - only four of the renewed five turns have passed
await Assert.That(targetVolatile.Contains(ScriptUtils.ResolveName<EmbargoEffect>())).IsTrue();
}
}