From 7d4c30f2877b9f56100f1d74a57a49ede774503f Mon Sep 17 00:00:00 2001 From: Ari Sulistiono Date: Tue, 18 Aug 2026 08:32:20 +0700 Subject: [PATCH] test: ensure every uncovered point remains dynamic-first --- .../Iec61850ReportPlannerRegressionTests.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/ARSAS.Tests/Iec61850ReportPlannerRegressionTests.cs b/tests/ARSAS.Tests/Iec61850ReportPlannerRegressionTests.cs index f66b44bc3..65cb08e4f 100644 --- a/tests/ARSAS.Tests/Iec61850ReportPlannerRegressionTests.cs +++ b/tests/ARSAS.Tests/Iec61850ReportPlannerRegressionTests.cs @@ -35,6 +35,36 @@ public void BuildPlans_FastPointWithoutStaticCoverage_BecomesDynamicCandidate() Assert.Contains(point, plan.Bindings); } + [Fact] + public void BuildPlans_SlowMeasurementWithoutStaticCoverage_BecomesDynamicCandidate() + { + var device = BuildDevice(); + var point = BuildSlowMeasurementPoint(device); + + var plans = Iec61850ReportPlanner.BuildPlans(device, new[] { point }); + + var plan = Assert.Single(plans); + Assert.Equal("Dynamic candidate", plan.Status); + Assert.True(plan.AllowDynamicDataSetWrites); + Assert.Contains(point, plan.Bindings); + } + + [Fact] + public void BuildPlans_AllUncoveredPoints_AppearExactlyOnceInDynamicCandidates() + { + var device = BuildDevice(); + var fast = BuildFastStatusPoint(device); + var slow = BuildSlowMeasurementPoint(device); + + var plans = Iec61850ReportPlanner.BuildPlans(device, new[] { fast, slow }); + + Assert.All(plans, plan => Assert.Equal("Dynamic candidate", plan.Status)); + var bindings = plans.SelectMany(plan => plan.Bindings).ToArray(); + Assert.Equal(2, bindings.Length); + Assert.Single(bindings, point => point.PointKey == fast.PointKey); + Assert.Single(bindings, point => point.PointKey == slow.PointKey); + } + [Fact] public void BuildDynamicFallbackPlans_FastPoint_IsNotExcludedByPollingInterval() { @@ -70,4 +100,18 @@ private static Iec61850MonitorPoint BuildFastStatusPoint(Iec61850MonitorDevice d Category = "Position", PollingIntervalMs = 250 }; + + private static Iec61850MonitorPoint BuildSlowMeasurementPoint(Iec61850MonitorDevice device) + => new() + { + DeviceId = device.DeviceId, + DeviceName = device.Name, + IpAddress = device.IpAddress, + SignalName = "Phase A current", + IecReference = "IED1LD0/MMXU1.A.phsA.cVal.mag.f", + FunctionalConstraint = "MX", + IecDataType = "Float32", + Category = "Measurement", + PollingIntervalMs = 2000 + }; }