testsAndMisc/linux_configuration/tests/test_transcribe_diarize_probe.py
Krzysztof kuhy Rudnicki dbf2f29b00 _transcribe_diarize: split 356 -> 164 + 143 + 105
The last Python file over the cap:

  _transcribe_media.py    143  _try_import, both duration probes,
                               get_media_duration, ffmpeg transcode, cleanup
  _transcribe_cluster.py  105  _resample_linear, _kmeans_cosine and its
                               iteration loop
  _transcribe_diarize.py  164  the pipeline: audio loading, the classifier,
                               embedding extraction, diarize_segments

The graph is a tree: _transcribe_media imports nothing local, _cluster takes
only _try_import from it, _diarize imports from both. All 13 top-level
definitions verified AST-identical to HEAD, and an AST scan confirms the
three module constants travelled to the modules that use them.

transcribe_fw.py now imports get_media_duration from _transcribe_media
rather than through _transcribe_diarize. Ruff removed that re-export as
unused and broke the import; running the program is what caught it, and
naming the owning module is the correct fix under the no-barrels rule.

Verified: transcribe_fw.py /nonexistent.wav still exits 2 and --help exits
0; 63 tests pass at 100% line and branch on all three modules; 338 pass in
the directory. Over-cap files 33 -> 32, and no Python file is over the cap
any more - the remaining 32 are 29 shell, 2 kotlin, 1 dart.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
2026-08-17 13:59:39 +02:00

173 lines
6.0 KiB
Python

"""Tests for media-duration probing and temp-file handling.
Duration is probed twice: through the ffmpeg-python binding if it is
importable, then by shelling out to ffprobe. Both are patched here, so the
tests pass whether or not ffmpeg is installed on the machine running them.
"""
from __future__ import annotations
import shutil
import subprocess
import _transcribe_media as diar
import pytest
class _FfmpegModule:
"""An ffmpeg-python double whose probe() returns a fixed payload."""
def __init__(self, payload: object) -> None:
self._payload = payload
def probe(self, _path: str) -> object:
"""Return the canned probe result, or raise it if it is an error."""
if isinstance(self._payload, Exception):
raise self._payload
return self._payload
def _only(name: str, module: object) -> object:
"""Return a _try_import double resolving exactly one module name."""
def _try(requested: str) -> object | None:
return module if requested == name else None
return _try
# --------------------------------------------------------------------------- #
# The optional-dependency import seam
# --------------------------------------------------------------------------- #
def test_try_import_returns_the_module_when_present() -> None:
"""The seam the other tests patch works against a real module."""
assert diar._try_import("json") is not None
def test_try_import_returns_none_for_a_missing_module() -> None:
"""A missing optional dependency is None, not an ImportError."""
assert diar._try_import("no_such_module_anywhere_12345") is None
# --------------------------------------------------------------------------- #
# _probe_with_ffmpeg_python
# --------------------------------------------------------------------------- #
def test_probe_with_ffmpeg_python_reads_the_format_duration(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""The binding reports duration under probe()['format']['duration']."""
module = _FfmpegModule({"format": {"duration": "123.5"}})
monkeypatch.setattr(diar, "_try_import", _only("ffmpeg", module))
assert diar._probe_with_ffmpeg_python("clip.wav") == pytest.approx(123.5)
def test_probe_with_ffmpeg_python_returns_none_without_the_binding(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Without ffmpeg-python installed this probe declines."""
monkeypatch.setattr(diar, "_try_import", lambda _n: None)
assert diar._probe_with_ffmpeg_python("clip.wav") is None
def test_probe_with_ffmpeg_python_returns_none_without_a_duration_key(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""A probe result with no duration falls through to the next method."""
module = _FfmpegModule({"format": {}})
monkeypatch.setattr(diar, "_try_import", _only("ffmpeg", module))
assert diar._probe_with_ffmpeg_python("clip.wav") is None
@pytest.mark.parametrize("error", [OSError("boom"), RuntimeError("boom")])
def test_probe_with_ffmpeg_python_survives_a_probe_error(
monkeypatch: pytest.MonkeyPatch, error: Exception
) -> None:
"""A failing probe returns None rather than propagating."""
monkeypatch.setattr(diar, "_try_import", _only("ffmpeg", _FfmpegModule(error)))
assert diar._probe_with_ffmpeg_python("clip.wav") is None
# --------------------------------------------------------------------------- #
# _probe_with_ffprobe
# --------------------------------------------------------------------------- #
def test_probe_with_ffprobe_parses_the_duration(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""ffprobe prints a bare float, which is parsed to seconds."""
monkeypatch.setattr(shutil, "which", lambda _b: "/usr/bin/ffprobe")
monkeypatch.setattr(subprocess, "check_output", lambda *_a, **_k: b" 42.25 \n")
assert diar._probe_with_ffprobe("clip.wav") == pytest.approx(42.25)
def test_probe_with_ffprobe_returns_none_when_not_installed(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""No ffprobe on PATH means no duration."""
monkeypatch.setattr(shutil, "which", lambda _b: None)
assert diar._probe_with_ffprobe("clip.wav") is None
@pytest.mark.parametrize(
"error",
[
OSError("boom"),
subprocess.CalledProcessError(1, "ffprobe"),
ValueError("not a float"),
],
)
def test_probe_with_ffprobe_survives_every_failure_mode(
monkeypatch: pytest.MonkeyPatch, error: Exception
) -> None:
"""A crash, a non-zero exit, or unparsable output all yield None."""
monkeypatch.setattr(shutil, "which", lambda _b: "/usr/bin/ffprobe")
def _boom(*_a: object, **_k: object) -> None:
raise error
monkeypatch.setattr(subprocess, "check_output", _boom)
assert diar._probe_with_ffprobe("clip.wav") is None
# --------------------------------------------------------------------------- #
# get_media_duration
# --------------------------------------------------------------------------- #
def test_get_media_duration_prefers_the_python_binding(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""When the binding answers, ffprobe is never invoked."""
called: list[str] = []
def _record_ffprobe(_path: str) -> None:
called.append("ffprobe")
monkeypatch.setattr(diar, "_probe_with_ffmpeg_python", lambda _p: 10.0)
monkeypatch.setattr(diar, "_probe_with_ffprobe", _record_ffprobe)
assert diar.get_media_duration("clip.wav") == pytest.approx(10.0)
assert called == []
def test_get_media_duration_falls_back_to_ffprobe(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Without the binding, the CLI is tried next."""
monkeypatch.setattr(diar, "_probe_with_ffmpeg_python", lambda _p: None)
monkeypatch.setattr(diar, "_probe_with_ffprobe", lambda _p: 20.0)
assert diar.get_media_duration("clip.wav") == pytest.approx(20.0)
def test_get_media_duration_is_none_when_both_fail(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""An unprobeable file is not an error - the caller drops the percentage."""
monkeypatch.setattr(diar, "_probe_with_ffmpeg_python", lambda _p: None)
monkeypatch.setattr(diar, "_probe_with_ffprobe", lambda _p: None)