using Xunit; using YZWater.Core.Services; namespace YZWater.Core.Tests.Services; /// /// DeviceStateMachine 单元测试 /// public class DeviceStateMachineTests { [Fact] public void InitialState_ShouldBeStopped() { var sm = new DeviceStateMachine("P001", "泵1"); Assert.Equal(DeviceStateMachine.DeviceState.Stopped, sm.CurrentState); } [Fact] public void Start_ShouldTransitionToRunning() { var sm = new DeviceStateMachine("P001", "泵1"); sm.Start(); Assert.Equal(DeviceStateMachine.DeviceState.Running, sm.CurrentState); } [Fact] public void Stop_FromRunning_ShouldTransitionToStopped() { var sm = new DeviceStateMachine("P001", "泵1"); sm.Start(); sm.Stop(); Assert.Equal(DeviceStateMachine.DeviceState.Stopped, sm.CurrentState); } [Fact] public void ReportFault_ShouldTransitionToFault() { var sm = new DeviceStateMachine("P001", "泵1"); sm.Start(); sm.ReportFault(); Assert.Equal(DeviceStateMachine.DeviceState.Fault, sm.CurrentState); } [Fact] public void Recover_FromFault_ShouldTransitionToStopped() { var sm = new DeviceStateMachine("P001", "泵1"); sm.Start(); sm.ReportFault(); sm.Recover(); Assert.Equal(DeviceStateMachine.DeviceState.Stopped, sm.CurrentState); } [Fact] public void FaultCannotDirectlyTransitionToRunning() { var sm = new DeviceStateMachine("P001", "泵1"); sm.ReportFault(); var canStart = sm.CanFire(DeviceStateMachine.DeviceTrigger.Start); Assert.False(canStart); } [Fact] public void TryFire_InvalidTransition_ShouldReturnFalse() { var sm = new DeviceStateMachine("P001", "泵1"); // 从 Stopped 不能直接 Stop var result = sm.TryFire(DeviceStateMachine.DeviceTrigger.Stop); Assert.False(result); Assert.Equal(DeviceStateMachine.DeviceState.Stopped, sm.CurrentState); } [Fact] public void StateChanged_EventShouldFire() { var sm = new DeviceStateMachine("P001", "泵1"); var eventFired = false; DeviceStateMachine.DeviceState? fromState = null; DeviceStateMachine.DeviceState? toState = null; sm.StateChanged += (id, from, to) => { eventFired = true; fromState = from; toState = to; }; sm.Start(); Assert.True(eventFired); Assert.Equal(DeviceStateMachine.DeviceState.Stopped, fromState); Assert.Equal(DeviceStateMachine.DeviceState.Running, toState); } [Fact] public void BeginMaintenance_ShouldTransitionToMaintenance() { var sm = new DeviceStateMachine("P001", "泵1"); sm.BeginMaintenance(); Assert.Equal(DeviceStateMachine.DeviceState.Maintenance, sm.CurrentState); } [Fact] public void CompleteMaintenance_ShouldTransitionToStopped() { var sm = new DeviceStateMachine("P001", "泵1"); sm.BeginMaintenance(); sm.CompleteMaintenance(); Assert.Equal(DeviceStateMachine.DeviceState.Stopped, sm.CurrentState); } [Fact] public void ToDeviceStatus_ShouldConvertCorrectly() { var sm = new DeviceStateMachine("P001", "泵1"); Assert.Equal(YZWater.Core.Models.DeviceStatus.Stopped, sm.ToDeviceStatus()); sm.Start(); Assert.Equal(YZWater.Core.Models.DeviceStatus.Running, sm.ToDeviceStatus()); sm.ReportFault(); Assert.Equal(YZWater.Core.Models.DeviceStatus.Fault, sm.ToDeviceStatus()); } } /// /// DeviceStateMachineManager 单元测试 /// public class DeviceStateMachineManagerTests { [Fact] public void GetOrCreate_ShouldCreateNewMachine() { var manager = new DeviceStateMachineManager(); var sm = manager.GetOrCreate("P001", "泵1"); Assert.NotNull(sm); Assert.Equal("P001", sm.DeviceId); Assert.Equal("泵1", sm.DeviceName); } [Fact] public void GetOrCreate_SameId_ShouldReturnSameInstance() { var manager = new DeviceStateMachineManager(); var sm1 = manager.GetOrCreate("P001", "泵1"); var sm2 = manager.GetOrCreate("P001", "泵1"); Assert.Same(sm1, sm2); } [Fact] public void Get_ExistingMachine_ShouldReturnIt() { var manager = new DeviceStateMachineManager(); manager.GetOrCreate("P001", "泵1"); var sm = manager.Get("P001"); Assert.NotNull(sm); } [Fact] public void Get_NonExistingMachine_ShouldReturnNull() { var manager = new DeviceStateMachineManager(); var sm = manager.Get("P999"); Assert.Null(sm); } [Fact] public void Clear_ShouldRemoveAllMachines() { var manager = new DeviceStateMachineManager(); manager.GetOrCreate("P001", "泵1"); manager.GetOrCreate("P002", "泵2"); manager.Clear(); Assert.Empty(manager.GetAll()); } }