Correct the theme KDoc's switch claim and cover the branches that actually run #119

Merged
JMR-dev merged 2 commits from test/theme-live-branches into main 2026-08-26 03:05:29 +00:00
JMR-dev commented 2026-08-26 02:46:47 +00:00 (Migrated from github.com)

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):

-        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:

-        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

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)
Sign in to join this conversation.