fix(driver-focas): equipment tags forced read-only until PMC writes exist; shared readers + Inspect (R2-11, 05/UNDER-1)

This commit is contained in:
Joseph Doherty
2026-07-13 11:01:55 -04:00
parent 4f5bbd253c
commit e294416087
4 changed files with 105 additions and 7 deletions
@@ -0,0 +1,57 @@
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Driver.FOCAS;
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests;
/// <summary>
/// R2-11 (05/CONV-2 + 05/UNDER-1) strictness surface for the FOCAS equipment-tag parser: lenient
/// runtime freeze on <c>dataType</c>, forced read-only (<c>Writable == false</c> regardless of any
/// authored <c>writable:true</c>), and <c>Inspect</c> reporting the typo + the write-request.
/// </summary>
public sealed class FocasEquipmentTagParserStrictnessTests
{
[Fact]
public void Freeze_typo_dataType_still_defaults_to_Int32()
{
FocasEquipmentTagParser.TryParse("{\"address\":\"D0100\",\"dataType\":\"Int322\"}", out var def)
.ShouldBeTrue();
def.DataType.ShouldBe(FocasDataType.Int32);
}
[Fact]
public void Writable_is_always_false_even_when_requested_true()
{
FocasEquipmentTagParser.TryParse("{\"address\":\"D0100\",\"dataType\":\"Int32\",\"writable\":true}", out var def)
.ShouldBeTrue();
def.Writable.ShouldBeFalse();
}
[Fact]
public void Writable_is_false_when_absent()
{
FocasEquipmentTagParser.TryParse("{\"address\":\"D0100\",\"dataType\":\"Int32\"}", out var def)
.ShouldBeTrue();
def.Writable.ShouldBeFalse();
}
[Fact]
public void Inspect_warns_on_writable_true_request()
{
var warnings = FocasEquipmentTagParser.Inspect("{\"address\":\"D0100\",\"dataType\":\"Int32\",\"writable\":true}");
warnings.ShouldContain(w => w.Contains("read-only") && w.Contains("writable"));
}
[Fact]
public void Inspect_reports_typo_dataType()
{
var warnings = FocasEquipmentTagParser.Inspect("{\"address\":\"D0100\",\"dataType\":\"Int322\"}");
warnings.ShouldContain(w => w.Contains("Int322") && w.Contains("dataType"));
}
[Fact]
public void Inspect_clean_read_only_config_has_no_warnings()
{
FocasEquipmentTagParser.Inspect("{\"address\":\"D0100\",\"dataType\":\"Int32\"}").ShouldBeEmpty();
}
}