feat(gateway): add ArrayAddressNormalizer for bare-name array AddItem

This commit is contained in:
Joseph Doherty
2026-06-18 02:51:37 -04:00
parent 8ac9a33d91
commit 52cd0da9f5
2 changed files with 148 additions and 0 deletions
@@ -0,0 +1,105 @@
using ZB.MOM.WW.MxGateway.Contracts.Proto.Galaxy;
using ZB.MOM.WW.MxGateway.Server.Galaxy;
using ZB.MOM.WW.MxGateway.Server.Sessions;
namespace ZB.MOM.WW.MxGateway.Tests.Gateway.Sessions;
public sealed class ArrayAddressNormalizerTests
{
/// <summary>Verifies a bare array attribute name gains the trailing array suffix.</summary>
[Fact]
public void Normalize_BareArrayName_AppendsArraySuffix()
{
ArrayAddressNormalizer normalizer = CreateNormalizer();
Assert.Equal("Obj.Arr[]", normalizer.Normalize("Obj.Arr"));
}
/// <summary>Verifies an already-suffixed address is returned unchanged.</summary>
[Fact]
public void Normalize_AlreadySuffixed_ReturnsUnchanged()
{
ArrayAddressNormalizer normalizer = CreateNormalizer();
Assert.Equal("Obj.Arr[]", normalizer.Normalize("Obj.Arr[]"));
}
/// <summary>Verifies a scalar attribute is returned unchanged.</summary>
[Fact]
public void Normalize_ScalarAttribute_ReturnsUnchanged()
{
ArrayAddressNormalizer normalizer = CreateNormalizer();
Assert.Equal("Obj.Scalar", normalizer.Normalize("Obj.Scalar"));
}
/// <summary>Verifies an address absent from the cache is returned unchanged.</summary>
[Fact]
public void Normalize_UnknownAddress_ReturnsUnchanged()
{
ArrayAddressNormalizer normalizer = CreateNormalizer();
Assert.Equal("Obj.Unknown", normalizer.Normalize("Obj.Unknown"));
}
/// <summary>Verifies null, empty, and whitespace addresses are returned unchanged.</summary>
[Theory]
[InlineData("")]
[InlineData(" ")]
public void Normalize_BlankAddress_ReturnsUnchanged(string address)
{
ArrayAddressNormalizer normalizer = CreateNormalizer();
Assert.Equal(address, normalizer.Normalize(address));
}
private static ArrayAddressNormalizer CreateNormalizer()
{
IReadOnlyList<GalaxyObject> objects =
[
new GalaxyObject
{
GobjectId = 1,
TagName = "Obj",
ContainedName = "Obj",
Attributes =
{
new GalaxyAttribute
{
AttributeName = "Arr",
// Galaxy SQL already appends "[]" to array attribute references.
FullTagReference = "Obj.Arr[]",
IsArray = true,
},
new GalaxyAttribute
{
AttributeName = "Scalar",
FullTagReference = "Obj.Scalar",
IsArray = false,
},
},
},
];
GalaxyHierarchyCacheEntry entry = GalaxyHierarchyCacheEntry.Empty with
{
Status = GalaxyCacheStatus.Healthy,
Objects = objects,
Index = GalaxyHierarchyIndex.Build(objects),
};
return new ArrayAddressNormalizer(new StubGalaxyHierarchyCache(entry));
}
private sealed class StubGalaxyHierarchyCache(GalaxyHierarchyCacheEntry current) : IGalaxyHierarchyCache
{
/// <summary>Gets the current cache entry.</summary>
public GalaxyHierarchyCacheEntry Current { get; } = current;
/// <inheritdoc />
public Task RefreshAsync(CancellationToken cancellationToken) => Task.CompletedTask;
/// <inheritdoc />
public Task WaitForFirstLoadAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
}