Skip to content

Add coverage increments 1–3 tests for preserved C# seams and close remaining #199 coverage gaps - #201

Merged
drmoisan merged 10 commits into
mainfrom
refactor/coverage-increments-1-3-199
Jun 15, 2026
Merged

Add coverage increments 1–3 tests for preserved C# seams and close remaining #199 coverage gaps#201
drmoisan merged 10 commits into
mainfrom
refactor/coverage-increments-1-3-199

Conversation

@drmoisan

@drmoisan drmoisan commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Add coverage increments 1–3 tests for preserved C# seams and close remaining #199 coverage gaps

Summary

  • Add MSTest coverage increments across ToDoModel, QuickFiler, and TaskMaster for the post-Refactor: com-vsto-coverage-exemption #197 testable seams, including 14 new test files and recorded covered-line increases in all three production assemblies.
  • Close the remaining #199 gaps by finishing ProjectEntry dialog-branch coverage in Phase 6 and AppFileSystemFolderPaths.MatchBestSpecialFolder coverage in Phase 5.
  • Preserve the Refactor: com-vsto-coverage-exemption #197 coverage-exemption boundary: no ExcludeFromCodeCoverage changes, no coverage.config or TaskMaster.runsettings changes, and no live Outlook/WinForms test execution.
  • Keep the feature focused on coverage uplift rather than product behavior changes, with only three maintainer-authorized seams used to enable deterministic testing.
  • Record evidence for formatter, analyzer, nullable, MSTest-with-coverage, invariants, and coverage comparisons under docs/features/active/2026-06-14-coverage-increments-1-3-testable-seams-199/evidence/.
  • Add scoping, plan, review, audit, and remediation artifacts for the feature folder to document acceptance-criteria delivery and final review state.

Why

  • #197 made the repository coverage metric meaningful by excluding architecturally untestable COM/VSTO/WinForms code, but the post-Refactor: com-vsto-coverage-exemption #197 production-only rate was still 71.65%, below the 80% floor.
  • #199 exists to implement coverage roadmap increments 1–3 on seams that #197 deliberately kept in the measured denominator, so coverage rises by testing genuinely testable code rather than by changing the exemption boundary.
  • The feature specification and issue documents both constrain this work to deterministic MSTest coverage using MSTest + Moq + FluentAssertions, with no temp files, no external dependencies, no live Outlook process, and no silent production refactors.
  • Two previously deferred gaps required explicit follow-up:
    • AppFileSystemFolderPaths.MatchBestSpecialFolder needed a pure-helper extraction to cover the matching logic without crossing prohibited boundaries.
    • ProjectEntry dialog branches needed an injectable dialog seam so the malformed-ID and change-confirmation branches could be tested without invoking raw MessageBox.Show(...).
  • The final acceptance audit records all nine acceptance criteria as PASS and confirms that the remaining gaps from earlier phases were closed before the final review.

What Changed

  • Core behavior / architecture

    • Added the minimal authorized seams needed to finish coverage:
      • UtilitiesCS/Properties/AssemblyInfo.cs: InternalsVisibleTo("ToDoModel.Test").
      • TaskMaster/AppGlobals/AppFileSystemFolderPaths.cs: extracted MatchBestSpecialFolder into an internal static helper while keeping instance delegation.
      • ToDoModel/Data Model/Project/ProjectEntry.cs: replaced three MessageBox.Show(...) calls in the ProjectID setter with equivalent MyBox.ShowDialog(...) routing through MyBox.DialogInvoker.
    • Updated test project files for QuickFiler.Test, TaskMaster.Test, and ToDoModel.Test to support the new coverage work.
  • Tests

    • Added ToDoModel coverage tests for:
      • ToDoLoader.SetAndSave<T>
      • IDList.GetNextToDoID
      • ProjectEntry
      • ProjectEntryDialogBranches
      • BaseChanger remaining branches
    • Added QuickFiler coverage tests for:
      • KaChar
      • KaKey
      • KaStringAsync
      • KbdActions<> remaining branches
      • FilerQueue
      • QfcQueue pure paths
    • Added TaskMaster coverage tests for:
      • AppStagingFilenames
      • AppQuickFilerSettings remaining properties
      • AppFileSystemFolderPaths.MatchBestSpecialFolder
    • The recorded evidence states this feature added 99 passing MSTest unit tests.
  • Docs / templates / agents

    • Added the active feature folder for #199, including issue.md, spec.md, two phase plans, multiple review artifacts, policy audits, remediation inputs, and QA evidence.
    • Updated .claude/agent-memory/... entries to capture lessons from the ProjectEntry raw-message-box coverage blocker and its remediation.

