using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; namespace ZB.MOM.WW.OtOpcUa.Driver.S7.Tests; /// /// Gitea #610 — pins 's S7 row against the REAL array encoder /// (). For every , the server advertises an /// array node writable exactly when the encoder accepts the element type, so a driver change that adds or /// drops an array element type fails here until the table follows. /// [Trait("Category", "Unit")] public sealed class S7ArrayWriteSupportParityTests { public static TheoryData AllTypes() => new(Enum.GetValues()); // An address whose access size matches the element type, so only the element type can make the encoder refuse. private static string AddressFor(S7DataType dt) => dt switch { S7DataType.Bool => "DB1.DBX0.0", S7DataType.Byte => "DB1.DBB0", S7DataType.Int16 or S7DataType.UInt16 => "DB1.DBW0", _ => "DB1.DBD0", }; [Theory] [MemberData(nameof(AllTypes))] public void Table_agrees_with_EncodeArrayBlock(S7DataType dataType) { var address = AddressFor(dataType); var tag = new S7TagDefinition("Arr", address, dataType, Writable: true, ArrayCount: 2); bool encoderAccepts; try { S7Driver.EncodeArrayBlock(tag, S7AddressParser.Parse(address), new object[] { 1, 1 }); encoderAccepts = true; } catch (NotSupportedException) { encoderAccepts = false; } DriverArrayWriteSupport.Supports( DriverTypeNames.S7, "Int16", $$"""{"address":"{{address}}","dataType":"{{dataType}}","isArray":true,"arrayLength":2}""") .ShouldBe(encoderAccepts, dataType.ToString()); } }