feat(centralui): BindingGroupBuilder — group flattened binding rows by module, infer the shared MxAccess object prefix, count unbound
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
using ZB.MOM.WW.ScadaBridge.CentralUI.Services;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Services;
|
||||
|
||||
public class BindingGroupBuilderTests
|
||||
{
|
||||
private static BindingRow Row(string canonical, string? dflt, int? conn, string? ovr) =>
|
||||
new(canonical, dflt, conn, ovr);
|
||||
|
||||
[Fact]
|
||||
public void Groups_DirectAttributesFirst_ThenModules_InNameOrder()
|
||||
{
|
||||
var rows = new[]
|
||||
{
|
||||
Row("RightMESReceiver.MoveInFlag", "MoveInFlag", 1, "MESReceiver_022.MoveInFlag"),
|
||||
Row("ChlorineFlow", "ChlorineFlow", 1, "Z28061.ChlorineFlow"),
|
||||
Row("LeftMESReceiver.MoveInFlag", "MoveInFlag", 1, "MESReceiver_023.MoveInFlag"),
|
||||
};
|
||||
var groups = BindingGroupBuilder.Build(rows);
|
||||
Assert.Equal(new[] { BindingGroupBuilder.InstanceGroupKey, "LeftMESReceiver", "RightMESReceiver" },
|
||||
groups.Select(g => g.Key));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NestedModule_FoldsIntoFirstSegment_AndKeepsNestedTail()
|
||||
{
|
||||
var rows = new[]
|
||||
{
|
||||
Row("LeftReactorSide.AIR_SVC", "AIR_SVC", 1, "Left_002.AIR_SVC"),
|
||||
Row("LeftReactorSide.LeakTest.DeltaVac", "DeltaVac", 1, "Left_002.LeakTest.DeltaVac"),
|
||||
};
|
||||
var g = Assert.Single(BindingGroupBuilder.Build(rows));
|
||||
Assert.Equal("LeftReactorSide", g.Key);
|
||||
Assert.Equal(new[] { "AIR_SVC", "LeakTest.DeltaVac" }, g.Members.Select(m => m.MemberTail));
|
||||
Assert.Equal(new[] { "LeakTest" }, g.NestedModules);
|
||||
Assert.Equal("Left_002", g.InferredObject);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InferredObject_NestedObjectPath()
|
||||
{
|
||||
var rows = new[]
|
||||
{
|
||||
Row("LeftDelmiaReceiver.ReadyFlag", "ReadyFlag", 1, "Left_002.DelmiaReceiver.ReadyFlag"),
|
||||
Row("LeftDelmiaReceiver.PartNumber", "PartNumber", 1, "Left_002.DelmiaReceiver.PartNumber"),
|
||||
};
|
||||
Assert.Equal("Left_002.DelmiaReceiver", Assert.Single(BindingGroupBuilder.Build(rows)).InferredObject);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InferredObject_NullWhenMixed_AndStateMixed()
|
||||
{
|
||||
var rows = new[]
|
||||
{
|
||||
Row("M.A", "A", 1, "Obj1.A"),
|
||||
Row("M.B", "B", 1, "Obj2.B"),
|
||||
};
|
||||
var g = Assert.Single(BindingGroupBuilder.Build(rows));
|
||||
Assert.Null(g.InferredObject);
|
||||
Assert.True(g.IsObjectMixed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InferredObject_NullWhenNoOverrides_NotMixed()
|
||||
{
|
||||
var rows = new[] { Row("M.A", "A", 1, null), Row("M.B", "B", 1, null) };
|
||||
var g = Assert.Single(BindingGroupBuilder.Build(rows));
|
||||
Assert.Null(g.InferredObject);
|
||||
Assert.False(g.IsObjectMixed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InstanceGroup_InfersObjectFromOverrides()
|
||||
{
|
||||
var rows = new[] { Row("ChlorineFlow", "ChlorineFlow", 1, "Z28061.ChlorineFlow"), Row("MachineID", "MachineID", 1, "Z28061.MachineID") };
|
||||
var g = Assert.Single(BindingGroupBuilder.Build(rows));
|
||||
Assert.Equal(BindingGroupBuilder.InstanceGroupKey, g.Key);
|
||||
Assert.Equal("Z28061", g.InferredObject);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Counts_UnboundAndConnectionState()
|
||||
{
|
||||
var rows = new[]
|
||||
{
|
||||
Row("M.A", "A", 1, "O.A"),
|
||||
Row("M.B", "B", null, null),
|
||||
Row("M.C", "C", 2, "O.C"),
|
||||
};
|
||||
var g = Assert.Single(BindingGroupBuilder.Build(rows));
|
||||
Assert.Equal(3, g.Members.Count);
|
||||
Assert.Equal(1, g.UnboundCount);
|
||||
Assert.Equal(BindingConnectionState.Mixed, g.ConnectionState);
|
||||
Assert.Null(g.CommonConnectionId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConnectionState_SingleWhenAllAgree()
|
||||
{
|
||||
var rows = new[] { Row("M.A", "A", 1, null), Row("M.B", "B", 1, null) };
|
||||
var g = Assert.Single(BindingGroupBuilder.Build(rows));
|
||||
Assert.Equal(BindingConnectionState.Single, g.ConnectionState);
|
||||
Assert.Equal(1, g.CommonConnectionId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MemberTail_OverrideThatDoesNotEndWithTail_CountsAsMixed()
|
||||
{
|
||||
// An operator typed a reference that does not end in the member tail —
|
||||
// the prefix cannot be inferred for that row, so the group is mixed.
|
||||
var rows = new[] { Row("M.A", "A", 1, "Obj.A"), Row("M.B", "B", 1, "Obj.Other") };
|
||||
Assert.True(Assert.Single(BindingGroupBuilder.Build(rows)).IsObjectMixed);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user