using PkmnLib.Dynamic.Libraries; using PkmnLib.Dynamic.Models; using PkmnLib.Dynamic.ScriptHandling; using PkmnLib.Plugin.Gen7.Scripts.Battle; using PkmnLib.Plugin.Gen7.Scripts.Moves; using PkmnLib.Static; using PkmnLib.Static.Libraries; using PkmnLib.Static.Utils; namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves; /// /// Tests for the move. /// public class JudgementTests { public record TestCaseData(string? ItemName, string ExpectedTypeName) { public override string ToString() => $"Judgement {ItemName ?? "None"} => {ExpectedTypeName}"; } public static IEnumerable> ChangeMoveTypeData() { yield return () => new TestCaseData("draco_plate", "dragon"); yield return () => new TestCaseData("dread_plate", "dark"); yield return () => new TestCaseData("earth_plate", "ground"); yield return () => new TestCaseData("fist_plate", "fighting"); yield return () => new TestCaseData("flame_plate", "fire"); yield return () => new TestCaseData("icicle_plate", "ice"); yield return () => new TestCaseData("insect_plate", "bug"); yield return () => new TestCaseData("iron_plate", "steel"); yield return () => new TestCaseData("meadow_plate", "grass"); yield return () => new TestCaseData("mind_plate", "psychic"); yield return () => new TestCaseData("pixie_plate", "fairy"); yield return () => new TestCaseData("sky_plate", "flying"); yield return () => new TestCaseData("splash_plate", "water"); yield return () => new TestCaseData("spooky_plate", "ghost"); yield return () => new TestCaseData("stone_plate", "rock"); yield return () => new TestCaseData("toxic_plate", "poison"); yield return () => new TestCaseData("zap_plate", "electric"); } private static TypeLibrary CreateTypeLibrary() { var typeLibrary = new TypeLibrary(); typeLibrary.RegisterType("normal"); typeLibrary.RegisterType("fighting"); typeLibrary.RegisterType("flying"); typeLibrary.RegisterType("poison"); typeLibrary.RegisterType("ground"); typeLibrary.RegisterType("rock"); typeLibrary.RegisterType("bug"); typeLibrary.RegisterType("ghost"); typeLibrary.RegisterType("steel"); typeLibrary.RegisterType("fire"); typeLibrary.RegisterType("water"); typeLibrary.RegisterType("grass"); typeLibrary.RegisterType("electric"); typeLibrary.RegisterType("psychic"); typeLibrary.RegisterType("ice"); typeLibrary.RegisterType("dragon"); typeLibrary.RegisterType("dark"); typeLibrary.RegisterType("fairy"); return typeLibrary; } private static (Judgement Script, IExecutingMove Move, IPokemon Target) CreateTestSetup(string? itemName) { var move = Substitute.For(); var target = Substitute.For(); var user = Substitute.For(); var dynamicLibrary = Substitute.For(); var staticLibrary = Substitute.For(); target.Library.Returns(dynamicLibrary); dynamicLibrary.StaticLibrary.Returns(staticLibrary); staticLibrary.Types.Returns(CreateTypeLibrary()); move.User.Returns(user); if (itemName != null) { var item = Substitute.For(); item.Name.Returns(new StringKey(itemName)); user.HeldItem.Returns(item); } else { user.HeldItem.Returns((IItem?)null); } return (new Judgement(), move, target); } /// /// Bulbapedia: "The type of Judgment depends on the type of Plate held by the user". /// [Test, MethodDataSource(nameof(ChangeMoveTypeData))] public async Task ChangeMoveType_UserHoldingPlate_ChangesMoveType(TestCaseData test) { // Arrange var (script, move, target) = CreateTestSetup(test.ItemName); TypeIdentifier? typeIdentifier = new TypeIdentifier(1, "normal"); // Act script.ChangeMoveType(move, target, 0, ref typeIdentifier); // Assert await Assert.That(typeIdentifier!.Value.Name.ToString()).IsEqualTo(test.ExpectedTypeName); } /// /// Bulbapedia: "being Normal-type if there is no held Plate". Without a held item the move type /// is left unchanged. /// [Test] public async Task ChangeMoveType_UserNotHoldingItem_MoveTypeUnchanged() { // Arrange var (script, move, target) = CreateTestSetup(null); TypeIdentifier? typeIdentifier = new TypeIdentifier(1, "normal"); // Act script.ChangeMoveType(move, target, 0, ref typeIdentifier); // Assert await Assert.That(typeIdentifier!.Value.Name.ToString()).IsEqualTo("normal"); } /// /// Bulbapedia: "being Normal-type if there is no held Plate". A held item that is not a Plate /// leaves the move type unchanged. /// [Test] public async Task ChangeMoveType_UserHoldingNonPlateItem_MoveTypeUnchanged() { // Arrange var (script, move, target) = CreateTestSetup("oran_berry"); TypeIdentifier? typeIdentifier = new TypeIdentifier(1, "normal"); // Act script.ChangeMoveType(move, target, 0, ref typeIdentifier); // Assert await Assert.That(typeIdentifier!.Value.Name.ToString()).IsEqualTo("normal"); } /// /// Bulbapedia: "Judgment's type is unaffected by Z-Crystals held by the user, remaining a /// Normal-type move." /// [Test] public async Task ChangeMoveType_UserHoldingZCrystal_MoveTypeRemainsNormal() { // Arrange var (script, move, target) = CreateTestSetup("firium_z"); TypeIdentifier? typeIdentifier = new TypeIdentifier(1, "normal"); // Act script.ChangeMoveType(move, target, 0, ref typeIdentifier); // Assert await Assert.That(typeIdentifier!.Value.Name.ToString()).IsEqualTo("normal"); } /// /// Bulbapedia: "If Magic Room is in effect, Judgment's type will always be Normal regardless of /// the Plate held." With on the battle, a held Plate must not /// change the move type. /// [Test] public async Task ChangeMoveType_MagicRoomInEffect_MoveTypeRemainsNormal() { // Arrange var (script, move, target) = CreateTestSetup("flame_plate"); var battle = Substitute.For(); battle.GetScripts().Returns(_ => new ScriptIterator(new List>())); var battleVolatile = new ScriptSet(battle); battleVolatile.Add(new MagicRoomEffect()); battle.Volatile.Returns(battleVolatile); move.Battle.Returns(battle); TypeIdentifier? typeIdentifier = new TypeIdentifier(1, "normal"); // Act script.ChangeMoveType(move, target, 0, ref typeIdentifier); // Assert await Assert.That(typeIdentifier!.Value.Name.ToString()).IsEqualTo("normal"); } }