using Shouldly; using Xunit; namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests; public sealed class ModbusCrcTests { // Known CRC-16/MODBUS vectors (init 0xFFFF, poly 0xA001). CRC returned as ushort; // on the wire it is appended low-byte-first. [Theory] // FC03 read HR: unit 1, addr 0, qty 1 -> CRC 0x0A84 (bytes 84 0A on the wire) [InlineData(new byte[] { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 }, (ushort)0x0A84)] // "123456789" canonical check value for CRC-16/MODBUS = 0x4B37 [InlineData(new byte[] { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 }, (ushort)0x4B37)] public void Compute_matches_known_vectors(byte[] frame, ushort expected) => ModbusCrc.Compute(frame).ShouldBe(expected); [Fact] public void AppendLowByteFirst_writes_lo_then_hi() { var body = new byte[] { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 }; var withCrc = ModbusCrc.Append(body); withCrc.Length.ShouldBe(body.Length + 2); withCrc[^2].ShouldBe((byte)0x84); // CRC low byte withCrc[^1].ShouldBe((byte)0x0A); // CRC high byte } }