using PkmnLib.Dynamic.Models; using PkmnLib.Static; using PkmnLib.Static.Species; using PkmnLib.Tests.Integration; namespace PkmnLib.Tests.Dynamic; public class PokemonStatBoostTests { private static IBattlePokemon CreatePokemon() { var library = LibraryHelpers.LoadLibrary(); if (!library.StaticLibrary.Species.TryGet("bulbasaur", out var species)) throw new InvalidOperationException("Failed to load bulbasaur species."); var pokemon = new PokemonImpl(library, species, species.GetDefaultForm(), new AbilityIndex { Index = 0, IsHidden = false, }, 50, 0, Gender.Male, 0, "hardy"); var party = new PokemonPartyImpl(1); party.SwapInto(pokemon, 0); var opponentParty = new PokemonPartyImpl(1); opponentParty.SwapInto(new PokemonImpl(library, species, species.GetDefaultForm(), new AbilityIndex { Index = 0, IsHidden = false, }, 50, 0, Gender.Male, 0, "hardy"), 0); var parties = new[] { new BattlePartyImpl(party, [new ResponsibleIndex(0, 0)]), new BattlePartyImpl(opponentParty, [new ResponsibleIndex(1, 0)]), }; var battle = new BattleImpl(library, parties, false, 2, 1, false, "grass", 0); return battle.Parties[0].GetBattlePokemon(pokemon)!; } [Test] public async Task ChangeStatBoost_IncreasesStatBoost() { var pokemon = CreatePokemon(); var changed = pokemon.ChangeStatBoost(Statistic.Attack, 2, true, false); await Assert.That(changed).IsTrue(); await Assert.That(pokemon.StatBoost.Attack).IsEqualTo((sbyte)2); } [Test] public async Task ChangeStatBoost_DecreasesStatBoost() { var pokemon = CreatePokemon(); var changed = pokemon.ChangeStatBoost(Statistic.Attack, -2, true, false); await Assert.That(changed).IsTrue(); await Assert.That(pokemon.StatBoost.Attack).IsEqualTo((sbyte)-2); } [Test] public async Task ChangeStatBoost_ReturnsFalseWhenChangeIsZero() { var pokemon = CreatePokemon(); var changed = pokemon.ChangeStatBoost(Statistic.Attack, 0, true, false); await Assert.That(changed).IsFalse(); await Assert.That(pokemon.StatBoost.Attack).IsEqualTo((sbyte)0); } [Test] public async Task ChangeStatBoost_ReturnsFalseWhenMaxCapReached() { var pokemon = CreatePokemon(); // Raise the stat boost all the way to the maximum of +6. var raised = pokemon.ChangeStatBoost(Statistic.Attack, StatBoostStatisticSet.MaxStatBoost, true, false); await Assert.That(raised).IsTrue(); await Assert.That(pokemon.StatBoost.Attack).IsEqualTo(StatBoostStatisticSet.MaxStatBoost); // The cap has been reached, so a further increase should do nothing and report failure. var changed = pokemon.ChangeStatBoost(Statistic.Attack, 1, true, false); await Assert.That(changed).IsFalse(); await Assert.That(pokemon.StatBoost.Attack).IsEqualTo(StatBoostStatisticSet.MaxStatBoost); } [Test] public async Task ChangeStatBoost_ReturnsFalseWhenMinCapReached() { var pokemon = CreatePokemon(); // Lower the stat boost all the way to the minimum of -6. var lowered = pokemon.ChangeStatBoost(Statistic.Attack, StatBoostStatisticSet.MinStatBoost, true, false); await Assert.That(lowered).IsTrue(); await Assert.That(pokemon.StatBoost.Attack).IsEqualTo(StatBoostStatisticSet.MinStatBoost); // The floor has been reached, so a further decrease should do nothing and report failure. var changed = pokemon.ChangeStatBoost(Statistic.Attack, -1, true, false); await Assert.That(changed).IsFalse(); await Assert.That(pokemon.StatBoost.Attack).IsEqualTo(StatBoostStatisticSet.MinStatBoost); } [Test] public async Task ChangeStatBoost_ClampsToCapButStillReportsChangeWhenPartiallyApplied() { var pokemon = CreatePokemon(); // Raise to +5, one below the cap. await Assert.That(pokemon.ChangeStatBoost(Statistic.Attack, 5, true, false)).IsTrue(); await Assert.That(pokemon.StatBoost.Attack).IsEqualTo((sbyte)5); // Asking for +4 can only apply +1 before hitting the cap. Since a change is still made, it reports success. var changed = pokemon.ChangeStatBoost(Statistic.Attack, 4, true, false); await Assert.That(changed).IsTrue(); await Assert.That(pokemon.StatBoost.Attack).IsEqualTo(StatBoostStatisticSet.MaxStatBoost); } }