Files
PkmnLib.NET/Plugins/PkmnLib.Plugin.Gen7.Tests/Scripts/Moves/MagicRoomTests.cs

156 lines
5.9 KiB
C#

using PkmnLib.Dynamic.Models;
using PkmnLib.Dynamic.ScriptHandling;
using PkmnLib.Plugin.Gen7.Scripts.Battle;
using PkmnLib.Plugin.Gen7.Scripts.Moves;
using PkmnLib.Static;
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
/// <summary>
/// Tests for the <see cref="MagicRoom"/> move script and the <see cref="MagicRoomEffect"/> battle volatile it
/// applies. Gen VII Bulbapedia behavior: "Magic Room suppresses the effect of all items held by the Pokémon on
/// the field. This effect lasts for five turns." Using the move again while active removes the effect
/// immediately.
/// </summary>
public class MagicRoomTests
{
/// <summary>
/// Creates a fully mocked test setup for Magic Room tests. The battle gets a real
/// <see cref="ScriptSet"/> as its volatile set, so the applied effect can be inspected.
/// </summary>
private static (MagicRoom script, IExecutingMove move, IBattlePokemon target, IBattle battle, IScriptSet
battleVolatile) CreateTestSetup()
{
var script = new MagicRoom();
var move = Substitute.For<IExecutingMove>();
var target = Substitute.For<IBattlePokemon>();
var battle = Substitute.For<IBattle>();
battle.GetScripts().Returns(_ => new ScriptIterator(new List<IEnumerable<ScriptContainer>>()));
var battleVolatile = new ScriptSet(battle);
battle.Volatile.Returns(battleVolatile);
var user = Substitute.For<IBattlePokemon>();
move.User.Returns(user);
user.Battle.Returns(battle);
return (script, move, target, battle, battleVolatile);
}
/// <summary>
/// Bulbapedia: "Magic Room suppresses the effect of all items held by the Pokémon on the field."
/// The move script applies the <see cref="MagicRoomEffect"/> volatile, which implements the item
/// suppression, to the battle.
/// </summary>
[Test]
public async Task OnSecondaryEffect_MoveUsed_AddsMagicRoomEffectToBattleVolatile()
{
// Arrange
var (script, move, target, _, battleVolatile) = CreateTestSetup();
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(battleVolatile.Get<MagicRoomEffect>()).IsNotNull();
}
/// <summary>
/// Bulbapedia: "If Magic Room is used while it is already in effect, it will end immediately."
/// Using the move a second time must remove the active effect from the battle instead of leaving it in
/// place.
/// </summary>
[Test]
public async Task OnSecondaryEffect_UsedWhileActive_RemovesEffectImmediately()
{
// Arrange
var (script, move, target, _, battleVolatile) = CreateTestSetup();
// Act - second use while the effect is active
script.OnSecondaryEffect(move, target, 0);
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(battleVolatile.Contains("magic_room")).IsFalse();
}
// ----- MagicRoomEffect behavior (the volatile the move applies) -----
/// <summary>
/// Bulbapedia: "Magic Room suppresses the effect of all items held by the Pokémon on the field."
/// While the effect is active no Pokémon can consume its held item.
/// </summary>
[Test]
public async Task PreventHeldItemConsume_MagicRoomActive_ItemConsumptionPrevented()
{
// Arrange
var effect = new MagicRoomEffect();
var pokemon = Substitute.For<IBattlePokemon>();
var item = Substitute.For<IItem>();
var prevented = false;
// Act
effect.PreventHeldItemConsume(pokemon, item, ref prevented);
// Assert
await Assert.That(prevented).IsTrue();
}
/// <summary>
/// Bulbapedia: "Magic Room suppresses the effect of all items held by the Pokémon on the field."
/// The effect suppresses all item battle trigger scripts while active.
/// </summary>
[Test]
public async Task OnBeforeAnyHookInvoked_NullCategoryList_SuppressesItemBattleTriggers()
{
// Arrange
var effect = new MagicRoomEffect();
List<ScriptCategory>? suppressedCategories = null;
// Act
effect.OnBeforeAnyHookInvoked(ref suppressedCategories);
// Assert
await Assert.That(suppressedCategories).IsNotNull();
await Assert.That(suppressedCategories!.Contains(ScriptCategory.ItemBattleTrigger)).IsTrue();
}
/// <summary>
/// Bulbapedia: "Magic Room suppresses the effect of all items held by the Pokémon on the field."
/// When other suppressions are already present, the item suppression is added to the existing list.
/// </summary>
[Test]
public async Task OnBeforeAnyHookInvoked_ExistingCategoryList_AddsItemBattleTriggerSuppression()
{
// Arrange
var effect = new MagicRoomEffect();
List<ScriptCategory>? suppressedCategories = [ScriptCategory.Weather];
// Act
effect.OnBeforeAnyHookInvoked(ref suppressedCategories);
// Assert
await Assert.That(suppressedCategories!.Contains(ScriptCategory.ItemBattleTrigger)).IsTrue();
await Assert.That(suppressedCategories!.Contains(ScriptCategory.Weather)).IsTrue();
}
/// <summary>
/// Bulbapedia: "This effect lasts for five turns." The turn Magic Room is used counts as the first turn,
/// so after five end-of-turn ticks the effect must have removed itself from the battle.
/// </summary>
[Test]
public async Task OnEndTurn_AfterFiveEndOfTurns_EffectHasEnded()
{
// Arrange
var (script, move, target, battle, battleVolatile) = CreateTestSetup();
script.OnSecondaryEffect(move, target, 0);
var effect = battleVolatile.Get<MagicRoomEffect>()!;
// Act - five end-of-turn ticks, the duration of the effect
for (var i = 0; i < 5; i++)
effect.OnEndTurn(battle, battle);
// Assert
await Assert.That(battleVolatile.Contains("magic_room")).IsFalse();
}
}