test(opcua): cover missing-script fallback; rename composer local for clarity
This commit is contained in:
@@ -190,7 +190,7 @@ public static class Phase7Composer
|
|||||||
IReadOnlyList<Script>? scripts = null)
|
IReadOnlyList<Script>? scripts = null)
|
||||||
{
|
{
|
||||||
var vtags = virtualTags ?? Array.Empty<VirtualTag>();
|
var vtags = virtualTags ?? Array.Empty<VirtualTag>();
|
||||||
var scripts2 = scripts ?? Array.Empty<Script>();
|
var resolvedScripts = scripts ?? Array.Empty<Script>();
|
||||||
var areas = unsAreas
|
var areas = unsAreas
|
||||||
.OrderBy(a => a.UnsAreaId, StringComparer.Ordinal)
|
.OrderBy(a => a.UnsAreaId, StringComparer.Ordinal)
|
||||||
.Select(a => new UnsAreaProjection(a.UnsAreaId, a.Name))
|
.Select(a => new UnsAreaProjection(a.UnsAreaId, a.Name))
|
||||||
@@ -267,7 +267,7 @@ public static class Phase7Composer
|
|||||||
// Equipment VirtualTags = each VirtualTag joined to its Script (by ScriptId) for the
|
// Equipment VirtualTags = each VirtualTag joined to its Script (by ScriptId) for the
|
||||||
// expression source. DependencyRefs = the distinct ctx.GetTag("…") literals the
|
// expression source. DependencyRefs = the distinct ctx.GetTag("…") literals the
|
||||||
// VirtualTagActor subscribes to. VirtualTag has no FolderPath today → "".
|
// VirtualTagActor subscribes to. VirtualTag has no FolderPath today → "".
|
||||||
var scriptsById = scripts2.ToDictionary(s => s.ScriptId, StringComparer.Ordinal);
|
var scriptsById = resolvedScripts.ToDictionary(s => s.ScriptId, StringComparer.Ordinal);
|
||||||
var equipmentVirtualTags = vtags
|
var equipmentVirtualTags = vtags
|
||||||
.OrderBy(v => v.EquipmentId, StringComparer.Ordinal)
|
.OrderBy(v => v.EquipmentId, StringComparer.Ordinal)
|
||||||
.ThenBy(v => v.Name, StringComparer.Ordinal)
|
.ThenBy(v => v.Name, StringComparer.Ordinal)
|
||||||
|
|||||||
@@ -182,6 +182,34 @@ public sealed class Phase7ComposerPurityTests
|
|||||||
plan.DependencyRefs.ShouldBe(new[] { "A.X", "B.Y" });
|
plan.DependencyRefs.ShouldBe(new[] { "A.X", "B.Y" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>A <see cref="VirtualTag"/> whose <c>ScriptId</c> has no matching <see cref="Script"/>
|
||||||
|
/// in the supplied list falls back to an empty Expression and an empty DependencyRefs —
|
||||||
|
/// the plan is always emitted (never dropped) and never carries a null Expression.</summary>
|
||||||
|
[Fact]
|
||||||
|
public void Compose_virtualtag_with_missing_script_yields_empty_expression_and_deps()
|
||||||
|
{
|
||||||
|
var vt = new VirtualTag
|
||||||
|
{
|
||||||
|
VirtualTagId = "vt-missing",
|
||||||
|
EquipmentId = "eq-1",
|
||||||
|
Name = "mystery-tag",
|
||||||
|
DataType = "Float64",
|
||||||
|
ScriptId = "s-does-not-exist",
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = Phase7Composer.Compose(
|
||||||
|
Array.Empty<UnsArea>(), Array.Empty<UnsLine>(), Array.Empty<Equipment>(),
|
||||||
|
Array.Empty<DriverInstance>(), Array.Empty<ScriptedAlarm>(),
|
||||||
|
Array.Empty<Tag>(), Array.Empty<Namespace>(),
|
||||||
|
virtualTags: new[] { vt },
|
||||||
|
scripts: Array.Empty<Script>());
|
||||||
|
|
||||||
|
var plan = result.EquipmentVirtualTags.ShouldHaveSingleItem();
|
||||||
|
plan.VirtualTagId.ShouldBe("vt-missing");
|
||||||
|
plan.Expression.ShouldBe(string.Empty);
|
||||||
|
plan.DependencyRefs.ShouldBeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
private static Equipment NewEquipment(string id) => new()
|
private static Equipment NewEquipment(string id) => new()
|
||||||
{
|
{
|
||||||
EquipmentId = id,
|
EquipmentId = id,
|
||||||
|
|||||||
Reference in New Issue
Block a user