Files
lmxopcua/tests/Core/ZB.MOM.WW.OtOpcUa.Commons.Tests/EquipmentScriptPathsTests.cs
T

188 lines
5.4 KiB
C#

using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Commons.Types;
namespace ZB.MOM.WW.OtOpcUa.Commons.Tests;
public class EquipmentScriptPathsTests
{
// ---- DeriveEquipmentBase ----
[Fact]
public void DeriveEquipmentBase_returns_shared_prefix()
{
EquipmentScriptPaths
.DeriveEquipmentBase(["TestMachine_001.A", "TestMachine_001.B"])
.ShouldBe("TestMachine_001");
}
[Fact]
public void DeriveEquipmentBase_returns_null_when_prefixes_diverge()
{
EquipmentScriptPaths
.DeriveEquipmentBase(["TestMachine_001.A", "DelmiaReceiver_001.B"])
.ShouldBeNull();
}
[Fact]
public void DeriveEquipmentBase_returns_null_for_empty_sequence()
{
EquipmentScriptPaths
.DeriveEquipmentBase([])
.ShouldBeNull();
}
[Fact]
public void DeriveEquipmentBase_returns_whole_value_when_no_dot()
{
EquipmentScriptPaths
.DeriveEquipmentBase(["NoDot"])
.ShouldBe("NoDot");
}
[Fact]
public void DeriveEquipmentBase_skips_null_empty_and_whitespace_entries()
{
EquipmentScriptPaths
.DeriveEquipmentBase([null, "", " ", "TestMachine_001.A"])
.ShouldBe("TestMachine_001");
}
// ---- SubstituteEquipmentToken ----
[Fact]
public void SubstituteEquipmentToken_substitutes_inside_GetTag()
{
var result = EquipmentScriptPaths.SubstituteEquipmentToken(
"ctx.GetTag(\"{{equip}}.Source\")", "TestMachine_001");
result.ShouldContain("ctx.GetTag(\"TestMachine_001.Source\")");
}
[Fact]
public void SubstituteEquipmentToken_substitutes_inside_SetVirtualTag()
{
var result = EquipmentScriptPaths.SubstituteEquipmentToken(
"ctx.SetVirtualTag(\"{{equip}}.Out\", x)", "TestMachine_001");
result.ShouldContain("ctx.SetVirtualTag(\"TestMachine_001.Out\"");
}
[Fact]
public void SubstituteEquipmentToken_leaves_comment_unchanged()
{
var source = "// uses {{equip}} here";
EquipmentScriptPaths.SubstituteEquipmentToken(source, "TestMachine_001")
.ShouldBe(source);
}
[Fact]
public void SubstituteEquipmentToken_leaves_logger_string_unchanged()
{
var source = "ctx.Logger.Information(\"{{equip}}\")";
EquipmentScriptPaths.SubstituteEquipmentToken(source, "TestMachine_001")
.ShouldBe(source);
}
[Fact]
public void SubstituteEquipmentToken_substitutes_all_occurrences()
{
var source = "ctx.GetTag(\"{{equip}}.A\"); ctx.GetTag(\"{{equip}}.B\");";
var result = EquipmentScriptPaths.SubstituteEquipmentToken(source, "TestMachine_001");
result.ShouldContain("ctx.GetTag(\"TestMachine_001.A\")");
result.ShouldContain("ctx.GetTag(\"TestMachine_001.B\")");
result.ShouldNotContain(EquipmentScriptPaths.EquipToken);
}
[Fact]
public void SubstituteEquipmentToken_is_identity_when_equipBase_is_null()
{
var source = "ctx.GetTag(\"{{equip}}.Source\")";
EquipmentScriptPaths.SubstituteEquipmentToken(source, null)
.ShouldBe(source);
}
[Fact]
public void SubstituteEquipmentToken_is_identity_when_equipBase_is_empty()
{
var source = "ctx.GetTag(\"{{equip}}.Source\")";
EquipmentScriptPaths.SubstituteEquipmentToken(source, "")
.ShouldBe(source);
}
[Fact]
public void SubstituteEquipmentToken_is_identity_when_token_absent()
{
var source = "ctx.GetTag(\"TestMachine_001.Source\")";
EquipmentScriptPaths.SubstituteEquipmentToken(source, "TestMachine_001")
.ShouldBe(source);
}
[Fact]
public void SubstituteEquipmentToken_does_not_touch_raw_string_literal()
{
// Documents the regex limitation: only "double-quote" literals are handled,
// matching the existing seam extractors. A raw-string literal is left as-is.
var source = "ctx.GetTag(\"\"\"{{equip}}.X\"\"\")";
EquipmentScriptPaths.SubstituteEquipmentToken(source, "TestMachine_001")
.ShouldBe(source);
}
// ---- ExtractDependencyRefs ----
[Fact]
public void ExtractDependencyRefs_returns_distinct_refs_in_first_seen_order()
{
var source = "ctx.GetTag(\"A\"); ctx.GetTag(\"B\"); ctx.GetTag(\"A\");";
EquipmentScriptPaths.ExtractDependencyRefs(source)
.ShouldBe(["A", "B"]);
}
[Fact]
public void ExtractDependencyRefs_excludes_SetVirtualTag_writes()
{
var source = "ctx.GetTag(\"X\"); ctx.SetVirtualTag(\"Y\", 1);";
EquipmentScriptPaths.ExtractDependencyRefs(source)
.ShouldBe(["X"]);
}
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
public void ExtractDependencyRefs_returns_empty_for_null_or_whitespace(string? source)
{
EquipmentScriptPaths.ExtractDependencyRefs(source).ShouldBeEmpty();
}
// ---- ContainsEquipToken ----
[Fact]
public void ContainsEquipToken_true_when_token_present()
{
EquipmentScriptPaths.ContainsEquipToken("ctx.GetTag(\"{{equip}}.X\")").ShouldBeTrue();
}
[Fact]
public void ContainsEquipToken_false_when_token_absent()
{
EquipmentScriptPaths.ContainsEquipToken("ctx.GetTag(\"X\")").ShouldBeFalse();
}
[Fact]
public void ContainsEquipToken_false_for_null()
{
EquipmentScriptPaths.ContainsEquipToken(null).ShouldBeFalse();
}
}