using libplctag;
using ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport;
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Driver.AbCip;
namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.Tests;
[Trait("Category", "Unit")]
public sealed class AbCipStatusMapperTests
{
/// Verifies that transport status values are mapped to OPC UA status codes.
/// The transport status to map.
/// The expected OPC UA status code.
[Theory]
[InlineData(AbStatus.Ok, AbCipStatusMapper.Good)]
[InlineData(AbStatus.Pending, AbCipStatusMapper.GoodMoreData)]
[InlineData(AbStatus.Timeout, AbCipStatusMapper.BadTimeout)]
[InlineData(AbStatus.NotFound, AbCipStatusMapper.BadNodeIdUnknown)]
[InlineData(AbStatus.NotAllowed, AbCipStatusMapper.BadNotWritable)]
[InlineData(AbStatus.OutOfBounds, AbCipStatusMapper.BadOutOfRange)]
[InlineData(AbStatus.TooLarge, AbCipStatusMapper.BadOutOfRange)]
[InlineData(AbStatus.TooSmall, AbCipStatusMapper.BadOutOfRange)]
[InlineData(AbStatus.Unsupported, AbCipStatusMapper.BadNotSupported)]
[InlineData(AbStatus.TypeMismatch, AbCipStatusMapper.BadTypeMismatch)]
[InlineData(AbStatus.DeviceStateConflict, AbCipStatusMapper.BadDeviceFailure)]
[InlineData(AbStatus.BadConnection, AbCipStatusMapper.BadCommunicationError)]
[InlineData(AbStatus.BadReply, AbCipStatusMapper.BadCommunicationError)]
[InlineData(AbStatus.Partial, AbCipStatusMapper.BadCommunicationError)]
[InlineData(AbStatus.Abort, AbCipStatusMapper.BadCommunicationError)]
public void MapStatus_maps_every_AbStatus(AbStatus status, uint expected)
{
AbCipStatusMapper.MapStatus(status).ShouldBe(expected);
// The int overload must agree - it is the seam IAbCipTagRuntime.GetStatus() drives.
AbCipStatusMapper.MapStatus((int)status).ShouldBe(expected);
}
/// Verifies that timeout is distinguished from generic communication error.
[Fact]
public void MapStatus_distinguishes_timeout_from_generic_comms_error()
{
AbCipStatusMapper.MapStatus((int)AbStatus.Timeout).ShouldBe(AbCipStatusMapper.BadTimeout);
AbCipStatusMapper.MapStatus((int)AbStatus.NotFound).ShouldBe(AbCipStatusMapper.BadNodeIdUnknown);
AbCipStatusMapper.MapStatus((int)AbStatus.NotFound).ShouldNotBe(AbCipStatusMapper.BadCommunicationError);
}
/// Verifies MapException maps transport exceptions by status and everything else to comms error.
[Fact]
public void MapException_uses_the_transport_status()
{
AbCipStatusMapper.MapException(new AbTransportException(AbStatus.NotFound, "x"))
.ShouldBe(AbCipStatusMapper.BadNodeIdUnknown);
AbCipStatusMapper.MapException(new InvalidOperationException("x"))
.ShouldBe(AbCipStatusMapper.BadCommunicationError);
}
///
/// Regression oracle: the OPC UA code the pre-AbStatus MapLibplctagStatus returned for every
/// libplctag member (table copied from the deleted switch) must equal
/// MapStatus(ToAbStatus(member)).
///
/// A libplctag status.
[Theory]
[MemberData(nameof(AllLibplctagStatuses))]
public void Translation_plus_MapStatus_matches_the_old_libplctag_mapping(Status status)
{
AbCipStatusMapper.MapStatus(LibplctagStatusTranslation.ToAbStatus(status)).ShouldBe(OldMapLibplctagStatus(status));
}
/// Every defined libplctag member.
/// One row per member.
public static IEnumerable