docs(tests): fix CommentChecker findings across tests/ — 13,392 → 0 (repo-wide scan clean)

Comment/XML-doc changes only:
- add summaries to ~10k test methods, fixtures, fakes and helpers
  (+ <param> on theories, <returns> on async Task methods,
  <inheritdoc/> on interface implementations the checker can resolve)
- strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N,
  #NN, Component-0NN) from comments, keeping the explanatory text;
  reword false positives in comments only
- real docs on fakes implementing BCL/library interfaces
  (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime)
- reword the last 5 src/ false positives (CWE-1236, failures-1,
  year-0001, M365)

Only non-comment edits: four one-line nested classes split across lines
so members can carry docs. Build 0 errors / 0 warnings.
This commit is contained in:
Joseph Doherty
2026-10-07 15:05:49 -04:00
parent 0ffd4bdbea
commit 513fa1aa16
998 changed files with 17896 additions and 2395 deletions
@@ -18,6 +18,7 @@ public class ScriptAnalysisServiceTests
private static ParameterShape Param(string name, string type = "String", bool required = true) =>
new(name, type, required);
/// <summary>Initializes the service under test with a substitute shared-script catalog.</summary>
public ScriptAnalysisServiceTests()
{
_catalog.GetShapesAsync().Returns(Array.Empty<ScriptShape>());
@@ -26,6 +27,7 @@ public class ScriptAnalysisServiceTests
// ── Diagnose ──────────────────────────────────────────────────────────
/// <summary>Verifies that empty code produces no diagnostic markers.</summary>
[Fact]
public void EmptyCode_NoMarkers()
{
@@ -33,6 +35,7 @@ public class ScriptAnalysisServiceTests
Assert.Empty(resp.Markers);
}
/// <summary>Verifies that a clean script produces no diagnostic markers.</summary>
[Fact]
public void CleanScript_NoMarkers()
{
@@ -40,6 +43,7 @@ public class ScriptAnalysisServiceTests
Assert.Empty(resp.Markers);
}
/// <summary>Verifies that a missing semicolon is reported as a Roslyn diagnostic.</summary>
[Fact]
public void MissingSemicolon_ReportsRoslynDiagnostic()
{
@@ -47,6 +51,7 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Markers, m => m.Code.StartsWith("CS"));
}
/// <summary>Verifies that a forbidden using directive raises diagnostic SCADA001.</summary>
[Fact]
public void ForbiddenUsingDirective_RaisesSCADA001()
{
@@ -54,19 +59,22 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Markers, m => m.Code == "SCADA001" && m.Message.Contains("System.IO"));
}
/// <summary>Verifies that every banned namespace raises a forbidden-using diagnostic.</summary>
/// <param name="ns">The banned namespace to import.</param>
[Theory]
[InlineData("System.Reflection")]
[InlineData("System.Net")]
[InlineData("System.Threading")]
public void ForbiddenUsing_AllBannedNamespaces(string ns)
{
// M3.5: the editor deny-list is sourced from the shared ScriptTrustPolicy.
// The editor deny-list is sourced from the shared ScriptTrustPolicy.
// System.Threading is now a forbidden root (only Tasks +
// CancellationToken(Source) are excepted).
var resp = _svc.Diagnose(new DiagnoseRequest($"using {ns};"));
Assert.Contains(resp.Markers, m => m.Code == "SCADA001" && m.Message.Contains(ns));
}
/// <summary>Verifies that forbidden type usage is detected through the semantic model.</summary>
[Fact]
public void ForbiddenTypeUsage_ResolvesViaSemanticModel()
{
@@ -75,16 +83,18 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Markers, m => m.Code == "SCADA002" && m.Message.Contains("File"));
}
/// <summary>Verifies that the System.Diagnostics namespace is no longer forbidden wholesale.</summary>
[Fact]
public void SystemDiagnosticsNamespace_NoLongerWholesaleForbidden()
{
// M3.5: the unified policy forbids only System.Diagnostics.Process, not the
// The unified policy forbids only System.Diagnostics.Process, not the
// whole System.Diagnostics namespace — so a bare `using System.Diagnostics;`
// is no longer flagged (Stopwatch & friends are allowed).
var resp = _svc.Diagnose(new DiagnoseRequest("using System.Diagnostics;"));
Assert.DoesNotContain(resp.Markers, m => m.Code == "SCADA001");
}
/// <summary>Verifies that Stopwatch usage is allowed under the unified trust policy.</summary>
[Fact]
public void StopwatchUsage_IsAllowedUnderUnifiedPolicy()
{
@@ -95,6 +105,7 @@ public class ScriptAnalysisServiceTests
Assert.DoesNotContain(resp.Markers, m => m.Code is "SCADA001" or "SCADA002");
}
/// <summary>Verifies that Process usage is forbidden under the unified trust policy.</summary>
[Fact]
public void ProcessUsage_IsForbiddenUnderUnifiedPolicy()
{
@@ -105,6 +116,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Markers, m => m.Code == "SCADA002" && m.Message.Contains("Process"));
}
/// <summary>Verifies that threading primitives are flagged under the unified trust policy.</summary>
/// <param name="typeName">The threading type used in the script.</param>
[Theory]
[InlineData("Monitor")]
[InlineData("Interlocked")]
@@ -120,6 +133,7 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Markers, m => m.Code is "SCADA001" or "SCADA002");
}
/// <summary>Verifies that CancellationToken usage stays allowed under the unified trust policy.</summary>
[Fact]
public void CancellationToken_StaysAllowed_UnderUnifiedPolicy()
{
@@ -130,6 +144,7 @@ public class ScriptAnalysisServiceTests
Assert.DoesNotContain(resp.Markers, m => m.Code is "SCADA001" or "SCADA002");
}
/// <summary>Verifies that a user identifier named File does not trigger a false positive.</summary>
[Fact]
public void UserIdentifierNamedFile_DoesNotFalsePositive()
{
@@ -138,6 +153,7 @@ public class ScriptAnalysisServiceTests
Assert.DoesNotContain(resp.Markers, m => m.Code == "SCADA002");
}
/// <summary>Verifies that a user identifier named Thread does not trigger a false positive.</summary>
[Fact]
public void UserIdentifierNamedThread_DoesNotFalsePositive()
{
@@ -146,6 +162,7 @@ public class ScriptAnalysisServiceTests
Assert.DoesNotContain(resp.Markers, m => m.Code == "SCADA002");
}
/// <summary>Verifies that diagnostics are cached so a second call skips recompilation.</summary>
[Fact]
public void DiagnosticsAreCached_SecondCallSkipsRecompile()
{
@@ -155,6 +172,7 @@ public class ScriptAnalysisServiceTests
Assert.Same(first, second);
}
/// <summary>Verifies that different code gets different cache entries.</summary>
[Fact]
public void DifferentCode_GetsDifferentCacheEntries()
{
@@ -163,6 +181,7 @@ public class ScriptAnalysisServiceTests
Assert.NotSame(a, b);
}
/// <summary>Verifies that an unknown parameter key raises diagnostic SCADA003.</summary>
[Fact]
public void UnknownParameterKey_RaisesSCADA003()
{
@@ -172,6 +191,7 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Markers, m => m.Code == "SCADA003" && m.Message.Contains("'typo'"));
}
/// <summary>Verifies that a declared parameter key produces no marker.</summary>
[Fact]
public void DeclaredParameterKey_NoMarker()
{
@@ -183,6 +203,8 @@ public class ScriptAnalysisServiceTests
// ── Completions ───────────────────────────────────────────────────────
/// <summary>Verifies that completion inside a Parameters string literal returns the declared parameter names.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ParametersStringLiteral_ReturnsDeclaredParameterNames()
{
@@ -198,6 +220,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Items, i => i.Label == "temperature");
}
/// <summary>Verifies that completion inside a CallScript string literal returns sibling script names with a snippet.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task CallScriptStringLiteral_ReturnsSiblingNamesWithSnippet()
{
@@ -218,6 +242,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains("sibling script", item.Detail);
}
/// <summary>Verifies that completion inside a CallShared string literal resolves shared scripts through the catalog with their shapes.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task CallSharedStringLiteral_ResolvesViaCatalogWithShapes()
{
@@ -243,6 +269,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains("shared script", greet.Detail);
}
/// <summary>Verifies that general completion returns the in-scope symbols.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GeneralCompletion_ReturnsInScopeSymbols()
{
@@ -258,6 +286,8 @@ public class ScriptAnalysisServiceTests
// ── Hover ─────────────────────────────────────────────────────────────
/// <summary>Verifies that hovering over a sibling script name returns its signature.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Hover_OnSiblingName_ReturnsSignature()
{
@@ -273,6 +303,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains("Calc(x: Integer, y: Float): void", resp.Markdown);
}
/// <summary>Verifies that hovering over an unrelated token returns null.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Hover_OnUnrelatedToken_ReturnsNull()
{
@@ -285,6 +317,8 @@ public class ScriptAnalysisServiceTests
// ── Signature help ────────────────────────────────────────────────────
/// <summary>Verifies that signature help inside a CallScript call returns the parameter strip.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task SignatureHelp_InsideCallScript_ReturnsParameterStrip()
{
@@ -301,6 +335,8 @@ public class ScriptAnalysisServiceTests
Assert.Equal(1, resp.ActiveParameter);
}
/// <summary>Verifies that signature help outside a call returns null.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task SignatureHelp_OutsideCall_ReturnsNull()
{
@@ -313,6 +349,7 @@ public class ScriptAnalysisServiceTests
// ── Format ────────────────────────────────────────────────────────────
/// <summary>Verifies that formatting scrambled code returns pretty-printed code.</summary>
[Fact]
public void Format_ScrambledCode_ReturnsPrettyPrinted()
{
@@ -322,6 +359,7 @@ public class ScriptAnalysisServiceTests
Assert.NotEqual("if(x){return 1;}else{return 2;}", resp.Code);
}
/// <summary>Verifies that formatting empty code returns an empty result.</summary>
[Fact]
public void Format_EmptyCode_ReturnsEmpty()
{
@@ -334,6 +372,8 @@ public class ScriptAnalysisServiceTests
private static CompositionContext Comp(string name, AttributeShape[]? attrs = null, ScriptShape[]? scripts = null)
=> new(name, attrs ?? Array.Empty<AttributeShape>(), scripts ?? Array.Empty<ScriptShape>());
/// <summary>Verifies that completion inside a self attribute literal returns the self attribute names.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task SelfAttribute_Literal_ReturnsSelfAttributeNames()
{
@@ -347,6 +387,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Items, i => i.Label == "Setpoint" && i.Detail.Contains("Float"));
}
/// <summary>Verifies that completion inside a child attribute literal returns the child attribute names.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ChildAttribute_Literal_ReturnsChildAttributeNames()
{
@@ -360,6 +402,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Items, i => i.Label == "Humidity");
}
/// <summary>Verifies that completion inside a parent attribute literal returns the parent attribute names.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ParentAttribute_Literal_ReturnsParentAttributeNames()
{
@@ -372,6 +416,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Items, i => i.Label == "SpeedRPM");
}
/// <summary>Verifies that completion inside a children literal returns the composition names.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ChildrenLiteral_ReturnsCompositionNames()
{
@@ -385,6 +431,7 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Items, i => i.Label == "PressureSensor");
}
/// <summary>Verifies that an unknown self attribute raises diagnostic SCADA006.</summary>
[Fact]
public void UnknownSelfAttribute_RaisesSCADA006()
{
@@ -394,6 +441,7 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Markers, m => m.Code == "SCADA006" && m.Message.Contains("Typo"));
}
/// <summary>Verifies that a known self attribute produces no marker.</summary>
[Fact]
public void KnownSelfAttribute_NoMarker()
{
@@ -403,6 +451,7 @@ public class ScriptAnalysisServiceTests
Assert.DoesNotContain(resp.Markers, m => m.Code == "SCADA006");
}
/// <summary>Verifies that an unknown child attribute raises diagnostic SCADA006.</summary>
[Fact]
public void UnknownChildAttribute_RaisesSCADA006()
{
@@ -412,6 +461,7 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Markers, m => m.Code == "SCADA006" && m.Message.Contains("TempSensor"));
}
/// <summary>Verifies that an unknown composition raises diagnostic SCADA007.</summary>
[Fact]
public void UnknownComposition_RaisesSCADA007()
{
@@ -421,6 +471,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Markers, m => m.Code == "SCADA007" && m.Message.Contains("Unknown"));
}
/// <summary>Verifies that completion inside a children CallScript call returns the child scripts.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ChildrenCallScript_ReturnsChildScripts()
{
@@ -438,6 +490,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains("${1:count}", sample.InsertText);
}
/// <summary>Verifies that completion inside a parent CallScript call returns the parent scripts.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ParentCallScript_ReturnsParentScripts()
{
@@ -452,6 +506,8 @@ public class ScriptAnalysisServiceTests
// ── Hover on Parameters["name"] ───────────────────────────────────────
/// <summary>Verifies that hovering over a Parameters key shows the declared type.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Hover_OnParametersKey_ShowsDeclaredType()
{
@@ -465,8 +521,9 @@ public class ScriptAnalysisServiceTests
Assert.Contains("String", resp.Markdown);
}
// ── CentralUI-001: trust-model gate before sandbox execution ──────────
// ── Trust-model gate before sandbox execution ──────────
/// <summary>Verifies that a fully qualified forbidden call raises diagnostic SCADA002.</summary>
[Fact]
public void Diagnose_FullyQualifiedForbiddenCall_RaisesSCADA002()
{
@@ -478,10 +535,12 @@ public class ScriptAnalysisServiceTests
Assert.Contains(resp.Markers, m => m.Code == "SCADA002");
}
/// <summary>Verifies that a fully qualified forbidden API is blocked before the sandbox executes the script.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RunInSandbox_FullyQualifiedForbiddenApi_IsBlockedBeforeExecution()
{
// Regression test for CentralUI-001. RunInSandboxAsync used to execute any
// Regression test: RunInSandboxAsync used to execute any
// script that compiled, with no trust-model enforcement — so fully-qualified
// forbidden API code ran in the central host process. The fix gates execution
// on the forbidden-API analysis.
@@ -499,6 +558,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains(result.Markers!, m => m.Code is "SCADA001" or "SCADA002");
}
/// <summary>Verifies that a forbidden using directive is blocked before the sandbox executes the script.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RunInSandbox_ForbiddenUsingDirective_IsBlockedBeforeExecution()
{
@@ -513,6 +574,8 @@ public class ScriptAnalysisServiceTests
Assert.Equal(SandboxErrorKind.CompileError, result.ErrorKind);
}
/// <summary>Verifies that a clean script still runs in the sandbox.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RunInSandbox_CleanScript_StillRuns()
{
@@ -525,6 +588,7 @@ public class ScriptAnalysisServiceTests
Assert.Equal("42", result.ReturnValueJson);
}
/// <summary>Verifies that a script using the notification outbox shape diagnoses clean.</summary>
[Fact]
public void NotifyOutboxShape_DiagnosesClean()
{
@@ -542,6 +606,8 @@ public class ScriptAnalysisServiceTests
Assert.DoesNotContain(resp.Markers, m => m.Code.StartsWith("SCADA"));
}
/// <summary>Verifies that a script using the notification outbox shape still runs in the sandbox.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RunInSandbox_NotifyOutboxShape_StillRuns()
{
@@ -561,6 +627,8 @@ public class ScriptAnalysisServiceTests
Assert.Equal("\"Unknown\"", result.ReturnValueJson);
}
/// <summary>Verifies that the sandbox captures console output.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RunInSandbox_CapturesConsoleOutput()
{
@@ -575,6 +643,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains("hello-sandbox", result.ConsoleOutput);
}
/// <summary>Verifies that the Log global writes to the sandbox console output.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RunInSandbox_LogGlobal_WritesToConsoleOutput()
{
@@ -592,6 +662,8 @@ public class ScriptAnalysisServiceTests
Assert.Contains("[info] hello", result.ConsoleOutput);
}
/// <summary>Verifies that the Log global in an inbound script writes to the sandbox console output.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RunInSandbox_InboundScript_LogGlobal_WritesToConsoleOutput()
{
@@ -609,10 +681,12 @@ public class ScriptAnalysisServiceTests
Assert.Contains("[info] hello", result.ConsoleOutput);
}
/// <summary>Verifies that concurrent sandbox runs do not cross-contaminate each other's console output.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RunInSandbox_ConcurrentRuns_DoNotCrossContaminateConsoleOutput()
{
// Regression test for CentralUI-003. RunInSandboxAsync used to redirect the
// Regression test: RunInSandboxAsync used to redirect the
// process-global Console.Out/Error to a per-call StringWriter. While one run
// is mid-flight, any concurrent run's `finally` restores Console.Out to the
// ORIGINAL writer — so the long run loses every Console.WriteLine it makes
@@ -682,6 +756,7 @@ public class ScriptAnalysisServiceTests
// ── Inbound-script analysis surface ──────────────────────────────────
/// <summary>Verifies that an inbound script using WaitForAttribute diagnoses clean.</summary>
[Fact]
public void InboundScript_WaitForAttribute_DiagnosesClean()
{
@@ -696,6 +771,7 @@ public class ScriptAnalysisServiceTests
Assert.DoesNotContain(resp.Markers, m => m.Code.StartsWith("SCADA"));
}
/// <summary>Verifies that an inbound script using Log diagnoses clean.</summary>
[Fact]
public void InboundScript_Log_DiagnosesClean()
{
@@ -714,6 +790,7 @@ public class ScriptAnalysisServiceTests
Assert.DoesNotContain(resp.Markers, m => m.Code.StartsWith("SCADA"));
}
/// <summary>Verifies that a site script using Log diagnoses clean.</summary>
[Fact]
public void SiteScript_Log_DiagnosesClean()
{
@@ -730,10 +807,11 @@ public class ScriptAnalysisServiceTests
Assert.DoesNotContain(resp.Markers, m => m.Code.StartsWith("SCADA"));
}
/// <summary>Verifies that an inbound script using the Database helper diagnoses clean.</summary>
[Fact]
public void InboundScript_Database_DiagnosesClean()
{
// InboundAPI-026/030: the scoped Database helper is a shipped inbound-script
// The scoped Database helper is a shipped inbound-script
// capability. The editor must not flag its async read/write API as an error —
// the InboundScriptHost mirror must expose QuerySingleAsync/QueryAsync/ExecuteAsync
// with signatures matching the runtime helper so Roslyn resolves them.
@@ -747,16 +825,17 @@ public class ScriptAnalysisServiceTests
Assert.DoesNotContain(resp.Markers, m => m.Code.StartsWith("SCADA"));
}
// ── Instance-script batch/wait surface (follow-up #7) ─────────────────
// ── Instance-script batch/wait surface ─────────────────
/// <summary>Verifies that an instance script using the batch-write and wait helpers diagnoses clean.</summary>
[Fact]
public void InstanceScript_BatchAndWaitHelpers_DiagnoseClean()
{
// Follow-up #7: SandboxAttributeAccessor was missing WriteBatchAndWaitAsync /
// SandboxAttributeAccessor was missing WriteBatchAndWaitAsync /
// WaitAsync / WaitForAsync, so the editor false-flagged valid instance scripts
// with CS1061 even though `template validate` and the deploy gate accept them.
// The sandbox surface must mirror the runtime AttributeAccessor member-for-member.
// Gitea #36: also covers the reset-aware WriteBatchAndWaitAsync overload
// Also covers the reset-aware WriteBatchAndWaitAsync overload
// (writes+waits a reset key/value before the batch) with and without the
// optional resetTimeout, returning a HandshakeResult.
var code =
@@ -774,6 +853,7 @@ public class ScriptAnalysisServiceTests
Assert.DoesNotContain(resp.Markers, m => m.Code.StartsWith("SCADA"));
}
/// <summary>Verifies that a child instance script using WriteBatchAndWait diagnoses clean.</summary>
[Fact]
public void ChildInstanceScript_WriteBatchAndWait_DiagnoseClean()
{
@@ -796,6 +876,7 @@ public class ScriptAnalysisServiceTests
// ── Alarms read surface (MES alarm-status API §5.2) ───────────────────
/// <summary>Verifies that an instance script using Alarms.CurrentAsync diagnoses clean.</summary>
[Fact]
public void InstanceScript_AlarmsCurrentAsync_DiagnoseClean()
{