Architecture / How It Fits Together

  • The feature follows a coverage-first workflow:
    1. Identify post-Refactor: com-vsto-coverage-exemption #197 seams that remain in the testable denominator.
    2. Add deterministic MSTest coverage in each existing .Test assembly.
    3. Introduce only maintainer-authorized seams where a pure or injectable boundary is required.
    4. Re-run formatter, analyzer, nullable, MSTest-with-coverage, and coverage comparison evidence gates.
  • By assembly, the wiring is:
    • ToDoModel.Test exercises internal loader/id/project logic, using InternalsVisibleTo and MyBox.DialogInvoker for dialog-path isolation.
    • QuickFiler.Test targets pure controller/value-object/queue behavior with no Outlook or UI dependencies.
    • TaskMaster.Test isolates settings/path logic, including the extracted MatchBestSpecialFolder helper.
  • The acceptance criteria are organized around three coverage increments:
    • Increment 1: ToDoModel seam coverage
    • Increment 2: QuickFiler seam coverage
    • Increment 3: TaskMaster seam coverage
  • The control-flow change in ProjectEntry is intentionally narrow: dialog calls now route through MyBox.ShowDialog(...), which preserves dialog text, button choices, icons, and DialogResult.Yes comparisons while enabling deterministic tests through the existing dialog invoker seam.

Verification

Completed

  • Formatter evidence recorded:
    • csharpier check .
    • EXIT_CODE: 0
    • Sources: final-csharpier.2026-06-14T08-22.md, p6-final-csharpier.2026-06-14T17-00.md
  • Analyzer evidence recorded:
    • MSBuild.exe TaskMaster.sln -t:Build -p:Configuration=Debug -p:Platform="Any CPU" -p:EnableNETAnalyzers=true -p:EnforceCodeStyleInBuild=true
    • EXIT_CODE: 0
    • Sources: final-analyzers.2026-06-14T08-22.md, p6-final-msbuild-analyzers.2026-06-14T17-00.md
  • Nullable/type-safety evidence recorded:
    • MSBuild.exe TaskMaster.sln -t:Build -p:Configuration=Debug -p:Platform="Any CPU" -p:Nullable=enable -p:TreatWarningsAsErrors=true
    • EXIT_CODE: 0
    • Sources: final-nullable.2026-06-14T08-22.md, p6-final-msbuild-nullable.2026-06-14T17-00.md
  • MSTest-with-coverage evidence recorded:
    • Full three-assembly run:
      • vstest.console.exe ToDoModel.Test/bin/Debug/ToDoModel.Test.dll QuickFiler.Test/bin/Debug/QuickFiler.Test.dll TaskMaster.Test/bin/Debug/TaskMaster.Test.dll /InIsolation /EnableCodeCoverage
      • EXIT_CODE: 0
      • Source: final-mstest-coverage.2026-06-14T08-22.md
    • Phase 6 ToDoModel final run:
      • vstest.console.exe ...\ToDoModel.Test.dll /EnableCodeCoverage /InIsolation
      • EXIT_CODE: 0
      • Source: p6-final-mstest-todomodel.2026-06-14T17-00.md
  • Invariant evidence recorded:
    • Diff and status checks passed with EXIT_CODE: 0
    • Source: final-invariant-check.2026-06-14T08-22.md
  • Coverage comparison evidence recorded:
    • Baseline aggregate production-only rate: 71.65%
    • Assembly deltas recorded:
      • ToDoModel: 10.82% -> 25.22%
      • QuickFiler: 25.20% -> 30.57%
      • TaskMaster: 25.78% -> 44.05%
    • Additional final audit notes:
      • ProjectEntry class coverage increased 44.20% -> 54.35%
      • MatchBestSpecialFolder helper reached 7/7 lines = 100%
  • Final feature audit:
    • feature-audit.2026-06-15T12-30.md marks all 9 acceptance criteria as PASS.
  • Current GitHub status note:
    • CI status (HEAD): in_progress

Recommended

  • csharpier check .
  • msbuild TaskMaster.sln -t:Build -p:Configuration=Debug -p:Platform="Any CPU" -p:EnableNETAnalyzers=true -p:EnforceCodeStyleInBuild=true
  • msbuild TaskMaster.sln -t:Build -p:Configuration=Debug -p:Platform="Any CPU" -p:Nullable=enable -p:TreatWarningsAsErrors=true
  • vstest.console.exe ToDoModel.Test/bin/Debug/ToDoModel.Test.dll QuickFiler.Test/bin/Debug/QuickFiler.Test.dll TaskMaster.Test/bin/Debug/TaskMaster.Test.dll /InIsolation /EnableCodeCoverage
  • Re-run the production-only coverage comparison against the current branch tip if a post-merge exact aggregate percentage is required for the next coverage increment.

