/ GUNRPG.Tests / AwarenessModelTests.cs
AwarenessModelTests.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 AwarenessModel - visibility and recognition mechanics. 9 /// </summary> 10 public class AwarenessModelTests 11 { 12 #region CanSeeTarget Tests 13 14 [Fact] 15 public void CanSeeTarget_NoCover_ReturnsTrue() 16 { 17 Assert.True(AwarenessModel.CanSeeTarget(CoverState.None)); 18 } 19 20 [Fact] 21 public void CanSeeTarget_PartialCover_ReturnsTrue() 22 { 23 Assert.True(AwarenessModel.CanSeeTarget(CoverState.Partial)); 24 } 25 26 [Fact] 27 public void CanSeeTarget_FullCover_ReturnsFalse() 28 { 29 Assert.False(AwarenessModel.CanSeeTarget(CoverState.Full)); 30 } 31 32 #endregion 33 34 #region GetVisibilityLevel Tests 35 36 [Fact] 37 public void GetVisibilityLevel_NoCover_ReturnsOne() 38 { 39 Assert.Equal(1.0f, AwarenessModel.GetVisibilityLevel(CoverState.None)); 40 } 41 42 [Fact] 43 public void GetVisibilityLevel_PartialCover_ReturnsHalf() 44 { 45 Assert.Equal(0.5f, AwarenessModel.GetVisibilityLevel(CoverState.Partial)); 46 } 47 48 [Fact] 49 public void GetVisibilityLevel_FullCover_ReturnsZero() 50 { 51 Assert.Equal(0.0f, AwarenessModel.GetVisibilityLevel(CoverState.Full)); 52 } 53 54 #endregion 55 56 #region Recognition Delay Tests 57 58 [Fact] 59 public void CalculateRecognitionDelayMs_HighProficiency_ReturnsLowDelay() 60 { 61 float delay = AwarenessModel.CalculateRecognitionDelayMs( 62 observerAccuracyProficiency: 1.0f, 63 observerSuppressionLevel: 0f); 64 65 // High proficiency should approach minimum delay 66 Assert.True(delay <= AwarenessModel.MinRecognitionDelayMs + 10f, 67 $"High proficiency should result in low delay. Got: {delay}ms"); 68 } 69 70 [Fact] 71 public void CalculateRecognitionDelayMs_LowProficiency_ReturnsHighDelay() 72 { 73 float delay = AwarenessModel.CalculateRecognitionDelayMs( 74 observerAccuracyProficiency: 0.0f, 75 observerSuppressionLevel: 0f); 76 77 // Low proficiency should result in base delay 78 Assert.True(delay >= AwarenessModel.BaseRecognitionDelayMs * 0.9f, 79 $"Low proficiency should result in high delay. Got: {delay}ms"); 80 } 81 82 [Fact] 83 public void CalculateRecognitionDelayMs_SuppressionIncreasesDelay() 84 { 85 float noSuppressionDelay = AwarenessModel.CalculateRecognitionDelayMs( 86 observerAccuracyProficiency: 0.5f, 87 observerSuppressionLevel: 0f); 88 89 float fullSuppressionDelay = AwarenessModel.CalculateRecognitionDelayMs( 90 observerAccuracyProficiency: 0.5f, 91 observerSuppressionLevel: 1.0f); 92 93 Assert.True(fullSuppressionDelay > noSuppressionDelay, 94 $"Suppression should increase delay. No suppression: {noSuppressionDelay}ms, Full suppression: {fullSuppressionDelay}ms"); 95 } 96 97 [Fact] 98 public void CalculateRecognitionDelayMs_ClampsToMinimum() 99 { 100 float delay = AwarenessModel.CalculateRecognitionDelayMs( 101 observerAccuracyProficiency: 1.0f, 102 observerSuppressionLevel: 0f); 103 104 Assert.True(delay >= AwarenessModel.MinRecognitionDelayMs, 105 $"Delay should be at least {AwarenessModel.MinRecognitionDelayMs}ms. Got: {delay}ms"); 106 } 107 108 [Fact] 109 public void CalculateRecognitionDelayMs_ClampsToMaximum() 110 { 111 float delay = AwarenessModel.CalculateRecognitionDelayMs( 112 observerAccuracyProficiency: 0.0f, 113 observerSuppressionLevel: 1.0f); 114 115 Assert.True(delay <= AwarenessModel.MaxRecognitionDelayMs, 116 $"Delay should be at most {AwarenessModel.MaxRecognitionDelayMs}ms. Got: {delay}ms"); 117 } 118 119 #endregion 120 121 #region Recognition Accuracy Multiplier Tests 122 123 [Fact] 124 public void GetRecognitionAccuracyMultiplier_ZeroProgress_ReturnsLowMultiplier() 125 { 126 float multiplier = AwarenessModel.GetRecognitionAccuracyMultiplier(0f); 127 128 Assert.Equal(AwarenessModel.RecognitionPenaltyAccuracyMultiplier, multiplier); 129 } 130 131 [Fact] 132 public void GetRecognitionAccuracyMultiplier_FullProgress_ReturnsOne() 133 { 134 float multiplier = AwarenessModel.GetRecognitionAccuracyMultiplier(1.0f); 135 136 Assert.Equal(1.0f, multiplier); 137 } 138 139 [Fact] 140 public void GetRecognitionAccuracyMultiplier_HalfProgress_ReturnsMidValue() 141 { 142 float multiplier = AwarenessModel.GetRecognitionAccuracyMultiplier(0.5f); 143 144 float expected = AwarenessModel.RecognitionPenaltyAccuracyMultiplier + 145 (1.0f - AwarenessModel.RecognitionPenaltyAccuracyMultiplier) * 0.5f; 146 147 Assert.Equal(expected, multiplier, precision: 3); 148 } 149 150 #endregion 151 }