This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
using PkmnLib.Dynamic.Events;
|
||||
using PkmnLib.Dynamic.Models;
|
||||
using PkmnLib.Dynamic.ScriptHandling;
|
||||
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="Autotomize"/> move script.
|
||||
/// Gen VII Bulbapedia behavior: "Autotomize raises the user's Speed stat by two stages and (if the user
|
||||
/// successfully changes its Speed) decreases its weight by 220 lbs. (100 kg). If the user successfully
|
||||
/// changes its weight, the message '<Pokémon> became nimble!' is displayed. Autotomize cannot decrease
|
||||
/// the user's weight below the minimum 0.2 lbs (0.1 kg); if the user's weight would drop below the minimum,
|
||||
/// it becomes the minimum instead. Weight loss from Autotomize stacks".
|
||||
/// </summary>
|
||||
public class AutotomizeTests
|
||||
{
|
||||
private static (Autotomize script, IExecutingMove move, IPokemon user, IScriptSet userVolatile, EventHook eventHook)
|
||||
CreateTestSetup(float weightInKg, bool speedRaiseSucceeds, AutotomizeEffect? existingEffect = null)
|
||||
{
|
||||
var script = new Autotomize();
|
||||
var move = Substitute.For<IExecutingMove>();
|
||||
|
||||
var eventHook = new EventHook();
|
||||
var battle = Substitute.For<IBattle>();
|
||||
battle.EventHook.Returns(eventHook);
|
||||
var battleData = Substitute.For<IPokemonBattleData>();
|
||||
battleData.Battle.Returns(battle);
|
||||
|
||||
var userVolatile = Substitute.For<IScriptSet>();
|
||||
userVolatile.Get<AutotomizeEffect>().Returns(existingEffect);
|
||||
|
||||
var user = Substitute.For<IPokemon>();
|
||||
user.BattleData.Returns(battleData);
|
||||
user.Volatile.Returns(userVolatile);
|
||||
user.WeightInKg.Returns(weightInKg);
|
||||
user.ChangeStatBoost(Arg.Any<Statistic>(), Arg.Any<sbyte>(), Arg.Any<bool>(), Arg.Any<bool>())
|
||||
.Returns(speedRaiseSucceeds);
|
||||
move.User.Returns(user);
|
||||
|
||||
return (script, move, user, userVolatile, eventHook);
|
||||
}
|
||||
|
||||
private static bool ReceivedStackOrAdd(IScriptSet scriptSet) =>
|
||||
scriptSet.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "StackOrAdd");
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "Autotomize raises the user's Speed stat by two stages". The stat change is self-inflicted.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OnSecondaryEffect_RaisesUserSpeedByTwoStages()
|
||||
{
|
||||
// Arrange
|
||||
var (script, move, user, _, _) = CreateTestSetup(100f, true);
|
||||
|
||||
// Act
|
||||
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
|
||||
|
||||
// Assert
|
||||
user.Received(1).ChangeStatBoost(Statistic.Speed, 2, true, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "(if the user successfully changes its Speed) decreases its weight by 220 lbs. (100 kg).
|
||||
/// If the user successfully changes its weight, the message '<Pokémon> became nimble!' is displayed."
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task OnSecondaryEffect_SpeedRaiseSucceeds_AddsWeightReductionAndShowsMessage()
|
||||
{
|
||||
// Arrange
|
||||
var (script, move, _, userVolatile, eventHook) = CreateTestSetup(100f, true);
|
||||
DialogEvent? capturedEvent = null;
|
||||
eventHook.Handler += (_, args) =>
|
||||
{
|
||||
if (args is DialogEvent dialogEvent)
|
||||
capturedEvent = dialogEvent;
|
||||
};
|
||||
|
||||
// Act
|
||||
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
|
||||
|
||||
// Assert
|
||||
await Assert.That(ReceivedStackOrAdd(userVolatile)).IsTrue();
|
||||
await Assert.That(capturedEvent).IsNotNull();
|
||||
await Assert.That(capturedEvent!.Message).IsEqualTo("pokemon_became_nimble");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: the weight decrease only happens "if the user successfully changes its Speed". When the
|
||||
/// Speed stat cannot be raised (already at +6), no weight reduction is applied and no message is shown.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task OnSecondaryEffect_SpeedRaiseFails_NoWeightReductionOrMessage()
|
||||
{
|
||||
// Arrange
|
||||
var (script, move, _, userVolatile, eventHook) = CreateTestSetup(100f, false);
|
||||
var eventFired = false;
|
||||
eventHook.Handler += (_, _) => eventFired = true;
|
||||
|
||||
// Act
|
||||
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
|
||||
|
||||
// Assert
|
||||
await Assert.That(ReceivedStackOrAdd(userVolatile)).IsFalse();
|
||||
await Assert.That(eventFired).IsFalse();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "Autotomize cannot decrease the user's weight below the minimum 0.2 lbs (0.1 kg); if the
|
||||
/// user's weight would drop below the minimum, it becomes the minimum instead." A first use on a Pokémon
|
||||
/// lighter than 100 kg still applies the weight reduction (the weight clamps to the minimum).
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task OnSecondaryEffect_FirstUseOnLightPokemon_StillAppliesWeightReduction()
|
||||
{
|
||||
// Arrange - 50 kg Pokémon, no previous Autotomize use
|
||||
var (script, move, _, userVolatile, _) = CreateTestSetup(50f, true);
|
||||
|
||||
// Act
|
||||
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
|
||||
|
||||
// Assert
|
||||
await Assert.That(ReceivedStackOrAdd(userVolatile)).IsTrue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "Weight loss from Autotomize stacks, so using it multiple times will continue to decrease
|
||||
/// the user's weight accordingly until it reaches the minimum weight" and "if the user's weight would drop
|
||||
/// below the minimum, it becomes the minimum instead." A Pokémon that still weighs more than the minimum
|
||||
/// after two stacks must receive another stack (its weight drops to the 0.1 kg minimum).
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task OnSecondaryEffect_WeightWouldDropBelowMinimum_StillReducesToMinimum()
|
||||
{
|
||||
// Arrange - the user already has two stacks and currently weighs 50 kg
|
||||
var existingEffect = new AutotomizeEffect();
|
||||
existingEffect.Stack();
|
||||
var (script, move, _, userVolatile, _) = CreateTestSetup(50f, true, existingEffect);
|
||||
|
||||
// Act
|
||||
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
|
||||
|
||||
// Assert - the weight should still be reduced (to the minimum)
|
||||
await Assert.That(ReceivedStackOrAdd(userVolatile)).IsTrue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "Autotomize cannot decrease the user's weight below the minimum 0.2 lbs (0.1 kg)".
|
||||
/// A Pokémon already at the minimum weight cannot lose more weight, so no new stack is added and no
|
||||
/// message is shown; the Speed boost itself is still applied.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task OnSecondaryEffect_AlreadyAtMinimumWeight_NoFurtherReductionButSpeedStillRaised()
|
||||
{
|
||||
// Arrange - the user already has a stack and is at the minimum weight
|
||||
var (script, move, user, userVolatile, eventHook) = CreateTestSetup(0.1f, true, new AutotomizeEffect());
|
||||
var eventFired = false;
|
||||
eventHook.Handler += (_, _) => eventFired = true;
|
||||
|
||||
// Act
|
||||
script.OnSecondaryEffect(move, Substitute.For<IPokemon>(), 0);
|
||||
|
||||
// Assert
|
||||
user.Received(1).ChangeStatBoost(Statistic.Speed, 2, true, false);
|
||||
await Assert.That(ReceivedStackOrAdd(userVolatile)).IsFalse();
|
||||
await Assert.That(eventFired).IsFalse();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user