C1: pin readSpec's three enum fallbacks #145

Merged
JMR-dev merged 4 commits from test/readspec-enum-fallbacks into test/outputpublisher-seams 2026-08-27 13:55:02 +00:00
JMR-dev commented 2026-08-27 03:24:12 +00:00 (Migrated from github.com)

Closes #135.

WorkerEnumFallbackTest already existed for exactly this defect class, and its KDoc states the signature precisely: a name this build does not define, read above the try, threw out of doWork() entirely — FAILED with reschedule = false, empty output Data so the screen said "Conversion failed." with nothing else, and the staged file never deleted.

It covered 2 of the 5 above-the-try reads (quality, engine preference). readSpec() is called at ConversionWorker.kt:69, also above the try, and its three were cold.

The baseline is the part worth reviewing

readSpec returns the entire fallback spec the moment any one axis fails to resolve. So a test starting from MP4_H265 — which is the fallback — could not distinguish a worker that read the spec correctly from one that gave up on it. These start from MKV_H264, which differs on container and video codec, making the fallback visible on two axes at once.

They also assert the spec that actually reached the transcoder, not just that a Result came back. "A Result at all" is only half the assertion here, and it is the half that would pass against a fallback to something arbitrary.

Mutations — four, for three tests

mutation result
KEY_CONTAINER's ?: return fallback → ?: error(...) red — container test only
KEY_VIDEO_CODEC, same red — video test only
KEY_AUDIO_CODEC, same red — audio test only
fallback = MP4_H264 instead of MP4_H265 red — all three

The first three show each test is isolated to its own axis. The fourth shows they pin which spec ran — the thing a Result-only assertion would miss.

Coverage

readSpec() is now fully covered — zero missed lines and zero missed branches (L330-338, all mb=0).

Local gate green: ktlintCheck, detekt, testDebugUnitTest, compileDebugAndroidTestKotlin.

🤖 Generated with Claude Code

Closes #135. `WorkerEnumFallbackTest` already existed for exactly this defect class, and its KDoc states the signature precisely: a name this build does not define, read **above the `try`**, threw out of `doWork()` entirely — FAILED with `reschedule = false`, empty output `Data` so the screen said "Conversion failed." with nothing else, and the staged file never deleted. It covered 2 of the 5 above-the-`try` reads (quality, engine preference). `readSpec()` is called at `ConversionWorker.kt:69`, also above the `try`, and its three were cold. ### The baseline is the part worth reviewing `readSpec` returns the **entire** fallback spec the moment any one axis fails to resolve. So a test starting from `MP4_H265` — which *is* the fallback — could not distinguish a worker that read the spec correctly from one that gave up on it. These start from `MKV_H264`, which differs on container **and** video codec, making the fallback visible on two axes at once. They also assert the spec that actually reached the transcoder, not just that a `Result` came back. "A Result at all" is only half the assertion here, and it is the half that would pass against a fallback to something arbitrary. ### Mutations — four, for three tests | mutation | result | |---|---| | `KEY_CONTAINER`'s `?: return fallback` → `?: error(...)` | **red** — container test only | | `KEY_VIDEO_CODEC`, same | **red** — video test only | | `KEY_AUDIO_CODEC`, same | **red** — audio test only | | `fallback = MP4_H264` instead of `MP4_H265` | **red** — all three | The first three show each test is isolated to its own axis. The fourth shows they pin *which* spec ran — the thing a Result-only assertion would miss. ### Coverage `readSpec()` is now fully covered — zero missed lines and **zero missed branches** (`L330-338`, all `mb=0`). Local gate green: `ktlintCheck`, `detekt`, `testDebugUnitTest`, `compileDebugAndroidTestKotlin`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.