107 lines
3.5 KiB
C#
107 lines
3.5 KiB
C#
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Driver.FOCAS;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests;
|
|
|
|
/// <summary>
|
|
/// Tests for the managed helpers inside FwlibNative + FwlibFocasClient that don't require the
|
|
/// licensed Fwlib32.dll — letter→ADR_* mapping, FocasDataType→data-type mapping, byte encoding.
|
|
/// The actual P/Invoke calls can only run where the DLL is present; field testing covers those.
|
|
/// </summary>
|
|
[Trait("Category", "Unit")]
|
|
public sealed class FwlibNativeHelperTests
|
|
{
|
|
[Theory]
|
|
[InlineData("G", 0)]
|
|
[InlineData("F", 1)]
|
|
[InlineData("Y", 2)]
|
|
[InlineData("X", 3)]
|
|
[InlineData("A", 4)]
|
|
[InlineData("R", 5)]
|
|
[InlineData("T", 6)]
|
|
[InlineData("K", 7)]
|
|
[InlineData("C", 8)]
|
|
[InlineData("D", 9)]
|
|
[InlineData("E", 10)]
|
|
[InlineData("g", 0)] // case-insensitive
|
|
public void PmcAddrType_maps_every_valid_letter(string letter, short expected)
|
|
{
|
|
FocasPmcAddrType.FromLetter(letter).ShouldBe(expected);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("Z")]
|
|
[InlineData("")]
|
|
[InlineData("XX")]
|
|
public void PmcAddrType_rejects_unknown_letters(string letter)
|
|
{
|
|
FocasPmcAddrType.FromLetter(letter).ShouldBeNull();
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(FocasDataType.Bit, 0)] // byte
|
|
[InlineData(FocasDataType.Byte, 0)]
|
|
[InlineData(FocasDataType.Int16, 1)] // word
|
|
[InlineData(FocasDataType.Int32, 2)] // long
|
|
[InlineData(FocasDataType.Float32, 4)]
|
|
[InlineData(FocasDataType.Float64, 5)]
|
|
public void PmcDataType_maps_FocasDataType_to_FOCAS_code(FocasDataType input, short expected)
|
|
{
|
|
FocasPmcDataType.FromFocasDataType(input).ShouldBe(expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void EncodePmcValue_Byte_writes_signed_byte_at_offset_0()
|
|
{
|
|
var buf = new byte[40];
|
|
FwlibFocasClient.EncodePmcValue(buf, FocasDataType.Byte, (sbyte)-5, bitIndex: null);
|
|
((sbyte)buf[0]).ShouldBe((sbyte)-5);
|
|
}
|
|
|
|
[Fact]
|
|
public void EncodePmcValue_Int16_writes_little_endian()
|
|
{
|
|
var buf = new byte[40];
|
|
FwlibFocasClient.EncodePmcValue(buf, FocasDataType.Int16, (short)0x1234, bitIndex: null);
|
|
buf[0].ShouldBe((byte)0x34);
|
|
buf[1].ShouldBe((byte)0x12);
|
|
}
|
|
|
|
[Fact]
|
|
public void EncodePmcValue_Int32_writes_little_endian()
|
|
{
|
|
var buf = new byte[40];
|
|
FwlibFocasClient.EncodePmcValue(buf, FocasDataType.Int32, 0x12345678, bitIndex: null);
|
|
buf[0].ShouldBe((byte)0x78);
|
|
buf[1].ShouldBe((byte)0x56);
|
|
buf[2].ShouldBe((byte)0x34);
|
|
buf[3].ShouldBe((byte)0x12);
|
|
}
|
|
|
|
[Fact]
|
|
public void EncodePmcValue_Bit_without_bit_index_writes_byte_boolean()
|
|
{
|
|
// Task #181 closed the Bit-write gap — PMC Bit with a bitIndex now routes through
|
|
// WritePmcBitAsync's RMW path upstream, and raw EncodePmcValue only gets the
|
|
// no-bit-index case (treated as a whole-byte boolean).
|
|
var buf = new byte[40];
|
|
FwlibFocasClient.EncodePmcValue(buf, FocasDataType.Bit, true, bitIndex: null);
|
|
buf[0].ShouldBe((byte)1);
|
|
|
|
FwlibFocasClient.EncodePmcValue(buf, FocasDataType.Bit, false, bitIndex: null);
|
|
buf[0].ShouldBe((byte)0);
|
|
}
|
|
|
|
[Fact]
|
|
public void EncodeParamValue_Int32_writes_little_endian()
|
|
{
|
|
var buf = new byte[32];
|
|
FwlibFocasClient.EncodeParamValue(buf, FocasDataType.Int32, 0x0A0B0C0D);
|
|
buf[0].ShouldBe((byte)0x0D);
|
|
buf[1].ShouldBe((byte)0x0C);
|
|
buf[2].ShouldBe((byte)0x0B);
|
|
buf[3].ShouldBe((byte)0x0A);
|
|
}
|
|
}
|