This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
using PkmnLib.Dynamic.Models;
|
||||
using PkmnLib.Dynamic.Models.Choices;
|
||||
using PkmnLib.Dynamic.ScriptHandling;
|
||||
using PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||
using PkmnLib.Plugin.Gen7.Scripts.MoveVolatile;
|
||||
using PkmnLib.Static.Moves;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for the <see cref="FirePledge"/> move script.
|
||||
/// Bulbapedia: "When two allies attempt to use Fire Pledge and either Water Pledge or Grass Pledge on the
|
||||
/// same turn, the ally moving first will not itself use a move, but instead the ally moving second will use
|
||||
/// a combined attack with a power of 150 and an additional effect immediately after it".
|
||||
/// </summary>
|
||||
public class FirePledgeTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a move choice for a Pokémon on the given side, using a move with the given name.
|
||||
/// The choice gets a real <see cref="ScriptSet"/> as its volatile set, so combination markers can be
|
||||
/// added to and read from it.
|
||||
/// </summary>
|
||||
private static IMoveChoice CreateQueuedChoice(string moveName, byte sideIndex)
|
||||
{
|
||||
var choice = Substitute.For<IMoveChoice>();
|
||||
choice.GetScripts().Returns(_ => new ScriptIterator(new List<IEnumerable<ScriptContainer>>()));
|
||||
|
||||
var pokemon = Substitute.For<IPokemon>();
|
||||
var battleData = Substitute.For<IPokemonBattleData>();
|
||||
battleData.SideIndex.Returns(sideIndex);
|
||||
pokemon.BattleData.Returns(battleData);
|
||||
choice.User.Returns(pokemon);
|
||||
|
||||
var moveData = Substitute.For<IMoveData>();
|
||||
moveData.Name.Returns(new StringKey(moveName));
|
||||
var learnedMove = Substitute.For<ILearnedMove>();
|
||||
learnedMove.MoveData.Returns(moveData);
|
||||
choice.ChosenMove.Returns(learnedMove);
|
||||
|
||||
var choiceVolatile = new ScriptSet(choice);
|
||||
choice.Volatile.Returns(choiceVolatile);
|
||||
return choice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a fully mocked test setup for Fire Pledge tests. The user is on side 0.
|
||||
/// </summary>
|
||||
private static (FirePledge script, IExecutingMove move, IMoveChoice ownChoice) CreateTestSetup(
|
||||
BattleChoiceQueue? queue)
|
||||
{
|
||||
var script = new FirePledge();
|
||||
var move = Substitute.For<IExecutingMove>();
|
||||
|
||||
var battle = Substitute.For<IBattle>();
|
||||
battle.ChoiceQueue.Returns(queue);
|
||||
move.Battle.Returns(battle);
|
||||
|
||||
var user = Substitute.For<IPokemon>();
|
||||
var userBattleData = Substitute.For<IPokemonBattleData>();
|
||||
userBattleData.SideIndex.Returns((byte)0);
|
||||
user.BattleData.Returns(userBattleData);
|
||||
move.User.Returns(user);
|
||||
|
||||
var ownChoice = CreateQueuedChoice("fire_pledge", 0);
|
||||
move.MoveChoice.Returns(ownChoice);
|
||||
|
||||
return (script, move, ownChoice);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "the ally moving first will not itself use a move".
|
||||
/// An ally on the same side still has Water Pledge queued, so this Fire Pledge is stopped.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task StopBeforeMove_AllyWaterPledgeQueued_StopsMove()
|
||||
{
|
||||
// Arrange
|
||||
var allyChoice = CreateQueuedChoice("water_pledge", 0);
|
||||
var (script, move, _) = CreateTestSetup(new BattleChoiceQueue([allyChoice]));
|
||||
var stop = false;
|
||||
|
||||
// Act
|
||||
script.StopBeforeMove(move, ref stop);
|
||||
|
||||
// Assert
|
||||
await Assert.That(stop).IsTrue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "If Fire Pledge and Water Pledge are used in the same turn, the ally moving second will
|
||||
/// use Water Pledge with a power of 150, and create a rainbow on the user's side of the field for four
|
||||
/// turns."
|
||||
/// The queued ally choice is marked with the <see cref="FireWaterPledgeMove"/> volatile that implements
|
||||
/// the combined move.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task StopBeforeMove_AllyWaterPledgeQueued_MarksAllyChoiceAsCombinedFireWaterPledge()
|
||||
{
|
||||
// Arrange
|
||||
var allyChoice = CreateQueuedChoice("water_pledge", 0);
|
||||
var (script, move, _) = CreateTestSetup(new BattleChoiceQueue([allyChoice]));
|
||||
var stop = false;
|
||||
|
||||
// Act
|
||||
script.StopBeforeMove(move, ref stop);
|
||||
|
||||
// Assert
|
||||
await Assert.That(allyChoice.Volatile.Contains<FireWaterPledgeMove>()).IsTrue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "the ally moving first will not itself use a move".
|
||||
/// An ally on the same side still has Grass Pledge queued, so this Fire Pledge is stopped.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task StopBeforeMove_AllyGrassPledgeQueued_StopsMove()
|
||||
{
|
||||
// Arrange
|
||||
var allyChoice = CreateQueuedChoice("grass_pledge", 0);
|
||||
var (script, move, _) = CreateTestSetup(new BattleChoiceQueue([allyChoice]));
|
||||
var stop = false;
|
||||
|
||||
// Act
|
||||
script.StopBeforeMove(move, ref stop);
|
||||
|
||||
// Assert
|
||||
await Assert.That(stop).IsTrue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "If Fire Pledge and Grass Pledge are used in the same turn, the ally moving second will
|
||||
/// use Fire Pledge with a power of 150, and create a sea of fire on the target's side of the field for
|
||||
/// four turns."
|
||||
/// The queued ally choice is marked with the <see cref="FireGrassPledgeMove"/> volatile that implements
|
||||
/// the combined move.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task StopBeforeMove_AllyGrassPledgeQueued_MarksAllyChoiceAsCombinedFireGrassPledge()
|
||||
{
|
||||
// Arrange
|
||||
var allyChoice = CreateQueuedChoice("grass_pledge", 0);
|
||||
var (script, move, _) = CreateTestSetup(new BattleChoiceQueue([allyChoice]));
|
||||
var stop = false;
|
||||
|
||||
// Act
|
||||
script.StopBeforeMove(move, ref stop);
|
||||
|
||||
// Assert
|
||||
await Assert.That(allyChoice.Volatile.Contains<FireGrassPledgeMove>()).IsTrue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: the combination only happens when allies use "Fire Pledge and either Water Pledge or
|
||||
/// Grass Pledge on the same turn".
|
||||
/// No Pledge move is queued by an ally, so Fire Pledge executes normally.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task StopBeforeMove_NoPledgeMoveQueued_DoesNotStop()
|
||||
{
|
||||
// Arrange
|
||||
var allyChoice = CreateQueuedChoice("tackle", 0);
|
||||
var (script, move, _) = CreateTestSetup(new BattleChoiceQueue([allyChoice]));
|
||||
var stop = false;
|
||||
|
||||
// Act
|
||||
script.StopBeforeMove(move, ref stop);
|
||||
|
||||
// Assert
|
||||
await Assert.That(stop).IsFalse();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "When two allies attempt to use Fire Pledge and either Water Pledge or Grass Pledge on
|
||||
/// the same turn" — a Pledge move queued by an opponent does not combine.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task StopBeforeMove_OpponentWaterPledgeQueued_DoesNotStop()
|
||||
{
|
||||
// Arrange
|
||||
var opponentChoice = CreateQueuedChoice("water_pledge", 1);
|
||||
var (script, move, _) = CreateTestSetup(new BattleChoiceQueue([opponentChoice]));
|
||||
var stop = false;
|
||||
|
||||
// Act
|
||||
script.StopBeforeMove(move, ref stop);
|
||||
|
||||
// Assert
|
||||
await Assert.That(stop).IsFalse();
|
||||
await Assert.That(opponentChoice.Volatile.Contains<FireWaterPledgeMove>()).IsFalse();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "the ally moving second will use Fire Pledge with a power of 150".
|
||||
/// When this Fire Pledge choice is itself the combined move of Grass Pledge and Fire Pledge (marked
|
||||
/// with <see cref="FireGrassPledgeMove"/>), it must execute instead of deferring again.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task StopBeforeMove_ChoiceIsCombinedFireGrassPledge_DoesNotStop()
|
||||
{
|
||||
// Arrange
|
||||
var allyChoice = CreateQueuedChoice("grass_pledge", 0);
|
||||
var (script, move, ownChoice) = CreateTestSetup(new BattleChoiceQueue([allyChoice]));
|
||||
ownChoice.Volatile.Add(new FireGrassPledgeMove());
|
||||
var stop = false;
|
||||
|
||||
// Act
|
||||
script.StopBeforeMove(move, ref stop);
|
||||
|
||||
// Assert
|
||||
await Assert.That(stop).IsFalse();
|
||||
await Assert.That(allyChoice.Volatile.Contains<FireGrassPledgeMove>()).IsFalse();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bulbapedia: "the ally moving second will use Water Pledge with a power of 150".
|
||||
/// When this choice is the combined move of Fire Pledge and Water Pledge (marked with
|
||||
/// <see cref="FireWaterPledgeMove"/>), it must execute instead of deferring again.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task StopBeforeMove_ChoiceIsCombinedFireWaterPledge_DoesNotStop()
|
||||
{
|
||||
// Arrange
|
||||
var allyChoice = CreateQueuedChoice("water_pledge", 0);
|
||||
var (script, move, ownChoice) = CreateTestSetup(new BattleChoiceQueue([allyChoice]));
|
||||
ownChoice.Volatile.Add(new FireWaterPledgeMove());
|
||||
var stop = false;
|
||||
|
||||
// Act
|
||||
script.StopBeforeMove(move, ref stop);
|
||||
|
||||
// Assert
|
||||
await Assert.That(stop).IsFalse();
|
||||
await Assert.That(allyChoice.Volatile.Contains<FireWaterPledgeMove>()).IsFalse();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Technical test: when the battle has no active choice queue, the move executes normally without
|
||||
/// throwing.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task StopBeforeMove_NullChoiceQueue_DoesNotStop()
|
||||
{
|
||||
// Arrange
|
||||
var (script, move, _) = CreateTestSetup(null);
|
||||
var stop = false;
|
||||
|
||||
// Act
|
||||
script.StopBeforeMove(move, ref stop);
|
||||
|
||||
// Assert
|
||||
await Assert.That(stop).IsFalse();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user