using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Driver.AbLegacy; namespace ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Tests; [Trait("Category", "Unit")] public sealed class AbLegacyAddressTests { [Theory] [InlineData("N7:0", "N", 7, 0, null, null)] [InlineData("N7:15", "N", 7, 15, null, null)] [InlineData("F8:5", "F", 8, 5, null, null)] [InlineData("B3:0/0", "B", 3, 0, 0, null)] [InlineData("B3:2/7", "B", 3, 2, 7, null)] [InlineData("ST9:0", "ST", 9, 0, null, null)] [InlineData("L9:3", "L", 9, 3, null, null)] [InlineData("I:0/0", "I", null, 0, 0, null)] [InlineData("O:1/2", "O", null, 1, 2, null)] [InlineData("S:1", "S", null, 1, null, null)] [InlineData("T4:0.ACC", "T", 4, 0, null, "ACC")] [InlineData("T4:0.PRE", "T", 4, 0, null, "PRE")] [InlineData("C5:2.CU", "C", 5, 2, null, "CU")] [InlineData("R6:0.LEN", "R", 6, 0, null, "LEN")] [InlineData("N7:0/3", "N", 7, 0, 3, null)] public void TryParse_accepts_valid_pccc_addresses(string input, string letter, int? file, int word, int? bit, string? sub) { var a = AbLegacyAddress.TryParse(input); a.ShouldNotBeNull(); a.FileLetter.ShouldBe(letter); a.FileNumber.ShouldBe(file); a.WordNumber.ShouldBe(word); a.BitIndex.ShouldBe(bit); a.SubElement.ShouldBe(sub); } [Theory] [InlineData(null)] [InlineData("")] [InlineData(" ")] [InlineData("N7")] // missing :word [InlineData(":0")] // missing file [InlineData("X7:0")] // unknown file letter [InlineData("N7:-1")] // negative word [InlineData("N7:abc")] // non-numeric word [InlineData("N7:0/-1")] // negative bit [InlineData("N7:0/32")] // bit out of range [InlineData("Nabc:0")] // non-numeric file number public void TryParse_rejects_invalid_forms(string? input) { AbLegacyAddress.TryParse(input).ShouldBeNull(); } [Theory] [InlineData("N7:0")] [InlineData("F8:5")] [InlineData("B3:0/0")] [InlineData("ST9:0")] [InlineData("T4:0.ACC")] [InlineData("I:0/0")] [InlineData("S:1")] public void ToLibplctagName_roundtrips(string input) { var a = AbLegacyAddress.TryParse(input); a.ShouldNotBeNull(); a.ToLibplctagName().ShouldBe(input); } }