73 lines
2.4 KiB
C#
73 lines
2.4 KiB
C#
using Shouldly;
|
|
using Xunit;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.Tests;
|
|
|
|
[Trait("Category", "Unit")]
|
|
public sealed class AbCipUdtMemberLayoutTests
|
|
{
|
|
[Fact]
|
|
public void Packed_Atomics_Get_Natural_Alignment_Offsets()
|
|
{
|
|
// DInt (4 align) + Real (4) + Int (2) + LInt (8 — forces 2-byte pad before it)
|
|
var members = new[]
|
|
{
|
|
new AbCipStructureMember("A", AbCipDataType.DInt),
|
|
new AbCipStructureMember("B", AbCipDataType.Real),
|
|
new AbCipStructureMember("C", AbCipDataType.Int),
|
|
new AbCipStructureMember("D", AbCipDataType.LInt),
|
|
};
|
|
|
|
var offsets = AbCipUdtMemberLayout.TryBuild(members);
|
|
offsets.ShouldNotBeNull();
|
|
offsets!["A"].ShouldBe(0);
|
|
offsets["B"].ShouldBe(4);
|
|
offsets["C"].ShouldBe(8);
|
|
// cursor at 10 after Int; LInt needs 8-byte alignment → pad to 16
|
|
offsets["D"].ShouldBe(16);
|
|
}
|
|
|
|
[Fact]
|
|
public void SInt_Packed_Without_Padding()
|
|
{
|
|
var members = new[]
|
|
{
|
|
new AbCipStructureMember("X", AbCipDataType.SInt),
|
|
new AbCipStructureMember("Y", AbCipDataType.SInt),
|
|
new AbCipStructureMember("Z", AbCipDataType.SInt),
|
|
};
|
|
var offsets = AbCipUdtMemberLayout.TryBuild(members);
|
|
offsets!["X"].ShouldBe(0);
|
|
offsets["Y"].ShouldBe(1);
|
|
offsets["Z"].ShouldBe(2);
|
|
}
|
|
|
|
[Fact]
|
|
public void Returns_Null_When_Member_Is_Bool()
|
|
{
|
|
// BOOL storage in Logix UDTs is packed into a hidden host byte; declaration-only
|
|
// layout can't place it. Grouping opts out; per-tag read path handles the member.
|
|
var members = new[]
|
|
{
|
|
new AbCipStructureMember("A", AbCipDataType.DInt),
|
|
new AbCipStructureMember("Flag", AbCipDataType.Bool),
|
|
};
|
|
AbCipUdtMemberLayout.TryBuild(members).ShouldBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void Returns_Null_When_Member_Is_String_Or_Structure()
|
|
{
|
|
AbCipUdtMemberLayout.TryBuild(
|
|
new[] { new AbCipStructureMember("Name", AbCipDataType.String) }).ShouldBeNull();
|
|
AbCipUdtMemberLayout.TryBuild(
|
|
new[] { new AbCipStructureMember("Nested", AbCipDataType.Structure) }).ShouldBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void Returns_Null_On_Empty_Members()
|
|
{
|
|
AbCipUdtMemberLayout.TryBuild(Array.Empty<AbCipStructureMember>()).ShouldBeNull();
|
|
}
|
|
}
|