@@ -123,6 +123,61 @@ public sealed class AbCipTagPathTests
|
||||
AbCipTagPath.TryParse("_private_tag")!.Segments.Single().Name.ShouldBe("_private_tag");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Slice_basic_inclusive_range()
|
||||
{
|
||||
var p = AbCipTagPath.TryParse("Data[0..15]");
|
||||
p.ShouldNotBeNull();
|
||||
p.Slice.ShouldNotBeNull();
|
||||
p.Slice!.Start.ShouldBe(0);
|
||||
p.Slice.End.ShouldBe(15);
|
||||
p.Slice.Count.ShouldBe(16);
|
||||
p.BitIndex.ShouldBeNull();
|
||||
p.Segments.Single().Name.ShouldBe("Data");
|
||||
p.Segments.Single().Subscripts.ShouldBeEmpty();
|
||||
p.ToLibplctagName().ShouldBe("Data[0..15]");
|
||||
// Slice array name omits the `..End` so libplctag sees an anchored read at the start
|
||||
// index; pair with ElementCount to cover the whole range.
|
||||
p.ToLibplctagSliceArrayName().ShouldBe("Data[0]");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Slice_with_program_scope_and_member_chain()
|
||||
{
|
||||
var p = AbCipTagPath.TryParse("Program:MainProgram.Motors.Data[3..7]");
|
||||
p.ShouldNotBeNull();
|
||||
p.ProgramScope.ShouldBe("MainProgram");
|
||||
p.Segments.Select(s => s.Name).ShouldBe(["Motors", "Data"]);
|
||||
p.Slice!.Start.ShouldBe(3);
|
||||
p.Slice.End.ShouldBe(7);
|
||||
p.ToLibplctagName().ShouldBe("Program:MainProgram.Motors.Data[3..7]");
|
||||
p.ToLibplctagSliceArrayName().ShouldBe("Program:MainProgram.Motors.Data[3]");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Slice_zero_length_single_element_allowed()
|
||||
{
|
||||
// [5..5] is a one-element slice — degenerate but legal (a single read of one element).
|
||||
var p = AbCipTagPath.TryParse("Data[5..5]");
|
||||
p.ShouldNotBeNull();
|
||||
p.Slice!.Count.ShouldBe(1);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Data[5..3]")] // M < N
|
||||
[InlineData("Data[-1..5]")] // negative start
|
||||
[InlineData("Data[0..15].Member")] // slice + sub-element
|
||||
[InlineData("Data[0..15].3")] // slice + bit index
|
||||
[InlineData("Data[0..15,1]")] // slice cannot be multi-dim
|
||||
[InlineData("Data[0..15,2..3]")] // multi-dim slice not supported
|
||||
[InlineData("Data[..5]")] // missing start
|
||||
[InlineData("Data[5..]")] // missing end
|
||||
[InlineData("Data[a..5]")] // non-numeric start
|
||||
public void Invalid_slice_shapes_return_null(string input)
|
||||
{
|
||||
AbCipTagPath.TryParse(input).ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToLibplctagName_recomposes_round_trip()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user