A1 (#167): pin all three foreground-service regimes, and the boundary between two of them #179

Merged
JMR-dev merged 1 commits from test/foreground-type-regimes into main 2026-09-02 03:13:13 +00:00
JMR-dev commented 2026-09-02 02:19:20 +00:00 (Migrated from github.com)

Closes #167.

ConversionForegroundType.current() has three arms and the JVM suite executed one of them. app/src/test/resources/robolectric.properties pins the whole suite to sdk=36, and @Config appears nowhere in app/src/test, so the 33 and 34 arms were cold — 3 lines and 3 of 4 branches on main at d354f64.

The instrumented test is not a substitute, for a specific reason rather than a general one. ConversionWorkerTest.foregroundTypeMatchesTheRunningApiLevel asserts against whichever API the leg happens to be, so it covers one arm per leg and never the other two — and the legs that would cover 33 and 34 are the ones #122 wedges. docs/coverage-read-findings.md records an API 33 run reporting received: 60 with failed: unknown: the regime was exercised, and that leg could not have reported a failure if there had been one.

Four classes, not three

35 shares its answer with 36, which makes it look redundant. It is the point. Relaxing >= VANILLA_ICE_CREAM to > is invisible at every level except exactly 35.

Measured, not assumed:

mutation what went red
>= VANILLA_ICE_CREAM → > ForegroundTypeApi35Test only
swap DATA_SYNC / MEDIA_PROCESSING 34, 35 and 36

Without the 35 class the first mutation survives the suite.

Gate

assembleDebug + testDebugUnitTest + compileDebugAndroidTestKotlin + ktlintCheck + detekt + lintDebug, all green. 546 → 550 JVM tests, 0 failures. No production code changed.

🤖 Generated with Claude Code

Closes #167. `ConversionForegroundType.current()` has three arms and the JVM suite executed one of them. `app/src/test/resources/robolectric.properties` pins the whole suite to `sdk=36`, and `@Config` appears nowhere in `app/src/test`, so the 33 and 34 arms were cold — 3 lines and 3 of 4 branches on `main` at `d354f64`. **The instrumented test is not a substitute**, for a specific reason rather than a general one. `ConversionWorkerTest.foregroundTypeMatchesTheRunningApiLevel` asserts against whichever API the leg happens to be, so it covers one arm per leg and never the other two — and the legs that would cover 33 and 34 are the ones #122 wedges. `docs/coverage-read-findings.md` records an API 33 run reporting `received: 60` with `failed: unknown`: the regime *was* exercised, and that leg could not have reported a failure if there had been one. ### Four classes, not three 35 shares its answer with 36, which makes it look redundant. It is the point. Relaxing `>= VANILLA_ICE_CREAM` to `>` is invisible at every level except exactly 35. Measured, not assumed: | mutation | what went red | |---|---| | `>= VANILLA_ICE_CREAM` → `>` | `ForegroundTypeApi35Test` **only** | | swap `DATA_SYNC` / `MEDIA_PROCESSING` | 34, 35 and 36 | Without the 35 class the first mutation survives the suite. ### Gate `assembleDebug` + `testDebugUnitTest` + `compileDebugAndroidTestKotlin` + `ktlintCheck` + `detekt` + `lintDebug`, all green. 546 → 550 JVM tests, 0 failures. No production code changed. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.