using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Cli.Commands; namespace ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Cli.Tests; /// /// Covers . PCCC types are narrower than AB CIP /// (no 64-bit, no unsigned variants, no Structure / Dt) so the matrix is smaller. /// [Trait("Category", "Unit")] public sealed class WriteCommandParseValueTests { [Theory] [InlineData("true", true)] [InlineData("0", false)] [InlineData("yes", true)] [InlineData("OFF", false)] public void ParseValue_Bit_accepts_common_aliases(string raw, bool expected) { WriteCommand.ParseValue(raw, AbLegacyDataType.Bit).ShouldBe(expected); } [Fact] public void ParseValue_Int_signed_16bit() { WriteCommand.ParseValue("-32768", AbLegacyDataType.Int).ShouldBe((short)-32768); WriteCommand.ParseValue("32767", AbLegacyDataType.Int).ShouldBe((short)32767); } [Fact] public void ParseValue_AnalogInt_parses_same_as_Int() { // A-file uses N-file semantics — 16-bit signed with the same wire format. WriteCommand.ParseValue("100", AbLegacyDataType.AnalogInt).ShouldBeOfType(); } [Fact] public void ParseValue_Long_32bit() { WriteCommand.ParseValue("-2147483648", AbLegacyDataType.Long).ShouldBe(int.MinValue); WriteCommand.ParseValue("2147483647", AbLegacyDataType.Long).ShouldBe(int.MaxValue); } [Fact] public void ParseValue_Float_invariant_culture() { WriteCommand.ParseValue("3.14", AbLegacyDataType.Float).ShouldBe(3.14f); } [Fact] public void ParseValue_String_passthrough() { WriteCommand.ParseValue("hello slc", AbLegacyDataType.String).ShouldBe("hello slc"); } [Theory] [InlineData(AbLegacyDataType.TimerElement)] [InlineData(AbLegacyDataType.CounterElement)] [InlineData(AbLegacyDataType.ControlElement)] public void ParseValue_Element_types_land_on_int32(AbLegacyDataType type) { // T/C/R sub-elements are 32-bit at the wire level regardless of semantic meaning. WriteCommand.ParseValue("42", type).ShouldBeOfType(); } [Fact] public void ParseValue_Bit_rejects_unknown_strings() { Should.Throw( () => WriteCommand.ParseValue("perhaps", AbLegacyDataType.Bit)); } [Fact] public void ParseValue_non_numeric_for_numeric_types_throws() { Should.Throw( () => WriteCommand.ParseValue("xyz", AbLegacyDataType.Int)); } [Theory] [InlineData("N7:0", AbLegacyDataType.Int, "N7:0:Int")] [InlineData("B3:0/3", AbLegacyDataType.Bit, "B3:0/3:Bit")] [InlineData("F8:10", AbLegacyDataType.Float, "F8:10:Float")] [InlineData("T4:0.ACC", AbLegacyDataType.TimerElement, "T4:0.ACC:TimerElement")] public void SynthesiseTagName_preserves_PCCC_address_verbatim( string address, AbLegacyDataType type, string expected) { ReadCommand.SynthesiseTagName(address, type).ShouldBe(expected); } }