docs: backfill XML documentation across 756 files
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped

Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public
members surfaced by commentchecker — resolves 5,847 of 5,869 issues
(99.6%) across three /fixdocs passes.
This commit is contained in:
Joseph Doherty
2026-05-28 08:10:17 -04:00
parent f9fc7dd2e1
commit 64e3fbe035
756 changed files with 9876 additions and 96 deletions
@@ -12,6 +12,7 @@ namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions.Tests.Alarms;
/// </summary>
public sealed class AlarmConditionInfoTests
{
/// <summary>Verifies that the legacy three-argument constructor still compiles and defaults refs to null.</summary>
[Fact]
public void LegacyThreeArgConstructor_StillCompiles_AndDefaultsRefsToNull()
{
@@ -30,6 +31,7 @@ public sealed class AlarmConditionInfoTests
info.AckMsgWriteRef.ShouldBeNull();
}
/// <summary>Verifies that the full constructor populates all five sub-attribute references.</summary>
[Fact]
public void FullConstructor_PopulatesAllFiveSubAttributeRefs()
{
@@ -50,6 +52,7 @@ public sealed class AlarmConditionInfoTests
info.AckMsgWriteRef.ShouldBe("Tank1.HiAlarm.AckMsg");
}
/// <summary>Verifies that record equality compares all eight fields.</summary>
[Fact]
public void RecordEquality_ComparesAllEightFields()
{
@@ -66,6 +69,7 @@ public sealed class AlarmConditionInfoTests
a.ShouldBe(b);
}
/// <summary>Verifies that records are distinct when any reference differs.</summary>
[Fact]
public void RecordEquality_DistinctWhenAnyRefDiffers()
{
@@ -78,6 +82,7 @@ public sealed class AlarmConditionInfoTests
baseInfo.ShouldNotBe(differingAckRef);
}
/// <summary>Verifies that with-expressions allow partial updates.</summary>
[Fact]
public void WithExpression_AllowsPartialUpdates()
{
@@ -17,6 +17,7 @@ public sealed class DriverHealthTests
/// all carry a non-null message. The old XML doc "null when state is Healthy" was wrong;
/// this test makes the type's actual contract explicit so future doc churn cannot drift.
/// </summary>
/// <param name="state">The driver state to test.</param>
[Theory]
[InlineData(DriverState.Unknown)]
[InlineData(DriverState.Initializing)]
@@ -36,6 +37,7 @@ public sealed class DriverHealthTests
healthWithoutError.State.ShouldBe(state);
}
/// <summary>Verifies that DriverState enum contains all expected members.</summary>
[Fact]
public void DriverState_EnumContainsExpectedMembers()
{
@@ -16,6 +16,9 @@ public sealed class DriverTypeRegistryTests
TagConfigJsonSchema: "{\"type\": \"object\"}",
Tier: tier);
/// <summary>
/// Verifies that Register followed by Get round-trips metadata correctly.
/// </summary>
[Fact]
public void Register_ThenGet_RoundTrips()
{
@@ -27,6 +30,10 @@ public sealed class DriverTypeRegistryTests
registry.Get("Modbus").ShouldBe(metadata);
}
/// <summary>
/// Verifies that Register accepts and preserves non-null tier values.
/// </summary>
/// <param name="tier">The driver tier to test.</param>
[Theory]
[InlineData(DriverTier.A)]
[InlineData(DriverTier.B)]
@@ -41,6 +48,9 @@ public sealed class DriverTypeRegistryTests
registry.Get(metadata.TypeName).Tier.ShouldBe(tier);
}
/// <summary>
/// Verifies that Get is case-insensitive when looking up driver types.
/// </summary>
[Fact]
public void Get_IsCaseInsensitive()
{
@@ -51,6 +61,9 @@ public sealed class DriverTypeRegistryTests
registry.Get("GALAXY").ShouldNotBeNull();
}
/// <summary>
/// Verifies that Get throws when looking up an unknown type.
/// </summary>
[Fact]
public void Get_UnknownType_Throws()
{
@@ -60,6 +73,9 @@ public sealed class DriverTypeRegistryTests
Should.Throw<KeyNotFoundException>(() => registry.Get("UnregisteredType"));
}
/// <summary>
/// Verifies that TryGet returns null when looking up an unknown type.
/// </summary>
[Fact]
public void TryGet_UnknownType_ReturnsNull()
{
@@ -69,6 +85,9 @@ public sealed class DriverTypeRegistryTests
registry.TryGet("UnregisteredType").ShouldBeNull();
}
/// <summary>
/// Verifies that Register throws when attempting to register a duplicate type.
/// </summary>
[Fact]
public void Register_DuplicateType_Throws()
{
@@ -78,6 +97,9 @@ public sealed class DriverTypeRegistryTests
Should.Throw<InvalidOperationException>(() => registry.Register(SampleMetadata("Modbus")));
}
/// <summary>
/// Verifies that duplicate type detection is case-insensitive.
/// </summary>
[Fact]
public void Register_DuplicateTypeIsCaseInsensitive()
{
@@ -87,6 +109,9 @@ public sealed class DriverTypeRegistryTests
Should.Throw<InvalidOperationException>(() => registry.Register(SampleMetadata("modbus")));
}
/// <summary>
/// Verifies that All returns all registered driver types.
/// </summary>
[Fact]
public void All_ReturnsRegisteredTypes()
{
@@ -101,6 +126,9 @@ public sealed class DriverTypeRegistryTests
all.Select(m => m.TypeName).ShouldBe(new[] { "Modbus", "S7", "Galaxy" }, ignoreOrder: true);
}
/// <summary>
/// Verifies that NamespaceKindCompatibility flags are implemented as a bitmask.
/// </summary>
[Fact]
public void NamespaceKindCompatibility_FlagsAreBitmask()
{
@@ -112,6 +140,10 @@ public sealed class DriverTypeRegistryTests
both.HasFlag(NamespaceKindCompatibility.Simulated).ShouldBeFalse();
}
/// <summary>
/// Verifies that Get rejects empty or null type names.
/// </summary>
/// <param name="typeName">The type name to test (null, empty, or whitespace).</param>
[Theory]
[InlineData(null)]
[InlineData("")]
@@ -11,6 +11,7 @@ namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions.Tests.Historian;
/// </summary>
public sealed class IHistorianDataSourceContractTests
{
/// <summary>Verifies that the interface lives in the root namespace.</summary>
[Fact]
public void Interface_LivesInRootNamespace()
{
@@ -18,6 +19,7 @@ public sealed class IHistorianDataSourceContractTests
.ShouldBe("ZB.MOM.WW.OtOpcUa.Core.Abstractions");
}
/// <summary>Verifies that the interface is public.</summary>
[Fact]
public void Interface_IsPublic()
{
@@ -25,6 +27,7 @@ public sealed class IHistorianDataSourceContractTests
typeof(IHistorianDataSource).IsInterface.ShouldBeTrue();
}
/// <summary>Verifies that the interface extends IDisposable.</summary>
[Fact]
public void Interface_ExtendsIDisposable()
{
@@ -32,6 +35,9 @@ public sealed class IHistorianDataSourceContractTests
.ShouldBeTrue("data sources own backend connections; the server disposes them on shutdown");
}
/// <summary>Verifies that read methods return the expected task shape.</summary>
/// <param name="methodName">The name of the interface method to inspect.</param>
/// <param name="expectedReturnType">The expected Task return type of the method.</param>
[Theory]
[InlineData("ReadRawAsync", typeof(Task<HistoryReadResult>))]
[InlineData("ReadProcessedAsync", typeof(Task<HistoryReadResult>))]
@@ -44,6 +50,7 @@ public sealed class IHistorianDataSourceContractTests
method!.ReturnType.ShouldBe(expectedReturnType);
}
/// <summary>Verifies that GetHealthSnapshot is synchronous.</summary>
[Fact]
public void GetHealthSnapshot_IsSynchronous()
{
@@ -52,6 +59,7 @@ public sealed class IHistorianDataSourceContractTests
method!.ReturnType.ShouldBe(typeof(HistorianHealthSnapshot));
}
/// <summary>Verifies that HealthSnapshot accepts an empty cluster node list.</summary>
[Fact]
public void HealthSnapshot_AcceptsEmptyClusterNodeList()
{
@@ -72,6 +80,7 @@ public sealed class IHistorianDataSourceContractTests
snapshot.Nodes.ShouldBeEmpty();
}
/// <summary>Verifies that HealthSnapshot preserves cluster nodes.</summary>
[Fact]
public void HealthSnapshot_PreservesClusterNodes()
{
@@ -101,6 +110,7 @@ public sealed class IHistorianDataSourceContractTests
snapshot.Nodes[0].ShouldBe(node);
}
/// <summary>Verifies that ClusterNodeState records are equal by value.</summary>
[Fact]
public void ClusterNodeState_RecordEqualityByValue()
{
@@ -110,6 +120,7 @@ public sealed class IHistorianDataSourceContractTests
a.ShouldBe(b);
}
/// <summary>Verifies that ClusterNodeState instances are distinct by any field.</summary>
[Fact]
public void ClusterNodeState_DistinctByAnyField()
{
@@ -127,6 +138,9 @@ public sealed class IHistorianDataSourceContractTests
/// (see <c>WonderwareHistorianClient</c> / <c>HistorianDataSource</c> usage). This test
/// pins both shapes so accidental changes are caught.
/// </summary>
/// <param name="methodName">The name of the method to test.</param>
/// <param name="parameterName">The name of the parameter to verify.</param>
/// <param name="expectedType">The expected parameter type.</param>
[Theory]
[InlineData("ReadRawAsync", "maxValuesPerNode", typeof(uint))]
[InlineData("ReadEventsAsync", "maxEvents", typeof(int))]
@@ -139,6 +153,10 @@ public sealed class IHistorianDataSourceContractTests
parameter!.ParameterType.ShouldBe(expectedType);
}
/// <summary>Verifies that history provider max parameters have the expected type.</summary>
/// <param name="methodName">The name of the method to test.</param>
/// <param name="parameterName">The name of the parameter to verify.</param>
/// <param name="expectedType">The expected parameter type.</param>
[Theory]
[InlineData("ReadRawAsync", "maxValuesPerNode", typeof(uint))]
[InlineData("ReadEventsAsync", "maxEvents", typeof(int))]
@@ -159,6 +177,7 @@ public sealed class IHistorianDataSourceContractTests
/// historian must implement them). This test pins the asymmetry so an implementer cannot
/// accidentally collapse the two surfaces and so the documented rationale stays load-bearing.
/// </summary>
/// <param name="methodName">The name of the optional method to check.</param>
[Theory]
[InlineData("ReadAtTimeAsync")]
[InlineData("ReadEventsAsync")]
@@ -14,6 +14,7 @@ public sealed class InterfaceIndependenceTests
{
private static readonly Assembly Assembly = typeof(IDriver).Assembly;
/// <summary>Verifies that the assembly has no references outside the BCL.</summary>
[Fact]
public void Assembly_HasNoReferencesOutsideBcl()
{
@@ -37,6 +38,7 @@ public sealed class InterfaceIndependenceTests
$"Found disallowed references: {string.Join(", ", disallowed.Select(a => a.Name))}");
}
/// <summary>Verifies that all public types live in the root namespace.</summary>
[Fact]
public void AllPublicTypes_LiveInRootNamespace()
{
@@ -51,6 +53,8 @@ public sealed class InterfaceIndependenceTests
$"Found types in other namespaces: {string.Join(", ", nonRoot.Select(t => $"{t.FullName}"))}");
}
/// <summary>Verifies that every capability interface is public.</summary>
/// <param name="type">The interface type to check.</param>
[Theory]
[InlineData(typeof(IDriver))]
[InlineData(typeof(ITagDiscovery))]
@@ -10,9 +10,16 @@ public sealed class PollGroupEngineTests
{
private sealed class FakeSource
{
/// <summary>Gets the dictionary of test values keyed by reference.</summary>
public ConcurrentDictionary<string, object?> Values { get; } = new();
/// <summary>Gets or sets the number of read operations performed.</summary>
public int ReadCount;
/// <summary>Simulates reading values from the source.</summary>
/// <param name="refs">The references to read.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>A task returning the data value snapshots.</returns>
public Task<IReadOnlyList<DataValueSnapshot>> ReadAsync(
IReadOnlyList<string> refs, CancellationToken ct)
{
@@ -27,6 +34,7 @@ public sealed class PollGroupEngineTests
}
}
/// <summary>Verifies that the initial poll forces an event for every subscribed tag.</summary>
[Fact]
public async Task Initial_poll_force_raises_every_subscribed_tag()
{
@@ -45,6 +53,7 @@ public sealed class PollGroupEngineTests
engine.Unsubscribe(handle).ShouldBeTrue();
}
/// <summary>Verifies that unchanged values are only raised once.</summary>
[Fact]
public async Task Unchanged_value_raises_only_once()
{
@@ -62,6 +71,7 @@ public sealed class PollGroupEngineTests
events.Count.ShouldBe(1);
}
/// <summary>Verifies that value changes raise new events.</summary>
[Fact]
public async Task Value_change_raises_new_event()
{
@@ -81,6 +91,7 @@ public sealed class PollGroupEngineTests
events.Last().Item3.Value.ShouldBe(2);
}
/// <summary>Verifies that unsubscribe halts the polling loop.</summary>
[Fact]
public async Task Unsubscribe_halts_the_loop()
{
@@ -101,6 +112,7 @@ public sealed class PollGroupEngineTests
events.Count.ShouldBe(afterUnsub);
}
/// <summary>Verifies that intervals below the configured floor are clamped.</summary>
[Fact]
public async Task Interval_below_floor_is_clamped()
{
@@ -121,6 +133,7 @@ public sealed class PollGroupEngineTests
events.Count.ShouldBe(1);
}
/// <summary>Verifies that multiple subscriptions operate independently.</summary>
[Fact]
public async Task Multiple_subscriptions_are_independent()
{
@@ -151,6 +164,7 @@ public sealed class PollGroupEngineTests
engine.Unsubscribe(hb);
}
/// <summary>Verifies that reader exceptions do not crash the polling loop.</summary>
[Fact]
public async Task Reader_exception_does_not_crash_loop()
{
@@ -180,6 +194,7 @@ public sealed class PollGroupEngineTests
events.Count.ShouldBeGreaterThanOrEqualTo(1);
}
/// <summary>Verifies that unsubscribing an unknown handle returns false.</summary>
[Fact]
public async Task Unsubscribe_unknown_handle_returns_false()
{
@@ -190,6 +205,7 @@ public sealed class PollGroupEngineTests
engine.Unsubscribe(foreign).ShouldBeFalse();
}
/// <summary>Verifies that the active subscription count tracks lifecycle changes.</summary>
[Fact]
public async Task ActiveSubscriptionCount_tracks_lifecycle()
{
@@ -208,6 +224,7 @@ public sealed class PollGroupEngineTests
engine.ActiveSubscriptionCount.ShouldBe(0);
}
/// <summary>Verifies that disposing the engine cancels all active subscriptions.</summary>
[Fact]
public async Task DisposeAsync_cancels_all_subscriptions()
{
@@ -446,6 +463,7 @@ public sealed class PollGroupEngineTests
private sealed record DummyHandle : ISubscriptionHandle
{
/// <summary>Gets a diagnostic identifier for this handle.</summary>
public string DiagnosticId => "dummy";
}