using PkmnLib.Dynamic.Events;
using PkmnLib.Dynamic.Models;
using PkmnLib.Plugin.Gen7.Scripts.Moves;
using PkmnLib.Static;
using PkmnLib.Static.Utils;
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
///
/// Tests for the move script.
/// Gen VII Bulbapedia behavior: "Incinerate inflicts damage to all adjacent opponents. The move destroys any
/// Berries held by hit Pokémon". Generation VI onwards: "The move now also destroys Gems."
///
public class IncinerateTests
{
///
/// Creates a fully mocked test setup for Incinerate tests, with the target holding the given item
/// (nothing when null).
///
private static (Incinerate script, IExecutingMove move, IBattlePokemon target, IHitData hitData, EventHook eventHook
) CreateTestSetup(IItem? heldItem)
{
var script = new Incinerate();
var move = Substitute.For();
var target = Substitute.For();
var hitData = Substitute.For();
move.GetHitData(target, 0).Returns(hitData);
var eventHook = new EventHook();
var battle = Substitute.For();
battle.EventHook.Returns(eventHook);
move.Battle.Returns(battle);
target.HeldItem.Returns(heldItem);
if (heldItem != null)
{
target.TryStealHeldItem(out Arg.Any()).Returns(x =>
{
x[0] = heldItem;
return true;
});
}
return (script, move, target, hitData, eventHook);
}
///
/// Creates a substitute held item with the given name and category.
///
private static IItem CreateItem(string name, ItemCategory category)
{
var item = Substitute.For();
item.Name.Returns(new StringKey(name));
item.Category.Returns(category);
return item;
}
///
/// Helper to check whether the target's held item was taken away.
///
private static bool ItemWasRemoved(IBattlePokemon pokemon) =>
pokemon.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "TryStealHeldItem");
///
/// Bulbapedia: "The move destroys any Berries held by hit Pokémon." A held Berry is removed from the
/// target.
///
[Test]
public async Task OnSecondaryEffect_TargetHoldsBerry_BerryIsRemoved()
{
// Arrange
var berry = CreateItem("oran_berry", ItemCategory.Berry);
var (script, move, target, _, _) = CreateTestSetup(berry);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(ItemWasRemoved(target)).IsTrue();
}
///
/// Bulbapedia: "The move destroys any Berries held by hit Pokémon" — the destruction is announced
/// through a so the battle log can show it.
///
[Test]
public async Task OnSecondaryEffect_TargetHoldsBerry_FiresItemIncineratedDialogEvent()
{
// Arrange
var berry = CreateItem("oran_berry", ItemCategory.Berry);
var (script, move, target, _, eventHook) = CreateTestSetup(berry);
DialogEvent? captured = null;
eventHook.Handler += (_, args) =>
{
if (args is DialogEvent dialogEvent)
captured = dialogEvent;
};
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(captured).IsNotNull();
await Assert.That(captured!.Message).IsEqualTo("item_incinerated");
}
///
/// Bulbapedia: only Berries (and, from Gen VI, Gems) are destroyed. A regular held item is left alone.
///
[Test]
public async Task OnSecondaryEffect_TargetHoldsRegularItem_ItemIsNotRemoved()
{
// Arrange
var item = CreateItem("leftovers", ItemCategory.MiscItem);
var (script, move, target, _, _) = CreateTestSetup(item);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(ItemWasRemoved(target)).IsFalse();
}
///
/// Bulbapedia (Generation VI onwards): "The move now also destroys Gems." A held Gem is removed from
/// the target.
///
[Test]
public async Task OnSecondaryEffect_TargetHoldsGem_GemIsRemoved()
{
// Arrange
var gem = CreateItem("normal_gem", ItemCategory.MiscItem);
var (script, move, target, _, _) = CreateTestSetup(gem);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
await Assert.That(ItemWasRemoved(target)).IsTrue();
}
///
/// Bulbapedia: "Incinerate inflicts damage to all adjacent opponents." Destroying a Berry is a bonus
/// effect: against a target holding nothing the move still simply deals its damage, it does not fail.
///
[Test]
public void OnSecondaryEffect_TargetHoldsNoItem_HitIsNotMarkedAsFailed()
{
// Arrange
var (script, move, target, hitData, _) = CreateTestSetup(null);
// Act
script.OnSecondaryEffect(move, target, 0);
// Assert
hitData.DidNotReceive().Fail();
}
}