using Microsoft.Extensions.Options; using WIDESEAWCS_S7Simulator.Application.Protocol; using WIDESEAWCS_S7Simulator.Core.Entities; using WIDESEAWCS_S7Simulator.Core.Memory; using WIDESEAWCS_S7Simulator.Core.Protocol; namespace WIDESEAWCS_S7Simulator.UnitTests.Protocol; public class StackerInteractionProtocolHandlerTests { [Fact] public void Process_初始化时应写入固定偏移值() { var memory = BuildMemory(); var template = BuildTemplate(); var state = new ProtocolRuntimeState(); var handler = BuildHandler(); var changed = handler.Process(memory, template, state); Assert.True(changed); Assert.Equal((byte)5, memory.Read("DB1.DBB2")); Assert.Equal((byte)1, memory.Read("DB1.DBB4")); Assert.Equal((byte)1, memory.Read("DB1.DBB96")); } [Fact] public void Process_当Offset192为1时应设置Offset24和Offset4() { var memory = BuildMemory(); var template = BuildTemplate(); var state = new ProtocolRuntimeState(); var handler = BuildHandler(); memory.Write("DB1.DBB192", 1); var changed = handler.Process(memory, template, state); Assert.True(changed); Assert.Equal((byte)1, memory.Read("DB1.DBB24")); Assert.Equal((byte)2, memory.Read("DB1.DBB4")); } [Fact] public void Process_当Offset192为2时应复位Offset24和Offset4() { var memory = BuildMemory(); var template = BuildTemplate(); var state = new ProtocolRuntimeState(); var handler = BuildHandler(); memory.Write("DB1.DBB24", 9); memory.Write("DB1.DBB4", 9); memory.Write("DB1.DBB192", 2); var changed = handler.Process(memory, template, state); Assert.True(changed); Assert.Equal((byte)0, memory.Read("DB1.DBB24")); Assert.Equal((byte)1, memory.Read("DB1.DBB4")); } [Fact] public void Process_初始化只写一次_第二次调用不应覆盖运行值() { var memory = BuildMemory(); var template = BuildTemplate(); var state = new ProtocolRuntimeState(); var handler = BuildHandler(); var firstChanged = handler.Process(memory, template, state); Assert.True(firstChanged); // 模拟运行中被外部改写后的值。 memory.Write("DB1.DBB2", 99); memory.Write("DB1.DBB4", 77); memory.Write("DB1.DBB96", 55); var secondChanged = handler.Process(memory, template, state); Assert.False(secondChanged); Assert.Equal((byte)99, memory.Read("DB1.DBB2")); Assert.Equal((byte)77, memory.Read("DB1.DBB4")); Assert.Equal((byte)55, memory.Read("DB1.DBB96")); } private static StackerInteractionProtocolHandler BuildHandler() { return new StackerInteractionProtocolHandler( new MirrorAckProtocolHandler(), Options.Create(new ProtocolMonitoringOptions())); } private static MemoryStore BuildMemory() { return new MemoryStore(new MemoryRegionConfig { DBBlockCount = 2, DBBlockSize = 512 }); } private static ProtocolTemplate BuildTemplate() { return new ProtocolTemplate { Id = "stacker-interaction-v1", Name = "STACKER_INTERACTION_V1", Fields = new List { new() { FieldKey = "TRIGGER", DbNumber = 1, Offset = 192, DataType = ProtocolDataType.Byte } } }; } [Fact] public void Process_按Int类型配置读写() { var memory = BuildMemory(); var template = BuildIntTemplate(); var state = new ProtocolRuntimeState(); var handler = BuildHandler(); memory.Write("DB1.DBW192", 1); var changed = handler.Process(memory, template, state); Assert.True(changed); Assert.Equal((short)5, memory.Read("DB1.DBW2")); Assert.Equal((short)2, memory.Read("DB1.DBW4")); Assert.Equal((short)1, memory.Read("DB1.DBW24")); Assert.Equal((short)1, memory.Read("DB1.DBW96")); } private static ProtocolTemplate BuildIntTemplate() { return new ProtocolTemplate { Id = "stacker-interaction-int-v1", Name = "STACKER_INTERACTION_INT_V1", Fields = new List { new() { FieldKey = "OFFSET2", DbNumber = 1, Offset = 2, DataType = ProtocolDataType.Int }, new() { FieldKey = "OFFSET4", DbNumber = 1, Offset = 4, DataType = ProtocolDataType.Int }, new() { FieldKey = "OFFSET24", DbNumber = 1, Offset = 24, DataType = ProtocolDataType.Int }, new() { FieldKey = "OFFSET96", DbNumber = 1, Offset = 96, DataType = ProtocolDataType.Int }, new() { FieldKey = "OFFSET192", DbNumber = 1, Offset = 192, DataType = ProtocolDataType.Int } } }; } }