test: restore silently-dropped Emit_Unit_MeasurementUnit_Predefined theory coverage - #5615
Merged
Merged
Conversation
The theory declared its parameter as MeasurementUnit while its 24 [InlineData] rows were MeasurementUnit.Duration/Information/Fraction enum constants. The C# compiler accepts this via the implicit conversion operators, but xUnit does not apply user-defined implicit conversions when binding inline data, and drops the whole theory during discovery without emitting a diagnostic — even with diagnosticMessages enabled. The 24 cases had never run. Verified the mechanism in isolation: a theory taking a struct with an implicit operator from int and [InlineData(1)] is dropped the same way, while a built-in widening conversion (int -> long) is fine. So it is the user-defined conversion, not the mix of nested enum types. Split into three theories parameterized by the enum types xUnit can bind, sharing one assertion helper. All 24 cases are now discovered and pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5615 +/- ##
==========================================
- Coverage 74.87% 74.85% -0.02%
==========================================
Files 515 515
Lines 18962 18962
Branches 3694 3694
==========================================
- Hits 14197 14194 -3
- Misses 3888 3891 +3
Partials 877 877 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ric-oliv
approved these changes
Sep 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Emit_Unit_MeasurementUnit_Predefinedintest/Sentry.Tests/SentryMetricEmitterTests.Values.cswas never discovered or executed, so its 24[InlineData]rows provided no coverage:listed every sibling
Emit_Unit_*test but not this one.Cause
The theory declared its parameter as
MeasurementUnit(a struct) while the inline values wereMeasurementUnit.Duration/.Information/.Fractionenum constants. The C# compiler accepts that becauseMeasurementUnitdefinesimplicit operatoroverloads for each nested enum — but xUnit does not apply user-defined implicit conversions when binding inline data, and drops the entire theory during discovery without emitting a diagnostic. Nothing appeared even withdiagnosticMessages: trueinxunit.runner.json; the theory simply vanished.I isolated the mechanism with throwaway probes rather than assuming it:
[InlineData]long1MeasurementUnit.DurationMeasurementUnit.Duration.NanosecondobjectMeasurementUnit.Duration.NanosecondMeasurementUnitMeasurementUnit.Duration.NanosecondWrapper(struct,implicit operator Wrapper(int))1So it is the user-defined conversion that breaks discovery — not the mix of nested enum types, and not anything specific to
MeasurementUnit.Fix
Split into three theories parameterized by the enum types xUnit can bind (
Emit_Unit_MeasurementUnit_Duration/_Information/_Fraction), sharing oneAssertEmittedUnithelper. The implicit conversion still happens, just at the helper's call site where the compiler handles it. All 24 rows are preserved.All 24 cases are now discovered and pass — the assertions were correct, they had simply never executed.
Sweep for the same pattern
Since these tests fail invisibly, I diffed every
[Fact]/[Theory]declared undertest/Sentry.Testsagainst the full--list-testsoutput. Every other gap was either#if-guarded platform code (NETFRAMEWORK,ANDROID,IOS,MACCATALYST,DEBUG) not compiled fornet10.0, or regex noise — this theory was the only genuinely dropped one. The sibling files called out in the report (SentryMetricEmitterTests.Types.cs,.Options.cs,SentryStructuredLoggerTests.*) are clean. A repo-wide grep found no other[InlineData]relying on a user-defined implicit conversion.Notes for review
test/Sentry.Tests/Helpers/ImmutableTests.csandtest/Sentry.Tests/Protocol/ImmutableTests.csboth declareabstract class ImmutableTests<TType>with aType_IsImmutablefact, but neither has any subclass — so those never run either. Happy to remove them in a follow-up.dotnet build Sentry-CI-Build-macOS.slnfdoes not complete on my machine for reasons unrelated to this change (Xcode 27.0 vs the pinned 26.6 for the iOS/MacCatalyst SDKs, sample DSN#errors, missing workloads, sentry-native CMake).test/Sentry.Testsitself is green onnet9.0andnet10.0(2581 passed each),dotnet formatis clean, and there is no Verify snapshot churn.#skip-changelog