Zum Inhalt

tests/test_pipeline_core.py

"""Tests for pipeline_core shared helpers."""

from pathlib import Path


def test_match_line_detects_transcribe_phase(stdout_snippet):
    from pipeline_core import match_line

    lines = stdout_snippet("transcribe")
    events = [match_line(line, 0) for line in lines]
    assert any(e and e.step == 1 for e in events)
    schritt_event = next(e for e in events if e and "Transkription" in e.label)
    assert schritt_event.step == 1
    assert 0 < schritt_event.progress < 100


def test_match_line_extracts_render_progress(stdout_snippet):
    from pipeline_core import match_line

    lines = stdout_snippet("render")
    pct_events = [match_line(line, 3) for line in lines if "Rendering" in line and "%" in line]
    assert len(pct_events) >= 4
    progresses = [e.progress for e in pct_events if e]
    assert progresses == sorted(progresses)


def test_match_line_returns_none_for_unmatched():
    from pipeline_core import match_line

    assert match_line("random log line that means nothing", 0) is None


def test_build_command_minimal_config():
    from pipeline_core import PipelineConfig, build_command

    cfg = PipelineConfig(
        audio="/tmp/test.m4a",
        viz="dialogue",
        language="de",
        model="large-v3-turbo",
        diarize="auto",
        episode="EP 01",
        show_name="Signal",
        skip_transcribe=False,
        skip_meta=False,
        skip_render=False,
        skip_upload=False,
    )
    cmd = build_command(cfg, Path("/repo"))
    assert "pipeline.py" in cmd[1]
    assert cmd[2] == "/tmp/test.m4a"
    assert "--viz" in cmd and "dialogue" in cmd


def test_build_command_skip_flags():
    from pipeline_core import PipelineConfig, build_command

    cfg = PipelineConfig(
        audio="/tmp/test.m4a",
        viz="dialogue",
        language="de",
        model="large-v3-turbo",
        diarize="off",
        episode="EP 01",
        show_name="Signal",
        skip_transcribe=True,
        skip_meta=False,
        skip_render=False,
        skip_upload=True,
    )
    cmd = build_command(cfg, Path("/repo"))
    assert "--skip-transcribe" in cmd
    assert "--skip-upload" in cmd
    assert "--no-diarize" in cmd
    assert "--skip-meta" not in cmd


def test_resolve_audio_path_absolute():
    from pipeline_core import resolve_audio_path

    p = resolve_audio_path("/abs/path.m4a", Path("/some/fallback"))
    assert p == Path("/abs/path.m4a")


def test_resolve_audio_path_falls_back_to_pipeline_dir(tmp_path, monkeypatch):
    """When the cwd-relative path doesn't exist, resolve falls back to fallback_dir."""
    from pipeline_core import resolve_audio_path

    fallback = tmp_path / "fallback"
    fallback.mkdir()
    audio = fallback / "foo.m4a"
    audio.write_bytes(b"")
    monkeypatch.chdir(tmp_path / "elsewhere" if False else tmp_path)  # ensure cwd isn't fallback
    other_cwd = tmp_path / "other-cwd"
    other_cwd.mkdir()
    monkeypatch.chdir(other_cwd)
    p = resolve_audio_path("foo.m4a", fallback)
    assert p == audio


def test_match_line_render_pct_only_matches_rendering_lines():
    """A percent in an unrelated log line must not trigger render progress."""
    from pipeline_core import match_line

    # current_step==3 means we ARE in the render phase
    # but lines without 'Rendering' prefix should not be classified as render-progress
    assert match_line("Upload 50% complete", 3) is None
    assert match_line("Some 25% stat from elsewhere", 3) is None
    # genuine render line should still match
    evt = match_line("Rendering 42.0%", 3)
    assert evt is not None
    assert evt.step == 3


def test_resolve_audio_path_user_home(tmp_path, monkeypatch):
    from pipeline_core import resolve_audio_path

    monkeypatch.setenv("HOME", str(tmp_path))
    audio = tmp_path / "foo.m4a"
    audio.write_bytes(b"")
    p = resolve_audio_path("~/foo.m4a", Path("/some/fallback"))
    assert p == audio