feat(drivers): shared EquipmentTagRefResolver (by-name + parse-on-miss + cache)

This commit is contained in:
Joseph Doherty
2026-06-13 11:07:23 -04:00
parent 6b041c6daa
commit eaa335d779
2 changed files with 100 additions and 0 deletions
@@ -0,0 +1,54 @@
using Shouldly;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using Xunit;
namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions.Tests;
public class EquipmentTagRefResolverTests
{
private sealed record Def(string Id);
private static EquipmentTagRefResolver<Def> Make(
Dictionary<string, Def> byName, Func<string, Def?> parse)
=> new(r => byName.TryGetValue(r, out var d) ? d : null, parse);
[Fact]
public void Legacy_name_resolves_via_byName()
{
var r = Make(new() { ["Temp"] = new Def("Temp") }, _ => null);
r.TryResolve("Temp", out var def).ShouldBeTrue();
def!.Id.ShouldBe("Temp");
}
[Fact]
public void Equipment_ref_resolves_via_parse_and_is_cached()
{
var calls = 0;
var r = Make(new(), reference => { calls++; return reference.StartsWith("{") ? new Def(reference) : null; });
r.TryResolve("{\"a\":1}", out var d1).ShouldBeTrue();
r.TryResolve("{\"a\":1}", out var d2).ShouldBeTrue();
d1!.Id.ShouldBe("{\"a\":1}");
calls.ShouldBe(1);
}
[Fact]
public void Garbage_ref_returns_false_and_caches_negative()
{
var calls = 0;
var r = Make(new(), _ => { calls++; return null; });
r.TryResolve("nope", out _).ShouldBeFalse();
r.TryResolve("nope", out _).ShouldBeFalse();
calls.ShouldBe(1);
}
[Fact]
public void Clear_drops_transient_cache()
{
var calls = 0;
var r = Make(new(), reference => { calls++; return new Def(reference); });
r.TryResolve("{\"a\":1}", out _).ShouldBeTrue();
r.Clear();
r.TryResolve("{\"a\":1}", out _).ShouldBeTrue();
calls.ShouldBe(2);
}
}