Backward Compatibility / Migration Notes

  • No public API changes are introduced.
  • No migration steps are required.
  • coverage.config, TaskMaster.runsettings, and the coverage pipeline remain unchanged.
  • The feature preserves the #197 exemption boundary; it does not un-exempt or newly exempt COM/VSTO/WinForms code.
  • The only production-code changes are maintainer-authorized testing seams:
    • InternalsVisibleTo for ToDoModel.Test
    • MatchBestSpecialFolder pure-helper extraction
    • ProjectEntry dialog-call routing from MessageBox.Show(...) to MyBox.ShowDialog(...)
  • ProjectEntry dialog behavior is documented as functionally equivalent, with identical dialog intent and decision semantics; the change is in routing, not in feature scope or user workflow.

Risks and Mitigations

  • Risk: review noise from documentation and evidence artifacts
    • Mitigation: review the production/test changes first, then the feature-doc evidence folder second. The branch contains substantial documentation and audit output alongside the code changes.
  • Risk: small production seams could be mistaken for behavior changes
    • Mitigation: the seams are explicitly documented, maintainer-authorized, and covered by invariant checks plus final audit notes.
  • Risk: exact aggregate post-Phase-6 production-only percentage was not re-derived end-to-end
    • Mitigation: the recorded evidence establishes a net increase from the unchanged denominator plus covered-line gains in all target assemblies, and the final audit treats that as sufficient for #199.
  • Risk: CI for HEAD is still in progress
    • Mitigation: local evidence artifacts for formatter, analyzer, nullable, MSTest-with-coverage, and feature audit are already recorded and passing.
  • Risk: one delegation line remains a potential future coverage opportunity
    • Mitigation: the final audit records this as a follow-up candidate rather than a blocker for this PR.

Review Guide

  • Start with docs/features/active/2026-06-14-coverage-increments-1-3-testable-seams-199/spec.md to see the intended scope, constraints, and checked-off acceptance criteria.
  • Review the three production seam files next:
    • ToDoModel/Data Model/Project/ProjectEntry.cs
    • TaskMaster/AppGlobals/AppFileSystemFolderPaths.cs
    • UtilitiesCS/Properties/AssemblyInfo.cs
  • Review new ToDoModel tests, especially ProjectEntryDialogBranchesTests.cs, because they justify the final Phase 6 seam.
  • Review QuickFiler tests as a single pure-logic batch:
    • KaCharTests.cs
    • KaKeyTests.cs
    • KaStringAsyncTests.cs
    • KbdActionsRemainingBranchesTests.cs
    • FilerQueueTests.cs
    • QfcQueuePurePathsTests.cs
  • Review TaskMaster tests next, focusing on settings/path isolation and the extracted MatchBestSpecialFolder helper.
  • Review docs/features/.../evidence/qa-gates/ after code review to confirm the recorded formatter/build/test/coverage passes.
  • Treat the multiple code-review.*.md, policy-audit.*.md, and feature-audit.*.md files as review artifacts, not as primary implementation changes.
  • .claude/agent-memory/... updates are secondary repository-process artifacts.

Follow-ups

  • Record the exact aggregate post-Refactor: coverage-increments-1-3-testable-seams #199 production-only percentage with a full production-only Koverage re-run if that number is needed as the baseline for Increment 4+.
  • Consider covering the AppFileSystemFolderPaths instance delegation line in a future increment if it can be done without crossing prohibited filesystem-loading boundaries.
  • Use the final #199 evidence as the baseline when planning subsequent coverage-roadmap increments.

GitHub Auto-close

Related issues / PRs

drmoisan and others added 6 commits June 14, 2026 09:33
Adds 99 MSTest (+ Moq + FluentAssertions) unit tests across the seams #197
preserved as measured, raising covered code on the post-exemption denominator.

- Increment 1 (ToDoModel.Test): ToDoLoader.SetAndSave<T> overloads + guards,
  IDList.GetNextToDoID, ProjectEntry (dialog-free branches), BaseChanger.
  ToDoModel 10.82% -> 25.22%.
- Increment 2 (QuickFiler.Test): KaChar/KaKey/KaStringAsync (+async variants),
  KbdActions<> branches, FilerQueue, QfcQueue. QuickFiler 25.20% -> 30.57%.
