work-flow/tests/Workflow.Tests/StateMachine/TokenStateMachineTests.cs
2026-05-17 22:46:19 +08:00

159 lines
4.8 KiB
C#

using FluentAssertions;
using Workflow.Domain.Enums;
using Workflow.Domain.Exceptions;
using Workflow.Domain.StateMachine;
using Xunit;
namespace Workflow.Tests.StateMachine;
/// <summary>
/// TokenStateMachine TDD 红灯阶段测试
/// 测试令牌状态机的所有合法转换与非法转换
///
/// 令牌状态: Active, Completed, Terminated
/// 操作: NodeComplete, InstanceTerminate
/// </summary>
public class TokenStateMachineTests
{
private readonly TokenStateMachine _machine = new();
#region Active Completed
[Fact]
public void Transition_Active_To_Completed_On_NodeComplete()
{
// Arrange - 节点执行完毕,令牌正常完成
var currentState = TokenStatus.Active;
var operation = TokenOperation.NodeComplete;
var context = new TokenTransitionContext();
// Act
var newState = _machine.Transition(currentState, operation, context);
// Assert
newState.Should().Be(TokenStatus.Consumed);
}
#endregion
#region Active Terminated
[Fact]
public void Transition_Active_To_Terminated_On_InstanceTerminate()
{
// Arrange - 所属实例被终止,令牌随之终止
var currentState = TokenStatus.Active;
var operation = TokenOperation.InstanceTerminate;
var context = new TokenTransitionContext();
// Act
var newState = _machine.Transition(currentState, operation, context);
// Assert
newState.Should().Be(TokenStatus.Terminated);
}
#endregion
#region Illegal Transitions - Completed Is Terminal
[Fact]
public void Transition_Completed_To_Active_Should_Throw()
{
// Arrange - 已完成的令牌不能重新激活
var currentState = TokenStatus.Consumed;
var operation = TokenOperation.NodeComplete;
var context = new TokenTransitionContext();
// Act
var act = () => _machine.Transition(currentState, operation, context);
// Assert
act.Should().Throw<InvalidStateTransitionException>();
}
[Fact]
public void Transition_Completed_To_Terminated_Should_Throw()
{
// Arrange - 已完成的令牌不能再终止
var currentState = TokenStatus.Consumed;
var operation = TokenOperation.InstanceTerminate;
var context = new TokenTransitionContext();
// Act
var act = () => _machine.Transition(currentState, operation, context);
// Assert
act.Should().Throw<InvalidStateTransitionException>();
}
#endregion
#region Illegal Transitions - Terminated Is Terminal
[Fact]
public void Transition_Terminated_To_Active_Should_Throw()
{
// Arrange - 已终止的令牌不能重新激活
var currentState = TokenStatus.Terminated;
var operation = TokenOperation.NodeComplete;
var context = new TokenTransitionContext();
// Act
var act = () => _machine.Transition(currentState, operation, context);
// Assert
act.Should().Throw<InvalidStateTransitionException>();
}
[Fact]
public void Transition_Terminated_To_Completed_Should_Throw()
{
// Arrange - 已终止的令牌不能变为完成
var currentState = TokenStatus.Terminated;
var operation = TokenOperation.NodeComplete;
var context = new TokenTransitionContext();
// Act
var act = () => _machine.Transition(currentState, operation, context);
// Assert
act.Should().Throw<InvalidStateTransitionException>();
}
#endregion
#region Illegal Transitions - Active State Restrictions
[Fact]
public void Transition_Active_NodeComplete_Twice_Should_Throw_On_Second_Call()
{
// Arrange - 模拟令牌已完成后再尝试完成
// 第一次转换成功
var firstState = _machine.Transition(TokenStatus.Active, TokenOperation.NodeComplete, new TokenTransitionContext());
firstState.Should().Be(TokenStatus.Consumed);
// Act - 第二次从 Completed 状态再尝试完成
var act = () => _machine.Transition(firstState, TokenOperation.NodeComplete, new TokenTransitionContext());
// Assert
act.Should().Throw<InvalidStateTransitionException>();
}
[Fact]
public void Transition_Active_InstanceTerminate_Twice_Should_Throw_On_Second_Call()
{
// Arrange - 模拟令牌已终止后再尝试终止
var firstState = _machine.Transition(TokenStatus.Active, TokenOperation.InstanceTerminate, new TokenTransitionContext());
firstState.Should().Be(TokenStatus.Terminated);
// Act - 第二次从 Terminated 状态再尝试终止
var act = () => _machine.Transition(firstState, TokenOperation.InstanceTerminate, new TokenTransitionContext());
// Assert
act.Should().Throw<InvalidStateTransitionException>();
}
#endregion
}