Skip to content

refactor: make ScopeHandler a sealed class to drop untestable equality members - #443

Merged
samtrion merged 1 commit into
mainfrom
fix/stryker-scopehandler-untested-equality-members
Oct 29, 2026
Merged

samtrion merged 1 commit into
mainfrom
fix/stryker-scopehandler-untested-equality-members

Conversation

@samtrion

@samtrion samtrion commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Problem

The latest Stryker run on codebuilder reports 20 NoCoverage mutants ("Not covered by any test") out of 503 created. The private nested ScopeHandler struct in CSharpCodeBuilder.Scope.cs defines Equals(object), Equals(ScopeHandler), GetHashCode() and ==/!=. No test touches them and they are unreachable from outside: Scope()/ScopeLine() return IDisposable and the type is private.

Root cause

The struct implements IEquatable<ScopeHandler> and the operators, most likely to satisfy analyzer rules for structs (not proven, there are no suppressions in the repo). The members are dead code.

Change

private readonly struct ScopeHandler : IDisposable, IEquatable<ScopeHandler> becomes private sealed class ScopeHandler : IDisposable with only the constructor and Dispose. The five equality members and their docs are removed (4 lines added, 40 removed).

Before / After

metric before after
mutation score 91.94 % 93.21 %
mutants created 503 499
NoCoverage 20 15
CompileError 70 70
run time 3m21s 3m20s

After run (single run, branch): https://github.com/dailydevops/codebuilder/actions/runs/40805882274. About 5 of the original 20 NoCoverage mutants sat in the removed members; the remaining 15 are elsewhere.

Risk / what this does not change

Behaviour is unchanged: the type is private and always returned as IDisposable. The struct was already boxed on return, so there is no extra allocation in practice. Locally, the unit tests pass (395/395, net10.0) and the library compiles with 0 warnings.

…y members

ScopeHandler was a readonly struct implementing IEquatable<T> with
Equals, GetHashCode and ==/!= operators that no test can reach, since
Scope() and ScopeLine() only expose IDisposable. They showed up as
NoCoverage mutants in Stryker. A private sealed class needs none of them.
@codecov

codecov Bot commented Oct 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.15%. Comparing base (0caae59) to head (176eb45).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #443      +/-   ##
==========================================
+ Coverage   91.76%   93.15%   +1.39%     
==========================================
  Files          15       15              
  Lines         340      336       -4     
  Branches      100       99       -1     
==========================================
+ Hits          312      313       +1     
+ Misses         17       12       -5     
  Partials       11       11              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@samtrion
samtrion merged commit 1326621 into main Oct 29, 2026
13 checks passed
@samtrion
samtrion deleted the fix/stryker-scopehandler-untested-equality-members branch October 29, 2026 15:07
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.

1 participant