from app.segmentation import Segment from app.ssml import ( PAUSE_DELIM, build_ssml, build_ssml_chunks, explicit_pause_char, strip_sentinels, ) def seg(text, lang="ru", para=0): return Segment(text=text, lang=lang, para=para) # --- 2.1 структура /

/ и --- def test_single_segment_structure(): out = build_ssml([seg("Привет мир")]) assert out == "

Привет мир

" def test_empty_returns_empty(): assert build_ssml([]) == "" def test_paragraph_grouping_nesting(): out = build_ssml([seg("а", para=0), seg("б", para=0), seg("в", para=1)]) assert out.count("

") == 2 assert out.count("") == 3 assert "

аб

" in out def test_no_prosody_by_default(): out = build_ssml([seg("привет")]) assert "' in out assert out.endswith("") def test_prosody_medium_omitted(): out = build_ssml([seg("а")], rate="medium", pitch="medium") assert " , вырезание PUA --- def test_sentinel_becomes_single_break(): out = build_ssml([seg(f"а{PAUSE_DELIM}б")]) assert out.count(" d")]) assert "&" in out and "<" in out and ">" in out assert "" not in out # --- 2.4 разбиение по абзацам/лимиту --- def test_chunking_splits_into_valid_documents(): segs = [seg("предложение номер " + str(i) + " достаточно длинное") for i in range(20)] chunks = build_ssml_chunks(segs, max_chars=200) assert len(chunks) >= 2 for c in chunks: assert c.startswith("") and c.endswith("") # ни одно предложение не потеряно и не разорвано assert sum(c.count("") for c in chunks) == len(segs) def test_chunking_respects_max_chars(): segs = [seg("с" * 60) for _ in range(10)] chunks = build_ssml_chunks(segs, max_chars=200) assert len(chunks) > 1 for c in chunks: assert c.count("") >= 1 def test_paragraphs_never_split_mid_segment(): segs = [seg("маленький абзац", para=0), seg("другой абзац", para=1)] chunks = build_ssml_chunks(segs, max_chars=5000) assert len(chunks) == 1 assert "

маленький абзац

" in chunks[0] assert "

другой абзац

" in chunks[0] def test_chunking_applies_prosody_to_each_document(): segs = [seg("текст " * 30) for _ in range(10)] chunks = build_ssml_chunks(segs, rate="fast", max_chars=200) assert len(chunks) >= 2 for c in chunks: assert 'rate="fast"' in c # --- strip_sentinels (для webui-отображения) --- def test_strip_sentinels_removes_all_and_collapses_spaces(): raw = f"он {PAUSE_DELIM} сказал {explicit_pause_char(500)} слово" clean = strip_sentinels(raw) assert PAUSE_DELIM not in clean assert explicit_pause_char(500) not in clean assert " " not in clean