DeviceStateMachineTests.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. using Xunit;
  2. using YZWater.Core.Services;
  3. namespace YZWater.Core.Tests.Services;
  4. /// <summary>
  5. /// DeviceStateMachine 单元测试
  6. /// </summary>
  7. public class DeviceStateMachineTests
  8. {
  9. [Fact]
  10. public void InitialState_ShouldBeStopped()
  11. {
  12. var sm = new DeviceStateMachine("P001", "泵1");
  13. Assert.Equal(DeviceStateMachine.DeviceState.Stopped, sm.CurrentState);
  14. }
  15. [Fact]
  16. public void Start_ShouldTransitionToRunning()
  17. {
  18. var sm = new DeviceStateMachine("P001", "泵1");
  19. sm.Start();
  20. Assert.Equal(DeviceStateMachine.DeviceState.Running, sm.CurrentState);
  21. }
  22. [Fact]
  23. public void Stop_FromRunning_ShouldTransitionToStopped()
  24. {
  25. var sm = new DeviceStateMachine("P001", "泵1");
  26. sm.Start();
  27. sm.Stop();
  28. Assert.Equal(DeviceStateMachine.DeviceState.Stopped, sm.CurrentState);
  29. }
  30. [Fact]
  31. public void ReportFault_ShouldTransitionToFault()
  32. {
  33. var sm = new DeviceStateMachine("P001", "泵1");
  34. sm.Start();
  35. sm.ReportFault();
  36. Assert.Equal(DeviceStateMachine.DeviceState.Fault, sm.CurrentState);
  37. }
  38. [Fact]
  39. public void Recover_FromFault_ShouldTransitionToStopped()
  40. {
  41. var sm = new DeviceStateMachine("P001", "泵1");
  42. sm.Start();
  43. sm.ReportFault();
  44. sm.Recover();
  45. Assert.Equal(DeviceStateMachine.DeviceState.Stopped, sm.CurrentState);
  46. }
  47. [Fact]
  48. public void FaultCannotDirectlyTransitionToRunning()
  49. {
  50. var sm = new DeviceStateMachine("P001", "泵1");
  51. sm.ReportFault();
  52. var canStart = sm.CanFire(DeviceStateMachine.DeviceTrigger.Start);
  53. Assert.False(canStart);
  54. }
  55. [Fact]
  56. public void TryFire_InvalidTransition_ShouldReturnFalse()
  57. {
  58. var sm = new DeviceStateMachine("P001", "泵1");
  59. // 从 Stopped 不能直接 Stop
  60. var result = sm.TryFire(DeviceStateMachine.DeviceTrigger.Stop);
  61. Assert.False(result);
  62. Assert.Equal(DeviceStateMachine.DeviceState.Stopped, sm.CurrentState);
  63. }
  64. [Fact]
  65. public void StateChanged_EventShouldFire()
  66. {
  67. var sm = new DeviceStateMachine("P001", "泵1");
  68. var eventFired = false;
  69. DeviceStateMachine.DeviceState? fromState = null;
  70. DeviceStateMachine.DeviceState? toState = null;
  71. sm.StateChanged += (id, from, to) =>
  72. {
  73. eventFired = true;
  74. fromState = from;
  75. toState = to;
  76. };
  77. sm.Start();
  78. Assert.True(eventFired);
  79. Assert.Equal(DeviceStateMachine.DeviceState.Stopped, fromState);
  80. Assert.Equal(DeviceStateMachine.DeviceState.Running, toState);
  81. }
  82. [Fact]
  83. public void BeginMaintenance_ShouldTransitionToMaintenance()
  84. {
  85. var sm = new DeviceStateMachine("P001", "泵1");
  86. sm.BeginMaintenance();
  87. Assert.Equal(DeviceStateMachine.DeviceState.Maintenance, sm.CurrentState);
  88. }
  89. [Fact]
  90. public void CompleteMaintenance_ShouldTransitionToStopped()
  91. {
  92. var sm = new DeviceStateMachine("P001", "泵1");
  93. sm.BeginMaintenance();
  94. sm.CompleteMaintenance();
  95. Assert.Equal(DeviceStateMachine.DeviceState.Stopped, sm.CurrentState);
  96. }
  97. [Fact]
  98. public void ToDeviceStatus_ShouldConvertCorrectly()
  99. {
  100. var sm = new DeviceStateMachine("P001", "泵1");
  101. Assert.Equal(YZWater.Core.Models.DeviceStatus.Stopped, sm.ToDeviceStatus());
  102. sm.Start();
  103. Assert.Equal(YZWater.Core.Models.DeviceStatus.Running, sm.ToDeviceStatus());
  104. sm.ReportFault();
  105. Assert.Equal(YZWater.Core.Models.DeviceStatus.Fault, sm.ToDeviceStatus());
  106. }
  107. }
  108. /// <summary>
  109. /// DeviceStateMachineManager 单元测试
  110. /// </summary>
  111. public class DeviceStateMachineManagerTests
  112. {
  113. [Fact]
  114. public void GetOrCreate_ShouldCreateNewMachine()
  115. {
  116. var manager = new DeviceStateMachineManager();
  117. var sm = manager.GetOrCreate("P001", "泵1");
  118. Assert.NotNull(sm);
  119. Assert.Equal("P001", sm.DeviceId);
  120. Assert.Equal("泵1", sm.DeviceName);
  121. }
  122. [Fact]
  123. public void GetOrCreate_SameId_ShouldReturnSameInstance()
  124. {
  125. var manager = new DeviceStateMachineManager();
  126. var sm1 = manager.GetOrCreate("P001", "泵1");
  127. var sm2 = manager.GetOrCreate("P001", "泵1");
  128. Assert.Same(sm1, sm2);
  129. }
  130. [Fact]
  131. public void Get_ExistingMachine_ShouldReturnIt()
  132. {
  133. var manager = new DeviceStateMachineManager();
  134. manager.GetOrCreate("P001", "泵1");
  135. var sm = manager.Get("P001");
  136. Assert.NotNull(sm);
  137. }
  138. [Fact]
  139. public void Get_NonExistingMachine_ShouldReturnNull()
  140. {
  141. var manager = new DeviceStateMachineManager();
  142. var sm = manager.Get("P999");
  143. Assert.Null(sm);
  144. }
  145. [Fact]
  146. public void Clear_ShouldRemoveAllMachines()
  147. {
  148. var manager = new DeviceStateMachineManager();
  149. manager.GetOrCreate("P001", "泵1");
  150. manager.GetOrCreate("P002", "泵2");
  151. manager.Clear();
  152. Assert.Empty(manager.GetAll());
  153. }
  154. }