89 lines
2.7 KiB
Python
89 lines
2.7 KiB
Python
# tests/test_synthesizer.py
|
|
import json
|
|
import pytest
|
|
from pathlib import Path
|
|
from voice_gen.synthesizer import synthesize, _build_cmd
|
|
from voice_gen.errors import MmxError
|
|
|
|
|
|
def test_build_cmd_minimum():
|
|
cmd = _build_cmd(
|
|
text_file=Path("input.txt"),
|
|
voice_id=123,
|
|
out_path=Path("out.mp3"),
|
|
format="mp3",
|
|
)
|
|
assert cmd[:5] == ["mmx", "speech", "synthesize", "--non-interactive", "--quiet"]
|
|
assert "--text-file" in cmd and "input.txt" in cmd
|
|
assert "--text" not in cmd
|
|
assert "--voice" in cmd and "123" in cmd
|
|
assert "--out" in cmd and "out.mp3" in cmd
|
|
assert "--format" in cmd and "mp3" in cmd
|
|
|
|
|
|
def test_synthesize_invokes_mmx_and_returns_path(tmp_path):
|
|
captured = {}
|
|
|
|
def fake_run(cmd, **kwargs):
|
|
captured["cmd"] = cmd
|
|
captured["kwargs"] = kwargs
|
|
out = Path(cmd[cmd.index("--out") + 1])
|
|
out.parent.mkdir(parents=True, exist_ok=True)
|
|
out.write_bytes(b"fake-audio")
|
|
return type("R", (), {"returncode": 0, "stderr": ""})()
|
|
|
|
out = synthesize(
|
|
text="hello",
|
|
voice_id=999,
|
|
out_path=tmp_path / "x.mp3",
|
|
format="mp3",
|
|
run=fake_run,
|
|
)
|
|
assert out == tmp_path / "x.mp3"
|
|
assert out.exists()
|
|
assert captured["cmd"][2] == "synthesize"
|
|
assert "--voice" in captured["cmd"]
|
|
assert captured["cmd"][captured["cmd"].index("--voice") + 1] == "999"
|
|
|
|
|
|
def test_synthesize_passes_long_utf8_text_via_temporary_file(tmp_path):
|
|
text = ("这是一段用于验证 Windows 长命令行安全性的中文口播稿。\n" * 500)[:9000]
|
|
captured = {}
|
|
|
|
def fake_run(cmd, **kwargs):
|
|
captured["cmd"] = cmd
|
|
assert "--text" not in cmd
|
|
text_path = Path(cmd[cmd.index("--text-file") + 1])
|
|
captured["text_path"] = text_path
|
|
captured["text"] = text_path.read_text(encoding="utf-8")
|
|
out = Path(cmd[cmd.index("--out") + 1])
|
|
out.write_bytes(b"fake-audio")
|
|
return type("R", (), {"returncode": 0, "stderr": ""})()
|
|
|
|
out = synthesize(
|
|
text=text,
|
|
voice_id="test-voice",
|
|
out_path=tmp_path / "long.mp3",
|
|
run=fake_run,
|
|
)
|
|
|
|
assert out.exists()
|
|
assert captured["text"] == text
|
|
assert not captured["text_path"].exists()
|
|
|
|
|
|
def test_synthesize_raises_mmxerror_on_nonzero(tmp_path):
|
|
def fake_run(cmd, **kwargs):
|
|
return type("R", (), {"returncode": 3, "stderr": "auth failed"})()
|
|
|
|
with pytest.raises(MmxError) as exc:
|
|
synthesize(
|
|
text="x",
|
|
voice_id=1,
|
|
out_path=tmp_path / "x.mp3",
|
|
format="mp3",
|
|
run=fake_run,
|
|
)
|
|
assert exc.value.exit_code == 3
|
|
assert "auth failed" in str(exc.value)
|