from agr_assistent.tts.text import SpeechTextStream, normalize_for_speech, split_long_text def _feed_all(chunks: list[str]) -> list[str]: stream = SpeechTextStream() result = [] for chunk in chunks: result.extend(stream.feed(chunk)) return result + stream.flush() def test_sentences_are_emitted_as_soon_as_complete() -> None: stream = SpeechTextStream() assert stream.feed("Привет! Как ") == ["Привет!"] assert stream.feed("дела? Хоро") == ["Как дела?"] assert stream.flush() == ["Хоро"] def test_decimal_numbers_and_list_markers_do_not_split() -> None: assert _feed_all(["Будет 3.", "5 градуса.\n", "1. Первый пункт"]) == [ "Будет три целых пять десятых градуса.", "Первый пункт", ] def test_code_blocks_are_skipped() -> None: chunks = ["Пример:\n``", "`python\nprint('Привет')\n", "```\nГотово."] assert _feed_all(chunks) == ["Пример:", "Готово."] def test_normalize_removes_markdown_links_and_latin() -> None: text = "**Важно**: смотри [документацию](https://x.io) и https://y.io, Python тоже 😀" assert normalize_for_speech(text) == "Важно: смотри документацию и ссылка, тоже" def test_text_without_cyrillic_is_not_spoken() -> None: assert normalize_for_speech("Hello, world! 👋") == "" assert _feed_all(["Hello world.\n"]) == [] def test_long_text_is_split_on_commas_and_spaces() -> None: text = ", ".join(["слово"] * 100) parts = split_long_text(text, limit=50) assert all(len(part) <= 50 for part in parts) assert " ".join(parts).replace(" ,", ",") == text