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());
}
}