refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)
Solution + 23 src projects + 26 test projects renamed; folders, csproj, namespaces, and ScadaLinkDbContext/ScadaBridgeDbContext class updated. ActorSystem "scadalink" → "scadabridge", Akka seed-node URLs migrated. SQL roles/logins, LDAP domains, CLI command name, and CLI config dir (~/.scadalink → ~/.scadabridge) also renamed. Build green; 5 Host.Tests fail awaiting SQL login rename in next commit. Pre-existing StaleTagMonitor timing flakes unchanged. Rename script committed at tools/rename-to-scadabridge.sh.
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Templates;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.TemplateEngine.Tests;
|
||||
|
||||
public class CollisionDetectorTests
|
||||
{
|
||||
// ========================================================================
|
||||
// WP-12: Naming Collision Detection
|
||||
// ========================================================================
|
||||
|
||||
[Fact]
|
||||
public void DetectCollisions_NoCollisions_ReturnsEmpty()
|
||||
{
|
||||
var template = new Template("Pump") { Id = 1 };
|
||||
template.Attributes.Add(new TemplateAttribute("Speed") { Id = 1, TemplateId = 1, DataType = DataType.Float });
|
||||
template.Alarms.Add(new TemplateAlarm("HighTemp") { Id = 1, TemplateId = 1, TriggerType = AlarmTriggerType.ValueMatch });
|
||||
|
||||
var all = new List<Template> { template };
|
||||
var collisions = CollisionDetector.DetectCollisions(template, all);
|
||||
|
||||
Assert.Empty(collisions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectCollisions_DifferentModulesNoPrefixCollision_ReturnsEmpty()
|
||||
{
|
||||
// Two composed modules with same member name but different instance names
|
||||
var moduleA = new Template("ModuleA") { Id = 2 };
|
||||
moduleA.Attributes.Add(new TemplateAttribute("Value") { Id = 10, TemplateId = 2, DataType = DataType.Float });
|
||||
|
||||
var moduleB = new Template("ModuleB") { Id = 3 };
|
||||
moduleB.Attributes.Add(new TemplateAttribute("Value") { Id = 11, TemplateId = 3, DataType = DataType.Float });
|
||||
|
||||
var template = new Template("Pump") { Id = 1 };
|
||||
template.Compositions.Add(new TemplateComposition("modA") { Id = 1, TemplateId = 1, ComposedTemplateId = 2 });
|
||||
template.Compositions.Add(new TemplateComposition("modB") { Id = 2, TemplateId = 1, ComposedTemplateId = 3 });
|
||||
|
||||
var all = new List<Template> { template, moduleA, moduleB };
|
||||
var collisions = CollisionDetector.DetectCollisions(template, all);
|
||||
|
||||
// modA.Value and modB.Value are different canonical names => no collision
|
||||
Assert.Empty(collisions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectCollisions_DirectAndComposedNameCollision_ReturnsCollision()
|
||||
{
|
||||
// Template has a direct attribute "Speed"
|
||||
// Composed module also has an attribute that would produce canonical name "Speed"
|
||||
// This happens when a module's member has no prefix collision — actually
|
||||
// composed members always have a prefix so this shouldn't collide.
|
||||
// But a direct member "modA.Value" would collide with modA.Value from composition.
|
||||
// Let's test: direct attr named "modA.Value" and composition modA with member "Value"
|
||||
|
||||
var module = new Template("Module") { Id = 2 };
|
||||
module.Attributes.Add(new TemplateAttribute("Value") { Id = 10, TemplateId = 2, DataType = DataType.Float });
|
||||
|
||||
var template = new Template("Pump") { Id = 1 };
|
||||
template.Attributes.Add(new TemplateAttribute("modA.Value") { Id = 1, TemplateId = 1, DataType = DataType.Float });
|
||||
template.Compositions.Add(new TemplateComposition("modA") { Id = 1, TemplateId = 1, ComposedTemplateId = 2 });
|
||||
|
||||
var all = new List<Template> { template, module };
|
||||
var collisions = CollisionDetector.DetectCollisions(template, all);
|
||||
|
||||
Assert.NotEmpty(collisions);
|
||||
Assert.Contains(collisions, c => c.Contains("modA.Value"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectCollisions_NestedComposition_ReturnsCorrectCanonicalNames()
|
||||
{
|
||||
// Inner module
|
||||
var inner = new Template("Inner") { Id = 3 };
|
||||
inner.Attributes.Add(new TemplateAttribute("Pressure") { Id = 30, TemplateId = 3, DataType = DataType.Float });
|
||||
|
||||
// Outer module composes inner
|
||||
var outer = new Template("Outer") { Id = 2 };
|
||||
outer.Compositions.Add(new TemplateComposition("inner1") { Id = 1, TemplateId = 2, ComposedTemplateId = 3 });
|
||||
|
||||
// Main template composes outer
|
||||
var main = new Template("Main") { Id = 1 };
|
||||
main.Compositions.Add(new TemplateComposition("outer1") { Id = 2, TemplateId = 1, ComposedTemplateId = 2 });
|
||||
|
||||
var all = new List<Template> { main, outer, inner };
|
||||
var collisions = CollisionDetector.DetectCollisions(main, all);
|
||||
|
||||
// No collision, just checking it doesn't crash on nested compositions
|
||||
Assert.Empty(collisions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectCollisions_InheritedMembersCollideWithComposed_ReturnsCollision()
|
||||
{
|
||||
// Parent has a direct attribute "modA.Temp"
|
||||
var parent = new Template("Base") { Id = 1 };
|
||||
parent.Attributes.Add(new TemplateAttribute("modA.Temp") { Id = 10, TemplateId = 1, DataType = DataType.Float });
|
||||
|
||||
// Module has attribute "Temp"
|
||||
var module = new Template("Module") { Id = 3 };
|
||||
module.Attributes.Add(new TemplateAttribute("Temp") { Id = 30, TemplateId = 3, DataType = DataType.Float });
|
||||
|
||||
// Child inherits from parent and composes module as "modA"
|
||||
var child = new Template("Child") { Id = 2, ParentTemplateId = 1 };
|
||||
child.Compositions.Add(new TemplateComposition("modA") { Id = 1, TemplateId = 2, ComposedTemplateId = 3 });
|
||||
|
||||
var all = new List<Template> { parent, child, module };
|
||||
var collisions = CollisionDetector.DetectCollisions(child, all);
|
||||
|
||||
// "modA.Temp" from parent and "modA.Temp" from composed module
|
||||
Assert.NotEmpty(collisions);
|
||||
Assert.Contains(collisions, c => c.Contains("modA.Temp"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user