Coverage phase 1: JobScheduler unit tests + exclude Blazor Program bootstrap - #211
Conversation
Attach [ExcludeFromCodeCoverage] to the compiler-generated top-level- statements Program class so Coverlet drops Program.cs (218 lines @ 0%) from the coverable denominator. Declared internal to match the synthesized accessibility, leaving the assembly surface unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
20 deterministic tests over the binary min-heap: empty-heap guards, sift-up, grow-and-copy past the initial 16 capacity, sift-down across insertion orders, duplicate timestamps, non-mutating peek, and interleaved push/pop. No Thread.Sleep, no clock reads. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… paths Adds a shared no-op ITransportInit double (needed for the new() generic constraint, which a substitute cannot satisfy) and 6 tests: ctor null guard, IsDisposed toggle, idempotent dispose over empty collections, and the creation-reports-failure branch asserting the error message is surfaced. Queue-creation success paths call into a real transport container and stay uncovered; reaching them would need a transport project reference. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
24 tests over start/stop/update-schedule (including the missed-event window replay branches) and RunPendingEventAsync: stale run id, queued, requeued, already-queued, send-reports-exception, send-throws, and the unusable-next-occurrence path that terminates the schedule. Time and schedule are substituted, so nothing reads the clock. The fire-and-forget Raise* events are awaited via TaskCompletionSource rather than a delay. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t relay 23 tests over both AddUpdateJob overloads (guards, replace-existing, autoRun), GetAllJobs, RemoveJob (unknown/stopped/running), dispose and post-shutdown guards, the Start-then-Dispose path, and the three job-to-scheduler event relays. Adds a no-op IJobQueueCreation double to satisfy the TQueue constraint on the two-generic overload. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds comprehensive tests for the job scheduler, scheduled jobs, pending-event heap, and queue lifecycle. It also configures and documents a scoped Blazor ChangesJob scheduler test coverage
Coverage configuration
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
CA1861: hoist constant array arguments to static readonly fields. MSTEST0037: use Assert.HasCount instead of Assert.AreEqual on counts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replaces the [ExcludeFromCodeCoverage] partial-class approach, which tripped two SonarCloud rules that cannot be satisfied for this construct. S3903 (reported as a BUG) demands a named namespace, but the partial must stay in the global namespace to bind to the Program class synthesized from top-level statements; namespacing it creates a different type and silently breaks the exclusion. S1118 wants static or a protected ctor, neither of which is possible or meaningful here. Excluding by file removes the source file entirely, so no suppressions are needed. Dashboard.Ui/Program.cs is the only Program.cs in the repo. Verified: 0 Program.cs entries in the coverage report while 110 other Dashboard.Ui classes remain. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Source/Directory.Build.props (1)
30-36: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winPrevent future
Program.csfiles from being excluded unintentionally.The configuration and documentation use
**/Program.cs, which currently matches the Blazor bootstrap but will also match any future file with that name.
Source/Directory.Build.props#L30-L36: narrowExcludeByFileto the Dashboard UI path and add a CI guard for unexpected matches.docs/code-coverage.md#L59-L65: document the narrowed pattern and remove the claim that the broad glob is inherently unambiguous.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Source/Directory.Build.props` around lines 30 - 36, Scope the ExcludeByFile pattern in Source/Directory.Build.props to Dashboard.Ui/Program.cs, and add a CI guard that fails when unexpected Program.cs files are matched or introduced. Update docs/code-coverage.md lines 59-65 to document the narrowed pattern and remove the claim that the broad **/Program.cs glob is inherently unambiguous.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@Source/Directory.Build.props`:
- Around line 30-36: Scope the ExcludeByFile pattern in
Source/Directory.Build.props to Dashboard.Ui/Program.cs, and add a CI guard that
fails when unexpected Program.cs files are matched or introduced. Update
docs/code-coverage.md lines 59-65 to document the narrowed pattern and remove
the claim that the broad **/Program.cs glob is inherently unambiguous.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c9e5d9ab-cd4c-42b0-a22d-8cf4d49ccbb5
📒 Files selected for processing (3)
Source/Directory.Build.propsSource/DotNetWorkQueue.Tests/JobScheduler/JobSchedulerTests.csdocs/code-coverage.md
🚧 Files skipped from review as they are similar to previous changes (1)
- Source/DotNetWorkQueue.Tests/JobScheduler/JobSchedulerTests.cs
…ject Addresses CodeRabbit review: **/Program.cs would also match any Program.cs added to another project later, silently dropping real code from coverage -- the exact erosion this policy exists to prevent. Narrowed to **/DotNetWorkQueue.Dashboard.Ui/Program.cs and reworded the docs, which had claimed the broad glob was unambiguous (true of the current tree, but not enforced by the pattern). Verified: 0 Program.cs entries in the coverage report, 110 other Dashboard.Ui classes still covered. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Addressed the nitpick: narrowed Agreed on the substance — a bare filename glob would also match any I did not add the suggested CI guard for unexpected Verified after the change: 0 |
Reconciliation finished: the Codecov/badge gap is NOT a pipeline defect. Codecov excludes partially-covered lines from hits; ReportGenerator counts them as covered. 867 partial lines on master account for the entire ~2.5 point difference (87.45% vs 90.04% on identical denominators). Master build #132 was fully green with all 24 coverage inputs merged and still read 87.45%, which rules out the stale-upload and missing-stage theories recorded earlier in this doc. Coverage also did not erode gradually. Removing Dashboard.Ui (1,303 lines at 23.6%) from today's totals reproduces the historical figure exactly (29,066/32,282 = 90.04%), so one untested Blazor project accounts for the whole decline from the 90.25% Codecov reported in 2024. Changes: - Codecov is now documented as the authoritative number (it gates PRs). - project status: auto/2% -> auto/0%. Coverage may rise or stay flat but never drop below the parent commit. The old 2% slack is what let the number drift down unnoticed, since auto rebaselines every merge. - Documented that reaching 90% requires Dashboard.Ui specifically, and that partial lines are a cheaper secondary lever. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|



