feat(core-abstractions): TagConfigJson shared strict-capable field readers (R2-11, 05/CONV-2)
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
using System.Text.Json;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Pins the shared strict-capable TagConfig field readers (R2-11, 05/CONV-2): the
|
||||
/// <see cref="TagConfigJson.TryReadEnum{TEnum}"/> Absent/Valid/Invalid matrix (case-insensitive),
|
||||
/// <see cref="TagConfigJson.ReadEnumOrDefault{TEnum}"/> lenient equivalence to the retired copies,
|
||||
/// <see cref="TagConfigJson.ReadWritable"/> explicit-false-only semantics, and
|
||||
/// <see cref="TagConfigJson.DescribeInvalidEnum{TEnum}"/> messages.
|
||||
/// </summary>
|
||||
public sealed class TagConfigJsonTests
|
||||
{
|
||||
/// <summary>Sample enum for the reader matrix (public so it can be an <c>[InlineData]</c> arg).</summary>
|
||||
public enum Sample { Alpha, Beta, Gamma }
|
||||
|
||||
private static JsonElement Root(string json) => JsonDocument.Parse(json).RootElement;
|
||||
|
||||
[Theory]
|
||||
[InlineData("{\"k\":\"Beta\"}", JsonEnumRead.Valid, Sample.Beta)]
|
||||
[InlineData("{\"k\":\"beta\"}", JsonEnumRead.Valid, Sample.Beta)] // case-insensitive
|
||||
[InlineData("{\"k\":\"GAMMA\"}", JsonEnumRead.Valid, Sample.Gamma)]
|
||||
[InlineData("{\"k\":\"Deltaa\"}", JsonEnumRead.Invalid, default(Sample))] // typo → Invalid
|
||||
[InlineData("{}", JsonEnumRead.Absent, default(Sample))] // absent
|
||||
[InlineData("{\"k\":123}", JsonEnumRead.Absent, default(Sample))] // non-string → Absent (lenient)
|
||||
[InlineData("{\"k\":null}", JsonEnumRead.Absent, default(Sample))]
|
||||
public void TryReadEnum_matrix(string json, JsonEnumRead expected, Sample expectedValue)
|
||||
{
|
||||
var outcome = TagConfigJson.TryReadEnum<Sample>(Root(json), "k", out var v);
|
||||
outcome.ShouldBe(expected);
|
||||
v.ShouldBe(expectedValue);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("{\"k\":\"Gamma\"}", Sample.Gamma)] // valid → parsed
|
||||
[InlineData("{\"k\":\"typo\"}", Sample.Alpha)] // invalid → fallback
|
||||
[InlineData("{}", Sample.Alpha)] // absent → fallback
|
||||
[InlineData("{\"k\":42}", Sample.Alpha)] // non-string → fallback
|
||||
public void ReadEnumOrDefault_is_lenient(string json, Sample expected)
|
||||
{
|
||||
TagConfigJson.ReadEnumOrDefault(Root(json), "k", Sample.Alpha).ShouldBe(expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("{\"writable\":false}", true, false)] // explicit false → false
|
||||
[InlineData("{\"writable\":true}", true, true)] // explicit true → default
|
||||
[InlineData("{}", true, true)] // absent → default
|
||||
[InlineData("{\"writable\":\"no\"}", true, true)] // non-bool → default
|
||||
[InlineData("{}", false, false)] // absent, default false
|
||||
[InlineData("{\"writable\":false}", false, false)] // explicit false, default false
|
||||
public void ReadWritable_explicit_false_only(string json, bool dflt, bool expected)
|
||||
{
|
||||
TagConfigJson.ReadWritable(Root(json), dflt).ShouldBe(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DescribeInvalidEnum_names_field_value_and_valid_members()
|
||||
{
|
||||
var msg = TagConfigJson.DescribeInvalidEnum<Sample>(Root("{\"dataType\":\"Betaa\"}"), "dataType");
|
||||
msg.ShouldNotBeNull();
|
||||
msg.ShouldContain("Betaa");
|
||||
msg.ShouldContain("dataType");
|
||||
msg.ShouldContain("Alpha");
|
||||
msg.ShouldContain("Beta");
|
||||
msg.ShouldContain("Gamma");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("{\"dataType\":\"Beta\"}")] // valid → null
|
||||
[InlineData("{}")] // absent → null
|
||||
[InlineData("{\"dataType\":5}")] // non-string → null
|
||||
public void DescribeInvalidEnum_null_when_absent_or_valid(string json)
|
||||
{
|
||||
TagConfigJson.DescribeInvalidEnum<Sample>(Root(json), "dataType").ShouldBeNull();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user