/ GUNRPG.Tests / CoverTransitionModelTests.cs
CoverTransitionModelTests.cs
  1  using GUNRPG.Core.Combat;
  2  using GUNRPG.Core.Operators;
  3  using Xunit;
  4  
  5  namespace GUNRPG.Tests;
  6  
  7  /// <summary>
  8  /// Unit tests for the CoverTransitionModel - cover transition delays and exposure windows.
  9  /// </summary>
 10  public class CoverTransitionModelTests
 11  {
 12      #region Transition Delay Tests
 13  
 14      [Fact]
 15      public void GetTransitionDelayMs_SameState_ReturnsZero()
 16      {
 17          Assert.Equal(0, CoverTransitionModel.GetTransitionDelayMs(CoverState.None, CoverState.None));
 18          Assert.Equal(0, CoverTransitionModel.GetTransitionDelayMs(CoverState.Partial, CoverState.Partial));
 19          Assert.Equal(0, CoverTransitionModel.GetTransitionDelayMs(CoverState.Full, CoverState.Full));
 20      }
 21  
 22      [Fact]
 23      public void GetTransitionDelayMs_NoneToPartial_ReturnsConfiguredDelay()
 24      {
 25          int delay = CoverTransitionModel.GetTransitionDelayMs(CoverState.None, CoverState.Partial);
 26          Assert.Equal(CoverTransitionModel.NoneToPartialDelayMs, delay);
 27      }
 28  
 29      [Fact]
 30      public void GetTransitionDelayMs_PartialToFull_ReturnsConfiguredDelay()
 31      {
 32          int delay = CoverTransitionModel.GetTransitionDelayMs(CoverState.Partial, CoverState.Full);
 33          Assert.Equal(CoverTransitionModel.PartialToFullDelayMs, delay);
 34      }
 35  
 36      [Fact]
 37      public void GetTransitionDelayMs_FullToPartial_ReturnsConfiguredDelay()
 38      {
 39          int delay = CoverTransitionModel.GetTransitionDelayMs(CoverState.Full, CoverState.Partial);
 40          Assert.Equal(CoverTransitionModel.FullToPartialDelayMs, delay);
 41      }
 42  
 43      [Fact]
 44      public void GetTransitionDelayMs_PartialToNone_ReturnsConfiguredDelay()
 45      {
 46          int delay = CoverTransitionModel.GetTransitionDelayMs(CoverState.Partial, CoverState.None);
 47          Assert.Equal(CoverTransitionModel.PartialToNoneDelayMs, delay);
 48      }
 49  
 50      [Fact]
 51      public void GetTransitionDelayMs_NoneToFull_ReturnsCombinedDelay()
 52      {
 53          int delay = CoverTransitionModel.GetTransitionDelayMs(CoverState.None, CoverState.Full);
 54          Assert.Equal(CoverTransitionModel.NoneToFullDelayMs, delay);
 55          Assert.Equal(CoverTransitionModel.NoneToPartialDelayMs + CoverTransitionModel.PartialToFullDelayMs, delay);
 56      }
 57  
 58      [Fact]
 59      public void GetTransitionDelayMs_FullToNone_ReturnsCombinedDelay()
 60      {
 61          int delay = CoverTransitionModel.GetTransitionDelayMs(CoverState.Full, CoverState.None);
 62          Assert.Equal(CoverTransitionModel.FullToNoneDelayMs, delay);
 63          Assert.Equal(CoverTransitionModel.FullToPartialDelayMs + CoverTransitionModel.PartialToNoneDelayMs, delay);
 64      }
 65  
 66      [Fact]
 67      public void GetTransitionDelayMs_ExitingFullCoverTakesLonger()
 68      {
 69          int fullToPartial = CoverTransitionModel.GetTransitionDelayMs(CoverState.Full, CoverState.Partial);
 70          int partialToFull = CoverTransitionModel.GetTransitionDelayMs(CoverState.Partial, CoverState.Full);
 71  
 72          Assert.True(fullToPartial >= partialToFull,
 73              $"Exiting full cover ({fullToPartial}ms) should take at least as long as entering ({partialToFull}ms)");
 74      }
 75  
 76      #endregion
 77  
 78      #region Delay Range Validation
 79  
 80      [Fact]
 81      public void TransitionDelays_AreWithinRealisticRange()
 82      {
 83          // All delays should be between 80ms and 250ms as per design
 84          Assert.InRange(CoverTransitionModel.NoneToPartialDelayMs, 80, 250);
 85          Assert.InRange(CoverTransitionModel.PartialToFullDelayMs, 80, 250);
 86          Assert.InRange(CoverTransitionModel.FullToPartialDelayMs, 80, 250);
 87          Assert.InRange(CoverTransitionModel.PartialToNoneDelayMs, 80, 250);
 88      }
 89  
 90      [Fact]
 91      public void MultiStepTransitionDelays_AreSumOfComponents()
 92      {
 93          Assert.Equal(
 94              CoverTransitionModel.NoneToPartialDelayMs + CoverTransitionModel.PartialToFullDelayMs,
 95              CoverTransitionModel.NoneToFullDelayMs);
 96  
 97          Assert.Equal(
 98              CoverTransitionModel.FullToPartialDelayMs + CoverTransitionModel.PartialToNoneDelayMs,
 99              CoverTransitionModel.FullToNoneDelayMs);
100      }
101  
102      [Fact]
103      public void CombinedTransitionDelays_AreWithinReasonableRange()
104      {
105          // Combined delays (multi-step transitions) should be reasonable
106          // NoneToFull and FullToNone go through intermediate state, so they're longer
107          // Expected range: 160ms to 500ms for combined transitions
108          Assert.InRange(CoverTransitionModel.NoneToFullDelayMs, 160, 500);
109          Assert.InRange(CoverTransitionModel.FullToNoneDelayMs, 160, 500);
110      }
111  
112      #endregion
113  }