From 1268a83cff05e2ea21a26316a4101a11bad10128 Mon Sep 17 00:00:00 2001 From: Artem Akymenko Date: Thu, 16 Jul 2026 06:57:12 +0000 Subject: [PATCH] fix(webui): voice.py imports from domain modules instead of conversion_runner Replace private imports (_select_device, _to_float32, SAMPLE_RATE, SPLIT_PATTERN) from abogen.webui.conversion_runner with proper domain imports: - select_device from abogen.domain.device - to_float32, SAMPLE_RATE from abogen.domain.audio_helpers - SPLIT_PATTERN defined locally (r'\n+') Also verifies preview.py already uses domain imports correctly. 7 new tests in tests/test_domain_imports.py enforce the architecture rule. --- abogen/webui/routes/utils/voice.py | 5 ++- tests/test_domain_imports.py | 72 ++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 tests/test_domain_imports.py diff --git a/abogen/webui/routes/utils/voice.py b/abogen/webui/routes/utils/voice.py index 80c8960..3433369 100644 --- a/abogen/webui/routes/utils/voice.py +++ b/abogen/webui/routes/utils/voice.py @@ -21,7 +21,10 @@ from abogen.constants import ( from abogen.tts_plugin.utils import get_voices from abogen.speaker_configs import list_configs from abogen.tts_plugin.utils import create_pipeline -from abogen.webui.conversion_runner import _select_device, _to_float32, SAMPLE_RATE, SPLIT_PATTERN +from abogen.domain.device import select_device as _select_device +from abogen.domain.audio_helpers import to_float32 as _to_float32, SAMPLE_RATE + +SPLIT_PATTERN = r"\n+" _preview_pipeline_lock = threading.RLock() _preview_pipelines: Dict[Tuple[str, str], Any] = {} diff --git a/tests/test_domain_imports.py b/tests/test_domain_imports.py new file mode 100644 index 0000000..7cd39dd --- /dev/null +++ b/tests/test_domain_imports.py @@ -0,0 +1,72 @@ +"""Tests that voice.py imports from domain modules, not from conversion_runner.""" +import pathlib + + +def _read_source(module_file: str) -> str: + return pathlib.Path(module_file).read_text(encoding="utf-8") + + +def test_voice_module_does_not_import_conversion_runner(): + """voice.py must not import from conversion_runner (architecture rule).""" + import abogen.webui.routes.utils.voice as voice_mod + + source_text = _read_source(voice_mod.__file__) + + assert "from abogen.webui.conversion_runner import" not in source_text, ( + "voice.py still imports from conversion_runner — must use domain modules" + ) + + +def test_voice_module_imports_select_device_from_domain(): + """voice.py must import select_device from abogen.domain.device.""" + import abogen.webui.routes.utils.voice as voice_mod + + with open(voice_mod.__file__, "r", encoding="utf-8") as fh: + source_text = fh.read() + + assert "from abogen.domain.device import" in source_text + + +def test_voice_module_imports_to_float32_from_domain(): + """voice.py must import to_float32 from abogen.domain.audio_helpers.""" + import abogen.webui.routes.utils.voice as voice_mod + + with open(voice_mod.__file__, "r", encoding="utf-8") as fh: + source_text = fh.read() + + assert "from abogen.domain.audio_helpers import" in source_text + + +def test_voice_module_has_sample_rate(): + """voice.py must define SAMPLE_RATE = 24000.""" + from abogen.webui.routes.utils.voice import SAMPLE_RATE + + assert SAMPLE_RATE == 24000 + + +def test_voice_module_has_split_pattern(): + """voice.py must define SPLIT_PATTERN.""" + from abogen.webui.routes.utils.voice import SPLIT_PATTERN + + assert isinstance(SPLIT_PATTERN, str) + assert len(SPLIT_PATTERN) > 0 + + +def test_preview_module_does_not_import_conversion_runner(): + """preview.py must not import from conversion_runner.""" + import abogen.webui.routes.utils.preview as preview_mod + + with open(preview_mod.__file__, "r", encoding="utf-8") as fh: + source_text = fh.read() + + assert "from abogen.webui.conversion_runner import" not in source_text + + +def test_preview_module_imports_select_device_from_domain(): + """preview.py must import select_device from abogen.domain.device.""" + import abogen.webui.routes.utils.preview as preview_mod + + with open(preview_mod.__file__, "r", encoding="utf-8") as fh: + source_text = fh.read() + + assert "from abogen.domain.device import" in source_text