fix(transport): base-first template reference resolution on import (ScadaBridge#100 item 1)
TemplateLibrary.GetIdByNameAsync was first-row-wins, so a derived slot template could shadow a same-named base. Now: exact name, base first, derived-only name only when unique, otherwise unresolved (composition audit says ambiguous). Tracked-template indexes are base-first too. Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
+70
@@ -0,0 +1,70 @@
|
||||
using ZB.MOM.WW.ScadaBridge.Transport.Import;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.Transport.Tests.Import;
|
||||
|
||||
/// <summary>
|
||||
/// ScadaBridge#100 item 1: how a bundle's by-name template reference (composed, base or
|
||||
/// instance template name) resolves against target templates the import did not stage.
|
||||
/// Derived (composition-slot) templates carry their slot name and sit outside the filtered
|
||||
/// unique index, so a name can be held by a base template and any number of derived ones.
|
||||
/// </summary>
|
||||
public class TemplateReferenceResolutionTests
|
||||
{
|
||||
/// <summary>A base template wins even when a same-named derived slot template has a lower id
|
||||
/// (the old first-row-wins rule bound the reference to the derived row).</summary>
|
||||
[Fact]
|
||||
public void Base_template_wins_over_a_lower_id_derived_template_of_the_same_name()
|
||||
{
|
||||
var ids = BundleImporter.ResolveTemplateReferenceIds(new[]
|
||||
{
|
||||
(Id: 3, Name: "Motor", IsDerived: true),
|
||||
(Id: 7, Name: "Motor", IsDerived: false),
|
||||
(Id: 9, Name: "Motor", IsDerived: true),
|
||||
});
|
||||
|
||||
Assert.Equal(7, ids["Motor"]);
|
||||
}
|
||||
|
||||
/// <summary>A name held by exactly one derived template and no base still resolves to it —
|
||||
/// composition targets may legitimately be derived templates.</summary>
|
||||
[Fact]
|
||||
public void A_unique_derived_only_name_resolves()
|
||||
{
|
||||
var ids = BundleImporter.ResolveTemplateReferenceIds(new[]
|
||||
{
|
||||
(Id: 4, Name: "Slot1", IsDerived: true),
|
||||
(Id: 5, Name: "Pump", IsDerived: false),
|
||||
});
|
||||
|
||||
Assert.Equal(4, ids["Slot1"]);
|
||||
Assert.Equal(5, ids["Pump"]);
|
||||
}
|
||||
|
||||
/// <summary>Several derived templates sharing a name with no base is ambiguous: the name is
|
||||
/// left unresolved rather than bound to an arbitrary slot owned by another composition.</summary>
|
||||
[Fact]
|
||||
public void Several_derived_templates_and_no_base_is_ambiguous_and_unresolved()
|
||||
{
|
||||
var ids = BundleImporter.ResolveTemplateReferenceIds(new[]
|
||||
{
|
||||
(Id: 2, Name: "Motor", IsDerived: true),
|
||||
(Id: 6, Name: "Motor", IsDerived: true),
|
||||
});
|
||||
|
||||
Assert.False(ids.ContainsKey("Motor"));
|
||||
}
|
||||
|
||||
/// <summary>References stay exact-name: a case variant is a different key (case-insensitive
|
||||
/// matching of references is outside this rule).</summary>
|
||||
[Fact]
|
||||
public void Matching_is_exact_name()
|
||||
{
|
||||
var ids = BundleImporter.ResolveTemplateReferenceIds(new[]
|
||||
{
|
||||
(Id: 1, Name: "Pump", IsDerived: false),
|
||||
});
|
||||
|
||||
Assert.False(ids.ContainsKey("pump"));
|
||||
Assert.Equal(1, ids["Pump"]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user