Build a command for the audio the user turned off #208

Merged
JMR-dev merged 2 commits from test/audio-drop-arm into main 2026-09-06 00:59:14 +00:00
JMR-dev commented 2026-09-02 23:05:27 +00:00 (Migrated from github.com)

Closes #198.

The gap

audioArgs' Drop arm (ffmpeg/FFmpegCommandBuilder.kt:181) was ci == 0:

AudioPlan.Drop -> listOf("-an")

The suite's only -an assertion is in "gif generates a palette to avoid banding and drops audio" — and that one comes from the image path (:79/:90), which emits -an directly and never reaches audioArgs. Two sites, one string, one tested.

It is a live path

AdvancedPicker renders all of AudioCodec.entries including NONE, ContainerCapabilities.validate permits audio-off whenever the input has video, and MKV routes the job to FFmpeg. "Convert this and drop the soundtrack" is something a user can do today, and nothing had built the command for it.

Why two assertions

-an alone still passes if the arm falls through to the else and emits an AAC encoder beside the flag — a file that is silent because the flag won, carrying an encoder nobody asked for. So the test also asserts no -c:a.

Acceptance: three mutations, run and restored

mutation result
Drop -> emptyList() red
Drop -> the else arm's aac encoder red (loses -an too)
Drop -> listOf("-an", "-c:a", "aac") red — -an intact, caught by the assertFalse

The third is the one that justifies the second assertion. The first two break -an as a side effect, so neither can show whether the assertFalse does any work; the third keeps -an valid and fails on the encoder alone.

Verification

testDebugUnitTest (full suite) + ktlintCheck + detekt + lintDebug — green, production tree clean.

🤖 Generated with Claude Code

Closes #198. ## The gap `audioArgs`' `Drop` arm (`ffmpeg/FFmpegCommandBuilder.kt:181`) was `ci == 0`: ```kotlin AudioPlan.Drop -> listOf("-an") ``` The suite's only `-an` assertion is in *"gif generates a palette to avoid banding and drops audio"* — and that one comes from the **image path** (`:79`/`:90`), which emits `-an` directly and never reaches `audioArgs`. Two sites, one string, one tested. ## It is a live path `AdvancedPicker` renders all of `AudioCodec.entries` including `NONE`, `ContainerCapabilities.validate` permits audio-off whenever the input has video, and MKV routes the job to FFmpeg. "Convert this and drop the soundtrack" is something a user can do today, and nothing had built the command for it. ## Why two assertions `-an` alone still passes if the arm falls through to the `else` and emits an AAC encoder *beside* the flag — a file that is silent because the flag won, carrying an encoder nobody asked for. So the test also asserts no `-c:a`. ## Acceptance: three mutations, run and restored | mutation | result | |---|---| | `Drop -> emptyList()` | **red** | | `Drop ->` the `else` arm's aac encoder | **red** (loses `-an` too) | | `Drop -> listOf("-an", "-c:a", "aac")` | **red** — `-an` intact, caught by the `assertFalse` | The third is the one that justifies the second assertion. The first two break `-an` as a side effect, so neither can show whether the `assertFalse` does any work; the third keeps `-an` valid and fails on the encoder alone. ## Verification `testDebugUnitTest` (full suite) + `ktlintCheck` + `detekt` + `lintDebug` — green, production tree clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.