OmniVoice-Studio / tests /test_translator.py
LΓͺ Phi Nam
Deploy to HF Space
94004a2
Raw
History Blame Contribute Delete
3.76 kB
"""Phase 1.1 / 2.7 β€” translator service.
Validates the glossary prompt-prefixing and the graceful "no LLM" path.
Does NOT hit a real LLM β€” the client is mocked.
"""
import os
os.environ.setdefault("OMNIVOICE_DISABLE_FILE_LOG", "1")
from unittest.mock import MagicMock, patch
import pytest
from services import translator as tr
# ── Glossary preamble ──────────────────────────────────────────────────────
def test_glossary_text_empty_inputs():
assert tr._glossary_text(None) == ""
assert tr._glossary_text([]) == ""
assert tr._glossary_text([{"source": "", "target": "y"}]) == ""
def test_glossary_text_includes_each_term():
out = tr._glossary_text([
{"source": "Marcus", "target": "Marcus", "note": "character name"},
{"source": "breakthrough", "target": "Durchbruch"},
])
assert "Marcus β†’ Marcus" in out
assert "breakthrough β†’ Durchbruch" in out
assert "character name" in out
# ── No-LLM graceful path ───────────────────────────────────────────────────
def test_cinematic_no_llm_returns_literal_with_marker(monkeypatch):
monkeypatch.setattr(tr, "_llm_client", lambda: None)
res = tr.cinematic_refine_sync(
"Hello.",
"Hola.",
source_lang="en",
target_lang="es",
)
# With no LLM, "text" falls back to literal and an error marker is present.
assert res["text"] == "Hola."
assert res["literal"] == "Hola."
assert res["critique"] == ""
assert res.get("error") == "no-llm"
def test_cinematic_empty_literal_is_passthrough():
res = tr.cinematic_refine_sync(
"Source",
"",
source_lang="en",
target_lang="es",
)
assert res["text"] == ""
assert res["literal"] == ""
# No error when there's literally nothing to refine.
assert "error" not in res
# ── Happy-path 3-step chain (mocked client) ────────────────────────────────
def test_cinematic_full_chain_with_mocked_llm(monkeypatch):
calls = []
responses = iter([
"reads stiff; prefer idiomatic phrasing", # reflect
"Hola, mundo.", # adapt
])
def fake_chat(client, *, system, user):
calls.append({"system": system, "user": user})
return next(responses)
mock_client = MagicMock()
monkeypatch.setattr(tr, "_llm_client", lambda: mock_client)
monkeypatch.setattr(tr, "_chat", fake_chat)
res = tr.cinematic_refine_sync(
"Hello, world.",
"Hola mundo.",
source_lang="en",
target_lang="es",
glossary=[{"source": "world", "target": "mundo"}],
)
assert res["literal"] == "Hola mundo."
assert res["text"] == "Hola, mundo."
assert res["critique"] == "reads stiff; prefer idiomatic phrasing"
assert len(calls) == 2
# Glossary prepended to both system prompts (reflect + adapt).
assert "world β†’ mundo" in calls[0]["system"]
assert "world β†’ mundo" in calls[1]["system"]
def test_cinematic_reflect_failure_returns_literal(monkeypatch):
mock_client = MagicMock()
monkeypatch.setattr(tr, "_llm_client", lambda: mock_client)
def boom(*a, **kw):
raise RuntimeError("LLM down")
monkeypatch.setattr(tr, "_chat", boom)
res = tr.cinematic_refine_sync(
"Hello",
"Hola",
source_lang="en",
target_lang="es",
)
assert res["text"] == "Hola"
assert res["literal"] == "Hola"
assert "reflect" in res.get("error", "")