- Increment 3 (TaskMaster.Test): AppStagingFilenames and AppQuickFilerSettings
  via the established Settings.Default snapshot/restore pattern (no production
  seam). TaskMaster 25.78% -> 44.05%.

Test-only; zero production-line change (denominator unchanged, aggregate rate
strictly increases vs 71.65%). New-code coverage 100% on reachable targets.
The three .Test csproj files received additive <Compile Include> registrations
(legacy non-SDK projects, no globbing); no production project/config touched.

Two documented gaps (no production seam added): ProjectEntry static-MyBox
dialog branches and AppFileSystemFolderPaths.MatchBestSpecialFolder (requires
filesystem mutation / a production seam) — recorded under evidence/other/.

Full C# toolchain green; 349/349 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
policy-audit, code-review, feature-audit (2026-06-14T14-30). Verdict GO,
0 blocking findings. Two PARTIAL ACs (#1 ProjectEntry dialog branches, #3
MatchBestSpecialFolder) are spec-authorized Flag-and-Stop gaps that cannot
be closed without an unauthorized production seam or filesystem mutation;
pending maintainer acknowledgement.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Maintainer-authorized (option B) production seams to cover the previously
Flag-and-Stop coverage gaps:

- UtilitiesCS: add [assembly: InternalsVisibleTo("ToDoModel.Test")] so the
  existing MyBox.DialogInvoker seam is injectable from ToDoModel.Test.
- AppFileSystemFolderPaths: extract the pure MatchBestSpecialFolder matching
  logic into an internal static helper (semantics preserved exactly); the
  instance method delegates to it.

Tests added: ProjectEntry malformed-ID and CompareTo length tie-break
branches (dialog stub injected, no WinForms loop); MatchBestSpecialFolder
best-match / case / trailing-separator / no-match (in-memory, no filesystem).
185/185 tests pass; full C# toolchain green; no production behavior change.

AC3 fully delivered. AC1 delivered for malformed-ID and tie-break. One
residual gap flagged for maintainer decision: the ProjectEntry
change-confirmation branch routes through the ProjectID property setter's
raw MessageBox.Show (not the MyBox seam) and would require a third
production seam to cover (see evidence/other/p5-projectentry-changeconfirm-gap).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Re-audit (2026-06-14T16-05): GO, 0 blocking findings. AC3 now PASS; AC1
PARTIAL (change-confirmation sub-branch deferred). Production changes
confirmed limited to the two authorized seams; no behavior change.

Corrects the AC1 spec prose that overstated the change-confirmation branch
as "fully covered" — it remains uncovered pending a maintainer decision on a
third seam (ProjectID property setter -> MyBox).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…am (#199)

Route ProjectEntry.ProjectID setter MessageBox.Show calls through MyBox.ShowDialog
seam (third maintainer-authorized production change for #199). Add four deterministic
MSTest change-confirmation tests covering Yes/No paths with and without _idUpdate
action. AC1 now FULLY PASS; all 98 ToDoModel.Test tests pass; toolchain clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Feature-review after Phase 6 change-confirmation seam: all 9 ACs PASS, 349/349
tests pass. ToDoModel +14.40 pp, QuickFiler +5.37 pp, TaskMaster +18.27 pp.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@drmoisan drmoisan changed the title Refactor/coverage increments 1 3 199 Add coverage increments 1–3 tests for preserved C# seams and close remaining #199 coverage gaps Jun 15, 2026
drmoisan and others added 4 commits June 15, 2026 10:11
…199)

AddEntry_UseUiThreadTrue_DequeuesEntryAndSuppressesDispatcherException
asserted UiThread.Dispatcher is null, but Dispatcher is process-global
set-once static state. An earlier test triggering UiThread.Initialize()
left it non-null, so the action dispatched and callCount became 1, failing
the assertion under the assembly's execution order surfaced by PR #201.

Deterministically establish the documented precondition by forcing the
private static _dispatcher field to null in Arrange (capturing the prior
value) and restoring it in a finally block. Test-only; no production change,
no assertion weakening, no [DoNotParallelize], no sleeps/retries/timing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mark remediation plan tasks complete and record the qa-gates CI-check
evidence confirming PR #201 required check is green on branch head.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
End-of-cycle reaudit for the PR #201 post-open CI-failure remediation.
code-review/feature-audit/policy-audit all GO; blocking_count 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@drmoisan
drmoisan merged commit a21d09e into main Jun 15, 2026
2 checks passed
@drmoisan
drmoisan deleted the refactor/coverage-increments-1-3-199 branch June 15, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor: coverage-increments-1-3-testable-seams

1 participant