@@ -165,6 +165,55 @@ public sealed class AbCipDriverReadTests
|
||||
p.TagName.ShouldBe("Program:P.Counter");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Slice_tag_reads_one_array_and_decodes_n_elements()
|
||||
{
|
||||
// PR abcip-1.3 — `Data[0..3]` slice routes through AbCipArrayReadPlanner: one libplctag
|
||||
// tag-create at TagName="Data[0]" with ElementCount=4, single PLC read, contiguous
|
||||
// buffer decoded at element stride into one snapshot whose Value is an object?[].
|
||||
var (drv, factory) = NewDriver(
|
||||
new AbCipTagDefinition("DataSlice", "ab://10.0.0.5/1,0", "Data[0..3]", AbCipDataType.DInt));
|
||||
await drv.InitializeAsync("{}", CancellationToken.None);
|
||||
factory.Customise = p =>
|
||||
{
|
||||
var t = new FakeAbCipTag(p);
|
||||
t.ValuesByOffset[0] = 10;
|
||||
t.ValuesByOffset[4] = 20;
|
||||
t.ValuesByOffset[8] = 30;
|
||||
t.ValuesByOffset[12] = 40;
|
||||
return t;
|
||||
};
|
||||
|
||||
var snapshots = await drv.ReadAsync(["DataSlice"], CancellationToken.None);
|
||||
|
||||
snapshots.Single().StatusCode.ShouldBe(AbCipStatusMapper.Good);
|
||||
var values = snapshots.Single().Value.ShouldBeOfType<object?[]>();
|
||||
values.ShouldBe(new object?[] { 10, 20, 30, 40 });
|
||||
|
||||
// Exactly ONE libplctag tag was created — anchored at the slice start with
|
||||
// ElementCount=4. Without the planner this would have been four scalar reads.
|
||||
factory.Tags.Count.ShouldBe(1);
|
||||
factory.Tags.ShouldContainKey("Data[0]");
|
||||
factory.Tags["Data[0]"].CreationParams.ElementCount.ShouldBe(4);
|
||||
factory.Tags["Data[0]"].ReadCount.ShouldBe(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Slice_tag_with_unsupported_element_type_returns_BadNotSupported()
|
||||
{
|
||||
// BOOL slices can't be laid out from the declaration alone (Logix packs BOOLs into a
|
||||
// hidden host byte). The planner refuses; the driver surfaces BadNotSupported instead
|
||||
// of attempting a best-effort decode.
|
||||
var (drv, _) = NewDriver(
|
||||
new AbCipTagDefinition("BoolSlice", "ab://10.0.0.5/1,0", "Flags[0..7]", AbCipDataType.Bool));
|
||||
await drv.InitializeAsync("{}", CancellationToken.None);
|
||||
|
||||
var snapshots = await drv.ReadAsync(["BoolSlice"], CancellationToken.None);
|
||||
|
||||
snapshots.Single().StatusCode.ShouldBe(AbCipStatusMapper.BadNotSupported);
|
||||
snapshots.Single().Value.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Cancellation_propagates_from_read()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user