/ GUNRPG.Tests / OperatorStatusRendererTests.cs
OperatorStatusRendererTests.cs
  1  using GUNRPG.Core.Rendering;
  2  using GUNRPG.Core.VirtualPet;
  3  using System.Text;
  4  using Xunit;
  5  
  6  namespace GUNRPG.Tests;
  7  
  8  public class OperatorStatusRendererTests
  9  {
 10      [Fact]
 11      public void Render_OutputsAllPhysicalStats()
 12      {
 13          // Arrange
 14          var view = new OperatorStatusView(
 15              Health: 75.0f,
 16              Injury: 10.0f,
 17              Fatigue: 30.0f,
 18              Stress: 40.0f,
 19              Morale: 80.0f,
 20              Hunger: 25.0f,
 21              Hydration: 60.0f,
 22              CombatReadiness: null
 23          );
 24  
 25          var output = new StringBuilder();
 26          using var writer = new StringWriter(output);
 27          var originalOut = Console.Out;
 28          Console.SetOut(writer);
 29  
 30          try
 31          {
 32              // Act
 33              OperatorStatusRenderer.Render(view);
 34              var result = output.ToString();
 35  
 36              // Assert
 37              Assert.Contains("PHYSICAL", result);
 38              Assert.Contains("Health:   75", result);
 39              Assert.Contains("Injury:   10", result);
 40              Assert.Contains("Fatigue:  30", result);
 41          }
 42          finally
 43          {
 44              Console.SetOut(originalOut);
 45          }
 46      }
 47  
 48      [Fact]
 49      public void Render_OutputsAllMentalStats()
 50      {
 51          // Arrange
 52          var view = new OperatorStatusView(
 53              Health: 100.0f,
 54              Injury: 0.0f,
 55              Fatigue: 0.0f,
 56              Stress: 45.0f,
 57              Morale: 85.0f,
 58              Hunger: 0.0f,
 59              Hydration: 100.0f,
 60              CombatReadiness: null
 61          );
 62  
 63          var output = new StringBuilder();
 64          using var writer = new StringWriter(output);
 65          var originalOut = Console.Out;
 66          Console.SetOut(writer);
 67  
 68          try
 69          {
 70              // Act
 71              OperatorStatusRenderer.Render(view);
 72              var result = output.ToString();
 73  
 74              // Assert
 75              Assert.Contains("MENTAL", result);
 76              Assert.Contains("Stress:   45", result);
 77              Assert.Contains("Morale:   85", result);
 78          }
 79          finally
 80          {
 81              Console.SetOut(originalOut);
 82          }
 83      }
 84  
 85      [Fact]
 86      public void Render_OutputsAllCareStats()
 87      {
 88          // Arrange
 89          var view = new OperatorStatusView(
 90              Health: 100.0f,
 91              Injury: 0.0f,
 92              Fatigue: 0.0f,
 93              Stress: 0.0f,
 94              Morale: 100.0f,
 95              Hunger: 35.0f,
 96              Hydration: 65.0f,
 97              CombatReadiness: null
 98          );
 99  
100          var output = new StringBuilder();
101          using var writer = new StringWriter(output);
102          var originalOut = Console.Out;
103          Console.SetOut(writer);
104  
105          try
106          {
107              // Act
108              OperatorStatusRenderer.Render(view);
109              var result = output.ToString();
110  
111              // Assert
112              Assert.Contains("CARE", result);
113              Assert.Contains("Hunger:     35", result);
114              Assert.Contains("Hydration:  65", result);
115          }
116          finally
117          {
118              Console.SetOut(originalOut);
119          }
120      }
121  
122      [Fact]
123      public void Render_ShowsCombatReadiness_WhenPresent()
124      {
125          // Arrange
126          var view = new OperatorStatusView(
127              Health: 100.0f,
128              Injury: 0.0f,
129              Fatigue: 0.0f,
130              Stress: 0.0f,
131              Morale: 100.0f,
132              Hunger: 0.0f,
133              Hydration: 100.0f,
134              CombatReadiness: 92.0f
135          );
136  
137          var output = new StringBuilder();
138          using var writer = new StringWriter(output);
139          var originalOut = Console.Out;
140          Console.SetOut(writer);
141  
142          try
143          {
144              // Act
145              OperatorStatusRenderer.Render(view);
146              var result = output.ToString();
147  
148              // Assert
149              Assert.Contains("DERIVED", result);
150              Assert.Contains("Combat Readiness:  92", result);
151          }
152          finally
153          {
154              Console.SetOut(originalOut);
155          }
156      }
157  
158      [Fact]
159      public void Render_HidesCombatReadiness_WhenNull()
160      {
161          // Arrange
162          var view = new OperatorStatusView(
163              Health: 100.0f,
164              Injury: 0.0f,
165              Fatigue: 0.0f,
166              Stress: 0.0f,
167              Morale: 100.0f,
168              Hunger: 0.0f,
169              Hydration: 100.0f,
170              CombatReadiness: null
171          );
172  
173          var output = new StringBuilder();
174          using var writer = new StringWriter(output);
175          var originalOut = Console.Out;
176          Console.SetOut(writer);
177  
178          try
179          {
180              // Act
181              OperatorStatusRenderer.Render(view);
182              var result = output.ToString();
183  
184              // Assert
185              Assert.DoesNotContain("DERIVED", result);
186              Assert.DoesNotContain("Combat Readiness", result);
187          }
188          finally
189          {
190              Console.SetOut(originalOut);
191          }
192      }
193  
194      [Fact]
195      public void Render_FormatsValuesWithNoDecimals()
196      {
197          // Arrange
198          var view = new OperatorStatusView(
199              Health: 75.7f,
200              Injury: 10.3f,
201              Fatigue: 30.9f,
202              Stress: 40.2f,
203              Morale: 80.8f,
204              Hunger: 25.1f,
205              Hydration: 60.6f,
206              CombatReadiness: null
207          );
208  
209          var output = new StringBuilder();
210          using var writer = new StringWriter(output);
211          var originalOut = Console.Out;
212          Console.SetOut(writer);
213  
214          try
215          {
216              // Act
217              OperatorStatusRenderer.Render(view);
218              var result = output.ToString();
219  
220              // Assert - Values should be rounded to whole numbers
221              Assert.Contains("Health:   76", result);
222              Assert.Contains("Injury:   10", result);
223              Assert.Contains("Fatigue:  31", result);
224              Assert.Contains("Stress:   40", result);
225              Assert.Contains("Morale:   81", result);
226              Assert.Contains("Hunger:     25", result);
227              Assert.Contains("Hydration:  61", result);
228          }
229          finally
230          {
231              Console.SetOut(originalOut);
232          }
233      }
234  
235      [Fact]
236      public void Render_IncludesASCIISeparators()
237      {
238          // Arrange
239          var view = new OperatorStatusView(
240              Health: 50.0f,
241              Injury: 50.0f,
242              Fatigue: 50.0f,
243              Stress: 50.0f,
244              Morale: 50.0f,
245              Hunger: 50.0f,
246              Hydration: 50.0f,
247              CombatReadiness: null
248          );
249  
250          var output = new StringBuilder();
251          using var writer = new StringWriter(output);
252          var originalOut = Console.Out;
253          Console.SetOut(writer);
254  
255          try
256          {
257              // Act
258              OperatorStatusRenderer.Render(view);
259              var result = output.ToString();
260  
261              // Assert - Check for ASCII separators with context
262              Assert.Contains("================================================================================", result);
263              Assert.Contains("OPERATOR STATUS", result);
264              Assert.Contains($"PHYSICAL{Environment.NewLine}--------", result);
265              Assert.Contains($"MENTAL{Environment.NewLine}------", result);
266              Assert.Contains($"CARE{Environment.NewLine}----", result);
267          }
268          finally
269          {
270              Console.SetOut(originalOut);
271          }
272      }
273  
274      [Fact]
275      public void Render_HandlesMinimumValues()
276      {
277          // Arrange
278          var view = new OperatorStatusView(
279              Health: 0.0f,
280              Injury: 0.0f,
281              Fatigue: 0.0f,
282              Stress: 0.0f,
283              Morale: 0.0f,
284              Hunger: 0.0f,
285              Hydration: 0.0f,
286              CombatReadiness: null
287          );
288  
289          var output = new StringBuilder();
290          using var writer = new StringWriter(output);
291          var originalOut = Console.Out;
292          Console.SetOut(writer);
293  
294          try
295          {
296              // Act
297              OperatorStatusRenderer.Render(view);
298              var result = output.ToString();
299  
300              // Assert - All values should be 0
301              // Note: Spacing varies by label length to accommodate right-aligned 3-digit formatting
302              // Format: "Label: " + "{value,3:F0}" where value,3 right-aligns in 3 chars
303              Assert.Contains("Health:    0", result);    // "  0" (2 spaces before 0)
304              Assert.Contains("Injury:    0", result);    // "  0" (2 spaces before 0)
305              Assert.Contains("Fatigue:   0", result);    // "  0" (2 spaces before 0)
306              Assert.Contains("Stress:    0", result);    // "  0" (2 spaces before 0)
307              Assert.Contains("Morale:    0", result);    // "  0" (2 spaces before 0)
308              Assert.Contains("Hunger:      0", result);  // "  0" (2 spaces before 0, 4 after colon)
309              Assert.Contains("Hydration:   0", result);  // "  0" (2 spaces before 0, 1 after colon)
310          }
311          finally
312          {
313              Console.SetOut(originalOut);
314          }
315      }
316  
317      [Fact]
318      public void Render_HandlesMaximumValues()
319      {
320          // Arrange
321          var view = new OperatorStatusView(
322              Health: 100.0f,
323              Injury: 100.0f,
324              Fatigue: 100.0f,
325              Stress: 100.0f,
326              Morale: 100.0f,
327              Hunger: 100.0f,
328              Hydration: 100.0f,
329              CombatReadiness: 100.0f
330          );
331  
332          var output = new StringBuilder();
333          using var writer = new StringWriter(output);
334          var originalOut = Console.Out;
335          Console.SetOut(writer);
336  
337          try
338          {
339              // Act
340              OperatorStatusRenderer.Render(view);
341              var result = output.ToString();
342  
343              // Assert - All values should be 100
344              Assert.Contains("Health:  100", result);
345              Assert.Contains("Injury:  100", result);
346              Assert.Contains("Fatigue: 100", result);
347              Assert.Contains("Stress:  100", result);
348              Assert.Contains("Morale:  100", result);
349              Assert.Contains("Hunger:    100", result);
350              Assert.Contains("Hydration: 100", result);
351              Assert.Contains("Combat Readiness: 100", result);
352          }
353          finally
354          {
355              Console.SetOut(originalOut);
356          }
357      }
358  }