using PkmnLib.Dynamic.Models; using PkmnLib.Dynamic.Models.Choices; using PkmnLib.Dynamic.ScriptHandling; using PkmnLib.Dynamic.ScriptHandling.Registry; using PkmnLib.Plugin.Gen7.Scripts.Moves; using PkmnLib.Plugin.Gen7.Scripts.Pokemon; namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves; /// /// Tests for the move script. /// Gen VII Bulbapedia behavior: "Block prevents the target from switching out or fleeing (including via /// Teleport)." From Generation VI onward: "Block no longer affects Ghost-type Pokémon." /// public class BlockTests { private static (Block script, IExecutingMove move, IPokemon target, ScriptSet targetVolatile) CreateTestSetup() { var script = new Block(); var move = Substitute.For(); var user = Substitute.For(); move.User.Returns(user); var target = Substitute.For(); // Use a real script set so the volatile script added by Block can be inspected afterwards. var targetVolatile = new ScriptSet(target); target.Volatile.Returns(targetVolatile); target.GetScripts().Returns(_ => new ScriptIterator(new List>())); move.GetHitData(target, 0).Returns(Substitute.For()); return (script, move, target, targetVolatile); } /// /// Bulbapedia: "Block prevents the target from switching out or fleeing (including via Teleport)." /// Hitting the target attaches the volatile script to it. /// [Test] public async Task OnSecondaryEffect_Hit_AddsBlockEffectToTarget() { // Arrange var (script, move, target, targetVolatile) = CreateTestSetup(); // Act script.OnSecondaryEffect(move, target, 0); // Assert await Assert.That(targetVolatile.Contains(ScriptUtils.ResolveName())).IsTrue(); } /// /// Bulbapedia: "Block prevents the target from switching out". /// The applied by the move prevents the target's switch choices through /// . /// [Test] public async Task OnSecondaryEffect_AppliedEffect_PreventsTargetFromSwitchingOut() { // Arrange var (script, move, target, targetVolatile) = CreateTestSetup(); script.OnSecondaryEffect(move, target, 0); await Assert.That(targetVolatile.TryGet(out var effect)).IsTrue(); // Act var prevent = false; effect!.PreventSelfSwitch(Substitute.For(), ref prevent); // Assert await Assert.That(prevent).IsTrue(); } /// /// Bulbapedia: "Block prevents the target from [...] fleeing (including via Teleport)." /// The applied by the move prevents the target's flee choices through /// . /// [Test] public async Task OnSecondaryEffect_AppliedEffect_PreventsTargetFromFleeing() { // Arrange var (script, move, target, targetVolatile) = CreateTestSetup(); script.OnSecondaryEffect(move, target, 0); await Assert.That(targetVolatile.TryGet(out var effect)).IsTrue(); // Act var prevent = false; effect!.PreventSelfRunAway(Substitute.For(), ref prevent); // Assert await Assert.That(prevent).IsTrue(); } /// /// Bulbapedia (Generation VI onward): "Block no longer affects Ghost-type Pokémon." /// Using Block on a Ghost-type target should not trap it, so no may be added. /// [Test] public async Task OnSecondaryEffect_GhostTypeTarget_DoesNotTrapTarget() { // Arrange var (script, move, target, targetVolatile) = CreateTestSetup(); var library = LibraryHelpers.LoadLibrary(); await Assert.That(library.StaticLibrary.Types.TryGetTypeIdentifier("ghost", out var ghostType)).IsTrue(); target.Types.Returns(new[] { ghostType }); var battle = Substitute.For(); battle.Library.Returns(library); var battleData = Substitute.For(); battleData.Battle.Returns(battle); move.User.BattleData.Returns(battleData); target.BattleData.Returns(battleData); // Act script.OnSecondaryEffect(move, target, 0); // Assert await Assert.That(targetVolatile.Contains(ScriptUtils.ResolveName())).IsFalse(); } }