using System.Collections.Immutable; using SideScrollerGame.Sim.Input; using SideScrollerGame.Sim.Math; using SideScrollerGame.Sim.Runtime; namespace SideScrollerGame.Sim.Tests; public sealed class SimulationStateTests { [Fact] public void PlayerState_CloneAndButtonReleasePreserveIndependentState() { PlayerState player = new(new(1), new(3, 4), 1, 2, 5, 6, 7, 0, 9, FixPoint16.One, true, 3, 4); player.SetButton(InputButton.Dash, true); player.ApplyDamage(4); player.BufferJump(6); var clone = player.Clone(); player.SetButton(InputButton.Dash, false); player.SetPosition(new(8, 9)); player.SetVerticalVelocity(new(5)); Assert.NotEqual(player.ButtonMask, clone.ButtonMask); Assert.Equal(7, clone.SelectedWeaponSlot); Assert.Equal(3, clone.Position.m_X.ToIntRound()); Assert.Equal(4, clone.Position.m_Y.ToIntRound()); Assert.Equal(5, clone.Health); Assert.Equal(1, clone.VerticalVelocity.ToIntRound()); Assert.True(clone.IsGrounded); Assert.Equal(3, clone.LastGroundedTick); Assert.Equal(6, clone.BufferedJumpTick); } [Fact] public void SimulationState_CloneCreatesDeepCopy() { SimulationState original = new(4, 9, 123UL, 456UL, ImmutableArray.Create(new PlayerState(new(1), new(1, 2), 3, 4, 5, 6, 7, 8, 9, new(2), true, 4, -1)), ImmutableHashSet.Empty.Add("checkpoint_a")); var clone = original.Clone(); original.GetRequiredPlayer(new(1)).SetMoveAxis(9, 9); original.ActivateTrigger("checkpoint_b"); Assert.Equal(4, clone.Tick); Assert.Equal(9, clone.Seed); Assert.Equal((ulong)123, clone.RandomState); Assert.Equal((ulong)456, clone.LastRandomValue); Assert.Equal(3, clone.GetRequiredPlayer(new(1)).MoveAxisX); Assert.Equal(2, clone.GetRequiredPlayer(new(1)).VerticalVelocity.ToIntRound()); Assert.DoesNotContain("checkpoint_b", clone.ActivatedTriggerIds); } [Fact] public void SimulationState_AcceptsDefaultPlayerArray() { SimulationState state = new(0, 1, 1UL, 0UL, default, ImmutableHashSet.Empty); Assert.Empty(state.Players); Assert.Empty(state.ActivatedTriggerIds); } [Fact] public void SimulationState_AcceptsDefaultTriggerSet() { SimulationState state = new(0, 1, 1UL, 0UL, ImmutableArray.Empty, default!); Assert.Empty(state.ActivatedTriggerIds); } [Fact] public void ActivateTrigger_ReturnsFalseWhenRepeated() { SimulationState state = new(0, 1, 1UL, 0UL, ImmutableArray.Empty, ImmutableHashSet.Empty); Assert.True(state.ActivateTrigger("checkpoint_a")); Assert.False(state.ActivateTrigger("checkpoint_a")); } [Fact] public void PlayerState_BufferedJumpExpiresOutsideWindow() { PlayerState player = new(new(1), new(0, 0), 0, 0, 0, 0, 0, 0, 10, FixPoint16.Zero, false, -1, -1); player.BufferJump(3); Assert.True(player.HasBufferedJump(4, 1)); Assert.False(player.HasBufferedJump(5, 1)); player.ConsumeBufferedJump(); Assert.False(player.HasBufferedJump(5, 5)); } }