Refs #68 — this does not close it.#68 offers three options (add a theme toggle, delete the
dead branches with the template palette, or replace that palette first) and says the choice is the
maintainer's. This PR takes none of them. It does only the half that is correct under all three, so #68 stays open holding exactly that decision, plus the DarkColorScheme / LightColorScheme
branches, the six template brand colours in Color.kt, and the dynamicColor parameter — all
untouched here.
1 — the false sentence
The KDoc on LibreMediaConverterTheme said dynamic colour "stays switchable so users can opt back
to the brand palette". Re-verified on this branch before touching anything: grep -rn "dynamicColor\|LibreMediaConverterTheme" app/src --include="*.kt" returns the
declaration, the two branches that read it, and one caller — MainActivity.kt:77, argument-less.
No switch, no setting, no caller that could flip it, unchanged since the ticket was filed.
Rewritten to describe what is true today and to name #68 as the open decision, so a reader learns
the parameter is unused and that this is known — rather than concluding it is an oversight and
either "fixing" it or hunting for a setting. It does not read as though any option has been chosen.
2 — the branches that are reachable
ThemeKt had no test at all. ThemeColorSchemeTest (Robolectric, sdk=36, v2 createComposeRule)
reads MaterialTheme.colorScheme inside the content lambda — the only place that shows what the
theme actually chose — and asserts:
the two live branches, dynamicDarkColorScheme vs dynamicLightColorScheme, on background
luminance. Both come off the same device palette, so identity or a bare assertNotEquals on the ColorScheme object would prove nothing (ColorScheme has no equals override). Under
Robolectric they are #121318 (lum 0.0066) against #FAF8FF (lum 0.9468) — genuinely far apart.
that a live call takes the dynamic palette, not the brand one, since the dynamic primary
(#B0C6FF) is a different hue from Purple80.
the two dead branches, reached by passing dynamicColor = false directly. Both this test's
KDoc and Theme.kt's say plainly that the test is the only thing in the tree that passes the
parameter, so the coverage is not evidence the feature is wired up — that misreading is why #68
was filed. Tests for the live branches survive whichever option wins; these two go with the
branches if the maintainer deletes them.
Mutations
The one the ticket names, verbatim — the first branch, Theme.kt:49 on this branch (line 39
before the KDoc edit above added ten lines):
dark mode resolves a darker scheme than light mode fails, and only it —
java.lang.AssertionError: darkTheme = true should resolve the dynamic dark scheme,
whose background luminance (0.94678795) is below the light scheme's (0.94678795)
An assertion failure, not an exception, and the other two tests stayed green, so the mutation is
targeted rather than blowing up the class.
A second one, because the first cannot see a mis-capture. All four schemes are resolved in one
composition, so if the test had captured them into the wrong slots, three of the three tests would
still have passed. Swapping the two dead branches proves the slots:
the brand palette branches run only when dynamicColor is passed explicitly fails, and only it — expected:<Color(0.8156863, 0.7372549, 1.0, ...)> but was:<Color(0.4, 0.3137255, 0.6431373, ...)>,
i.e. Purple80 asked for and Purple40 received.
Both restored with git restore and the class re-run green (3/3) before pushing.
No instrumented test: dynamic colour is a Context read with no UI of its own, and on a device the
palette is whatever the wallpaper produced, so an e2e assertion could only restate the branch. The
Robolectric palette is a fixed stub, which is what makes the comparison stable here. This PR adds no androidTest, so the @FailsOnEmulatorApi37 baseline is untouched. Nothing here changes app
behaviour — the diff is one KDoc and one new test file.
Refs #68 — **this does not close it.** #68 offers three options (add a theme toggle, delete the
dead branches with the template palette, or replace that palette first) and says the choice is the
maintainer's. This PR takes none of them. It does only the half that is correct under all three, so
#68 stays open holding exactly that decision, plus the `DarkColorScheme` / `LightColorScheme`
branches, the six template brand colours in `Color.kt`, and the `dynamicColor` parameter — all
untouched here.
## 1 — the false sentence
The KDoc on `LibreMediaConverterTheme` said dynamic colour "stays switchable so users can opt back
to the brand palette". Re-verified on this branch before touching anything:
`grep -rn "dynamicColor\|LibreMediaConverterTheme" app/src --include="*.kt"` returns the
declaration, the two branches that read it, and one caller — `MainActivity.kt:77`, argument-less.
No switch, no setting, no caller that could flip it, unchanged since the ticket was filed.
Rewritten to describe what is true today and to name #68 as the open decision, so a reader learns
the parameter is unused *and* that this is known — rather than concluding it is an oversight and
either "fixing" it or hunting for a setting. It does not read as though any option has been chosen.
## 2 — the branches that are reachable
`ThemeKt` had no test at all. `ThemeColorSchemeTest` (Robolectric, `sdk=36`, v2 `createComposeRule`)
reads `MaterialTheme.colorScheme` inside the content lambda — the only place that shows what the
theme actually chose — and asserts:
- **the two live branches**, `dynamicDarkColorScheme` vs `dynamicLightColorScheme`, on background
luminance. Both come off the same device palette, so identity or a bare `assertNotEquals` on the
`ColorScheme` object would prove nothing (`ColorScheme` has no `equals` override). Under
Robolectric they are `#121318` (lum 0.0066) against `#FAF8FF` (lum 0.9468) — genuinely far apart.
- **that a live call takes the dynamic palette, not the brand one**, since the dynamic primary
(`#B0C6FF`) is a different hue from `Purple80`.
- **the two dead branches**, reached by passing `dynamicColor = false` directly. Both this test's
KDoc and `Theme.kt`'s say plainly that the test is the only thing in the tree that passes the
parameter, so the coverage is not evidence the feature is wired up — that misreading is why #68
was filed. Tests for the live branches survive whichever option wins; these two go with the
branches if the maintainer deletes them.
## Mutations
**The one the ticket names, verbatim** — the first branch, `Theme.kt:49` on this branch (line 39
before the KDoc edit above added ten lines):
```kotlin
- dynamicColor && darkTheme -> dynamicDarkColorScheme(context)
+ dynamicColor && darkTheme -> dynamicLightColorScheme(context)
```
`dark mode resolves a darker scheme than light mode` fails, and only it —
```
java.lang.AssertionError: darkTheme = true should resolve the dynamic dark scheme,
whose background luminance (0.94678795) is below the light scheme's (0.94678795)
```
An assertion failure, not an exception, and the other two tests stayed green, so the mutation is
targeted rather than blowing up the class.
**A second one, because the first cannot see a mis-capture.** All four schemes are resolved in one
composition, so if the test had captured them into the wrong slots, three of the three tests would
still have passed. Swapping the two dead branches proves the slots:
```kotlin
- darkTheme -> DarkColorScheme
- else -> LightColorScheme
+ darkTheme -> LightColorScheme
+ else -> DarkColorScheme
```
`the brand palette branches run only when dynamicColor is passed explicitly` fails, and only it —
`expected:<Color(0.8156863, 0.7372549, 1.0, ...)> but was:<Color(0.4, 0.3137255, 0.6431373, ...)>`,
i.e. `Purple80` asked for and `Purple40` received.
Both restored with `git restore` and the class re-run green (3/3) before pushing.
## Gate
`assembleDebug testDebugUnitTest compileDebugAndroidTestKotlin ktlintCheck detekt lintDebug
--continue` — BUILD SUCCESSFUL.
## Not covered
No instrumented test: dynamic colour is a `Context` read with no UI of its own, and on a device the
palette is whatever the wallpaper produced, so an e2e assertion could only restate the branch. The
Robolectric palette is a fixed stub, which is what makes the comparison stable here. This PR adds no
`androidTest`, so the `@FailsOnEmulatorApi37` baseline is untouched. Nothing here changes app
behaviour — the diff is one KDoc and one new test file.
🤖 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.
Refs #68 — this does not close it. #68 offers three options (add a theme toggle, delete the
dead branches with the template palette, or replace that palette first) and says the choice is the
maintainer's. This PR takes none of them. It does only the half that is correct under all three, so
#68 stays open holding exactly that decision, plus the
DarkColorScheme/LightColorSchemebranches, the six template brand colours in
Color.kt, and thedynamicColorparameter — alluntouched here.
1 — the false sentence
The KDoc on
LibreMediaConverterThemesaid dynamic colour "stays switchable so users can opt backto the brand palette". Re-verified on this branch before touching anything:
grep -rn "dynamicColor\|LibreMediaConverterTheme" app/src --include="*.kt"returns thedeclaration, the two branches that read it, and one caller —
MainActivity.kt:77, argument-less.No switch, no setting, no caller that could flip it, unchanged since the ticket was filed.
Rewritten to describe what is true today and to name #68 as the open decision, so a reader learns
the parameter is unused and that this is known — rather than concluding it is an oversight and
either "fixing" it or hunting for a setting. It does not read as though any option has been chosen.
2 — the branches that are reachable
ThemeKthad no test at all.ThemeColorSchemeTest(Robolectric,sdk=36, v2createComposeRule)reads
MaterialTheme.colorSchemeinside the content lambda — the only place that shows what thetheme actually chose — and asserts:
dynamicDarkColorSchemevsdynamicLightColorScheme, on backgroundluminance. Both come off the same device palette, so identity or a bare
assertNotEqualson theColorSchemeobject would prove nothing (ColorSchemehas noequalsoverride). UnderRobolectric they are
#121318(lum 0.0066) against#FAF8FF(lum 0.9468) — genuinely far apart.(
#B0C6FF) is a different hue fromPurple80.dynamicColor = falsedirectly. Both this test'sKDoc and
Theme.kt's say plainly that the test is the only thing in the tree that passes theparameter, so the coverage is not evidence the feature is wired up — that misreading is why #68
was filed. Tests for the live branches survive whichever option wins; these two go with the
branches if the maintainer deletes them.
Mutations
The one the ticket names, verbatim — the first branch,
Theme.kt:49on this branch (line 39before the KDoc edit above added ten lines):
dark mode resolves a darker scheme than light modefails, and only it —An assertion failure, not an exception, and the other two tests stayed green, so the mutation is
targeted rather than blowing up the class.
A second one, because the first cannot see a mis-capture. All four schemes are resolved in one
composition, so if the test had captured them into the wrong slots, three of the three tests would
still have passed. Swapping the two dead branches proves the slots:
the brand palette branches run only when dynamicColor is passed explicitlyfails, and only it —expected:<Color(0.8156863, 0.7372549, 1.0, ...)> but was:<Color(0.4, 0.3137255, 0.6431373, ...)>,i.e.
Purple80asked for andPurple40received.Both restored with
git restoreand the class re-run green (3/3) before pushing.Gate
assembleDebug testDebugUnitTest compileDebugAndroidTestKotlin ktlintCheck detekt lintDebug --continue— BUILD SUCCESSFUL.Not covered
No instrumented test: dynamic colour is a
Contextread with no UI of its own, and on a device thepalette is whatever the wallpaper produced, so an e2e assertion could only restate the branch. The
Robolectric palette is a fixed stub, which is what makes the comparison stable here. This PR adds no
androidTest, so the@FailsOnEmulatorApi37baseline is untouched. Nothing here changes appbehaviour — the diff is one KDoc and one new test file.
🤖 Generated with Claude Code