Files
abogen/tests/test_voice_utils.py
Artem Akymenko f63590932d refactor: extract voice utils to domain/voice_utils.py
- Extract infer_provider_from_spec, supertonic_voice_from_spec, split_speaker_reference, formula_from_kokoro_entry, coerce_truthy to domain/voice_utils.py
- Add tests/test_voice_utils.py with 24 tests
- All tests match old behavior
2026-07-14 11:02:34 +00:00

118 lines
3.6 KiB
Python

"""Tests for domain/voice_utils.py."""
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from abogen.domain.voice_utils import (
infer_provider_from_spec,
supertonic_voice_from_spec,
split_speaker_reference,
formula_from_kokoro_entry,
coerce_truthy,
)
class TestInferProviderFromSpec:
def test_empty_returns_fallback(self):
assert infer_provider_from_spec("", "kokoro") == "kokoro"
def test_supertonic_uppercase(self):
assert infer_provider_from_spec("M1", "kokoro") == "supertonic"
def test_kokoro_voice(self):
assert infer_provider_from_spec("af_bella", "kokoro") == "kokoro"
def test_custom_mix(self):
assert infer_provider_from_spec("__custom_mix", "kokoro") == "kokoro"
def test_formula(self):
assert infer_provider_from_spec("af_bella*0.5+am_adam*0.5", "kokoro") == "kokoro"
class TestSupertonicVoiceFromSpec:
def test_normal(self):
assert supertonic_voice_from_spec("m1", "m2") == "M1"
def test_empty_uses_fallback(self):
assert supertonic_voice_from_spec("", "m2") == "M2"
def test_formula_uses_fallback(self):
assert supertonic_voice_from_spec("m1*0.5", "m2") == "M2"
def test_both_empty_uses_default(self):
assert supertonic_voice_from_spec("", "") == "M1"
class TestSplitSpeakerReference:
def test_speaker(self):
name, original = split_speaker_reference("speaker:John")
assert name == "John"
assert original == "speaker:John"
def test_profile(self):
name, original = split_speaker_reference("profile:Main")
assert name == "Main"
assert original == "profile:Main"
def test_invalid_prefix(self):
name, original = split_speaker_reference("voice:John")
assert name is None
assert original == "voice:John"
def test_no_colon(self):
name, original = split_speaker_reference("John")
assert name is None
assert original == "John"
def test_empty(self):
name, original = split_speaker_reference("")
assert name is None
assert original == ""
class TestFormulaFromKokoroEntry:
def test_normal(self):
entry = {"voices": [["af_bella", 0.5], ["am_adam", 0.5]]}
result = formula_from_kokoro_entry(entry)
assert "af_bella" in result
assert "am_adam" in result
def test_empty(self):
assert formula_from_kokoro_entry({}) == ""
def test_invalid_items(self):
entry = {"voices": [["af_bella", "invalid"], ["am_adam", 0.5]]}
result = formula_from_kokoro_entry(entry)
assert "am_adam" in result
assert "af_bella" not in result
class TestCoerceTruthy:
def test_bool_true(self):
assert coerce_truthy(True) is True
def test_bool_false(self):
assert coerce_truthy(False) is False
def test_string_true(self):
assert coerce_truthy("true") is True
assert coerce_truthy("yes") is True
assert coerce_truthy("1") is True
assert coerce_truthy("on") is True
def test_string_false(self):
assert coerce_truthy("false") is False
assert coerce_truthy("no") is False
assert coerce_truthy("0") is False
assert coerce_truthy("off") is False
assert coerce_truthy("") is False
def test_none_default_true(self):
assert coerce_truthy(None, True) is True
def test_none_default_false(self):
assert coerce_truthy(None, False) is False
def test_int(self):
assert coerce_truthy(1) is True
assert coerce_truthy(0) is False