Phase 1 — Cheap structural wins (coverage recovery)
Second phase of the 90% coverage recovery (follows #210). No production behavior changes — 73 new unit tests plus one attribute-only file.
Changes
ProgramCoverage.cs(new) — attaches[ExcludeFromCodeCoverage]to the compiler-generated top-level-statementsProgramclass, dropping Blazor host bootstrap (218 lines @ 0%) from the coverable denominator. Declaredinternalto match the accessibility the compiler synthesizes, so the assembly surface is unchanged.PendingEventHeapTests.cs— 20 tests: empty-heap guards, sift-up, grow-and-copy past the initial capacity, sift-down across insertion orders, duplicate timestamps, non-mutating peek, interleaved push/pop.ScheduledJobTests.cs— 24 tests: start/stop/update-schedule incl. all missed-event-window branches;RunPendingEventAsyncacross stale run id, queued, requeued, already-queued, send-reports-exception, send-throws, and the unusable-next-occurrence path.JobSchedulerTests.cs— 23 tests: bothAddUpdateJoboverloads,GetAllJobs,RemoveJob, dispose/post-shutdown guards, and the three job→scheduler event relays.JobQueueTests.cs+TestDoubles.cs— 6 tests: ctor guard, dispose idempotency, creation-failure path.No
Thread.Sleepanywhere — the fire-and-forgetRaise*events are awaited viaTaskCompletionSource, so tests complete the moment the event fires. No new Sonar S2925 debt.Measured effect (unit-tests-only basis, before → after)
898 lines newly covered by unit tests.
Two honest caveats
Program.csdenominator reduction is the one part that's independent of overlap. Worth reading the merged number on this PR rather than assuming.JobQueuedid not reach the ~90% target. Its queue-creation success paths need a real transport (CreateMethodJobProducer), which would require aTransport.Memoryproject reference that was out of scope. Integration tests already cover those paths. Guard/dispose/creation-failure branches are covered.Verification:
dotnet build NoTests.sln -c Release -p:CI=true→ 0 warnings / 0 errors; core suite 993/993 green.🤖 Generated with Claude Code
Summary by CodeRabbit