ThemeColorSchemeTest resolves every branch of the when — and always passes darkTheme explicitly. So the $default bridge is never entered and isSystemInDarkTheme() is never called. MainActivity.kt:79 is its only default-argument caller and does not execute on the JVM, which left the app's actual call shape — no arguments at all — the one nothing exercised. LibreMediaConverterTheme reported mi=21, mb=6, cb=12 at method level.
#68 is about the two unreachable arms, DarkColorScheme and LightColorScheme, which cannot run because dynamicColor is always true and nothing can flip it. That is an open product decision and stays open. This is the reachable half.
Why it compares schemes instead of reading a number
A luminance threshold would be a guess about the device palette. What is asserted instead: the no-argument call resolves the same scheme an explicit darkTheme of the matching value does, and a different one from its opposite. That holds whatever palette the platform hands back, and it is exactly the claim — the default reads the system rather than picking a side.
The two assertions together are also what stops the pair passing vacuously: if all three resolutions were identical, both assertNotEquals halves would fail.
Two @Config(qualifiers = …) cases rather than two classes, since qualifiers are settable per method — unlike the sdk pinning that made ForegroundTypeRegimeTest use nested classes.
Acceptance: mutations run and restored
mutation
result
darkTheme defaulted to false
night case red
darkTheme defaulted to true
light case red
isSystemInDarkTheme() inverted
both red
Each reddens a different half, which is also what shows the qualifiers take effect rather than both cases quietly running in one mode.
Closes #197.
## The gap
`ThemeColorSchemeTest` resolves every branch of the `when` — and always passes `darkTheme` explicitly. So the `$default` bridge is never entered and **`isSystemInDarkTheme()` is never called**. `MainActivity.kt:79` is its only default-argument caller and does not execute on the JVM, which left the app's actual call shape — no arguments at all — the one nothing exercised. `LibreMediaConverterTheme` reported `mi=21, mb=6, cb=12` at method level.
## Not #68
#68 is about the two **unreachable** arms, `DarkColorScheme` and `LightColorScheme`, which cannot run because `dynamicColor` is always `true` and nothing can flip it. That is an open product decision and stays open. This is the reachable half.
## Why it compares schemes instead of reading a number
A luminance threshold would be a guess about the device palette. What is asserted instead: the no-argument call resolves **the same scheme** an explicit `darkTheme` of the matching value does, and a **different** one from its opposite. That holds whatever palette the platform hands back, and it is exactly the claim — the default reads the system rather than picking a side.
The two assertions together are also what stops the pair passing vacuously: if all three resolutions were identical, both `assertNotEquals` halves would fail.
Two `@Config(qualifiers = …)` cases rather than two classes, since qualifiers are settable per method — unlike the `sdk` pinning that made `ForegroundTypeRegimeTest` use nested classes.
## Acceptance: mutations run and restored
| mutation | result |
|---|---|
| `darkTheme` defaulted to `false` | **night case red** |
| `darkTheme` defaulted to `true` | **light case red** |
| `isSystemInDarkTheme()` inverted | **both red** |
Each reddens a different half, which is also what shows the qualifiers take effect rather than both cases quietly running in one mode.
## Verification
`testDebugUnitTest` (full suite) + `ktlintCheck` + `detekt` + `lintDebug` — green.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #197.
The gap
ThemeColorSchemeTestresolves every branch of thewhen— and always passesdarkThemeexplicitly. So the$defaultbridge is never entered andisSystemInDarkTheme()is never called.MainActivity.kt:79is its only default-argument caller and does not execute on the JVM, which left the app's actual call shape — no arguments at all — the one nothing exercised.LibreMediaConverterThemereportedmi=21, mb=6, cb=12at method level.Not #68
#68 is about the two unreachable arms,
DarkColorSchemeandLightColorScheme, which cannot run becausedynamicColoris alwaystrueand nothing can flip it. That is an open product decision and stays open. This is the reachable half.Why it compares schemes instead of reading a number
A luminance threshold would be a guess about the device palette. What is asserted instead: the no-argument call resolves the same scheme an explicit
darkThemeof the matching value does, and a different one from its opposite. That holds whatever palette the platform hands back, and it is exactly the claim — the default reads the system rather than picking a side.The two assertions together are also what stops the pair passing vacuously: if all three resolutions were identical, both
assertNotEqualshalves would fail.Two
@Config(qualifiers = …)cases rather than two classes, since qualifiers are settable per method — unlike thesdkpinning that madeForegroundTypeRegimeTestuse nested classes.Acceptance: mutations run and restored
darkThemedefaulted tofalsedarkThemedefaulted totrueisSystemInDarkTheme()invertedEach reddens a different half, which is also what shows the qualifiers take effect rather than both cases quietly running in one mode.
Verification
testDebugUnitTest(full suite) +ktlintCheck+detekt+lintDebug— green.🤖 Generated with Claude Code