from app.services import tts_text from app.services.tts_text import StableSentenceStream, normalize_for_speech def test_sentence_stream_waits_for_stable_boundary_across_tokens(): stream = StableSentenceStream() assert stream.feed("The first sen") == [] assert stream.feed("tence is ready. The second") == ["The first sentence is ready."] assert stream.finish() == ["The second"] def test_sentence_stream_does_not_emit_fenced_code_or_table_rows(): stream = StableSentenceStream() markdown = ( "Read this sentence.\n\n" "```python\nprint('Do not read me.')\n```\n\n" "| Model | Score |\n| --- | --- |\n| A | 1.0 |\n\n" "Read the final sentence." ) sentences = stream.feed(markdown) + stream.finish() assert sentences == ["Read this sentence.", "Read the final sentence."] def test_normalization_reads_prose_and_removes_markup_urls_and_citations(): text = ( "## Result\n" "See **the main finding** at https://example.com/a and [the appendix](https://example.com/b). " "It is grounded [Source: chunk 4] [12]." ) assert normalize_for_speech(text) == ( "Result See the main finding at and the appendix. It is grounded." ) def test_normalization_skips_tables_and_code_without_summarizing_them(): text = ( "Before.\n\n" "```python\nprint('hidden')\n```\n\n" "| A | B |\n| - | - |\n| 1 | 2 |\n\n" "- After." ) assert normalize_for_speech(text) == "Before. After." def test_synthesis_notation_verbalizes_numbers_percentages_and_scientific_symbols(): assert tts_text.normalize_synthesis_notation( "The value is 3.5%, the result is 42, x² + 2, and H₂O." ) == ( "The value is three point five percent, the result is forty-two, " "x squared plus two, and H two O." )